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.Log;
260011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
270011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
289c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines/**
29a90842283e322b1210e2bea5850b05177e3d87afTim Murray * @hide
300011bcf57ff711a221a3a4c73f2a79125111647dJason Sams *
31df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk * Program is a base class for all the objects that modify
32df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk * various stages of the graphics pipeline
33df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk *
340011bcf57ff711a221a3a4c73f2a79125111647dJason Sams **/
350011bcf57ff711a221a3a4c73f2a79125111647dJason Samspublic class Program extends BaseObj {
360473ff1ef653434a1a0f3c07be00f7ebcbb472adAlex Sakhartchouk    static final int MAX_INPUT = 8;
370473ff1ef653434a1a0f3c07be00f7ebcbb472adAlex Sakhartchouk    static final int MAX_OUTPUT = 8;
380473ff1ef653434a1a0f3c07be00f7ebcbb472adAlex Sakhartchouk    static final int MAX_CONSTANT = 8;
390473ff1ef653434a1a0f3c07be00f7ebcbb472adAlex Sakhartchouk    static final int MAX_TEXTURE = 8;
400011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
419c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
42df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     *
43df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * TextureType specifies what textures are attached to Program
44df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * objects
45df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     *
46df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     **/
4767f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    public enum TextureType {
4867f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        TEXTURE_2D (0),
4967f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        TEXTURE_CUBE (1);
5067f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk
5167f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        int mID;
5267f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        TextureType(int id) {
5367f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            mID = id;
5467f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        }
5567f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    }
5667f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk
5767f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    enum ProgramParam {
5867f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        INPUT (0),
5967f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        OUTPUT (1),
6067f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        CONSTANT (2),
6167f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        TEXTURE_TYPE (3);
6267f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk
6367f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        int mID;
6467f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        ProgramParam(int id) {
6567f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            mID = id;
6667f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        }
6767f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    };
6867f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk
690011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    Element mInputs[];
700011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    Element mOutputs[];
710011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    Type mConstants[];
7267f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk    TextureType mTextures[];
732123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk    String mTextureNames[];
747e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    int mTextureCount;
750011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    String mShader;
760011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
77460a04971c494fec39ffcb38e873bb8fdd82d113Tim Murray    Program(long id, RenderScript rs) {
780de9444aa6c25d2c586e8204a6168d10e67376e0Alex Sakhartchouk        super(id, rs);
79eb4dd08ec132f83745b8b28fa7da58eb4478b5b9Yang Ni        guard.open("destroy");
800011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    }
810011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
829c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
83918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * Program object can have zero or more constant allocations
84918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * associated with it. This method returns the total count.
85918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * @return number of constant input types
86d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk     */
87d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk    public int getConstantCount() {
88d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk        return mConstants != null ? mConstants.length : 0;
89d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk    }
90d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk
919c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
92918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * Returns the type of the constant buffer used in the program
93918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * object. It could be used to query internal elements or create
94918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * an allocation to store constant data.
95918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * @param slot index of the constant input type to return
96918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * @return constant input type
97d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk     */
98d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk    public Type getConstant(int slot) {
99d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk        if (slot < 0 || slot >= mConstants.length) {
100d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk            throw new IllegalArgumentException("Slot ID out of range.");
101d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk        }
102d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk        return mConstants[slot];
103d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk    }
104d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk
1059c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
106918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * Returns the number of textures used in this program object
107918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * @return number of texture inputs
108d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk     */
109d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk    public int getTextureCount() {
110d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk        return mTextureCount;
111d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk    }
112d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk
1139c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
114918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * Returns the type of texture at a given slot. e.g. 2D or Cube
115918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * @param slot index of the texture input
116918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * @return texture input type
117d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk     */
118d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk    public TextureType getTextureType(int slot) {
119d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk        if ((slot < 0) || (slot >= mTextureCount)) {
120d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk            throw new IllegalArgumentException("Slot ID out of range.");
121d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk        }
122d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk        return mTextures[slot];
123d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk    }
124d5a62bb802887134ed652b01fa6a3159a5c6ad0eAlex Sakhartchouk
1259c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
126918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * Returns the name of the texture input at a given slot. e.g.
127918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * tex0, diffuse, spec
128918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * @param slot index of the texture input
129918e840628a0b40a95fd42618f604ea5a44aebaeAlex Sakhartchouk     * @return texture input name
1302123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk     */
1312123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk    public String getTextureName(int slot) {
1322123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk        if ((slot < 0) || (slot >= mTextureCount)) {
1332123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            throw new IllegalArgumentException("Slot ID out of range.");
1342123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk        }
1352123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk        return mTextureNames[slot];
1362123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk    }
1372123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk
1389c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
139df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * Binds a constant buffer to be used as uniform inputs to the
140df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * program
141df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     *
142df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * @param a allocation containing uniform data
143df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * @param slot index within the program's list of constant
144df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     *             buffer allocations
145df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     */
1460011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    public void bindConstants(Allocation a, int slot) {
147c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams        if (slot < 0 || slot >= mConstants.length) {
148c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            throw new IllegalArgumentException("Slot ID out of range.");
149c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams        }
150c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams        if (a != null &&
151e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams            a.getType().getID(mRS) != mConstants[slot].getID(mRS)) {
152c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            throw new IllegalArgumentException("Allocation type does not match slot type.");
153c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams        }
154460a04971c494fec39ffcb38e873bb8fdd82d113Tim Murray        long id = a != null ? a.getID(mRS) : 0;
155e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams        mRS.nProgramBindConstants(getID(mRS), slot, id);
1560011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    }
1570011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
1589c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
159df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * Binds a texture to be used in the program
160df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     *
161df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * @param va allocation containing texture data
162df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * @param slot index within the program's list of textures
163df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     *
164df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     */
16568afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    public void bindTexture(Allocation va, int slot)
16668afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        throws IllegalArgumentException {
16768afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        mRS.validate();
16867f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        if ((slot < 0) || (slot >= mTextureCount)) {
16968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams            throw new IllegalArgumentException("Slot ID out of range.");
17068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        }
171bf6ef8d78fffbce6c1849a4a28fb3f4401ad039eJason Sams        if (va != null && va.getType().hasFaces() &&
17267f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            mTextures[slot] != TextureType.TEXTURE_CUBE) {
17367f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
17467f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        }
17568afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
176460a04971c494fec39ffcb38e873bb8fdd82d113Tim Murray        long id = va != null ? va.getID(mRS) : 0;
177e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams        mRS.nProgramBindTexture(getID(mRS), slot, id);
17868afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    }
17968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
1809c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines    /**
181df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * Binds an object that describes how a texture at the
182df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * corresponding location is sampled
183df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     *
184df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * @param vs sampler for a corresponding texture
185df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     * @param slot index within the program's list of textures to
186df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     *             use the sampler on
187df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     *
188df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk     */
18968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    public void bindSampler(Sampler vs, int slot)
19068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        throws IllegalArgumentException {
19168afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        mRS.validate();
19267f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        if ((slot < 0) || (slot >= mTextureCount)) {
19368afd01ec9fd37774d8291192952a25e5605b6fbJason Sams            throw new IllegalArgumentException("Slot ID out of range.");
19468afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        }
19568afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
196460a04971c494fec39ffcb38e873bb8fdd82d113Tim Murray        long id = vs != null ? vs.getID(mRS) : 0;
197e07694b24f7d12d72b084b6651356681ebd0efd6Jason Sams        mRS.nProgramBindSampler(getID(mRS), slot, id);
19868afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    }
19968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
20068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
2010011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    public static class BaseProgramBuilder {
2020011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        RenderScript mRS;
2030011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        Element mInputs[];
2040011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        Element mOutputs[];
2050011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        Type mConstants[];
2060011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        Type mTextures[];
20767f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        TextureType mTextureTypes[];
2082123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk        String mTextureNames[];
2090011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        int mInputCount;
2100011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        int mOutputCount;
2110011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        int mConstantCount;
2120011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        int mTextureCount;
2130011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        String mShader;
2140011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
2159c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines
2160011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        protected BaseProgramBuilder(RenderScript rs) {
2170011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mRS = rs;
2180011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mInputs = new Element[MAX_INPUT];
2190011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mOutputs = new Element[MAX_OUTPUT];
2200011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mConstants = new Type[MAX_CONSTANT];
2210011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mInputCount = 0;
2220011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mOutputCount = 0;
2230011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mConstantCount = 0;
2247e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            mTextureCount = 0;
22567f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            mTextureTypes = new TextureType[MAX_TEXTURE];
2262123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            mTextureNames = new String[MAX_TEXTURE];
2270011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
2280011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
2299c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines        /**
230df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * Sets the GLSL shader code to be used in the program
231df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         *
232df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * @param s GLSL shader string
233df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * @return  self
234df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         */
235288c8711a64893acb3f4a31caf69153be9809d17Jim Shuma        public BaseProgramBuilder setShader(String s) {
2360011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            mShader = s;
237288c8711a64893acb3f4a31caf69153be9809d17Jim Shuma            return this;
2380011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
2390011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
2409c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines        /**
241df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * Sets the GLSL shader code to be used in the program
242df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         *
243df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * @param resources application resources
244df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * @param resourceID id of the file containing GLSL shader code
245df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         *
246df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * @return  self
247df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         */
248a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk        public BaseProgramBuilder setShader(Resources resources, int resourceID) {
249a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            byte[] str;
250a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            int strLength;
251a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            InputStream is = resources.openRawResource(resourceID);
252a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            try {
253a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                try {
254a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    str = new byte[1024];
255a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    strLength = 0;
256a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    while(true) {
257a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        int bytesLeft = str.length - strLength;
258a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        if (bytesLeft == 0) {
259a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            byte[] buf2 = new byte[str.length * 2];
260a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            System.arraycopy(str, 0, buf2, 0, str.length);
261a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            str = buf2;
262a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            bytesLeft = str.length - strLength;
263a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        }
264a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        int bytesRead = is.read(str, strLength, bytesLeft);
265a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        if (bytesRead <= 0) {
266a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                            break;
267a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        }
268a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                        strLength += bytesRead;
269a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    }
270a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                } finally {
271a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                    is.close();
272a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                }
273a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            } catch(IOException e) {
274a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                throw new Resources.NotFoundException();
275a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            }
276a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk
277a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            try {
278a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk                mShader = new String(str, 0, strLength, "UTF-8");
279a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            } catch (UnsupportedEncodingException e) {
280c11e25c4e653124def1fb18e203b894f42106cbeTim Murray                Log.e("RenderScript shader creation", "Could not decode shader string");
281a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            }
282a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk
283a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk            return this;
284a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk        }
285a41174ecb03331d770614ecc6351cbc890874c28Alex Sakhartchouk
2869c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines        /**
287df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * Queries the index of the last added constant buffer type
288df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         *
289df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         */
290b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public int getCurrentConstantIndex() {
291b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            return mConstantCount - 1;
2920011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
2930011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
2949c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines        /**
295df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * Queries the index of the last added texture type
296df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         *
297df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         */
298b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public int getCurrentTextureIndex() {
299b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            return mTextureCount - 1;
3000011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
3010011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
3029c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines        /**
303df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * Adds constant (uniform) inputs to the program
304df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         *
305df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * @param t Type that describes the layout of the Allocation
306df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         *          object to be used as constant inputs to the Program
307df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * @return  self
308df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         */
309b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
3100011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            // Should check for consistant and non-conflicting names...
3110011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            if(mConstantCount >= MAX_CONSTANT) {
312c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams                throw new RSIllegalArgumentException("Max input count exceeded.");
313c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            }
314c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams            if (t.getElement().isComplex()) {
315c1d6210fb5cc558ccea95a59a2b33bb9015fc7deJason Sams                throw new RSIllegalArgumentException("Complex elements not allowed.");
3160011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            }
317ea87e96959895ef94cc3aa9576f41a660d2bbf03Jason Sams            mConstants[mConstantCount] = t;
318b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mConstantCount++;
31967f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            return this;
32067f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        }
32167f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk
3229c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines        /**
323df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * Adds a texture input to the Program
324df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         *
325df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * @param texType describes that the texture to append it (2D,
326df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         *                Cubemap, etc.)
327df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         * @return  self
328df27202debdc2573b7882405010fba31ee4d46e6Alex Sakhartchouk         */
32967f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk        public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
3302123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            addTexture(texType, "Tex" + mTextureCount);
3312123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            return this;
3322123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk        }
3332123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk
3349c9ad3f8c218954e46aab81f9af7834cea5675caStephen Hines        /**
3352123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk         * Adds a texture input to the Program
3362123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk         *
3372123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk         * @param texType describes that the texture to append it (2D,
3382123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk         *                Cubemap, etc.)
3392123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk         * @param texName what the texture should be called in the
3402123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk         *                shader
3412123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk         * @return  self
3422123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk         */
3432123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk        public BaseProgramBuilder addTexture(TextureType texType, String texName)
3442123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            throws IllegalArgumentException {
34567f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            if(mTextureCount >= MAX_TEXTURE) {
34667f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk                throw new IllegalArgumentException("Max texture count exceeded.");
34767f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            }
3482123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            mTextureTypes[mTextureCount] = texType;
3492123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            mTextureNames[mTextureCount] = texName;
3502123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            mTextureCount ++;
351288c8711a64893acb3f4a31caf69153be9809d17Jim Shuma            return this;
3520011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
3530011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
3540011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        protected void initProgram(Program p) {
3550011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            p.mInputs = new Element[mInputCount];
3560011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
3570011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            p.mOutputs = new Element[mOutputCount];
3580011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
3590011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            p.mConstants = new Type[mConstantCount];
3600011bcf57ff711a221a3a4c73f2a79125111647dJason Sams            System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
3617e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            p.mTextureCount = mTextureCount;
36267f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            p.mTextures = new TextureType[mTextureCount];
36367f2e442a31b8395e3c1951f8e91139ec7f2be99Alex Sakhartchouk            System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
3642123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            p.mTextureNames = new String[mTextureCount];
3652123b46ba85adb2cfb78068f8368e830640118d3Alex Sakhartchouk            System.arraycopy(mTextureNames, 0, p.mTextureNames, 0, mTextureCount);
3660011bcf57ff711a221a3a4c73f2a79125111647dJason Sams        }
3670011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    }
3680011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
3690011bcf57ff711a221a3a4c73f2a79125111647dJason Sams}
3700011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
3710011bcf57ff711a221a3a4c73f2a79125111647dJason Sams
372