rsProgramFragment.cpp revision 900f1616bf33c7ba13cf2a737832a95bcd176388
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#ifndef ANDROID_RS_BUILD_FOR_HOST 18#include "rsContext.h" 19#include <GLES/gl.h> 20#include <GLES/glext.h> 21#include <GLES2/gl2.h> 22#include <GLES2/gl2ext.h> 23#else 24#include "rsContextHostStub.h" 25#include <OpenGL/gl.h> 26#include <OpenGL/glext.h> 27#endif //ANDROID_RS_BUILD_FOR_HOST 28 29#include "rsProgramFragment.h" 30 31using namespace android; 32using namespace android::renderscript; 33 34 35ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params, 36 uint32_t paramLength) : 37 Program(rsc) 38{ 39 mAllocFile = __FILE__; 40 mAllocLine = __LINE__; 41 rsAssert(paramLength == 6); 42 43 mConstantColor[0] = 1.f; 44 mConstantColor[1] = 1.f; 45 mConstantColor[2] = 1.f; 46 mConstantColor[3] = 1.f; 47 48 mEnvModes[0] = (RsTexEnvMode)params[0]; 49 mTextureFormats[0] = params[1]; 50 mEnvModes[1] = (RsTexEnvMode)params[2]; 51 mTextureFormats[1] = params[3]; 52 mPointSpriteEnable = params[4] != 0; 53 mVaryingColor = false; 54 if (paramLength > 5) 55 mVaryingColor = params[5] != 0; 56 57 mTextureEnableMask = 0; 58 if (mEnvModes[0]) { 59 mTextureEnableMask |= 1; 60 } 61 if (mEnvModes[1]) { 62 mTextureEnableMask |= 2; 63 } 64 65 init(rsc); 66} 67 68ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, 69 uint32_t shaderLength, const uint32_t * params, 70 uint32_t paramLength) : 71 Program(rsc, shaderText, shaderLength, params, paramLength) 72{ 73 mAllocFile = __FILE__; 74 mAllocLine = __LINE__; 75 76 mConstantColor[0] = 1.f; 77 mConstantColor[1] = 1.f; 78 mConstantColor[2] = 1.f; 79 mConstantColor[3] = 1.f; 80 81 LOGE("Custom FP"); 82 83 mTextureEnableMask = (1 << mTextureCount) -1; 84 85 init(rsc); 86} 87 88 89ProgramFragment::~ProgramFragment() 90{ 91} 92 93void ProgramFragment::setConstantColor(float r, float g, float b, float a) 94{ 95 if(isUserProgram()) { 96 return; 97 } 98 mConstantColor[0] = r; 99 mConstantColor[1] = g; 100 mConstantColor[2] = b; 101 mConstantColor[3] = a; 102 memcpy(mConstants[0]->getPtr(), mConstantColor, 4*sizeof(float)); 103 mDirty = true; 104} 105 106void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc) 107{ 108 //LOGE("sgl2 frag1 %x", glGetError()); 109 if ((state->mLast.get() == this) && !mDirty) { 110 return; 111 } 112 state->mLast.set(this); 113 114 rsc->checkError("ProgramFragment::setupGL2 start"); 115 116 rsc->checkError("ProgramFragment::setupGL2 begin uniforms"); 117 setupUserConstants(sc, true); 118 119 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { 120 glActiveTexture(GL_TEXTURE0 + ct); 121 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) { 122 continue; 123 } 124 125 mTextures[ct]->uploadCheck(rsc); 126 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); 127 rsc->checkError("ProgramFragment::setupGL2 tex bind"); 128 if (mSamplers[ct].get()) { 129 mSamplers[ct]->setupGL(rsc, mTextures[ct].get()); 130 } else { 131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 135 rsc->checkError("ProgramFragment::setupGL2 tex env"); 136 } 137 138 glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct); 139 rsc->checkError("ProgramFragment::setupGL2 uniforms"); 140 } 141 142 glActiveTexture(GL_TEXTURE0); 143 mDirty = false; 144 rsc->checkError("ProgramFragment::setupGL2"); 145} 146 147void ProgramFragment::loadShader(Context *rsc) { 148 Program::loadShader(rsc, GL_FRAGMENT_SHADER); 149} 150 151void ProgramFragment::createShader() 152{ 153 if (mUserShader.length() > 1) { 154 mShader.append("precision mediump float;\n"); 155 appendUserConstants(); 156 for (uint32_t ct=0; ct < mTextureCount; ct++) { 157 char buf[256]; 158 sprintf(buf, "uniform sampler2D UNI_Tex%i;\n", ct); 159 mShader.append(buf); 160 } 161 mShader.append(mUserShader); 162 } else { 163 LOGE("ProgramFragment::createShader cannot create program, shader code not defined"); 164 rsAssert(0); 165 } 166} 167 168void ProgramFragment::init(Context *rsc) 169{ 170 mUniformCount = 0; 171 if (mUserShader.size() > 0) { 172 for (uint32_t ct=0; ct < mConstantCount; ct++) { 173 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_"); 174 } 175 } 176 mTextureUniformIndexStart = mUniformCount; 177 mUniformNames[mUniformCount++].setTo("UNI_Tex0"); 178 mUniformNames[mUniformCount++].setTo("UNI_Tex1"); 179 180 createShader(); 181} 182 183void ProgramFragment::serialize(OStream *stream) const 184{ 185 186} 187 188ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream) 189{ 190 return NULL; 191} 192 193ProgramFragmentState::ProgramFragmentState() 194{ 195 mPF = NULL; 196} 197 198ProgramFragmentState::~ProgramFragmentState() 199{ 200 delete mPF; 201 202} 203 204void ProgramFragmentState::init(Context *rsc) 205{ 206 String8 shaderString(RS_SHADER_INTERNAL); 207 shaderString.append("varying lowp vec4 varColor;\n"); 208 shaderString.append("varying vec4 varTex0;\n"); 209 shaderString.append("void main() {\n"); 210 shaderString.append(" lowp vec4 col = UNI_Color;\n"); 211 shaderString.append(" gl_FragColor = col;\n"); 212 shaderString.append("}\n"); 213 214 const Element *colorElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4); 215 rsc->mStateElement.elementBuilderBegin(); 216 rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1); 217 const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc); 218 219 Type *inputType = new Type(rsc); 220 inputType->setElement(constInput); 221 inputType->setDimX(1); 222 inputType->compute(); 223 224 uint32_t tmp[4]; 225 tmp[0] = RS_PROGRAM_PARAM_CONSTANT; 226 tmp[1] = (uint32_t)inputType; 227 tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT; 228 tmp[3] = 0; 229 230 Allocation *constAlloc = new Allocation(rsc, inputType); 231 ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(), 232 shaderString.length(), tmp, 4); 233 pf->bindAllocation(constAlloc, 0); 234 pf->setConstantColor(1.0f, 1.0f, 1.0f, 1.0f); 235 236 mDefault.set(pf); 237} 238 239void ProgramFragmentState::deinit(Context *rsc) 240{ 241 mDefault.clear(); 242 mLast.clear(); 243} 244 245 246namespace android { 247namespace renderscript { 248 249RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, 250 const uint32_t * params, 251 uint32_t paramLength) 252{ 253 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength); 254 pf->incUserRef(); 255 //LOGE("rsi_ProgramFragmentCreate %p", pf); 256 return pf; 257} 258 259RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText, 260 uint32_t shaderLength, const uint32_t * params, 261 uint32_t paramLength) 262{ 263 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength); 264 pf->incUserRef(); 265 //LOGE("rsi_ProgramFragmentCreate2 %p", pf); 266 return pf; 267} 268 269} 270} 271 272