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