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