Program.java revision b4d7bb6872f523b4318144202e119766ed9054ed
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
17package android.renderscript;
18
19
20import java.io.IOException;
21import java.io.InputStream;
22import java.io.UnsupportedEncodingException;
23
24import android.content.res.Resources;
25import android.util.Config;
26import android.util.Log;
27
28
29/**
30 * @hide
31 *
32 **/
33public class Program extends BaseObj {
34    public static final int MAX_INPUT = 8;
35    public static final int MAX_OUTPUT = 8;
36    public static final int MAX_CONSTANT = 8;
37    public static final int MAX_TEXTURE = 8;
38
39    public enum TextureType {
40        TEXTURE_2D (0),
41        TEXTURE_CUBE (1);
42
43        int mID;
44        TextureType(int id) {
45            mID = id;
46        }
47    }
48
49    enum ProgramParam {
50        INPUT (0),
51        OUTPUT (1),
52        CONSTANT (2),
53        TEXTURE_TYPE (3);
54
55        int mID;
56        ProgramParam(int id) {
57            mID = id;
58        }
59    };
60
61    Element mInputs[];
62    Element mOutputs[];
63    Type mConstants[];
64    TextureType mTextures[];
65    int mTextureCount;
66    String mShader;
67
68    Program(int id, RenderScript rs) {
69        super(id, rs);
70    }
71
72    public void bindConstants(Allocation a, int slot) {
73        if (slot < 0 || slot >= mConstants.length) {
74            throw new IllegalArgumentException("Slot ID out of range.");
75        }
76        if (a != null &&
77            a.getType().getID() != mConstants[slot].getID()) {
78            throw new IllegalArgumentException("Allocation type does not match slot type.");
79        }
80        int id = a != null ? a.getID() : 0;
81        mRS.nProgramBindConstants(getID(), slot, id);
82    }
83
84    public void bindTexture(Allocation va, int slot)
85        throws IllegalArgumentException {
86        mRS.validate();
87        if ((slot < 0) || (slot >= mTextureCount)) {
88            throw new IllegalArgumentException("Slot ID out of range.");
89        }
90        if (va != null && va.getType().hasFaces() &&
91            mTextures[slot] != TextureType.TEXTURE_CUBE) {
92            throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
93        }
94
95        int id = va != null ? va.getID() : 0;
96        mRS.nProgramBindTexture(getID(), slot, id);
97    }
98
99    public void bindSampler(Sampler vs, int slot)
100        throws IllegalArgumentException {
101        mRS.validate();
102        if ((slot < 0) || (slot >= mTextureCount)) {
103            throw new IllegalArgumentException("Slot ID out of range.");
104        }
105
106        int id = vs != null ? vs.getID() : 0;
107        mRS.nProgramBindSampler(getID(), slot, id);
108    }
109
110
111    public static class BaseProgramBuilder {
112        RenderScript mRS;
113        Element mInputs[];
114        Element mOutputs[];
115        Type mConstants[];
116        Type mTextures[];
117        TextureType mTextureTypes[];
118        int mInputCount;
119        int mOutputCount;
120        int mConstantCount;
121        int mTextureCount;
122        String mShader;
123
124
125        protected BaseProgramBuilder(RenderScript rs) {
126            mRS = rs;
127            mInputs = new Element[MAX_INPUT];
128            mOutputs = new Element[MAX_OUTPUT];
129            mConstants = new Type[MAX_CONSTANT];
130            mInputCount = 0;
131            mOutputCount = 0;
132            mConstantCount = 0;
133            mTextureCount = 0;
134            mTextureTypes = new TextureType[MAX_TEXTURE];
135        }
136
137        public BaseProgramBuilder setShader(String s) {
138            mShader = s;
139            return this;
140        }
141
142        public BaseProgramBuilder setShader(Resources resources, int resourceID) {
143            byte[] str;
144            int strLength;
145            InputStream is = resources.openRawResource(resourceID);
146            try {
147                try {
148                    str = new byte[1024];
149                    strLength = 0;
150                    while(true) {
151                        int bytesLeft = str.length - strLength;
152                        if (bytesLeft == 0) {
153                            byte[] buf2 = new byte[str.length * 2];
154                            System.arraycopy(str, 0, buf2, 0, str.length);
155                            str = buf2;
156                            bytesLeft = str.length - strLength;
157                        }
158                        int bytesRead = is.read(str, strLength, bytesLeft);
159                        if (bytesRead <= 0) {
160                            break;
161                        }
162                        strLength += bytesRead;
163                    }
164                } finally {
165                    is.close();
166                }
167            } catch(IOException e) {
168                throw new Resources.NotFoundException();
169            }
170
171            try {
172                mShader = new String(str, 0, strLength, "UTF-8");
173            } catch (UnsupportedEncodingException e) {
174                Log.e("Renderscript shader creation", "Could not decode shader string");
175            }
176
177            return this;
178        }
179
180        public int getCurrentConstantIndex() {
181            return mConstantCount - 1;
182        }
183
184        public int getCurrentTextureIndex() {
185            return mTextureCount - 1;
186        }
187
188        public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
189            // Should check for consistant and non-conflicting names...
190            if(mConstantCount >= MAX_CONSTANT) {
191                throw new RSIllegalArgumentException("Max input count exceeded.");
192            }
193            if (t.getElement().isComplex()) {
194                throw new RSIllegalArgumentException("Complex elements not allowed.");
195            }
196            mConstants[mConstantCount] = t;
197            mConstantCount++;
198            return this;
199        }
200
201        public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
202            if(mTextureCount >= MAX_TEXTURE) {
203                throw new IllegalArgumentException("Max texture count exceeded.");
204            }
205            mTextureTypes[mTextureCount ++] = texType;
206            return this;
207        }
208
209        protected void initProgram(Program p) {
210            p.mInputs = new Element[mInputCount];
211            System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
212            p.mOutputs = new Element[mOutputCount];
213            System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
214            p.mConstants = new Type[mConstantCount];
215            System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
216            p.mTextureCount = mTextureCount;
217            p.mTextures = new TextureType[mTextureCount];
218            System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
219        }
220    }
221
222}
223
224
225