blob: a1b1ba3dac234ba20db50a166f351afb5423ceec [file] [log] [blame]
Jason Sams0011bcf2009-12-15 12:58:36 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.renderscript;
18
19
Alex Sakhartchouka41174e2010-08-27 16:10:55 -070020import java.io.IOException;
21import java.io.InputStream;
22import java.io.UnsupportedEncodingException;
23
24import android.content.res.Resources;
Jason Sams0011bcf2009-12-15 12:58:36 -080025import android.util.Log;
26
27
28/**
Jason Sams0011bcf2009-12-15 12:58:36 -080029 *
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080030 * Program is a base class for all the objects that modify
31 * various stages of the graphics pipeline
32 *
Jason Sams0011bcf2009-12-15 12:58:36 -080033 **/
34public class Program extends BaseObj {
Alex Sakhartchouk0473ff12011-01-14 11:27:27 -080035 static final int MAX_INPUT = 8;
36 static final int MAX_OUTPUT = 8;
37 static final int MAX_CONSTANT = 8;
38 static final int MAX_TEXTURE = 8;
Jason Sams0011bcf2009-12-15 12:58:36 -080039
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080040 /**
41 *
42 * TextureType specifies what textures are attached to Program
43 * objects
44 *
45 **/
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -080046 public enum TextureType {
47 TEXTURE_2D (0),
48 TEXTURE_CUBE (1);
49
50 int mID;
51 TextureType(int id) {
52 mID = id;
53 }
54 }
55
56 enum ProgramParam {
57 INPUT (0),
58 OUTPUT (1),
59 CONSTANT (2),
60 TEXTURE_TYPE (3);
61
62 int mID;
63 ProgramParam(int id) {
64 mID = id;
65 }
66 };
67
Jason Sams0011bcf2009-12-15 12:58:36 -080068 Element mInputs[];
69 Element mOutputs[];
70 Type mConstants[];
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -080071 TextureType mTextures[];
Jason Sams7e5ab3b2009-12-15 13:27:04 -080072 int mTextureCount;
Jason Sams0011bcf2009-12-15 12:58:36 -080073 String mShader;
74
75 Program(int id, RenderScript rs) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -070076 super(id, rs);
Jason Sams0011bcf2009-12-15 12:58:36 -080077 }
78
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080079 /**
80 * Binds a constant buffer to be used as uniform inputs to the
81 * program
82 *
83 * @param a allocation containing uniform data
84 * @param slot index within the program's list of constant
85 * buffer allocations
86 */
Jason Sams0011bcf2009-12-15 12:58:36 -080087 public void bindConstants(Allocation a, int slot) {
Jason Samsc1d62102010-11-04 14:32:19 -070088 if (slot < 0 || slot >= mConstants.length) {
89 throw new IllegalArgumentException("Slot ID out of range.");
90 }
91 if (a != null &&
92 a.getType().getID() != mConstants[slot].getID()) {
93 throw new IllegalArgumentException("Allocation type does not match slot type.");
94 }
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -080095 int id = a != null ? a.getID() : 0;
96 mRS.nProgramBindConstants(getID(), slot, id);
Jason Sams0011bcf2009-12-15 12:58:36 -080097 }
98
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080099 /**
100 * Binds a texture to be used in the program
101 *
102 * @param va allocation containing texture data
103 * @param slot index within the program's list of textures
104 *
105 */
Jason Sams68afd012009-12-17 16:55:08 -0800106 public void bindTexture(Allocation va, int slot)
107 throws IllegalArgumentException {
108 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800109 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800110 throw new IllegalArgumentException("Slot ID out of range.");
111 }
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800112 if (va != null && va.getType().hasFaces() &&
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800113 mTextures[slot] != TextureType.TEXTURE_CUBE) {
114 throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
115 }
Jason Sams68afd012009-12-17 16:55:08 -0800116
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800117 int id = va != null ? va.getID() : 0;
118 mRS.nProgramBindTexture(getID(), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800119 }
120
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800121 /**
122 * Binds an object that describes how a texture at the
123 * corresponding location is sampled
124 *
125 * @param vs sampler for a corresponding texture
126 * @param slot index within the program's list of textures to
127 * use the sampler on
128 *
129 */
Jason Sams68afd012009-12-17 16:55:08 -0800130 public void bindSampler(Sampler vs, int slot)
131 throws IllegalArgumentException {
132 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800133 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800134 throw new IllegalArgumentException("Slot ID out of range.");
135 }
136
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800137 int id = vs != null ? vs.getID() : 0;
138 mRS.nProgramBindSampler(getID(), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800139 }
140
141
Jason Sams0011bcf2009-12-15 12:58:36 -0800142 public static class BaseProgramBuilder {
143 RenderScript mRS;
144 Element mInputs[];
145 Element mOutputs[];
146 Type mConstants[];
147 Type mTextures[];
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800148 TextureType mTextureTypes[];
Jason Sams0011bcf2009-12-15 12:58:36 -0800149 int mInputCount;
150 int mOutputCount;
151 int mConstantCount;
152 int mTextureCount;
153 String mShader;
154
155
156 protected BaseProgramBuilder(RenderScript rs) {
157 mRS = rs;
158 mInputs = new Element[MAX_INPUT];
159 mOutputs = new Element[MAX_OUTPUT];
160 mConstants = new Type[MAX_CONSTANT];
161 mInputCount = 0;
162 mOutputCount = 0;
163 mConstantCount = 0;
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800164 mTextureCount = 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800165 mTextureTypes = new TextureType[MAX_TEXTURE];
Jason Sams0011bcf2009-12-15 12:58:36 -0800166 }
167
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800168 /**
169 * Sets the GLSL shader code to be used in the program
170 *
171 * @param s GLSL shader string
172 * @return self
173 */
Jim Shuma288c8712010-07-07 14:24:21 -0700174 public BaseProgramBuilder setShader(String s) {
Jason Sams0011bcf2009-12-15 12:58:36 -0800175 mShader = s;
Jim Shuma288c8712010-07-07 14:24:21 -0700176 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800177 }
178
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800179 /**
180 * Sets the GLSL shader code to be used in the program
181 *
182 * @param resources application resources
183 * @param resourceID id of the file containing GLSL shader code
184 *
185 * @return self
186 */
Alex Sakhartchouka41174e2010-08-27 16:10:55 -0700187 public BaseProgramBuilder setShader(Resources resources, int resourceID) {
188 byte[] str;
189 int strLength;
190 InputStream is = resources.openRawResource(resourceID);
191 try {
192 try {
193 str = new byte[1024];
194 strLength = 0;
195 while(true) {
196 int bytesLeft = str.length - strLength;
197 if (bytesLeft == 0) {
198 byte[] buf2 = new byte[str.length * 2];
199 System.arraycopy(str, 0, buf2, 0, str.length);
200 str = buf2;
201 bytesLeft = str.length - strLength;
202 }
203 int bytesRead = is.read(str, strLength, bytesLeft);
204 if (bytesRead <= 0) {
205 break;
206 }
207 strLength += bytesRead;
208 }
209 } finally {
210 is.close();
211 }
212 } catch(IOException e) {
213 throw new Resources.NotFoundException();
214 }
215
216 try {
217 mShader = new String(str, 0, strLength, "UTF-8");
218 } catch (UnsupportedEncodingException e) {
219 Log.e("Renderscript shader creation", "Could not decode shader string");
220 }
221
222 return this;
223 }
224
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800225 /**
226 * Queries the index of the last added constant buffer type
227 *
228 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800229 public int getCurrentConstantIndex() {
230 return mConstantCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800231 }
232
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800233 /**
234 * Queries the index of the last added texture type
235 *
236 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800237 public int getCurrentTextureIndex() {
238 return mTextureCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800239 }
240
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800241 /**
242 * Adds constant (uniform) inputs to the program
243 *
244 * @param t Type that describes the layout of the Allocation
245 * object to be used as constant inputs to the Program
246 * @return self
247 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800248 public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
Jason Sams0011bcf2009-12-15 12:58:36 -0800249 // Should check for consistant and non-conflicting names...
250 if(mConstantCount >= MAX_CONSTANT) {
Jason Samsc1d62102010-11-04 14:32:19 -0700251 throw new RSIllegalArgumentException("Max input count exceeded.");
252 }
253 if (t.getElement().isComplex()) {
254 throw new RSIllegalArgumentException("Complex elements not allowed.");
Jason Sams0011bcf2009-12-15 12:58:36 -0800255 }
Jason Samsea87e962010-01-12 12:12:28 -0800256 mConstants[mConstantCount] = t;
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800257 mConstantCount++;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800258 return this;
259 }
260
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800261 /**
262 * Adds a texture input to the Program
263 *
264 * @param texType describes that the texture to append it (2D,
265 * Cubemap, etc.)
266 * @return self
267 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800268 public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
269 if(mTextureCount >= MAX_TEXTURE) {
270 throw new IllegalArgumentException("Max texture count exceeded.");
271 }
272 mTextureTypes[mTextureCount ++] = texType;
Jim Shuma288c8712010-07-07 14:24:21 -0700273 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800274 }
275
276 protected void initProgram(Program p) {
277 p.mInputs = new Element[mInputCount];
278 System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
279 p.mOutputs = new Element[mOutputCount];
280 System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
281 p.mConstants = new Type[mConstantCount];
282 System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800283 p.mTextureCount = mTextureCount;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800284 p.mTextures = new TextureType[mTextureCount];
285 System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
Jason Sams0011bcf2009-12-15 12:58:36 -0800286 }
287 }
288
289}
290
291