diff options
Diffstat (limited to 'rs/java/android/renderscript/Program.java')
| -rw-r--r-- | rs/java/android/renderscript/Program.java | 370 | 
1 files changed, 370 insertions, 0 deletions
| diff --git a/rs/java/android/renderscript/Program.java b/rs/java/android/renderscript/Program.java new file mode 100644 index 000000000000..3eb9b7590f45 --- /dev/null +++ b/rs/java/android/renderscript/Program.java @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import android.content.res.Resources; +import android.util.Log; + + +/** + * @hide + * + * Program is a base class for all the objects that modify + * various stages of the graphics pipeline + * + **/ +public class Program extends BaseObj { +    static final int MAX_INPUT = 8; +    static final int MAX_OUTPUT = 8; +    static final int MAX_CONSTANT = 8; +    static final int MAX_TEXTURE = 8; + +    /** +     * +     * TextureType specifies what textures are attached to Program +     * objects +     * +     **/ +    public enum TextureType { +        TEXTURE_2D (0), +        TEXTURE_CUBE (1); + +        int mID; +        TextureType(int id) { +            mID = id; +        } +    } + +    enum ProgramParam { +        INPUT (0), +        OUTPUT (1), +        CONSTANT (2), +        TEXTURE_TYPE (3); + +        int mID; +        ProgramParam(int id) { +            mID = id; +        } +    }; + +    Element mInputs[]; +    Element mOutputs[]; +    Type mConstants[]; +    TextureType mTextures[]; +    String mTextureNames[]; +    int mTextureCount; +    String mShader; + +    Program(long id, RenderScript rs) { +        super(id, rs); +    } + +    /** +     * Program object can have zero or more constant allocations +     * associated with it. This method returns the total count. +     * @return number of constant input types +     */ +    public int getConstantCount() { +        return mConstants != null ? mConstants.length : 0; +    } + +    /** +     * Returns the type of the constant buffer used in the program +     * object. It could be used to query internal elements or create +     * an allocation to store constant data. +     * @param slot index of the constant input type to return +     * @return constant input type +     */ +    public Type getConstant(int slot) { +        if (slot < 0 || slot >= mConstants.length) { +            throw new IllegalArgumentException("Slot ID out of range."); +        } +        return mConstants[slot]; +    } + +    /** +     * Returns the number of textures used in this program object +     * @return number of texture inputs +     */ +    public int getTextureCount() { +        return mTextureCount; +    } + +    /** +     * Returns the type of texture at a given slot. e.g. 2D or Cube +     * @param slot index of the texture input +     * @return texture input type +     */ +    public TextureType getTextureType(int slot) { +        if ((slot < 0) || (slot >= mTextureCount)) { +            throw new IllegalArgumentException("Slot ID out of range."); +        } +        return mTextures[slot]; +    } + +    /** +     * Returns the name of the texture input at a given slot. e.g. +     * tex0, diffuse, spec +     * @param slot index of the texture input +     * @return texture input name +     */ +    public String getTextureName(int slot) { +        if ((slot < 0) || (slot >= mTextureCount)) { +            throw new IllegalArgumentException("Slot ID out of range."); +        } +        return mTextureNames[slot]; +    } + +    /** +     * Binds a constant buffer to be used as uniform inputs to the +     * program +     * +     * @param a allocation containing uniform data +     * @param slot index within the program's list of constant +     *             buffer allocations +     */ +    public void bindConstants(Allocation a, int slot) { +        if (slot < 0 || slot >= mConstants.length) { +            throw new IllegalArgumentException("Slot ID out of range."); +        } +        if (a != null && +            a.getType().getID(mRS) != mConstants[slot].getID(mRS)) { +            throw new IllegalArgumentException("Allocation type does not match slot type."); +        } +        long id = a != null ? a.getID(mRS) : 0; +        mRS.nProgramBindConstants(getID(mRS), slot, id); +    } + +    /** +     * Binds a texture to be used in the program +     * +     * @param va allocation containing texture data +     * @param slot index within the program's list of textures +     * +     */ +    public void bindTexture(Allocation va, int slot) +        throws IllegalArgumentException { +        mRS.validate(); +        if ((slot < 0) || (slot >= mTextureCount)) { +            throw new IllegalArgumentException("Slot ID out of range."); +        } +        if (va != null && va.getType().hasFaces() && +            mTextures[slot] != TextureType.TEXTURE_CUBE) { +            throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot"); +        } + +        long id = va != null ? va.getID(mRS) : 0; +        mRS.nProgramBindTexture(getID(mRS), slot, id); +    } + +    /** +     * Binds an object that describes how a texture at the +     * corresponding location is sampled +     * +     * @param vs sampler for a corresponding texture +     * @param slot index within the program's list of textures to +     *             use the sampler on +     * +     */ +    public void bindSampler(Sampler vs, int slot) +        throws IllegalArgumentException { +        mRS.validate(); +        if ((slot < 0) || (slot >= mTextureCount)) { +            throw new IllegalArgumentException("Slot ID out of range."); +        } + +        long id = vs != null ? vs.getID(mRS) : 0; +        mRS.nProgramBindSampler(getID(mRS), slot, id); +    } + + +    public static class BaseProgramBuilder { +        RenderScript mRS; +        Element mInputs[]; +        Element mOutputs[]; +        Type mConstants[]; +        Type mTextures[]; +        TextureType mTextureTypes[]; +        String mTextureNames[]; +        int mInputCount; +        int mOutputCount; +        int mConstantCount; +        int mTextureCount; +        String mShader; + + +        protected BaseProgramBuilder(RenderScript rs) { +            mRS = rs; +            mInputs = new Element[MAX_INPUT]; +            mOutputs = new Element[MAX_OUTPUT]; +            mConstants = new Type[MAX_CONSTANT]; +            mInputCount = 0; +            mOutputCount = 0; +            mConstantCount = 0; +            mTextureCount = 0; +            mTextureTypes = new TextureType[MAX_TEXTURE]; +            mTextureNames = new String[MAX_TEXTURE]; +        } + +        /** +         * Sets the GLSL shader code to be used in the program +         * +         * @param s GLSL shader string +         * @return  self +         */ +        public BaseProgramBuilder setShader(String s) { +            mShader = s; +            return this; +        } + +        /** +         * Sets the GLSL shader code to be used in the program +         * +         * @param resources application resources +         * @param resourceID id of the file containing GLSL shader code +         * +         * @return  self +         */ +        public BaseProgramBuilder setShader(Resources resources, int resourceID) { +            byte[] str; +            int strLength; +            InputStream is = resources.openRawResource(resourceID); +            try { +                try { +                    str = new byte[1024]; +                    strLength = 0; +                    while(true) { +                        int bytesLeft = str.length - strLength; +                        if (bytesLeft == 0) { +                            byte[] buf2 = new byte[str.length * 2]; +                            System.arraycopy(str, 0, buf2, 0, str.length); +                            str = buf2; +                            bytesLeft = str.length - strLength; +                        } +                        int bytesRead = is.read(str, strLength, bytesLeft); +                        if (bytesRead <= 0) { +                            break; +                        } +                        strLength += bytesRead; +                    } +                } finally { +                    is.close(); +                } +            } catch(IOException e) { +                throw new Resources.NotFoundException(); +            } + +            try { +                mShader = new String(str, 0, strLength, "UTF-8"); +            } catch (UnsupportedEncodingException e) { +                Log.e("RenderScript shader creation", "Could not decode shader string"); +            } + +            return this; +        } + +        /** +         * Queries the index of the last added constant buffer type +         * +         */ +        public int getCurrentConstantIndex() { +            return mConstantCount - 1; +        } + +        /** +         * Queries the index of the last added texture type +         * +         */ +        public int getCurrentTextureIndex() { +            return mTextureCount - 1; +        } + +        /** +         * Adds constant (uniform) inputs to the program +         * +         * @param t Type that describes the layout of the Allocation +         *          object to be used as constant inputs to the Program +         * @return  self +         */ +        public BaseProgramBuilder addConstant(Type t) throws IllegalStateException { +            // Should check for consistant and non-conflicting names... +            if(mConstantCount >= MAX_CONSTANT) { +                throw new RSIllegalArgumentException("Max input count exceeded."); +            } +            if (t.getElement().isComplex()) { +                throw new RSIllegalArgumentException("Complex elements not allowed."); +            } +            mConstants[mConstantCount] = t; +            mConstantCount++; +            return this; +        } + +        /** +         * Adds a texture input to the Program +         * +         * @param texType describes that the texture to append it (2D, +         *                Cubemap, etc.) +         * @return  self +         */ +        public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException { +            addTexture(texType, "Tex" + mTextureCount); +            return this; +        } + +        /** +         * Adds a texture input to the Program +         * +         * @param texType describes that the texture to append it (2D, +         *                Cubemap, etc.) +         * @param texName what the texture should be called in the +         *                shader +         * @return  self +         */ +        public BaseProgramBuilder addTexture(TextureType texType, String texName) +            throws IllegalArgumentException { +            if(mTextureCount >= MAX_TEXTURE) { +                throw new IllegalArgumentException("Max texture count exceeded."); +            } +            mTextureTypes[mTextureCount] = texType; +            mTextureNames[mTextureCount] = texName; +            mTextureCount ++; +            return this; +        } + +        protected void initProgram(Program p) { +            p.mInputs = new Element[mInputCount]; +            System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount); +            p.mOutputs = new Element[mOutputCount]; +            System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount); +            p.mConstants = new Type[mConstantCount]; +            System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount); +            p.mTextureCount = mTextureCount; +            p.mTextures = new TextureType[mTextureCount]; +            System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount); +            p.mTextureNames = new String[mTextureCount]; +            System.arraycopy(mTextureNames, 0, p.mTextureNames, 0, mTextureCount); +        } +    } + +} + + | 
