• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.renderscript;
18 
19 
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.UnsupportedEncodingException;
23 
24 import android.content.res.Resources;
25 import android.util.Log;
26 
27 
28 /**
29  *
30  * Program is a base class for all the objects that modify
31  * various stages of the graphics pipeline
32  *
33  **/
34 public class Program extends BaseObj {
35     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;
39 
40     /**
41      *
42      * TextureType specifies what textures are attached to Program
43      * objects
44      *
45      **/
46     public enum TextureType {
47         TEXTURE_2D (0),
48         TEXTURE_CUBE (1);
49 
50         int mID;
TextureType(int id)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;
ProgramParam(int id)63         ProgramParam(int id) {
64             mID = id;
65         }
66     };
67 
68     Element mInputs[];
69     Element mOutputs[];
70     Type mConstants[];
71     TextureType mTextures[];
72     String mTextureNames[];
73     int mTextureCount;
74     String mShader;
75 
Program(int id, RenderScript rs)76     Program(int id, RenderScript rs) {
77         super(id, rs);
78     }
79 
80     /**
81      * 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
84      */
getConstantCount()85     public int getConstantCount() {
86         return mConstants != null ? mConstants.length : 0;
87     }
88 
89     /**
90      * 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
95      */
getConstant(int slot)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 
103     /**
104      * Returns the number of textures used in this program object
105      * @return number of texture inputs
106      */
getTextureCount()107     public int getTextureCount() {
108         return mTextureCount;
109     }
110 
111     /**
112      * 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
115      */
getTextureType(int slot)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 
123     /**
124      * 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
128      */
getTextureName(int slot)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 
136     /**
137      * 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      */
bindConstants(Allocation a, int slot)144     public void bindConstants(Allocation a, int slot) {
145         if (slot < 0 || slot >= mConstants.length) {
146             throw new IllegalArgumentException("Slot ID out of range.");
147         }
148         if (a != null &&
149             a.getType().getID(mRS) != mConstants[slot].getID(mRS)) {
150             throw new IllegalArgumentException("Allocation type does not match slot type.");
151         }
152         int id = a != null ? a.getID(mRS) : 0;
153         mRS.nProgramBindConstants(getID(mRS), slot, id);
154     }
155 
156     /**
157      * 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      */
bindTexture(Allocation va, int slot)163     public void bindTexture(Allocation va, int slot)
164         throws IllegalArgumentException {
165         mRS.validate();
166         if ((slot < 0) || (slot >= mTextureCount)) {
167             throw new IllegalArgumentException("Slot ID out of range.");
168         }
169         if (va != null && va.getType().hasFaces() &&
170             mTextures[slot] != TextureType.TEXTURE_CUBE) {
171             throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
172         }
173 
174         int id = va != null ? va.getID(mRS) : 0;
175         mRS.nProgramBindTexture(getID(mRS), slot, id);
176     }
177 
178     /**
179      * 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      */
bindSampler(Sampler vs, int slot)187     public void bindSampler(Sampler vs, int slot)
188         throws IllegalArgumentException {
189         mRS.validate();
190         if ((slot < 0) || (slot >= mTextureCount)) {
191             throw new IllegalArgumentException("Slot ID out of range.");
192         }
193 
194         int id = vs != null ? vs.getID(mRS) : 0;
195         mRS.nProgramBindSampler(getID(mRS), slot, id);
196     }
197 
198 
199     public static class BaseProgramBuilder {
200         RenderScript mRS;
201         Element mInputs[];
202         Element mOutputs[];
203         Type mConstants[];
204         Type mTextures[];
205         TextureType mTextureTypes[];
206         String mTextureNames[];
207         int mInputCount;
208         int mOutputCount;
209         int mConstantCount;
210         int mTextureCount;
211         String mShader;
212 
213 
BaseProgramBuilder(RenderScript rs)214         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;
222             mTextureCount = 0;
223             mTextureTypes = new TextureType[MAX_TEXTURE];
224             mTextureNames = new String[MAX_TEXTURE];
225         }
226 
227         /**
228          * Sets the GLSL shader code to be used in the program
229          *
230          * @param s GLSL shader string
231          * @return  self
232          */
setShader(String s)233         public BaseProgramBuilder setShader(String s) {
234             mShader = s;
235             return this;
236         }
237 
238         /**
239          * 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          */
setShader(Resources resources, int resourceID)246         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 
284         /**
285          * Queries the index of the last added constant buffer type
286          *
287          */
getCurrentConstantIndex()288         public int getCurrentConstantIndex() {
289             return mConstantCount - 1;
290         }
291 
292         /**
293          * Queries the index of the last added texture type
294          *
295          */
getCurrentTextureIndex()296         public int getCurrentTextureIndex() {
297             return mTextureCount - 1;
298         }
299 
300         /**
301          * 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          */
addConstant(Type t)307         public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
308             // Should check for consistant and non-conflicting names...
309             if(mConstantCount >= MAX_CONSTANT) {
310                 throw new RSIllegalArgumentException("Max input count exceeded.");
311             }
312             if (t.getElement().isComplex()) {
313                 throw new RSIllegalArgumentException("Complex elements not allowed.");
314             }
315             mConstants[mConstantCount] = t;
316             mConstantCount++;
317             return this;
318         }
319 
320         /**
321          * 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          */
addTexture(TextureType texType)327         public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
328             addTexture(texType, "Tex" + mTextureCount);
329             return this;
330         }
331 
332         /**
333          * 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          */
addTexture(TextureType texType, String texName)341         public BaseProgramBuilder addTexture(TextureType texType, String texName)
342             throws IllegalArgumentException {
343             if(mTextureCount >= MAX_TEXTURE) {
344                 throw new IllegalArgumentException("Max texture count exceeded.");
345             }
346             mTextureTypes[mTextureCount] = texType;
347             mTextureNames[mTextureCount] = texName;
348             mTextureCount ++;
349             return this;
350         }
351 
initProgram(Program p)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);
359             p.mTextureCount = mTextureCount;
360             p.mTextures = new TextureType[mTextureCount];
361             System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
362             p.mTextureNames = new String[mTextureCount];
363             System.arraycopy(mTextureNames, 0, p.mTextureNames, 0, mTextureCount);
364         }
365     }
366 
367 }
368 
369 
370