blob: 104d1cd9b40771d9cea28e6a9a402d7a688a0aab [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[];
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
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080080 /**
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -080081 * @hide
82 */
83 public int getConstantCount() {
84 return mConstants != null ? mConstants.length : 0;
85 }
86
87 /**
88 * @hide
89 */
90 public Type getConstant(int slot) {
91 if (slot < 0 || slot >= mConstants.length) {
92 throw new IllegalArgumentException("Slot ID out of range.");
93 }
94 return mConstants[slot];
95 }
96
97 /**
98 * @hide
99 */
100 public int getTextureCount() {
101 return mTextureCount;
102 }
103
104 /**
105 * @hide
106 */
107 public TextureType getTextureType(int slot) {
108 if ((slot < 0) || (slot >= mTextureCount)) {
109 throw new IllegalArgumentException("Slot ID out of range.");
110 }
111 return mTextures[slot];
112 }
113
114 /**
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800115 * @hide
116 */
117 public String getTextureName(int slot) {
118 if ((slot < 0) || (slot >= mTextureCount)) {
119 throw new IllegalArgumentException("Slot ID out of range.");
120 }
121 return mTextureNames[slot];
122 }
123
124 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800125 * Binds a constant buffer to be used as uniform inputs to the
126 * program
127 *
128 * @param a allocation containing uniform data
129 * @param slot index within the program's list of constant
130 * buffer allocations
131 */
Jason Sams0011bcf2009-12-15 12:58:36 -0800132 public void bindConstants(Allocation a, int slot) {
Jason Samsc1d62102010-11-04 14:32:19 -0700133 if (slot < 0 || slot >= mConstants.length) {
134 throw new IllegalArgumentException("Slot ID out of range.");
135 }
136 if (a != null &&
Jason Samse07694b2012-04-03 15:36:36 -0700137 a.getType().getID(mRS) != mConstants[slot].getID(mRS)) {
Jason Samsc1d62102010-11-04 14:32:19 -0700138 throw new IllegalArgumentException("Allocation type does not match slot type.");
139 }
Jason Samse07694b2012-04-03 15:36:36 -0700140 int id = a != null ? a.getID(mRS) : 0;
141 mRS.nProgramBindConstants(getID(mRS), slot, id);
Jason Sams0011bcf2009-12-15 12:58:36 -0800142 }
143
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800144 /**
145 * Binds a texture to be used in the program
146 *
147 * @param va allocation containing texture data
148 * @param slot index within the program's list of textures
149 *
150 */
Jason Sams68afd012009-12-17 16:55:08 -0800151 public void bindTexture(Allocation va, int slot)
152 throws IllegalArgumentException {
153 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800154 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800155 throw new IllegalArgumentException("Slot ID out of range.");
156 }
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800157 if (va != null && va.getType().hasFaces() &&
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800158 mTextures[slot] != TextureType.TEXTURE_CUBE) {
159 throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
160 }
Jason Sams68afd012009-12-17 16:55:08 -0800161
Jason Samse07694b2012-04-03 15:36:36 -0700162 int id = va != null ? va.getID(mRS) : 0;
163 mRS.nProgramBindTexture(getID(mRS), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800164 }
165
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800166 /**
167 * Binds an object that describes how a texture at the
168 * corresponding location is sampled
169 *
170 * @param vs sampler for a corresponding texture
171 * @param slot index within the program's list of textures to
172 * use the sampler on
173 *
174 */
Jason Sams68afd012009-12-17 16:55:08 -0800175 public void bindSampler(Sampler vs, int slot)
176 throws IllegalArgumentException {
177 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800178 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800179 throw new IllegalArgumentException("Slot ID out of range.");
180 }
181
Jason Samse07694b2012-04-03 15:36:36 -0700182 int id = vs != null ? vs.getID(mRS) : 0;
183 mRS.nProgramBindSampler(getID(mRS), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800184 }
185
186
Jason Sams0011bcf2009-12-15 12:58:36 -0800187 public static class BaseProgramBuilder {
188 RenderScript mRS;
189 Element mInputs[];
190 Element mOutputs[];
191 Type mConstants[];
192 Type mTextures[];
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800193 TextureType mTextureTypes[];
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800194 String mTextureNames[];
Jason Sams0011bcf2009-12-15 12:58:36 -0800195 int mInputCount;
196 int mOutputCount;
197 int mConstantCount;
198 int mTextureCount;
199 String mShader;
200
201
202 protected BaseProgramBuilder(RenderScript rs) {
203 mRS = rs;
204 mInputs = new Element[MAX_INPUT];
205 mOutputs = new Element[MAX_OUTPUT];
206 mConstants = new Type[MAX_CONSTANT];
207 mInputCount = 0;
208 mOutputCount = 0;
209 mConstantCount = 0;
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800210 mTextureCount = 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800211 mTextureTypes = new TextureType[MAX_TEXTURE];
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800212 mTextureNames = new String[MAX_TEXTURE];
Jason Sams0011bcf2009-12-15 12:58:36 -0800213 }
214
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800215 /**
216 * Sets the GLSL shader code to be used in the program
217 *
218 * @param s GLSL shader string
219 * @return self
220 */
Jim Shuma288c8712010-07-07 14:24:21 -0700221 public BaseProgramBuilder setShader(String s) {
Jason Sams0011bcf2009-12-15 12:58:36 -0800222 mShader = s;
Jim Shuma288c8712010-07-07 14:24:21 -0700223 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800224 }
225
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800226 /**
227 * Sets the GLSL shader code to be used in the program
228 *
229 * @param resources application resources
230 * @param resourceID id of the file containing GLSL shader code
231 *
232 * @return self
233 */
Alex Sakhartchouka41174e2010-08-27 16:10:55 -0700234 public BaseProgramBuilder setShader(Resources resources, int resourceID) {
235 byte[] str;
236 int strLength;
237 InputStream is = resources.openRawResource(resourceID);
238 try {
239 try {
240 str = new byte[1024];
241 strLength = 0;
242 while(true) {
243 int bytesLeft = str.length - strLength;
244 if (bytesLeft == 0) {
245 byte[] buf2 = new byte[str.length * 2];
246 System.arraycopy(str, 0, buf2, 0, str.length);
247 str = buf2;
248 bytesLeft = str.length - strLength;
249 }
250 int bytesRead = is.read(str, strLength, bytesLeft);
251 if (bytesRead <= 0) {
252 break;
253 }
254 strLength += bytesRead;
255 }
256 } finally {
257 is.close();
258 }
259 } catch(IOException e) {
260 throw new Resources.NotFoundException();
261 }
262
263 try {
264 mShader = new String(str, 0, strLength, "UTF-8");
265 } catch (UnsupportedEncodingException e) {
266 Log.e("Renderscript shader creation", "Could not decode shader string");
267 }
268
269 return this;
270 }
271
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800272 /**
273 * Queries the index of the last added constant buffer type
274 *
275 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800276 public int getCurrentConstantIndex() {
277 return mConstantCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800278 }
279
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800280 /**
281 * Queries the index of the last added texture type
282 *
283 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800284 public int getCurrentTextureIndex() {
285 return mTextureCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800286 }
287
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800288 /**
289 * Adds constant (uniform) inputs to the program
290 *
291 * @param t Type that describes the layout of the Allocation
292 * object to be used as constant inputs to the Program
293 * @return self
294 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800295 public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
Jason Sams0011bcf2009-12-15 12:58:36 -0800296 // Should check for consistant and non-conflicting names...
297 if(mConstantCount >= MAX_CONSTANT) {
Jason Samsc1d62102010-11-04 14:32:19 -0700298 throw new RSIllegalArgumentException("Max input count exceeded.");
299 }
300 if (t.getElement().isComplex()) {
301 throw new RSIllegalArgumentException("Complex elements not allowed.");
Jason Sams0011bcf2009-12-15 12:58:36 -0800302 }
Jason Samsea87e962010-01-12 12:12:28 -0800303 mConstants[mConstantCount] = t;
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800304 mConstantCount++;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800305 return this;
306 }
307
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800308 /**
309 * Adds a texture input to the Program
310 *
311 * @param texType describes that the texture to append it (2D,
312 * Cubemap, etc.)
313 * @return self
314 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800315 public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800316 addTexture(texType, "Tex" + mTextureCount);
317 return this;
318 }
319
320 /**
321 * @hide
322 * Adds a texture input to the Program
323 *
324 * @param texType describes that the texture to append it (2D,
325 * Cubemap, etc.)
326 * @param texName what the texture should be called in the
327 * shader
328 * @return self
329 */
330 public BaseProgramBuilder addTexture(TextureType texType, String texName)
331 throws IllegalArgumentException {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800332 if(mTextureCount >= MAX_TEXTURE) {
333 throw new IllegalArgumentException("Max texture count exceeded.");
334 }
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800335 mTextureTypes[mTextureCount] = texType;
336 mTextureNames[mTextureCount] = texName;
337 mTextureCount ++;
Jim Shuma288c8712010-07-07 14:24:21 -0700338 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800339 }
340
341 protected void initProgram(Program p) {
342 p.mInputs = new Element[mInputCount];
343 System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
344 p.mOutputs = new Element[mOutputCount];
345 System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
346 p.mConstants = new Type[mConstantCount];
347 System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800348 p.mTextureCount = mTextureCount;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800349 p.mTextures = new TextureType[mTextureCount];
350 System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800351 p.mTextureNames = new String[mTextureCount];
352 System.arraycopy(mTextureNames, 0, p.mTextureNames, 0, mTextureCount);
Jason Sams0011bcf2009-12-15 12:58:36 -0800353 }
354 }
355
356}
357
358