blob: 3f769eecdd974bc576e421068907d080a4db7af8 [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 /**
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -080080 * @hide
81 */
82 public int getConstantCount() {
83 return mConstants != null ? mConstants.length : 0;
84 }
85
86 /**
87 * @hide
88 */
89 public Type getConstant(int slot) {
90 if (slot < 0 || slot >= mConstants.length) {
91 throw new IllegalArgumentException("Slot ID out of range.");
92 }
93 return mConstants[slot];
94 }
95
96 /**
97 * @hide
98 */
99 public int getTextureCount() {
100 return mTextureCount;
101 }
102
103 /**
104 * @hide
105 */
106 public TextureType getTextureType(int slot) {
107 if ((slot < 0) || (slot >= mTextureCount)) {
108 throw new IllegalArgumentException("Slot ID out of range.");
109 }
110 return mTextures[slot];
111 }
112
113 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800114 * Binds a constant buffer to be used as uniform inputs to the
115 * program
116 *
117 * @param a allocation containing uniform data
118 * @param slot index within the program's list of constant
119 * buffer allocations
120 */
Jason Sams0011bcf2009-12-15 12:58:36 -0800121 public void bindConstants(Allocation a, int slot) {
Jason Samsc1d62102010-11-04 14:32:19 -0700122 if (slot < 0 || slot >= mConstants.length) {
123 throw new IllegalArgumentException("Slot ID out of range.");
124 }
125 if (a != null &&
126 a.getType().getID() != mConstants[slot].getID()) {
127 throw new IllegalArgumentException("Allocation type does not match slot type.");
128 }
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800129 int id = a != null ? a.getID() : 0;
130 mRS.nProgramBindConstants(getID(), slot, id);
Jason Sams0011bcf2009-12-15 12:58:36 -0800131 }
132
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800133 /**
134 * Binds a texture to be used in the program
135 *
136 * @param va allocation containing texture data
137 * @param slot index within the program's list of textures
138 *
139 */
Jason Sams68afd012009-12-17 16:55:08 -0800140 public void bindTexture(Allocation va, int slot)
141 throws IllegalArgumentException {
142 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800143 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800144 throw new IllegalArgumentException("Slot ID out of range.");
145 }
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800146 if (va != null && va.getType().hasFaces() &&
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800147 mTextures[slot] != TextureType.TEXTURE_CUBE) {
148 throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
149 }
Jason Sams68afd012009-12-17 16:55:08 -0800150
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800151 int id = va != null ? va.getID() : 0;
152 mRS.nProgramBindTexture(getID(), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800153 }
154
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800155 /**
156 * Binds an object that describes how a texture at the
157 * corresponding location is sampled
158 *
159 * @param vs sampler for a corresponding texture
160 * @param slot index within the program's list of textures to
161 * use the sampler on
162 *
163 */
Jason Sams68afd012009-12-17 16:55:08 -0800164 public void bindSampler(Sampler vs, int slot)
165 throws IllegalArgumentException {
166 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800167 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800168 throw new IllegalArgumentException("Slot ID out of range.");
169 }
170
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800171 int id = vs != null ? vs.getID() : 0;
172 mRS.nProgramBindSampler(getID(), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800173 }
174
175
Jason Sams0011bcf2009-12-15 12:58:36 -0800176 public static class BaseProgramBuilder {
177 RenderScript mRS;
178 Element mInputs[];
179 Element mOutputs[];
180 Type mConstants[];
181 Type mTextures[];
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800182 TextureType mTextureTypes[];
Jason Sams0011bcf2009-12-15 12:58:36 -0800183 int mInputCount;
184 int mOutputCount;
185 int mConstantCount;
186 int mTextureCount;
187 String mShader;
188
189
190 protected BaseProgramBuilder(RenderScript rs) {
191 mRS = rs;
192 mInputs = new Element[MAX_INPUT];
193 mOutputs = new Element[MAX_OUTPUT];
194 mConstants = new Type[MAX_CONSTANT];
195 mInputCount = 0;
196 mOutputCount = 0;
197 mConstantCount = 0;
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800198 mTextureCount = 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800199 mTextureTypes = new TextureType[MAX_TEXTURE];
Jason Sams0011bcf2009-12-15 12:58:36 -0800200 }
201
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800202 /**
203 * Sets the GLSL shader code to be used in the program
204 *
205 * @param s GLSL shader string
206 * @return self
207 */
Jim Shuma288c8712010-07-07 14:24:21 -0700208 public BaseProgramBuilder setShader(String s) {
Jason Sams0011bcf2009-12-15 12:58:36 -0800209 mShader = s;
Jim Shuma288c8712010-07-07 14:24:21 -0700210 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800211 }
212
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800213 /**
214 * Sets the GLSL shader code to be used in the program
215 *
216 * @param resources application resources
217 * @param resourceID id of the file containing GLSL shader code
218 *
219 * @return self
220 */
Alex Sakhartchouka41174e2010-08-27 16:10:55 -0700221 public BaseProgramBuilder setShader(Resources resources, int resourceID) {
222 byte[] str;
223 int strLength;
224 InputStream is = resources.openRawResource(resourceID);
225 try {
226 try {
227 str = new byte[1024];
228 strLength = 0;
229 while(true) {
230 int bytesLeft = str.length - strLength;
231 if (bytesLeft == 0) {
232 byte[] buf2 = new byte[str.length * 2];
233 System.arraycopy(str, 0, buf2, 0, str.length);
234 str = buf2;
235 bytesLeft = str.length - strLength;
236 }
237 int bytesRead = is.read(str, strLength, bytesLeft);
238 if (bytesRead <= 0) {
239 break;
240 }
241 strLength += bytesRead;
242 }
243 } finally {
244 is.close();
245 }
246 } catch(IOException e) {
247 throw new Resources.NotFoundException();
248 }
249
250 try {
251 mShader = new String(str, 0, strLength, "UTF-8");
252 } catch (UnsupportedEncodingException e) {
253 Log.e("Renderscript shader creation", "Could not decode shader string");
254 }
255
256 return this;
257 }
258
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800259 /**
260 * Queries the index of the last added constant buffer type
261 *
262 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800263 public int getCurrentConstantIndex() {
264 return mConstantCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800265 }
266
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800267 /**
268 * Queries the index of the last added texture type
269 *
270 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800271 public int getCurrentTextureIndex() {
272 return mTextureCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800273 }
274
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800275 /**
276 * Adds constant (uniform) inputs to the program
277 *
278 * @param t Type that describes the layout of the Allocation
279 * object to be used as constant inputs to the Program
280 * @return self
281 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800282 public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
Jason Sams0011bcf2009-12-15 12:58:36 -0800283 // Should check for consistant and non-conflicting names...
284 if(mConstantCount >= MAX_CONSTANT) {
Jason Samsc1d62102010-11-04 14:32:19 -0700285 throw new RSIllegalArgumentException("Max input count exceeded.");
286 }
287 if (t.getElement().isComplex()) {
288 throw new RSIllegalArgumentException("Complex elements not allowed.");
Jason Sams0011bcf2009-12-15 12:58:36 -0800289 }
Jason Samsea87e962010-01-12 12:12:28 -0800290 mConstants[mConstantCount] = t;
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800291 mConstantCount++;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800292 return this;
293 }
294
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800295 /**
296 * Adds a texture input to the Program
297 *
298 * @param texType describes that the texture to append it (2D,
299 * Cubemap, etc.)
300 * @return self
301 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800302 public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
303 if(mTextureCount >= MAX_TEXTURE) {
304 throw new IllegalArgumentException("Max texture count exceeded.");
305 }
306 mTextureTypes[mTextureCount ++] = texType;
Jim Shuma288c8712010-07-07 14:24:21 -0700307 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800308 }
309
310 protected void initProgram(Program p) {
311 p.mInputs = new Element[mInputCount];
312 System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
313 p.mOutputs = new Element[mOutputCount];
314 System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
315 p.mConstants = new Type[mConstantCount];
316 System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800317 p.mTextureCount = mTextureCount;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800318 p.mTextures = new TextureType[mTextureCount];
319 System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
Jason Sams0011bcf2009-12-15 12:58:36 -0800320 }
321 }
322
323}
324
325