| /* | |
| * 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 android.compat.annotation.UnsupportedAppUsage; | |
| import android.content.res.Resources; | |
| import android.util.Log; | |
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.io.UnsupportedEncodingException; | |
| /** | |
| * @hide | |
| * | |
| * Program is a base class for all the objects that modify | |
| * various stages of the graphics pipeline | |
| * | |
| * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a | |
| * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration | |
| * guide</a> for the proposed alternatives. | |
| **/ | |
| @Deprecated | |
| 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 { | |
| @UnsupportedAppUsage | |
| 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); | |
| guard.open("destroy"); | |
| } | |
| /** | |
| * 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 { | |
| @UnsupportedAppUsage | |
| RenderScript mRS; | |
| @UnsupportedAppUsage | |
| Element mInputs[]; | |
| @UnsupportedAppUsage | |
| Element mOutputs[]; | |
| @UnsupportedAppUsage | |
| Type mConstants[]; | |
| Type mTextures[]; | |
| TextureType mTextureTypes[]; | |
| String mTextureNames[]; | |
| @UnsupportedAppUsage | |
| int mInputCount; | |
| @UnsupportedAppUsage | |
| int mOutputCount; | |
| @UnsupportedAppUsage | |
| int mConstantCount; | |
| @UnsupportedAppUsage | |
| int mTextureCount; | |
| @UnsupportedAppUsage | |
| String mShader; | |
| @UnsupportedAppUsage | |
| 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); | |
| } | |
| } | |
| } | |