rsProgramFragment.cpp revision 0002a17db181f2276464fe5d6caaa9d869ef7e7b
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 mUniformCount = 0; 66 mUniformNames[mUniformCount++].setTo("uni_Tex0"); 67 mUniformNames[mUniformCount++].setTo("uni_Tex1"); 68 69 mConstantColorUniformIndex = -1; 70 //if (!mVaryingColor) { 71 mConstantColorUniformIndex = mUniformCount; 72 mUniformNames[mUniformCount++].setTo("uni_Color"); 73 //} 74 createShader(); 75} 76 77ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, 78 uint32_t shaderLength, const uint32_t * params, 79 uint32_t paramLength) : 80 Program(rsc, shaderText, shaderLength, params, paramLength) 81{ 82 mAllocFile = __FILE__; 83 mAllocLine = __LINE__; 84 85 mConstantColor[0] = 1.f; 86 mConstantColor[1] = 1.f; 87 mConstantColor[2] = 1.f; 88 mConstantColor[3] = 1.f; 89 90 LOGE("Custom FP"); 91 92 mUniformCount = 2; 93 mUniformNames[0].setTo("uni_Tex0"); 94 mUniformNames[1].setTo("uni_Tex1"); 95 96 createShader(); 97 98 mTextureEnableMask = (1 << mTextureCount) -1; 99} 100 101 102ProgramFragment::~ProgramFragment() 103{ 104} 105 106void ProgramFragment::setConstantColor(float r, float g, float b, float a) 107{ 108 mConstantColor[0] = r; 109 mConstantColor[1] = g; 110 mConstantColor[2] = b; 111 mConstantColor[3] = a; 112 mDirty = true; 113} 114 115void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state) 116{ 117} 118 119void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc) 120{ 121 122 //LOGE("sgl2 frag1 %x", glGetError()); 123 if ((state->mLast.get() == this) && !mDirty) { 124 return; 125 } 126 state->mLast.set(this); 127 128 rsc->checkError("ProgramFragment::setupGL2 start"); 129 130 if (!mVaryingColor && 131 (sc->fragUniformSlot(mConstantColorUniformIndex) >= 0)) { 132 //LOGE("mConstantColorUniformIndex %i %i", mConstantColorUniformIndex, sc->fragUniformSlot(mConstantColorUniformIndex)); 133 glUniform4fv(sc->fragUniformSlot(mConstantColorUniformIndex), 1, mConstantColor); 134 rsc->checkError("ProgramFragment::color setup"); 135 } 136 137 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { 138 glActiveTexture(GL_TEXTURE0 + ct); 139 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) { 140 continue; 141 } 142 143 mTextures[ct]->uploadCheck(rsc); 144 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); 145 rsc->checkError("ProgramFragment::setupGL2 tex bind"); 146 if (mSamplers[ct].get()) { 147 mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2()); 148 } else { 149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 152 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 153 rsc->checkError("ProgramFragment::setupGL2 tex env"); 154 } 155 156 glUniform1i(sc->fragUniformSlot(ct), ct); 157 rsc->checkError("ProgramFragment::setupGL2 uniforms"); 158 } 159 160 glActiveTexture(GL_TEXTURE0); 161 mDirty = false; 162 rsc->checkError("ProgramFragment::setupGL2"); 163} 164 165void ProgramFragment::loadShader(Context *rsc) { 166 Program::loadShader(rsc, GL_FRAGMENT_SHADER); 167} 168 169void ProgramFragment::createShader() 170{ 171 mShader.setTo("precision mediump float;\n"); 172 mShader.append("varying lowp vec4 varColor;\n"); 173 mShader.append("varying vec4 varTex0;\n"); 174 mShader.append("uniform vec4 uni_Color;\n"); 175 176 if (mUserShader.length() > 1) { 177 for (uint32_t ct=0; ct < mTextureCount; ct++) { 178 char buf[256]; 179 sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct); 180 mShader.append(buf); 181 } 182 183 mShader.append(mUserShader); 184 } else { 185 uint32_t mask = mTextureEnableMask; 186 uint32_t texNum = 0; 187 while (mask) { 188 if (mask & 1) { 189 char buf[64]; 190 mShader.append("uniform sampler2D uni_Tex"); 191 sprintf(buf, "%i", texNum); 192 mShader.append(buf); 193 mShader.append(";\n"); 194 } 195 mask >>= 1; 196 texNum++; 197 } 198 199 200 mShader.append("void main() {\n"); 201 if (mVaryingColor) { 202 mShader.append(" lowp vec4 col = varColor;\n"); 203 } else { 204 mShader.append(" lowp vec4 col = uni_Color;\n"); 205 } 206 207 if (mTextureEnableMask) { 208 if (mPointSpriteEnable) { 209 mShader.append(" vec2 t0 = gl_PointCoord;\n"); 210 } else { 211 mShader.append(" vec2 t0 = varTex0.xy;\n"); 212 } 213 } 214 215 mask = mTextureEnableMask; 216 texNum = 0; 217 while (mask) { 218 if (mask & 1) { 219 switch(mEnvModes[texNum]) { 220 case RS_TEX_ENV_MODE_NONE: 221 rsAssert(0); 222 break; 223 case RS_TEX_ENV_MODE_REPLACE: 224 switch(mTextureFormats[texNum]) { 225 case 1: 226 mShader.append(" col.a = texture2D(uni_Tex0, t0).a;\n"); 227 break; 228 case 2: 229 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n"); 230 break; 231 case 3: 232 mShader.append(" col.rgb = texture2D(uni_Tex0, t0).rgb;\n"); 233 break; 234 case 4: 235 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n"); 236 break; 237 } 238 break; 239 case RS_TEX_ENV_MODE_MODULATE: 240 switch(mTextureFormats[texNum]) { 241 case 1: 242 mShader.append(" col.a *= texture2D(uni_Tex0, t0).a;\n"); 243 break; 244 case 2: 245 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n"); 246 break; 247 case 3: 248 mShader.append(" col.rgb *= texture2D(uni_Tex0, t0).rgb;\n"); 249 break; 250 case 4: 251 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n"); 252 break; 253 } 254 break; 255 case RS_TEX_ENV_MODE_DECAL: 256 mShader.append(" col = texture2D(uni_Tex0, t0);\n"); 257 break; 258 } 259 260 } 261 mask >>= 1; 262 texNum++; 263 } 264 265 //mShader.append(" col.a = 1.0;\n"); 266 //mShader.append(" col.r = 0.5;\n"); 267 268 mShader.append(" gl_FragColor = col;\n"); 269 mShader.append("}\n"); 270 } 271} 272 273void ProgramFragment::init(Context *rsc) 274{ 275} 276 277void ProgramFragment::serialize(OStream *stream) const 278{ 279 280} 281 282ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream) 283{ 284 return NULL; 285} 286 287ProgramFragmentState::ProgramFragmentState() 288{ 289 mPF = NULL; 290} 291 292ProgramFragmentState::~ProgramFragmentState() 293{ 294 delete mPF; 295 296} 297 298void ProgramFragmentState::init(Context *rsc) 299{ 300 uint32_t tmp[] = { 301 RS_TEX_ENV_MODE_NONE, 0, 302 RS_TEX_ENV_MODE_NONE, 0, 303 0, 0 304 }; 305 ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6); 306 mDefault.set(pf); 307 pf->init(rsc); 308} 309 310void ProgramFragmentState::deinit(Context *rsc) 311{ 312 mDefault.clear(); 313 mLast.clear(); 314} 315 316 317namespace android { 318namespace renderscript { 319 320RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, 321 const uint32_t * params, 322 uint32_t paramLength) 323{ 324 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength); 325 pf->incUserRef(); 326 //LOGE("rsi_ProgramFragmentCreate %p", pf); 327 return pf; 328} 329 330RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText, 331 uint32_t shaderLength, const uint32_t * params, 332 uint32_t paramLength) 333{ 334 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength); 335 pf->incUserRef(); 336 //LOGE("rsi_ProgramFragmentCreate2 %p", pf); 337 return pf; 338} 339 340} 341} 342 343