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 0000000..3eb9b75 --- /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); + } + } + +} + + |