blob: d9f64c62a40fd42e2f41380944adf6ecf1dd331f [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
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070028/**
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
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070040 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080041 *
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[];
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080072 String mTextureNames[];
Jason Sams7e5ab3b2009-12-15 13:27:04 -080073 int mTextureCount;
Jason Sams0011bcf2009-12-15 12:58:36 -080074 String mShader;
75
76 Program(int id, RenderScript rs) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -070077 super(id, rs);
Jason Sams0011bcf2009-12-15 12:58:36 -080078 }
79
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070080 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -070081 * Program object can have zero or more constant allocations
82 * associated with it. This method returns the total count.
83 * @return number of constant input types
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -080084 */
85 public int getConstantCount() {
86 return mConstants != null ? mConstants.length : 0;
87 }
88
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070089 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -070090 * Returns the type of the constant buffer used in the program
91 * object. It could be used to query internal elements or create
92 * an allocation to store constant data.
93 * @param slot index of the constant input type to return
94 * @return constant input type
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -080095 */
96 public Type getConstant(int slot) {
97 if (slot < 0 || slot >= mConstants.length) {
98 throw new IllegalArgumentException("Slot ID out of range.");
99 }
100 return mConstants[slot];
101 }
102
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700103 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700104 * Returns the number of textures used in this program object
105 * @return number of texture inputs
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -0800106 */
107 public int getTextureCount() {
108 return mTextureCount;
109 }
110
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700111 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700112 * Returns the type of texture at a given slot. e.g. 2D or Cube
113 * @param slot index of the texture input
114 * @return texture input type
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -0800115 */
116 public TextureType getTextureType(int slot) {
117 if ((slot < 0) || (slot >= mTextureCount)) {
118 throw new IllegalArgumentException("Slot ID out of range.");
119 }
120 return mTextures[slot];
121 }
122
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700123 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700124 * Returns the name of the texture input at a given slot. e.g.
125 * tex0, diffuse, spec
126 * @param slot index of the texture input
127 * @return texture input name
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800128 */
129 public String getTextureName(int slot) {
130 if ((slot < 0) || (slot >= mTextureCount)) {
131 throw new IllegalArgumentException("Slot ID out of range.");
132 }
133 return mTextureNames[slot];
134 }
135
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700136 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800137 * Binds a constant buffer to be used as uniform inputs to the
138 * program
139 *
140 * @param a allocation containing uniform data
141 * @param slot index within the program's list of constant
142 * buffer allocations
143 */
Jason Sams0011bcf2009-12-15 12:58:36 -0800144 public void bindConstants(Allocation a, int slot) {
Jason Samsc1d62102010-11-04 14:32:19 -0700145 if (slot < 0 || slot >= mConstants.length) {
146 throw new IllegalArgumentException("Slot ID out of range.");
147 }
148 if (a != null &&
Jason Samse07694b2012-04-03 15:36:36 -0700149 a.getType().getID(mRS) != mConstants[slot].getID(mRS)) {
Jason Samsc1d62102010-11-04 14:32:19 -0700150 throw new IllegalArgumentException("Allocation type does not match slot type.");
151 }
Jason Samse07694b2012-04-03 15:36:36 -0700152 int id = a != null ? a.getID(mRS) : 0;
153 mRS.nProgramBindConstants(getID(mRS), slot, id);
Jason Sams0011bcf2009-12-15 12:58:36 -0800154 }
155
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700156 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800157 * Binds a texture to be used in the program
158 *
159 * @param va allocation containing texture data
160 * @param slot index within the program's list of textures
161 *
162 */
Jason Sams68afd012009-12-17 16:55:08 -0800163 public void bindTexture(Allocation va, int slot)
164 throws IllegalArgumentException {
165 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800166 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800167 throw new IllegalArgumentException("Slot ID out of range.");
168 }
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800169 if (va != null && va.getType().hasFaces() &&
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800170 mTextures[slot] != TextureType.TEXTURE_CUBE) {
171 throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
172 }
Jason Sams68afd012009-12-17 16:55:08 -0800173
Jason Samse07694b2012-04-03 15:36:36 -0700174 int id = va != null ? va.getID(mRS) : 0;
175 mRS.nProgramBindTexture(getID(mRS), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800176 }
177
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700178 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800179 * Binds an object that describes how a texture at the
180 * corresponding location is sampled
181 *
182 * @param vs sampler for a corresponding texture
183 * @param slot index within the program's list of textures to
184 * use the sampler on
185 *
186 */
Jason Sams68afd012009-12-17 16:55:08 -0800187 public void bindSampler(Sampler vs, int slot)
188 throws IllegalArgumentException {
189 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800190 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800191 throw new IllegalArgumentException("Slot ID out of range.");
192 }
193
Jason Samse07694b2012-04-03 15:36:36 -0700194 int id = vs != null ? vs.getID(mRS) : 0;
195 mRS.nProgramBindSampler(getID(mRS), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800196 }
197
198
Jason Sams0011bcf2009-12-15 12:58:36 -0800199 public static class BaseProgramBuilder {
200 RenderScript mRS;
201 Element mInputs[];
202 Element mOutputs[];
203 Type mConstants[];
204 Type mTextures[];
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800205 TextureType mTextureTypes[];
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800206 String mTextureNames[];
Jason Sams0011bcf2009-12-15 12:58:36 -0800207 int mInputCount;
208 int mOutputCount;
209 int mConstantCount;
210 int mTextureCount;
211 String mShader;
212
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700213
Jason Sams0011bcf2009-12-15 12:58:36 -0800214 protected BaseProgramBuilder(RenderScript rs) {
215 mRS = rs;
216 mInputs = new Element[MAX_INPUT];
217 mOutputs = new Element[MAX_OUTPUT];
218 mConstants = new Type[MAX_CONSTANT];
219 mInputCount = 0;
220 mOutputCount = 0;
221 mConstantCount = 0;
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800222 mTextureCount = 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800223 mTextureTypes = new TextureType[MAX_TEXTURE];
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800224 mTextureNames = new String[MAX_TEXTURE];
Jason Sams0011bcf2009-12-15 12:58:36 -0800225 }
226
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700227 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800228 * Sets the GLSL shader code to be used in the program
229 *
230 * @param s GLSL shader string
231 * @return self
232 */
Jim Shuma288c8712010-07-07 14:24:21 -0700233 public BaseProgramBuilder setShader(String s) {
Jason Sams0011bcf2009-12-15 12:58:36 -0800234 mShader = s;
Jim Shuma288c8712010-07-07 14:24:21 -0700235 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800236 }
237
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700238 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800239 * Sets the GLSL shader code to be used in the program
240 *
241 * @param resources application resources
242 * @param resourceID id of the file containing GLSL shader code
243 *
244 * @return self
245 */
Alex Sakhartchouka41174e2010-08-27 16:10:55 -0700246 public BaseProgramBuilder setShader(Resources resources, int resourceID) {
247 byte[] str;
248 int strLength;
249 InputStream is = resources.openRawResource(resourceID);
250 try {
251 try {
252 str = new byte[1024];
253 strLength = 0;
254 while(true) {
255 int bytesLeft = str.length - strLength;
256 if (bytesLeft == 0) {
257 byte[] buf2 = new byte[str.length * 2];
258 System.arraycopy(str, 0, buf2, 0, str.length);
259 str = buf2;
260 bytesLeft = str.length - strLength;
261 }
262 int bytesRead = is.read(str, strLength, bytesLeft);
263 if (bytesRead <= 0) {
264 break;
265 }
266 strLength += bytesRead;
267 }
268 } finally {
269 is.close();
270 }
271 } catch(IOException e) {
272 throw new Resources.NotFoundException();
273 }
274
275 try {
276 mShader = new String(str, 0, strLength, "UTF-8");
277 } catch (UnsupportedEncodingException e) {
278 Log.e("Renderscript shader creation", "Could not decode shader string");
279 }
280
281 return this;
282 }
283
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700284 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800285 * Queries the index of the last added constant buffer type
286 *
287 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800288 public int getCurrentConstantIndex() {
289 return mConstantCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800290 }
291
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700292 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800293 * Queries the index of the last added texture type
294 *
295 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800296 public int getCurrentTextureIndex() {
297 return mTextureCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800298 }
299
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700300 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800301 * Adds constant (uniform) inputs to the program
302 *
303 * @param t Type that describes the layout of the Allocation
304 * object to be used as constant inputs to the Program
305 * @return self
306 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800307 public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
Jason Sams0011bcf2009-12-15 12:58:36 -0800308 // Should check for consistant and non-conflicting names...
309 if(mConstantCount >= MAX_CONSTANT) {
Jason Samsc1d62102010-11-04 14:32:19 -0700310 throw new RSIllegalArgumentException("Max input count exceeded.");
311 }
312 if (t.getElement().isComplex()) {
313 throw new RSIllegalArgumentException("Complex elements not allowed.");
Jason Sams0011bcf2009-12-15 12:58:36 -0800314 }
Jason Samsea87e962010-01-12 12:12:28 -0800315 mConstants[mConstantCount] = t;
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800316 mConstantCount++;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800317 return this;
318 }
319
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700320 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800321 * Adds a texture input to the Program
322 *
323 * @param texType describes that the texture to append it (2D,
324 * Cubemap, etc.)
325 * @return self
326 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800327 public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800328 addTexture(texType, "Tex" + mTextureCount);
329 return this;
330 }
331
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700332 /**
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800333 * Adds a texture input to the Program
334 *
335 * @param texType describes that the texture to append it (2D,
336 * Cubemap, etc.)
337 * @param texName what the texture should be called in the
338 * shader
339 * @return self
340 */
341 public BaseProgramBuilder addTexture(TextureType texType, String texName)
342 throws IllegalArgumentException {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800343 if(mTextureCount >= MAX_TEXTURE) {
344 throw new IllegalArgumentException("Max texture count exceeded.");
345 }
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800346 mTextureTypes[mTextureCount] = texType;
347 mTextureNames[mTextureCount] = texName;
348 mTextureCount ++;
Jim Shuma288c8712010-07-07 14:24:21 -0700349 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800350 }
351
352 protected void initProgram(Program p) {
353 p.mInputs = new Element[mInputCount];
354 System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
355 p.mOutputs = new Element[mOutputCount];
356 System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
357 p.mConstants = new Type[mConstantCount];
358 System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800359 p.mTextureCount = mTextureCount;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800360 p.mTextures = new TextureType[mTextureCount];
361 System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800362 p.mTextureNames = new String[mTextureCount];
363 System.arraycopy(mTextureNames, 0, p.mTextureNames, 0, mTextureCount);
Jason Sams0011bcf2009-12-15 12:58:36 -0800364 }
365 }
366
367}
368
369