Program.java revision c1d6210fb5cc558ccea95a59a2b33bb9015fc7de
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    Element mInputs[];
40    Element mOutputs[];
41    Type mConstants[];
42    int mTextureCount;
43    String mShader;
44
45    Program(int id, RenderScript rs) {
46        super(id, rs);
47    }
48
49    public void bindConstants(Allocation a, int slot) {
50        if (slot < 0 || slot >= mConstants.length) {
51            throw new IllegalArgumentException("Slot ID out of range.");
52        }
53        if (a != null &&
54            a.getType().getID() != mConstants[slot].getID()) {
55            throw new IllegalArgumentException("Allocation type does not match slot type.");
56        }
57        mRS.nProgramBindConstants(mID, slot, a.mID);
58    }
59
60    public void bindTexture(Allocation va, int slot)
61        throws IllegalArgumentException {
62        mRS.validate();
63        if((slot < 0) || (slot >= mTextureCount)) {
64            throw new IllegalArgumentException("Slot ID out of range.");
65        }
66
67        mRS.nProgramBindTexture(mID, slot, va.mID);
68    }
69
70    public void bindSampler(Sampler vs, int slot)
71        throws IllegalArgumentException {
72        mRS.validate();
73        if((slot < 0) || (slot >= mTextureCount)) {
74            throw new IllegalArgumentException("Slot ID out of range.");
75        }
76
77        mRS.nProgramBindSampler(mID, slot, vs.mID);
78    }
79
80
81    public static class BaseProgramBuilder {
82        RenderScript mRS;
83        Element mInputs[];
84        Element mOutputs[];
85        Type mConstants[];
86        Type mTextures[];
87        int mInputCount;
88        int mOutputCount;
89        int mConstantCount;
90        int mTextureCount;
91        String mShader;
92
93
94        protected BaseProgramBuilder(RenderScript rs) {
95            mRS = rs;
96            mInputs = new Element[MAX_INPUT];
97            mOutputs = new Element[MAX_OUTPUT];
98            mConstants = new Type[MAX_CONSTANT];
99            mInputCount = 0;
100            mOutputCount = 0;
101            mConstantCount = 0;
102            mTextureCount = 0;
103        }
104
105        public BaseProgramBuilder setShader(String s) {
106            mShader = s;
107            return this;
108        }
109
110        public BaseProgramBuilder setShader(Resources resources, int resourceID) {
111            byte[] str;
112            int strLength;
113            InputStream is = resources.openRawResource(resourceID);
114            try {
115                try {
116                    str = new byte[1024];
117                    strLength = 0;
118                    while(true) {
119                        int bytesLeft = str.length - strLength;
120                        if (bytesLeft == 0) {
121                            byte[] buf2 = new byte[str.length * 2];
122                            System.arraycopy(str, 0, buf2, 0, str.length);
123                            str = buf2;
124                            bytesLeft = str.length - strLength;
125                        }
126                        int bytesRead = is.read(str, strLength, bytesLeft);
127                        if (bytesRead <= 0) {
128                            break;
129                        }
130                        strLength += bytesRead;
131                    }
132                } finally {
133                    is.close();
134                }
135            } catch(IOException e) {
136                throw new Resources.NotFoundException();
137            }
138
139            try {
140                mShader = new String(str, 0, strLength, "UTF-8");
141            } catch (UnsupportedEncodingException e) {
142                Log.e("Renderscript shader creation", "Could not decode shader string");
143            }
144
145            return this;
146        }
147
148        public void addInput(Element e) throws IllegalStateException {
149            // Should check for consistant and non-conflicting names...
150            if(mInputCount >= MAX_INPUT) {
151                throw new RSIllegalArgumentException("Max input count exceeded.");
152            }
153            if (e.isComplex()) {
154                throw new RSIllegalArgumentException("Complex elements not allowed.");
155            }
156            mInputs[mInputCount++] = e;
157        }
158
159        public void addOutput(Element e) throws IllegalStateException {
160            // Should check for consistant and non-conflicting names...
161            if(mOutputCount >= MAX_OUTPUT) {
162                throw new RSIllegalArgumentException("Max output count exceeded.");
163            }
164            if (e.isComplex()) {
165                throw new RSIllegalArgumentException("Complex elements not allowed.");
166            }
167            mOutputs[mOutputCount++] = e;
168        }
169
170        void resetConstant() {
171            mConstantCount = 0;
172            for(int i = 0; i < MAX_CONSTANT; i ++) {
173                mConstants[i] = null;
174            }
175        }
176
177        public int addConstant(Type t) throws IllegalStateException {
178            // Should check for consistant and non-conflicting names...
179            if(mConstantCount >= MAX_CONSTANT) {
180                throw new RSIllegalArgumentException("Max input count exceeded.");
181            }
182            if (t.getElement().isComplex()) {
183                throw new RSIllegalArgumentException("Complex elements not allowed.");
184            }
185            mConstants[mConstantCount] = t;
186            return mConstantCount++;
187        }
188
189        public BaseProgramBuilder setTextureCount(int count) throws IllegalArgumentException {
190            // Should check for consistant and non-conflicting names...
191            if(count >= MAX_TEXTURE) {
192                throw new IllegalArgumentException("Max texture count exceeded.");
193            }
194            mTextureCount = count;
195            return this;
196        }
197
198        protected void initProgram(Program p) {
199            p.mInputs = new Element[mInputCount];
200            System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
201            p.mOutputs = new Element[mOutputCount];
202            System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
203            p.mConstants = new Type[mConstantCount];
204            System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
205            p.mTextureCount = mTextureCount;
206        }
207    }
208
209}
210
211
212