• 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     int mTextureCount;
73     String mShader;
74 
Program(int id, RenderScript rs)75     Program(int id, RenderScript rs) {
76         super(id, rs);
77     }
78 
79     /**
80      * Binds a constant buffer to be used as uniform inputs to the
81      * program
82      *
83      * @param a allocation containing uniform data
84      * @param slot index within the program's list of constant
85      *             buffer allocations
86      */
bindConstants(Allocation a, int slot)87     public void bindConstants(Allocation a, int slot) {
88         if (slot < 0 || slot >= mConstants.length) {
89             throw new IllegalArgumentException("Slot ID out of range.");
90         }
91         if (a != null &&
92             a.getType().getID() != mConstants[slot].getID()) {
93             throw new IllegalArgumentException("Allocation type does not match slot type.");
94         }
95         int id = a != null ? a.getID() : 0;
96         mRS.nProgramBindConstants(getID(), slot, id);
97     }
98 
99     /**
100      * Binds a texture to be used in the program
101      *
102      * @param va allocation containing texture data
103      * @param slot index within the program's list of textures
104      *
105      */
bindTexture(Allocation va, int slot)106     public void bindTexture(Allocation va, int slot)
107         throws IllegalArgumentException {
108         mRS.validate();
109         if ((slot < 0) || (slot >= mTextureCount)) {
110             throw new IllegalArgumentException("Slot ID out of range.");
111         }
112         if (va != null && va.getType().hasFaces() &&
113             mTextures[slot] != TextureType.TEXTURE_CUBE) {
114             throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
115         }
116 
117         int id = va != null ? va.getID() : 0;
118         mRS.nProgramBindTexture(getID(), slot, id);
119     }
120 
121     /**
122      * Binds an object that describes how a texture at the
123      * corresponding location is sampled
124      *
125      * @param vs sampler for a corresponding texture
126      * @param slot index within the program's list of textures to
127      *             use the sampler on
128      *
129      */
bindSampler(Sampler vs, int slot)130     public void bindSampler(Sampler vs, int slot)
131         throws IllegalArgumentException {
132         mRS.validate();
133         if ((slot < 0) || (slot >= mTextureCount)) {
134             throw new IllegalArgumentException("Slot ID out of range.");
135         }
136 
137         int id = vs != null ? vs.getID() : 0;
138         mRS.nProgramBindSampler(getID(), slot, id);
139     }
140 
141 
142     public static class BaseProgramBuilder {
143         RenderScript mRS;
144         Element mInputs[];
145         Element mOutputs[];
146         Type mConstants[];
147         Type mTextures[];
148         TextureType mTextureTypes[];
149         int mInputCount;
150         int mOutputCount;
151         int mConstantCount;
152         int mTextureCount;
153         String mShader;
154 
155 
BaseProgramBuilder(RenderScript rs)156         protected BaseProgramBuilder(RenderScript rs) {
157             mRS = rs;
158             mInputs = new Element[MAX_INPUT];
159             mOutputs = new Element[MAX_OUTPUT];
160             mConstants = new Type[MAX_CONSTANT];
161             mInputCount = 0;
162             mOutputCount = 0;
163             mConstantCount = 0;
164             mTextureCount = 0;
165             mTextureTypes = new TextureType[MAX_TEXTURE];
166         }
167 
168         /**
169          * Sets the GLSL shader code to be used in the program
170          *
171          * @param s GLSL shader string
172          * @return  self
173          */
setShader(String s)174         public BaseProgramBuilder setShader(String s) {
175             mShader = s;
176             return this;
177         }
178 
179         /**
180          * Sets the GLSL shader code to be used in the program
181          *
182          * @param resources application resources
183          * @param resourceID id of the file containing GLSL shader code
184          *
185          * @return  self
186          */
setShader(Resources resources, int resourceID)187         public BaseProgramBuilder setShader(Resources resources, int resourceID) {
188             byte[] str;
189             int strLength;
190             InputStream is = resources.openRawResource(resourceID);
191             try {
192                 try {
193                     str = new byte[1024];
194                     strLength = 0;
195                     while(true) {
196                         int bytesLeft = str.length - strLength;
197                         if (bytesLeft == 0) {
198                             byte[] buf2 = new byte[str.length * 2];
199                             System.arraycopy(str, 0, buf2, 0, str.length);
200                             str = buf2;
201                             bytesLeft = str.length - strLength;
202                         }
203                         int bytesRead = is.read(str, strLength, bytesLeft);
204                         if (bytesRead <= 0) {
205                             break;
206                         }
207                         strLength += bytesRead;
208                     }
209                 } finally {
210                     is.close();
211                 }
212             } catch(IOException e) {
213                 throw new Resources.NotFoundException();
214             }
215 
216             try {
217                 mShader = new String(str, 0, strLength, "UTF-8");
218             } catch (UnsupportedEncodingException e) {
219                 Log.e("Renderscript shader creation", "Could not decode shader string");
220             }
221 
222             return this;
223         }
224 
225         /**
226          * Queries the index of the last added constant buffer type
227          *
228          */
getCurrentConstantIndex()229         public int getCurrentConstantIndex() {
230             return mConstantCount - 1;
231         }
232 
233         /**
234          * Queries the index of the last added texture type
235          *
236          */
getCurrentTextureIndex()237         public int getCurrentTextureIndex() {
238             return mTextureCount - 1;
239         }
240 
241         /**
242          * Adds constant (uniform) inputs to the program
243          *
244          * @param t Type that describes the layout of the Allocation
245          *          object to be used as constant inputs to the Program
246          * @return  self
247          */
addConstant(Type t)248         public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
249             // Should check for consistant and non-conflicting names...
250             if(mConstantCount >= MAX_CONSTANT) {
251                 throw new RSIllegalArgumentException("Max input count exceeded.");
252             }
253             if (t.getElement().isComplex()) {
254                 throw new RSIllegalArgumentException("Complex elements not allowed.");
255             }
256             mConstants[mConstantCount] = t;
257             mConstantCount++;
258             return this;
259         }
260 
261         /**
262          * Adds a texture input to the Program
263          *
264          * @param texType describes that the texture to append it (2D,
265          *                Cubemap, etc.)
266          * @return  self
267          */
addTexture(TextureType texType)268         public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
269             if(mTextureCount >= MAX_TEXTURE) {
270                 throw new IllegalArgumentException("Max texture count exceeded.");
271             }
272             mTextureTypes[mTextureCount ++] = texType;
273             return this;
274         }
275 
initProgram(Program p)276         protected void initProgram(Program p) {
277             p.mInputs = new Element[mInputCount];
278             System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
279             p.mOutputs = new Element[mOutputCount];
280             System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
281             p.mConstants = new Type[mConstantCount];
282             System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
283             p.mTextureCount = mTextureCount;
284             p.mTextures = new TextureType[mTextureCount];
285             System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
286         }
287     }
288 
289 }
290 
291 
292