• 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  * @hide
30  *
31  * Program is a base class for all the objects that modify
32  * various stages of the graphics pipeline
33  *
34  **/
35 public class Program extends BaseObj {
36     static final int MAX_INPUT = 8;
37     static final int MAX_OUTPUT = 8;
38     static final int MAX_CONSTANT = 8;
39     static final int MAX_TEXTURE = 8;
40 
41     /**
42      *
43      * TextureType specifies what textures are attached to Program
44      * objects
45      *
46      **/
47     public enum TextureType {
48         TEXTURE_2D (0),
49         TEXTURE_CUBE (1);
50 
51         int mID;
TextureType(int id)52         TextureType(int id) {
53             mID = id;
54         }
55     }
56 
57     enum ProgramParam {
58         INPUT (0),
59         OUTPUT (1),
60         CONSTANT (2),
61         TEXTURE_TYPE (3);
62 
63         int mID;
ProgramParam(int id)64         ProgramParam(int id) {
65             mID = id;
66         }
67     };
68 
69     Element mInputs[];
70     Element mOutputs[];
71     Type mConstants[];
72     TextureType mTextures[];
73     String mTextureNames[];
74     int mTextureCount;
75     String mShader;
76 
Program(int id, RenderScript rs)77     Program(int id, RenderScript rs) {
78         super(id, rs);
79     }
80 
81     /**
82      * Program object can have zero or more constant allocations
83      * associated with it. This method returns the total count.
84      * @return number of constant input types
85      */
getConstantCount()86     public int getConstantCount() {
87         return mConstants != null ? mConstants.length : 0;
88     }
89 
90     /**
91      * Returns the type of the constant buffer used in the program
92      * object. It could be used to query internal elements or create
93      * an allocation to store constant data.
94      * @param slot index of the constant input type to return
95      * @return constant input type
96      */
getConstant(int slot)97     public Type getConstant(int slot) {
98         if (slot < 0 || slot >= mConstants.length) {
99             throw new IllegalArgumentException("Slot ID out of range.");
100         }
101         return mConstants[slot];
102     }
103 
104     /**
105      * Returns the number of textures used in this program object
106      * @return number of texture inputs
107      */
getTextureCount()108     public int getTextureCount() {
109         return mTextureCount;
110     }
111 
112     /**
113      * Returns the type of texture at a given slot. e.g. 2D or Cube
114      * @param slot index of the texture input
115      * @return texture input type
116      */
getTextureType(int slot)117     public TextureType getTextureType(int slot) {
118         if ((slot < 0) || (slot >= mTextureCount)) {
119             throw new IllegalArgumentException("Slot ID out of range.");
120         }
121         return mTextures[slot];
122     }
123 
124     /**
125      * Returns the name of the texture input at a given slot. e.g.
126      * tex0, diffuse, spec
127      * @param slot index of the texture input
128      * @return texture input name
129      */
getTextureName(int slot)130     public String getTextureName(int slot) {
131         if ((slot < 0) || (slot >= mTextureCount)) {
132             throw new IllegalArgumentException("Slot ID out of range.");
133         }
134         return mTextureNames[slot];
135     }
136 
137     /**
138      * Binds a constant buffer to be used as uniform inputs to the
139      * program
140      *
141      * @param a allocation containing uniform data
142      * @param slot index within the program's list of constant
143      *             buffer allocations
144      */
bindConstants(Allocation a, int slot)145     public void bindConstants(Allocation a, int slot) {
146         if (slot < 0 || slot >= mConstants.length) {
147             throw new IllegalArgumentException("Slot ID out of range.");
148         }
149         if (a != null &&
150             a.getType().getID(mRS) != mConstants[slot].getID(mRS)) {
151             throw new IllegalArgumentException("Allocation type does not match slot type.");
152         }
153         int id = a != null ? a.getID(mRS) : 0;
154         mRS.nProgramBindConstants(getID(mRS), slot, id);
155     }
156 
157     /**
158      * Binds a texture to be used in the program
159      *
160      * @param va allocation containing texture data
161      * @param slot index within the program's list of textures
162      *
163      */
bindTexture(Allocation va, int slot)164     public void bindTexture(Allocation va, int slot)
165         throws IllegalArgumentException {
166         mRS.validate();
167         if ((slot < 0) || (slot >= mTextureCount)) {
168             throw new IllegalArgumentException("Slot ID out of range.");
169         }
170         if (va != null && va.getType().hasFaces() &&
171             mTextures[slot] != TextureType.TEXTURE_CUBE) {
172             throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
173         }
174 
175         int id = va != null ? va.getID(mRS) : 0;
176         mRS.nProgramBindTexture(getID(mRS), slot, id);
177     }
178 
179     /**
180      * Binds an object that describes how a texture at the
181      * corresponding location is sampled
182      *
183      * @param vs sampler for a corresponding texture
184      * @param slot index within the program's list of textures to
185      *             use the sampler on
186      *
187      */
bindSampler(Sampler vs, int slot)188     public void bindSampler(Sampler vs, int slot)
189         throws IllegalArgumentException {
190         mRS.validate();
191         if ((slot < 0) || (slot >= mTextureCount)) {
192             throw new IllegalArgumentException("Slot ID out of range.");
193         }
194 
195         int id = vs != null ? vs.getID(mRS) : 0;
196         mRS.nProgramBindSampler(getID(mRS), slot, id);
197     }
198 
199 
200     public static class BaseProgramBuilder {
201         RenderScript mRS;
202         Element mInputs[];
203         Element mOutputs[];
204         Type mConstants[];
205         Type mTextures[];
206         TextureType mTextureTypes[];
207         String mTextureNames[];
208         int mInputCount;
209         int mOutputCount;
210         int mConstantCount;
211         int mTextureCount;
212         String mShader;
213 
214 
BaseProgramBuilder(RenderScript rs)215         protected BaseProgramBuilder(RenderScript rs) {
216             mRS = rs;
217             mInputs = new Element[MAX_INPUT];
218             mOutputs = new Element[MAX_OUTPUT];
219             mConstants = new Type[MAX_CONSTANT];
220             mInputCount = 0;
221             mOutputCount = 0;
222             mConstantCount = 0;
223             mTextureCount = 0;
224             mTextureTypes = new TextureType[MAX_TEXTURE];
225             mTextureNames = new String[MAX_TEXTURE];
226         }
227 
228         /**
229          * Sets the GLSL shader code to be used in the program
230          *
231          * @param s GLSL shader string
232          * @return  self
233          */
setShader(String s)234         public BaseProgramBuilder setShader(String s) {
235             mShader = s;
236             return this;
237         }
238 
239         /**
240          * Sets the GLSL shader code to be used in the program
241          *
242          * @param resources application resources
243          * @param resourceID id of the file containing GLSL shader code
244          *
245          * @return  self
246          */
setShader(Resources resources, int resourceID)247         public BaseProgramBuilder setShader(Resources resources, int resourceID) {
248             byte[] str;
249             int strLength;
250             InputStream is = resources.openRawResource(resourceID);
251             try {
252                 try {
253                     str = new byte[1024];
254                     strLength = 0;
255                     while(true) {
256                         int bytesLeft = str.length - strLength;
257                         if (bytesLeft == 0) {
258                             byte[] buf2 = new byte[str.length * 2];
259                             System.arraycopy(str, 0, buf2, 0, str.length);
260                             str = buf2;
261                             bytesLeft = str.length - strLength;
262                         }
263                         int bytesRead = is.read(str, strLength, bytesLeft);
264                         if (bytesRead <= 0) {
265                             break;
266                         }
267                         strLength += bytesRead;
268                     }
269                 } finally {
270                     is.close();
271                 }
272             } catch(IOException e) {
273                 throw new Resources.NotFoundException();
274             }
275 
276             try {
277                 mShader = new String(str, 0, strLength, "UTF-8");
278             } catch (UnsupportedEncodingException e) {
279                 Log.e("Renderscript shader creation", "Could not decode shader string");
280             }
281 
282             return this;
283         }
284 
285         /**
286          * Queries the index of the last added constant buffer type
287          *
288          */
getCurrentConstantIndex()289         public int getCurrentConstantIndex() {
290             return mConstantCount - 1;
291         }
292 
293         /**
294          * Queries the index of the last added texture type
295          *
296          */
getCurrentTextureIndex()297         public int getCurrentTextureIndex() {
298             return mTextureCount - 1;
299         }
300 
301         /**
302          * Adds constant (uniform) inputs to the program
303          *
304          * @param t Type that describes the layout of the Allocation
305          *          object to be used as constant inputs to the Program
306          * @return  self
307          */
addConstant(Type t)308         public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
309             // Should check for consistant and non-conflicting names...
310             if(mConstantCount >= MAX_CONSTANT) {
311                 throw new RSIllegalArgumentException("Max input count exceeded.");
312             }
313             if (t.getElement().isComplex()) {
314                 throw new RSIllegalArgumentException("Complex elements not allowed.");
315             }
316             mConstants[mConstantCount] = t;
317             mConstantCount++;
318             return this;
319         }
320 
321         /**
322          * Adds a texture input to the Program
323          *
324          * @param texType describes that the texture to append it (2D,
325          *                Cubemap, etc.)
326          * @return  self
327          */
addTexture(TextureType texType)328         public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
329             addTexture(texType, "Tex" + mTextureCount);
330             return this;
331         }
332 
333         /**
334          * Adds a texture input to the Program
335          *
336          * @param texType describes that the texture to append it (2D,
337          *                Cubemap, etc.)
338          * @param texName what the texture should be called in the
339          *                shader
340          * @return  self
341          */
addTexture(TextureType texType, String texName)342         public BaseProgramBuilder addTexture(TextureType texType, String texName)
343             throws IllegalArgumentException {
344             if(mTextureCount >= MAX_TEXTURE) {
345                 throw new IllegalArgumentException("Max texture count exceeded.");
346             }
347             mTextureTypes[mTextureCount] = texType;
348             mTextureNames[mTextureCount] = texName;
349             mTextureCount ++;
350             return this;
351         }
352 
initProgram(Program p)353         protected void initProgram(Program p) {
354             p.mInputs = new Element[mInputCount];
355             System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
356             p.mOutputs = new Element[mOutputCount];
357             System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
358             p.mConstants = new Type[mConstantCount];
359             System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
360             p.mTextureCount = mTextureCount;
361             p.mTextures = new TextureType[mTextureCount];
362             System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
363             p.mTextureNames = new String[mTextureCount];
364             System.arraycopy(mTextureNames, 0, p.mTextureNames, 0, mTextureCount);
365         }
366     }
367 
368 }
369 
370 
371