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