rsProgramFragment.cpp revision d01d970cf5973aa5186cc02c80fb2c143a69b0b1
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 "rsProgramFragment.h" 19 20#include <GLES/gl.h> 21#include <GLES/glext.h> 22#include <GLES2/gl2.h> 23#include <GLES2/gl2ext.h> 24 25using namespace android; 26using namespace android::renderscript; 27 28 29ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params, 30 uint32_t paramLength) : 31 Program(rsc) 32{ 33 mAllocFile = __FILE__; 34 mAllocLine = __LINE__; 35 rsAssert(paramLength = 5); 36 37 mEnvModes[0] = (RsTexEnvMode)params[0]; 38 mTextureFormats[0] = params[1]; 39 mEnvModes[1] = (RsTexEnvMode)params[2]; 40 mTextureFormats[1] = params[3]; 41 mPointSpriteEnable = params[4] != 0; 42 43 mTextureEnableMask = 0; 44 if (mEnvModes[0]) { 45 mTextureEnableMask |= 1; 46 } 47 if (mEnvModes[1]) { 48 mTextureEnableMask |= 2; 49 } 50 init(rsc); 51} 52 53ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, 54 uint32_t shaderLength, const uint32_t * params, 55 uint32_t paramLength) : 56 Program(rsc, shaderText, shaderLength, params, paramLength) 57{ 58 mAllocFile = __FILE__; 59 mAllocLine = __LINE__; 60 61 init(rsc); 62 mTextureEnableMask = (1 << mTextureCount) -1; 63} 64 65 66ProgramFragment::~ProgramFragment() 67{ 68} 69 70void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state) 71{ 72 if ((state->mLast.get() == this) && !mDirty) { 73 return; 74 } 75 state->mLast.set(this); 76 77 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { 78 glActiveTexture(GL_TEXTURE0 + ct); 79 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) { 80 glDisable(GL_TEXTURE_2D); 81 continue; 82 } 83 84 glEnable(GL_TEXTURE_2D); 85 if (rsc->checkVersion1_1()) { 86 if (mPointSpriteEnable) { 87 glEnable(GL_POINT_SPRITE_OES); 88 } else { 89 glDisable(GL_POINT_SPRITE_OES); 90 } 91 glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable); 92 } 93 mTextures[ct]->uploadCheck(rsc); 94 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); 95 96 switch(mEnvModes[ct]) { 97 case RS_TEX_ENV_MODE_NONE: 98 rsAssert(0); 99 break; 100 case RS_TEX_ENV_MODE_REPLACE: 101 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 102 break; 103 case RS_TEX_ENV_MODE_MODULATE: 104 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 105 break; 106 case RS_TEX_ENV_MODE_DECAL: 107 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 108 break; 109 } 110 111 if (mSamplers[ct].get()) { 112 mSamplers[ct]->setupGL(); 113 } else { 114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 118 } 119 120 // Gross hack. 121 if (ct == 2) { 122 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 123 124 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); 125 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); 126 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE); 127 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); 128 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); 129 130 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD); 131 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); 132 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE); 133 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); 134 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); 135 } 136 } 137 glActiveTexture(GL_TEXTURE0); 138 mDirty = false; 139} 140 141void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc) 142{ 143 //LOGE("sgl2 frag1 %x", glGetError()); 144 if ((state->mLast.get() == this) && !mDirty) { 145 //return; 146 } 147 state->mLast.set(this); 148 149 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { 150 glActiveTexture(GL_TEXTURE0 + ct); 151 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) { 152 glDisable(GL_TEXTURE_2D); 153 continue; 154 } 155 156 mTextures[ct]->uploadCheck(rsc); 157 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); 158 if (mSamplers[ct].get()) { 159 mSamplers[ct]->setupGL(); 160 } else { 161 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 165 } 166 167 glEnable(GL_TEXTURE_2D); 168 glUniform1i(sc->fragUniformSlot(ct), ct); 169 } 170 171 glActiveTexture(GL_TEXTURE0); 172 mDirty = false; 173 174 //LOGE("sgl2 frag2 %x", glGetError()); 175} 176 177void ProgramFragment::loadShader(Context *rsc) { 178 Program::loadShader(rsc, GL_FRAGMENT_SHADER); 179} 180 181void ProgramFragment::createShader() 182{ 183 mShader.setTo("precision mediump float;\n"); 184 mShader.append("varying vec4 varColor;\n"); 185 mShader.append("varying vec4 varTex0;\n"); 186 187 if (mUserShader.length() > 1) { 188 for (uint32_t ct=0; ct < mTextureCount; ct++) { 189 char buf[256]; 190 sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct); 191 mShader.append(buf); 192 } 193 194 mShader.append(mUserShader); 195 } else { 196 uint32_t mask = mTextureEnableMask; 197 uint32_t texNum = 0; 198 while (mask) { 199 if (mask & 1) { 200 char buf[64]; 201 mShader.append("uniform sampler2D uni_Tex"); 202 sprintf(buf, "%i", texNum); 203 mShader.append(buf); 204 mShader.append(";\n"); 205 } 206 mask >>= 1; 207 texNum++; 208 } 209 210 211 mShader.append("void main() {\n"); 212 mShader.append(" vec4 col = varColor;\n"); 213 214 if (mTextureEnableMask) { 215 if (mPointSpriteEnable) { 216 mShader.append(" vec2 t0 = gl_PointCoord;\n"); 217 } else { 218 mShader.append(" vec2 t0 = varTex0.xy;\n"); 219 } 220 } 221 222 mask = mTextureEnableMask; 223 texNum = 0; 224 while (mask) { 225 if (mask & 1) { 226 switch(mEnvModes[texNum]) { 227 case RS_TEX_ENV_MODE_NONE: 228 rsAssert(0); 229 break; 230 case RS_TEX_ENV_MODE_REPLACE: 231 switch(mTextureFormats[texNum]) { 232 case 1: 233 mShader.append(" col.a = texture2D(uni_Tex0, t0).a;\n"); 234 break; 235 case 2: 236 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n"); 237 break; 238 case 3: 239 mShader.append(" col.rgb = texture2D(uni_Tex0, t0).rgb;\n"); 240 break; 241 case 4: 242 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n"); 243 break; 244 } 245 break; 246 case RS_TEX_ENV_MODE_MODULATE: 247 switch(mTextureFormats[texNum]) { 248 case 1: 249 mShader.append(" col.a *= texture2D(uni_Tex0, t0).a;\n"); 250 break; 251 case 2: 252 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n"); 253 break; 254 case 3: 255 mShader.append(" col.rgb *= texture2D(uni_Tex0, t0).rgb;\n"); 256 break; 257 case 4: 258 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n"); 259 break; 260 } 261 break; 262 case RS_TEX_ENV_MODE_DECAL: 263 mShader.append(" col = texture2D(uni_Tex0, t0);\n"); 264 break; 265 } 266 267 } 268 mask >>= 1; 269 texNum++; 270 } 271 272 //mShader.append(" col.a = 1.0;\n"); 273 //mShader.append(" col.r = 0.5;\n"); 274 275 mShader.append(" gl_FragColor = col;\n"); 276 mShader.append("}\n"); 277 } 278} 279 280void ProgramFragment::init(Context *rsc) 281{ 282 mUniformCount = 2; 283 mUniformNames[0].setTo("uni_Tex0"); 284 mUniformNames[1].setTo("uni_Tex1"); 285 286 createShader(); 287} 288 289ProgramFragmentState::ProgramFragmentState() 290{ 291 mPF = NULL; 292} 293 294ProgramFragmentState::~ProgramFragmentState() 295{ 296 delete mPF; 297 298} 299 300void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h) 301{ 302 uint32_t tmp[5] = { 303 RS_TEX_ENV_MODE_NONE, 0, 304 RS_TEX_ENV_MODE_NONE, 0, 305 0 306 }; 307 ProgramFragment *pf = new ProgramFragment(rsc, tmp, 5); 308 mDefault.set(pf); 309 pf->init(rsc); 310} 311 312void ProgramFragmentState::deinit(Context *rsc) 313{ 314 mDefault.clear(); 315 mLast.clear(); 316} 317 318 319namespace android { 320namespace renderscript { 321 322RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, 323 const uint32_t * params, 324 uint32_t paramLength) 325{ 326 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength); 327 pf->incUserRef(); 328 return pf; 329} 330 331RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText, 332 uint32_t shaderLength, const uint32_t * params, 333 uint32_t paramLength) 334{ 335 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength); 336 pf->incUserRef(); 337 return pf; 338} 339 340} 341} 342 343