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