rsProgram.cpp revision cd50653f99c960e1a47c2c30e53b369b8805344a
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::createShader() 125{ 126} 127 128bool Program::loadShader(Context *rsc, uint32_t type) 129{ 130 mShaderID = glCreateShader(type); 131 rsAssert(mShaderID); 132 133 if (rsc->props.mLogShaders) { 134 LOGV("Loading shader type %x, ID %i", type, mShaderID); 135 LOGV(mShader.string()); 136 } 137 138 if (mShaderID) { 139 const char * ss = mShader.string(); 140 glShaderSource(mShaderID, 1, &ss, NULL); 141 glCompileShader(mShaderID); 142 143 GLint compiled = 0; 144 glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled); 145 if (!compiled) { 146 GLint infoLen = 0; 147 glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen); 148 if (infoLen) { 149 char* buf = (char*) malloc(infoLen); 150 if (buf) { 151 glGetShaderInfoLog(mShaderID, infoLen, NULL, buf); 152 LOGE("Could not compile shader \n%s\n", buf); 153 free(buf); 154 } 155 glDeleteShader(mShaderID); 156 mShaderID = 0; 157 return false; 158 } 159 } 160 } 161 162 if (rsc->props.mLogShaders) { 163 LOGV("--Shader load result %x ", glGetError()); 164 } 165 return true; 166} 167 168void Program::setShader(const char *txt, uint32_t len) 169{ 170 mUserShader.setTo(txt, len); 171} 172 173 174 175namespace android { 176namespace renderscript { 177 178 179void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants) 180{ 181 Program *p = static_cast<Program *>(vp); 182 p->bindAllocation(static_cast<Allocation *>(constants)); 183} 184 185 186} 187} 188 189