blob: e28d646f5f1c812defd9b6dfb8da50a1b519d08c [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
Mathew Inwood15324472018-08-06 11:18:49 +010024import android.annotation.UnsupportedAppUsage;
Alex Sakhartchouka41174e2010-08-27 16:10:55 -070025import android.content.res.Resources;
Jason Sams0011bcf2009-12-15 12:58:36 -080026import android.util.Log;
27
28
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070029/**
Tim Murraya9084222013-04-05 22:06:43 +000030 * @hide
Jason Sams0011bcf2009-12-15 12:58:36 -080031 *
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080032 * Program is a base class for all the objects that modify
33 * various stages of the graphics pipeline
34 *
Jason Sams0011bcf2009-12-15 12:58:36 -080035 **/
36public class Program extends BaseObj {
Alex Sakhartchouk0473ff12011-01-14 11:27:27 -080037 static final int MAX_INPUT = 8;
38 static final int MAX_OUTPUT = 8;
39 static final int MAX_CONSTANT = 8;
40 static final int MAX_TEXTURE = 8;
Jason Sams0011bcf2009-12-15 12:58:36 -080041
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070042 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080043 *
44 * TextureType specifies what textures are attached to Program
45 * objects
46 *
47 **/
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -080048 public enum TextureType {
Mathew Inwood15324472018-08-06 11:18:49 +010049 @UnsupportedAppUsage
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -080050 TEXTURE_2D (0),
51 TEXTURE_CUBE (1);
52
53 int mID;
54 TextureType(int id) {
55 mID = id;
56 }
57 }
58
59 enum ProgramParam {
60 INPUT (0),
61 OUTPUT (1),
62 CONSTANT (2),
63 TEXTURE_TYPE (3);
64
65 int mID;
66 ProgramParam(int id) {
67 mID = id;
68 }
69 };
70
Jason Sams0011bcf2009-12-15 12:58:36 -080071 Element mInputs[];
72 Element mOutputs[];
73 Type mConstants[];
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -080074 TextureType mTextures[];
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080075 String mTextureNames[];
Jason Sams7e5ab3b2009-12-15 13:27:04 -080076 int mTextureCount;
Jason Sams0011bcf2009-12-15 12:58:36 -080077 String mShader;
78
Tim Murray460a0492013-11-19 12:45:54 -080079 Program(long id, RenderScript rs) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -070080 super(id, rs);
Yang Nieb4dd082016-03-24 09:40:32 -070081 guard.open("destroy");
Jason Sams0011bcf2009-12-15 12:58:36 -080082 }
83
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070084 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -070085 * Program object can have zero or more constant allocations
86 * associated with it. This method returns the total count.
87 * @return number of constant input types
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -080088 */
89 public int getConstantCount() {
90 return mConstants != null ? mConstants.length : 0;
91 }
92
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070093 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -070094 * Returns the type of the constant buffer used in the program
95 * object. It could be used to query internal elements or create
96 * an allocation to store constant data.
97 * @param slot index of the constant input type to return
98 * @return constant input type
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -080099 */
100 public Type getConstant(int slot) {
101 if (slot < 0 || slot >= mConstants.length) {
102 throw new IllegalArgumentException("Slot ID out of range.");
103 }
104 return mConstants[slot];
105 }
106
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700107 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700108 * Returns the number of textures used in this program object
109 * @return number of texture inputs
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -0800110 */
111 public int getTextureCount() {
112 return mTextureCount;
113 }
114
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700115 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700116 * Returns the type of texture at a given slot. e.g. 2D or Cube
117 * @param slot index of the texture input
118 * @return texture input type
Alex Sakhartchoukd5a62bb2012-01-06 10:36:06 -0800119 */
120 public TextureType getTextureType(int slot) {
121 if ((slot < 0) || (slot >= mTextureCount)) {
122 throw new IllegalArgumentException("Slot ID out of range.");
123 }
124 return mTextures[slot];
125 }
126
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700127 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700128 * Returns the name of the texture input at a given slot. e.g.
129 * tex0, diffuse, spec
130 * @param slot index of the texture input
131 * @return texture input name
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800132 */
133 public String getTextureName(int slot) {
134 if ((slot < 0) || (slot >= mTextureCount)) {
135 throw new IllegalArgumentException("Slot ID out of range.");
136 }
137 return mTextureNames[slot];
138 }
139
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700140 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800141 * Binds a constant buffer to be used as uniform inputs to the
142 * program
143 *
144 * @param a allocation containing uniform data
145 * @param slot index within the program's list of constant
146 * buffer allocations
147 */
Jason Sams0011bcf2009-12-15 12:58:36 -0800148 public void bindConstants(Allocation a, int slot) {
Jason Samsc1d62102010-11-04 14:32:19 -0700149 if (slot < 0 || slot >= mConstants.length) {
150 throw new IllegalArgumentException("Slot ID out of range.");
151 }
152 if (a != null &&
Jason Samse07694b2012-04-03 15:36:36 -0700153 a.getType().getID(mRS) != mConstants[slot].getID(mRS)) {
Jason Samsc1d62102010-11-04 14:32:19 -0700154 throw new IllegalArgumentException("Allocation type does not match slot type.");
155 }
Tim Murray460a0492013-11-19 12:45:54 -0800156 long id = a != null ? a.getID(mRS) : 0;
Jason Samse07694b2012-04-03 15:36:36 -0700157 mRS.nProgramBindConstants(getID(mRS), slot, id);
Jason Sams0011bcf2009-12-15 12:58:36 -0800158 }
159
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700160 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800161 * Binds a texture to be used in the program
162 *
163 * @param va allocation containing texture data
164 * @param slot index within the program's list of textures
165 *
166 */
Jason Sams68afd012009-12-17 16:55:08 -0800167 public void bindTexture(Allocation va, int slot)
168 throws IllegalArgumentException {
169 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800170 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800171 throw new IllegalArgumentException("Slot ID out of range.");
172 }
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800173 if (va != null && va.getType().hasFaces() &&
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800174 mTextures[slot] != TextureType.TEXTURE_CUBE) {
175 throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
176 }
Jason Sams68afd012009-12-17 16:55:08 -0800177
Tim Murray460a0492013-11-19 12:45:54 -0800178 long id = va != null ? va.getID(mRS) : 0;
Jason Samse07694b2012-04-03 15:36:36 -0700179 mRS.nProgramBindTexture(getID(mRS), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800180 }
181
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700182 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800183 * Binds an object that describes how a texture at the
184 * corresponding location is sampled
185 *
186 * @param vs sampler for a corresponding texture
187 * @param slot index within the program's list of textures to
188 * use the sampler on
189 *
190 */
Jason Sams68afd012009-12-17 16:55:08 -0800191 public void bindSampler(Sampler vs, int slot)
192 throws IllegalArgumentException {
193 mRS.validate();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800194 if ((slot < 0) || (slot >= mTextureCount)) {
Jason Sams68afd012009-12-17 16:55:08 -0800195 throw new IllegalArgumentException("Slot ID out of range.");
196 }
197
Tim Murray460a0492013-11-19 12:45:54 -0800198 long id = vs != null ? vs.getID(mRS) : 0;
Jason Samse07694b2012-04-03 15:36:36 -0700199 mRS.nProgramBindSampler(getID(mRS), slot, id);
Jason Sams68afd012009-12-17 16:55:08 -0800200 }
201
202
Jason Sams0011bcf2009-12-15 12:58:36 -0800203 public static class BaseProgramBuilder {
Mathew Inwood15324472018-08-06 11:18:49 +0100204 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800205 RenderScript mRS;
Mathew Inwood15324472018-08-06 11:18:49 +0100206 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800207 Element mInputs[];
Mathew Inwood15324472018-08-06 11:18:49 +0100208 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800209 Element mOutputs[];
Mathew Inwood15324472018-08-06 11:18:49 +0100210 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800211 Type mConstants[];
212 Type mTextures[];
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800213 TextureType mTextureTypes[];
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800214 String mTextureNames[];
Mathew Inwood15324472018-08-06 11:18:49 +0100215 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800216 int mInputCount;
Mathew Inwood15324472018-08-06 11:18:49 +0100217 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800218 int mOutputCount;
Mathew Inwood15324472018-08-06 11:18:49 +0100219 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800220 int mConstantCount;
Mathew Inwood15324472018-08-06 11:18:49 +0100221 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800222 int mTextureCount;
Mathew Inwood15324472018-08-06 11:18:49 +0100223 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800224 String mShader;
225
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700226
Mathew Inwood15324472018-08-06 11:18:49 +0100227 @UnsupportedAppUsage
Jason Sams0011bcf2009-12-15 12:58:36 -0800228 protected BaseProgramBuilder(RenderScript rs) {
229 mRS = rs;
230 mInputs = new Element[MAX_INPUT];
231 mOutputs = new Element[MAX_OUTPUT];
232 mConstants = new Type[MAX_CONSTANT];
233 mInputCount = 0;
234 mOutputCount = 0;
235 mConstantCount = 0;
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800236 mTextureCount = 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800237 mTextureTypes = new TextureType[MAX_TEXTURE];
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800238 mTextureNames = new String[MAX_TEXTURE];
Jason Sams0011bcf2009-12-15 12:58:36 -0800239 }
240
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700241 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800242 * Sets the GLSL shader code to be used in the program
243 *
244 * @param s GLSL shader string
245 * @return self
246 */
Jim Shuma288c8712010-07-07 14:24:21 -0700247 public BaseProgramBuilder setShader(String s) {
Jason Sams0011bcf2009-12-15 12:58:36 -0800248 mShader = s;
Jim Shuma288c8712010-07-07 14:24:21 -0700249 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800250 }
251
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700252 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800253 * Sets the GLSL shader code to be used in the program
254 *
255 * @param resources application resources
256 * @param resourceID id of the file containing GLSL shader code
257 *
258 * @return self
259 */
Alex Sakhartchouka41174e2010-08-27 16:10:55 -0700260 public BaseProgramBuilder setShader(Resources resources, int resourceID) {
261 byte[] str;
262 int strLength;
263 InputStream is = resources.openRawResource(resourceID);
264 try {
265 try {
266 str = new byte[1024];
267 strLength = 0;
268 while(true) {
269 int bytesLeft = str.length - strLength;
270 if (bytesLeft == 0) {
271 byte[] buf2 = new byte[str.length * 2];
272 System.arraycopy(str, 0, buf2, 0, str.length);
273 str = buf2;
274 bytesLeft = str.length - strLength;
275 }
276 int bytesRead = is.read(str, strLength, bytesLeft);
277 if (bytesRead <= 0) {
278 break;
279 }
280 strLength += bytesRead;
281 }
282 } finally {
283 is.close();
284 }
285 } catch(IOException e) {
286 throw new Resources.NotFoundException();
287 }
288
289 try {
290 mShader = new String(str, 0, strLength, "UTF-8");
291 } catch (UnsupportedEncodingException e) {
Tim Murrayc11e25c2013-04-09 11:01:01 -0700292 Log.e("RenderScript shader creation", "Could not decode shader string");
Alex Sakhartchouka41174e2010-08-27 16:10:55 -0700293 }
294
295 return this;
296 }
297
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700298 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800299 * Queries the index of the last added constant buffer type
300 *
301 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800302 public int getCurrentConstantIndex() {
303 return mConstantCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800304 }
305
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700306 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800307 * Queries the index of the last added texture type
308 *
309 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800310 public int getCurrentTextureIndex() {
311 return mTextureCount - 1;
Jason Sams0011bcf2009-12-15 12:58:36 -0800312 }
313
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700314 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800315 * Adds constant (uniform) inputs to the program
316 *
317 * @param t Type that describes the layout of the Allocation
318 * object to be used as constant inputs to the Program
319 * @return self
320 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800321 public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
Jason Sams0011bcf2009-12-15 12:58:36 -0800322 // Should check for consistant and non-conflicting names...
323 if(mConstantCount >= MAX_CONSTANT) {
Jason Samsc1d62102010-11-04 14:32:19 -0700324 throw new RSIllegalArgumentException("Max input count exceeded.");
325 }
326 if (t.getElement().isComplex()) {
327 throw new RSIllegalArgumentException("Complex elements not allowed.");
Jason Sams0011bcf2009-12-15 12:58:36 -0800328 }
Jason Samsea87e962010-01-12 12:12:28 -0800329 mConstants[mConstantCount] = t;
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800330 mConstantCount++;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800331 return this;
332 }
333
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700334 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800335 * Adds a texture input to the Program
336 *
337 * @param texType describes that the texture to append it (2D,
338 * Cubemap, etc.)
339 * @return self
340 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800341 public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800342 addTexture(texType, "Tex" + mTextureCount);
343 return this;
344 }
345
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700346 /**
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800347 * Adds a texture input to the Program
348 *
349 * @param texType describes that the texture to append it (2D,
350 * Cubemap, etc.)
351 * @param texName what the texture should be called in the
352 * shader
353 * @return self
354 */
355 public BaseProgramBuilder addTexture(TextureType texType, String texName)
356 throws IllegalArgumentException {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800357 if(mTextureCount >= MAX_TEXTURE) {
358 throw new IllegalArgumentException("Max texture count exceeded.");
359 }
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800360 mTextureTypes[mTextureCount] = texType;
361 mTextureNames[mTextureCount] = texName;
362 mTextureCount ++;
Jim Shuma288c8712010-07-07 14:24:21 -0700363 return this;
Jason Sams0011bcf2009-12-15 12:58:36 -0800364 }
365
366 protected void initProgram(Program p) {
367 p.mInputs = new Element[mInputCount];
368 System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
369 p.mOutputs = new Element[mOutputCount];
370 System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
371 p.mConstants = new Type[mConstantCount];
372 System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800373 p.mTextureCount = mTextureCount;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800374 p.mTextures = new TextureType[mTextureCount];
375 System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
Alex Sakhartchouk2123b462012-02-15 16:21:46 -0800376 p.mTextureNames = new String[mTextureCount];
377 System.arraycopy(mTextureNames, 0, p.mTextureNames, 0, mTextureCount);
Jason Sams0011bcf2009-12-15 12:58:36 -0800378 }
379 }
380
381}
382
383