Program.java revision c1d6210fb5cc558ccea95a59a2b33bb9015fc7de
10011bcf57ff711a221a3a4c73f2a79125111647dJason Sams/*
20011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * Copyright (C) 2008 The Android Open Source Project
30011bcf57ff711a221a3a4c73f2a79125111647dJason Sams *
40011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
50011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * you may not use this file except in compliance with the License.
60011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * You may obtain a copy of the License at
70011bcf57ff711a221a3a4c73f2a79125111647dJason Sams *
80011bcf57ff711a221a3a4c73f2a79125111647dJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
90011bcf57ff711a221a3a4c73f2a79125111647dJason Sams *
100011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * Unless required by applicable law or agreed to in writing, software
110011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
120011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * See the License for the specific language governing permissions and
140011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * limitations under the License.
150011bcf57ff711a221a3a4c73f2a79125111647dJason Sams */
160011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
170011bcf57ff711a221a3a4c73f2a79125111647dJason Samspackage android.renderscript;
180011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
190011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
20a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchoukimport java.io.IOException;
21a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchoukimport java.io.InputStream;
22a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchoukimport java.io.UnsupportedEncodingException;
23a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk
24a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchoukimport android.content.res.Resources;
250011bcf57ff711a221a3a4c73f2a79125111647dJason Samsimport android.util.Config;
260011bcf57ff711a221a3a4c73f2a79125111647dJason Samsimport android.util.Log;
270011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
280011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
290011bcf57ff711a221a3a4c73f2a79125111647dJason Sams/**
300011bcf57ff711a221a3a4c73f2a79125111647dJason Sams * @hide
310011bcf57ff711a221a3a4c73f2a79125111647dJason Sams *
320011bcf57ff711a221a3a4c73f2a79125111647dJason Sams **/
330011bcf57ff711a221a3a4c73f2a79125111647dJason Samspublic class Program extends BaseObj {
340011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    public static final int MAX_INPUT = 8;
350011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    public static final int MAX_OUTPUT = 8;
360011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    public static final int MAX_CONSTANT = 8;
377e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    public static final int MAX_TEXTURE = 8;
380011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
390011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    Element mInputs[];
400011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    Element mOutputs[];
410011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    Type mConstants[];
427e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    int mTextureCount;
430011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    String mShader;
440011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
450011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    Program(int id, RenderScript rs) {
460de9444aa6c25d2c586e8204a6168d10e67376e0Alex Sakhartchouk        super(id, rs);
470011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    }
480011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
490011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    public void bindConstants(Allocation a, int slot) {
50c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams        if (slot < 0 || slot >= mConstants.length) {
51c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            throw new IllegalArgumentException("Slot ID out of range.");
52c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams        }
53c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams        if (a != null &&
54c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            a.getType().getID() != mConstants[slot].getID()) {
55c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            throw new IllegalArgumentException("Allocation type does not match slot type.");
56c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams        }
570011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        mRS.nProgramBindConstants(mID, slot, a.mID);
580011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    }
590011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
6068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    public void bindTexture(Allocation va, int slot)
6168afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        throws IllegalArgumentException {
6268afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        mRS.validate();
6368afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        if((slot < 0) || (slot >= mTextureCount)) {
6468afd01ec9fd37774d8291192952a25e5605b6fbJason Sams            throw new IllegalArgumentException("Slot ID out of range.");
6568afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        }
6668afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
6768afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        mRS.nProgramBindTexture(mID, slot, va.mID);
6868afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    }
6968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
7068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    public void bindSampler(Sampler vs, int slot)
7168afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        throws IllegalArgumentException {
7268afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        mRS.validate();
7368afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        if((slot < 0) || (slot >= mTextureCount)) {
7468afd01ec9fd37774d8291192952a25e5605b6fbJason Sams            throw new IllegalArgumentException("Slot ID out of range.");
7568afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        }
7668afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
7768afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        mRS.nProgramBindSampler(mID, slot, vs.mID);
7868afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    }
7968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
8068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
810011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    public static class BaseProgramBuilder {
820011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        RenderScript mRS;
830011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        Element mInputs[];
840011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        Element mOutputs[];
850011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        Type mConstants[];
860011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        Type mTextures[];
870011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        int mInputCount;
880011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        int mOutputCount;
890011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        int mConstantCount;
900011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        int mTextureCount;
910011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        String mShader;
920011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
930011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
940011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        protected BaseProgramBuilder(RenderScript rs) {
950011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mRS = rs;
960011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mInputs = new Element[MAX_INPUT];
970011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mOutputs = new Element[MAX_OUTPUT];
980011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mConstants = new Type[MAX_CONSTANT];
990011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mInputCount = 0;
1000011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mOutputCount = 0;
1010011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mConstantCount = 0;
1027e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            mTextureCount = 0;
1030011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
1040011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
105288c8711a64893acb3f4a31caf69153be9809d17Jim Shuma        public BaseProgramBuilder setShader(String s) {
1060011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mShader = s;
107288c8711a64893acb3f4a31caf69153be9809d17Jim Shuma            return this;
1080011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
1090011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
110a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk        public BaseProgramBuilder setShader(Resources resources, int resourceID) {
111a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            byte[] str;
112a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            int strLength;
113a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            InputStream is = resources.openRawResource(resourceID);
114a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            try {
115a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                try {
116a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    str = new byte[1024];
117a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    strLength = 0;
118a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    while(true) {
119a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        int bytesLeft = str.length - strLength;
120a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        if (bytesLeft == 0) {
121a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            byte[] buf2 = new byte[str.length * 2];
122a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            System.arraycopy(str, 0, buf2, 0, str.length);
123a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            str = buf2;
124a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            bytesLeft = str.length - strLength;
125a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        }
126a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        int bytesRead = is.read(str, strLength, bytesLeft);
127a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        if (bytesRead <= 0) {
128a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            break;
129a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        }
130a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        strLength += bytesRead;
131a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    }
132a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                } finally {
133a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    is.close();
134a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                }
135a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            } catch(IOException e) {
136a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                throw new Resources.NotFoundException();
137a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            }
138a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk
139a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            try {
140a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                mShader = new String(str, 0, strLength, "UTF-8");
141a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            } catch (UnsupportedEncodingException e) {
142a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                Log.e("Renderscript shader creation", "Could not decode shader string");
143a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            }
144a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk
145a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            return this;
146a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk        }
147a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk
1480011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        public void addInput(Element e) throws IllegalStateException {
1490011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            // Should check for consistant and non-conflicting names...
1500011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            if(mInputCount >= MAX_INPUT) {
151c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams                throw new RSIllegalArgumentException("Max input count exceeded.");
152c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            }
153c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            if (e.isComplex()) {
154c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams                throw new RSIllegalArgumentException("Complex elements not allowed.");
1550011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            }
1560011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mInputs[mInputCount++] = e;
1570011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
1580011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
1590011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        public void addOutput(Element e) throws IllegalStateException {
1600011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            // Should check for consistant and non-conflicting names...
1610011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            if(mOutputCount >= MAX_OUTPUT) {
162c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams                throw new RSIllegalArgumentException("Max output count exceeded.");
163c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            }
164c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            if (e.isComplex()) {
165c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams                throw new RSIllegalArgumentException("Complex elements not allowed.");
1660011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            }
1670011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mOutputs[mOutputCount++] = e;
1680011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
1690011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
170b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk        void resetConstant() {
171b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk            mConstantCount = 0;
172b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk            for(int i = 0; i < MAX_CONSTANT; i ++) {
173b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk                mConstants[i] = null;
174b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk            }
175b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk        }
176b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk
177ea87e96959895ef94cc3aa9576f41a660d2bbf03Jason Sams        public int addConstant(Type t) throws IllegalStateException {
1780011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            // Should check for consistant and non-conflicting names...
1790011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            if(mConstantCount >= MAX_CONSTANT) {
180c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams                throw new RSIllegalArgumentException("Max input count exceeded.");
181c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            }
182c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            if (t.getElement().isComplex()) {
183c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams                throw new RSIllegalArgumentException("Complex elements not allowed.");
1840011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            }
185ea87e96959895ef94cc3aa9576f41a660d2bbf03Jason Sams            mConstants[mConstantCount] = t;
186ea87e96959895ef94cc3aa9576f41a660d2bbf03Jason Sams            return mConstantCount++;
1870011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
1880011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
189288c8711a64893acb3f4a31caf69153be9809d17Jim Shuma        public BaseProgramBuilder setTextureCount(int count) throws IllegalArgumentException {
1900011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            // Should check for consistant and non-conflicting names...
191b89aaacb2ca9d062e0a17a32e3d4dbf3f6948a17Alex Sakhartchouk            if(count >= MAX_TEXTURE) {
1927e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                throw new IllegalArgumentException("Max texture count exceeded.");
1930011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            }
1947e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            mTextureCount = count;
195288c8711a64893acb3f4a31caf69153be9809d17Jim Shuma            return this;
1960011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
1970011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
1980011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        protected void initProgram(Program p) {
1990011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            p.mInputs = new Element[mInputCount];
2000011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
2010011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            p.mOutputs = new Element[mOutputCount];
2020011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
2030011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            p.mConstants = new Type[mConstantCount];
2040011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
2057e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            p.mTextureCount = mTextureCount;
2060011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
2070011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    }
2080011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
2090011bcf57ff711a221a3a4c73f2a79125111647dJason Sams}
2100011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
2110011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
212