rsProgram.cpp revision 7dad9c30a59c99b57269e1b498807b6f034d56e9
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "rsContext.h" 18#include "rsProgram.h" 19 20#include <GLES2/gl2.h> 21#include <GLES2/gl2ext.h> 22 23using namespace android; 24using namespace android::renderscript; 25 26 27Program::Program(Context *rsc) : ObjectBase(rsc) 28{ 29 mAllocFile = __FILE__; 30 mAllocLine = __LINE__; 31 mDirty = true; 32 mShaderID = 0; 33 mAttribCount = 0; 34 mUniformCount = 0; 35 36 mInputElements = NULL; 37 mOutputElements = NULL; 38 mConstantTypes = NULL; 39 mInputCount = 0; 40 mOutputCount = 0; 41 mConstantCount = 0; 42} 43 44Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, 45 const uint32_t * params, uint32_t paramLength) : 46 ObjectBase(rsc) 47{ 48 mAllocFile = __FILE__; 49 mAllocLine = __LINE__; 50 mDirty = true; 51 mShaderID = 0; 52 mAttribCount = 0; 53 mUniformCount = 0; 54 mTextureCount = 0; 55 56 mInputCount = 0; 57 mOutputCount = 0; 58 mConstantCount = 0; 59 60 for (uint32_t ct=0; ct < paramLength; ct+=2) { 61 if (params[ct] == RS_PROGRAM_PARAM_INPUT) { 62 mInputCount++; 63 } 64 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) { 65 mOutputCount++; 66 } 67 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) { 68 mConstantCount++; 69 } 70 if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) { 71 mTextureCount = params[ct+1]; 72 } 73 } 74 75 mInputElements = new ObjectBaseRef<Element>[mInputCount]; 76 mOutputElements = new ObjectBaseRef<Element>[mOutputCount]; 77 mConstantTypes = new ObjectBaseRef<Type>[mConstantCount]; 78 79 uint32_t input = 0; 80 uint32_t output = 0; 81 uint32_t constant = 0; 82 for (uint32_t ct=0; ct < paramLength; ct+=2) { 83 if (params[ct] == RS_PROGRAM_PARAM_INPUT) { 84 mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1])); 85 } 86 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) { 87 mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1])); 88 } 89 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) { 90 mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1])); 91 } 92 } 93 mUserShader.setTo(shaderText, shaderLength); 94} 95 96Program::~Program() 97{ 98 bindAllocation(NULL); 99 100 delete[] mInputElements; 101 delete[] mOutputElements; 102 delete[] mConstantTypes; 103 mInputCount = 0; 104 mOutputCount = 0; 105 mConstantCount = 0; 106} 107 108 109void Program::bindAllocation(Allocation *alloc) 110{ 111 if (mConstants.get() == alloc) { 112 return; 113 } 114 if (mConstants.get()) { 115 mConstants.get()->removeProgramToDirty(this); 116 } 117 mConstants.set(alloc); 118 if (alloc) { 119 alloc->addProgramToDirty(this); 120 } 121 mDirty = true; 122} 123 124void Program::bindTexture(uint32_t slot, Allocation *a) 125{ 126 if (slot >= MAX_TEXTURE) { 127 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE"); 128 return; 129 } 130 131 //LOGE("bindtex %i %p", slot, a); 132 mTextures[slot].set(a); 133 mDirty = true; 134} 135 136void Program::bindSampler(uint32_t slot, Sampler *s) 137{ 138 if (slot >= MAX_TEXTURE) { 139 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE"); 140 return; 141 } 142 143 mSamplers[slot].set(s); 144 mDirty = true; 145} 146 147 148void Program::createShader() 149{ 150} 151 152bool Program::loadShader(Context *rsc, uint32_t type) 153{ 154 mShaderID = glCreateShader(type); 155 rsAssert(mShaderID); 156 157 if (rsc->props.mLogShaders) { 158 LOGV("Loading shader type %x, ID %i", type, mShaderID); 159 LOGV(mShader.string()); 160 } 161 162 if (mShaderID) { 163 const char * ss = mShader.string(); 164 glShaderSource(mShaderID, 1, &ss, NULL); 165 glCompileShader(mShaderID); 166 167 GLint compiled = 0; 168 glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled); 169 if (!compiled) { 170 GLint infoLen = 0; 171 glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen); 172 if (infoLen) { 173 char* buf = (char*) malloc(infoLen); 174 if (buf) { 175 glGetShaderInfoLog(mShaderID, infoLen, NULL, buf); 176 LOGE("Could not compile shader \n%s\n", buf); 177 free(buf); 178 } 179 glDeleteShader(mShaderID); 180 mShaderID = 0; 181 return false; 182 } 183 } 184 } 185 186 if (rsc->props.mLogShaders) { 187 LOGV("--Shader load result %x ", glGetError()); 188 } 189 return true; 190} 191 192void Program::setShader(const char *txt, uint32_t len) 193{ 194 mUserShader.setTo(txt, len); 195} 196 197 198 199namespace android { 200namespace renderscript { 201 202 203void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants) 204{ 205 Program *p = static_cast<Program *>(vp); 206 p->bindAllocation(static_cast<Allocation *>(constants)); 207} 208 209void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a) 210{ 211 Program *p = static_cast<Program *>(vpf); 212 p->bindTexture(slot, static_cast<Allocation *>(a)); 213} 214 215void rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s) 216{ 217 Program *p = static_cast<Program *>(vpf); 218 p->bindSampler(slot, static_cast<Sampler *>(s)); 219} 220 221} 222} 223 224