rsProgramFragment.cpp revision 6e9342199959dc9beb5299fefc9775fe8c32620e
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 init(rsc); 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 mTextureEnableMask = (1 << mTextureCount) -1; 97 98 init(rsc); 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 rsc->checkError("ProgramFragment::setupGL2 begin uniforms"); 138 setupUserConstants(sc, true); 139 140 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { 141 glActiveTexture(GL_TEXTURE0 + ct); 142 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) { 143 continue; 144 } 145 146 mTextures[ct]->uploadCheck(rsc); 147 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); 148 rsc->checkError("ProgramFragment::setupGL2 tex bind"); 149 if (mSamplers[ct].get()) { 150 mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2()); 151 } else { 152 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 153 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 154 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 155 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 156 rsc->checkError("ProgramFragment::setupGL2 tex env"); 157 } 158 159 glUniform1i(sc->fragUniformSlot(ct), ct); 160 rsc->checkError("ProgramFragment::setupGL2 uniforms"); 161 } 162 163 glActiveTexture(GL_TEXTURE0); 164 mDirty = false; 165 rsc->checkError("ProgramFragment::setupGL2"); 166} 167 168void ProgramFragment::loadShader(Context *rsc) { 169 Program::loadShader(rsc, GL_FRAGMENT_SHADER); 170} 171 172void ProgramFragment::createShader() 173{ 174 mShader.setTo("precision mediump float;\n"); 175 mShader.append("varying lowp vec4 varColor;\n"); 176 mShader.append("varying vec4 varTex0;\n"); 177 mShader.append("uniform vec4 uni_Color;\n"); 178 179 if (mUserShader.length() > 1) { 180 for (uint32_t ct=0; ct < mTextureCount; ct++) { 181 char buf[256]; 182 sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct); 183 mShader.append(buf); 184 } 185 appendUserConstants(); 186 mShader.append(mUserShader); 187 } else { 188 uint32_t mask = mTextureEnableMask; 189 uint32_t texNum = 0; 190 while (mask) { 191 if (mask & 1) { 192 char buf[64]; 193 mShader.append("uniform sampler2D uni_Tex"); 194 sprintf(buf, "%i", texNum); 195 mShader.append(buf); 196 mShader.append(";\n"); 197 } 198 mask >>= 1; 199 texNum++; 200 } 201 202 203 mShader.append("void main() {\n"); 204 if (mVaryingColor) { 205 mShader.append(" lowp vec4 col = varColor;\n"); 206 } else { 207 mShader.append(" lowp vec4 col = uni_Color;\n"); 208 } 209 210 if (mTextureEnableMask) { 211 if (mPointSpriteEnable) { 212 mShader.append(" vec2 t0 = gl_PointCoord;\n"); 213 } else { 214 mShader.append(" vec2 t0 = varTex0.xy;\n"); 215 } 216 } 217 218 mask = mTextureEnableMask; 219 texNum = 0; 220 while (mask) { 221 if (mask & 1) { 222 switch(mEnvModes[texNum]) { 223 case RS_TEX_ENV_MODE_NONE: 224 rsAssert(0); 225 break; 226 case RS_TEX_ENV_MODE_REPLACE: 227 switch(mTextureFormats[texNum]) { 228 case 1: 229 mShader.append(" col.a = texture2D(uni_Tex0, t0).a;\n"); 230 break; 231 case 2: 232 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n"); 233 break; 234 case 3: 235 mShader.append(" col.rgb = texture2D(uni_Tex0, t0).rgb;\n"); 236 break; 237 case 4: 238 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n"); 239 break; 240 } 241 break; 242 case RS_TEX_ENV_MODE_MODULATE: 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_DECAL: 259 mShader.append(" col = texture2D(uni_Tex0, t0);\n"); 260 break; 261 } 262 263 } 264 mask >>= 1; 265 texNum++; 266 } 267 268 //mShader.append(" col.a = 1.0;\n"); 269 //mShader.append(" col.r = 0.5;\n"); 270 271 mShader.append(" gl_FragColor = col;\n"); 272 mShader.append("}\n"); 273 } 274} 275 276void ProgramFragment::init(Context *rsc) 277{ 278 if (mUserShader.size() > 0) { 279 for (uint32_t ct=0; ct < mConstantCount; ct++) { 280 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_"); 281 } 282 } 283 284 createShader(); 285} 286 287void ProgramFragment::serialize(OStream *stream) const 288{ 289 290} 291 292ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream) 293{ 294 return NULL; 295} 296 297ProgramFragmentState::ProgramFragmentState() 298{ 299 mPF = NULL; 300} 301 302ProgramFragmentState::~ProgramFragmentState() 303{ 304 delete mPF; 305 306} 307 308void ProgramFragmentState::init(Context *rsc) 309{ 310 uint32_t tmp[] = { 311 RS_TEX_ENV_MODE_NONE, 0, 312 RS_TEX_ENV_MODE_NONE, 0, 313 0, 0 314 }; 315 ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6); 316 mDefault.set(pf); 317} 318 319void ProgramFragmentState::deinit(Context *rsc) 320{ 321 mDefault.clear(); 322 mLast.clear(); 323} 324 325 326namespace android { 327namespace renderscript { 328 329RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, 330 const uint32_t * params, 331 uint32_t paramLength) 332{ 333 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength); 334 pf->incUserRef(); 335 //LOGE("rsi_ProgramFragmentCreate %p", pf); 336 return pf; 337} 338 339RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText, 340 uint32_t shaderLength, const uint32_t * params, 341 uint32_t paramLength) 342{ 343 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength); 344 pf->incUserRef(); 345 //LOGE("rsi_ProgramFragmentCreate2 %p", pf); 346 return pf; 347} 348 349} 350} 351 352