| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrGLProgram.h" | 8 #include "GrGLProgram.h" |
| 9 | 9 |
| 10 #include "GrAllocator.h" | 10 #include "GrAllocator.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 : fGpu(gpu) | 41 : fGpu(gpu) |
| 42 , fUniformManager(gpu) | 42 , fUniformManager(gpu) |
| 43 , fHasVertexShader(false) | 43 , fHasVertexShader(false) |
| 44 , fNumTexCoordSets(0) { | 44 , fNumTexCoordSets(0) { |
| 45 fDesc = desc; | 45 fDesc = desc; |
| 46 fProgramID = 0; | 46 fProgramID = 0; |
| 47 | 47 |
| 48 fDstCopyTexUnit = -1; | 48 fDstCopyTexUnit = -1; |
| 49 | 49 |
| 50 fColor = GrColor_ILLEGAL; | 50 fColor = GrColor_ILLEGAL; |
| 51 fColorFilterColor = GrColor_ILLEGAL; | |
| 52 | 51 |
| 53 if (fDesc.getHeader().fHasVertexCode || | 52 if (fDesc.getHeader().fHasVertexCode || |
| 54 !fGpu->glCaps().fixedFunctionSupport() || | 53 !fGpu->glCaps().fixedFunctionSupport() || |
| 55 !fGpu->glCaps().pathStencilingSupport()) { | 54 !fGpu->glCaps().pathStencilingSupport()) { |
| 56 | 55 |
| 57 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); | 56 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); |
| 58 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { | 57 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { |
| 59 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); | 58 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); |
| 60 fHasVertexShader = true; | 59 fHasVertexShader = true; |
| 61 } | 60 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 92 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: | 91 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: |
| 93 // We should only have set this if the blend was specified as (1, 0) | 92 // We should only have set this if the blend was specified as (1, 0) |
| 94 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds
tCoeff); | 93 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds
tCoeff); |
| 95 break; | 94 break; |
| 96 default: | 95 default: |
| 97 GrCrash("Unexpected coverage output"); | 96 GrCrash("Unexpected coverage output"); |
| 98 break; | 97 break; |
| 99 } | 98 } |
| 100 } | 99 } |
| 101 | 100 |
| 102 namespace { | |
| 103 // given two blend coefficients determine whether the src | |
| 104 // and/or dst computation can be omitted. | |
| 105 inline void need_blend_inputs(SkXfermode::Coeff srcCoeff, | |
| 106 SkXfermode::Coeff dstCoeff, | |
| 107 bool* needSrcValue, | |
| 108 bool* needDstValue) { | |
| 109 if (SkXfermode::kZero_Coeff == srcCoeff) { | |
| 110 switch (dstCoeff) { | |
| 111 // these all read the src | |
| 112 case SkXfermode::kSC_Coeff: | |
| 113 case SkXfermode::kISC_Coeff: | |
| 114 case SkXfermode::kSA_Coeff: | |
| 115 case SkXfermode::kISA_Coeff: | |
| 116 *needSrcValue = true; | |
| 117 break; | |
| 118 default: | |
| 119 *needSrcValue = false; | |
| 120 break; | |
| 121 } | |
| 122 } else { | |
| 123 *needSrcValue = true; | |
| 124 } | |
| 125 if (SkXfermode::kZero_Coeff == dstCoeff) { | |
| 126 switch (srcCoeff) { | |
| 127 // these all read the dst | |
| 128 case SkXfermode::kDC_Coeff: | |
| 129 case SkXfermode::kIDC_Coeff: | |
| 130 case SkXfermode::kDA_Coeff: | |
| 131 case SkXfermode::kIDA_Coeff: | |
| 132 *needDstValue = true; | |
| 133 break; | |
| 134 default: | |
| 135 *needDstValue = false; | |
| 136 break; | |
| 137 } | |
| 138 } else { | |
| 139 *needDstValue = true; | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 /** | |
| 144 * Create a blend_coeff * value string to be used in shader code. Sets empty | |
| 145 * string if result is trivially zero. | |
| 146 */ | |
| 147 inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff, | |
| 148 const char* src, const char* dst, | |
| 149 const char* value) { | |
| 150 switch (coeff) { | |
| 151 case SkXfermode::kZero_Coeff: /** 0 */ | |
| 152 *str = ""; | |
| 153 break; | |
| 154 case SkXfermode::kOne_Coeff: /** 1 */ | |
| 155 *str = value; | |
| 156 break; | |
| 157 case SkXfermode::kSC_Coeff: | |
| 158 str->printf("(%s * %s)", src, value); | |
| 159 break; | |
| 160 case SkXfermode::kISC_Coeff: | |
| 161 str->printf("((vec4(1) - %s) * %s)", src, value); | |
| 162 break; | |
| 163 case SkXfermode::kDC_Coeff: | |
| 164 str->printf("(%s * %s)", dst, value); | |
| 165 break; | |
| 166 case SkXfermode::kIDC_Coeff: | |
| 167 str->printf("((vec4(1) - %s) * %s)", dst, value); | |
| 168 break; | |
| 169 case SkXfermode::kSA_Coeff: /** src alpha */ | |
| 170 str->printf("(%s.a * %s)", src, value); | |
| 171 break; | |
| 172 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ | |
| 173 str->printf("((1.0 - %s.a) * %s)", src, value); | |
| 174 break; | |
| 175 case SkXfermode::kDA_Coeff: /** dst alpha */ | |
| 176 str->printf("(%s.a * %s)", dst, value); | |
| 177 break; | |
| 178 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ | |
| 179 str->printf("((1.0 - %s.a) * %s)", dst, value); | |
| 180 break; | |
| 181 default: | |
| 182 GrCrash("Unexpected xfer coeff."); | |
| 183 break; | |
| 184 } | |
| 185 } | |
| 186 /** | |
| 187 * Adds a line to the fragment shader code which modifies the color by | |
| 188 * the specified color filter. | |
| 189 */ | |
| 190 void add_color_filter(GrGLShaderBuilder* builder, | |
| 191 const char * outputVar, | |
| 192 SkXfermode::Coeff uniformCoeff, | |
| 193 SkXfermode::Coeff colorCoeff, | |
| 194 const char* filterColor, | |
| 195 const char* inColor) { | |
| 196 SkString colorStr, constStr; | |
| 197 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); | |
| 198 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); | |
| 199 GrGLSLExpr<4> sum; | |
| 200 if (colorStr.isEmpty() && constStr.isEmpty()) { | |
| 201 sum = GrGLSLExpr<4>(0); | |
| 202 } else if (colorStr.isEmpty()) { | |
| 203 sum = constStr; | |
| 204 } else if (constStr.isEmpty()) { | |
| 205 sum = colorStr; | |
| 206 } else { | |
| 207 sum = GrGLSLExpr<4>(colorStr) + GrGLSLExpr<4>(constStr); | |
| 208 } | |
| 209 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, | 101 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, |
| 214 const GrEffectStage* colorStages[], | 102 const GrEffectStage* colorStages[], |
| 215 const GrEffectStage* coverageStages[]) { | 103 const GrEffectStage* coverageStages[]) { |
| 216 SkASSERT(0 == fProgramID); | 104 SkASSERT(0 == fProgramID); |
| 217 | 105 |
| 218 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 106 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
| 219 | 107 |
| 220 // incoming color to current stage being processed. | 108 // incoming color to current stage being processed. |
| 221 GrGLSLExpr<4> inColor = builder->getInputColor(); | 109 GrGLSLExpr<4> inColor = builder->getInputColor(); |
| 222 | 110 |
| 223 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. | |
| 224 SkXfermode::Coeff colorCoeff; | |
| 225 SkXfermode::Coeff filterColorCoeff; | |
| 226 SkAssertResult( | |
| 227 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, | |
| 228 &filterColorCoeff, | |
| 229 &colorCoeff)); | |
| 230 bool needColor, needFilterColor; | |
| 231 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); | |
| 232 | |
| 233 fColorEffects.reset( | 111 fColorEffects.reset( |
| 234 builder->createAndEmitEffects(colorStages, | 112 builder->createAndEmitEffects(colorStages, |
| 235 fDesc.effectKeys(), | 113 fDesc.effectKeys(), |
| 236 needColor ? fDesc.numColorEffects() : 0, | 114 fDesc.numColorEffects(), |
| 237 &inColor)); | 115 &inColor)); |
| 238 | 116 |
| 239 // Insert the color filter. This will soon be replaced by a color effect. | |
| 240 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { | |
| 241 const char* colorFilterColorUniName = NULL; | |
| 242 fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder:
:kFragment_Visibility, | |
| 243 kVec4f_GrSLType, "
FilterColor", | |
| 244 &colorFilterColorU
niName); | |
| 245 | |
| 246 builder->fsCodeAppend("\tvec4 filteredColor;\n"); | |
| 247 add_color_filter(builder, "filteredColor", filterColorCoeff, | |
| 248 colorCoeff, colorFilterColorUniName, inColor.c_str()); | |
| 249 inColor = "filteredColor"; | |
| 250 } | |
| 251 | |
| 252 /////////////////////////////////////////////////////////////////////////// | 117 /////////////////////////////////////////////////////////////////////////// |
| 253 // compute the partial coverage | 118 // compute the partial coverage |
| 254 GrGLSLExpr<4> inCoverage = builder->getInputCoverage(); | 119 GrGLSLExpr<4> inCoverage = builder->getInputCoverage(); |
| 255 | 120 |
| 256 fCoverageEffects.reset( | 121 fCoverageEffects.reset( |
| 257 builder->createAndEmitEffects(coverageStages, | 122 builder->createAndEmitEffects(coverageStages, |
| 258 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), | 123 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), |
| 259 fDesc.numCoverageEffects(), | 124 fDesc.numCoverageEffects(), |
| 260 &inCoverage)); | 125 &inCoverage)); |
| 261 | 126 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 coverage = drawState.getCoverage(); | 212 coverage = drawState.getCoverage(); |
| 348 } else { | 213 } else { |
| 349 color = drawState.getColor(); | 214 color = drawState.getColor(); |
| 350 coverage = drawState.getCoverage(); | 215 coverage = drawState.getCoverage(); |
| 351 } | 216 } |
| 352 | 217 |
| 353 this->setColor(drawState, color, sharedState); | 218 this->setColor(drawState, color, sharedState); |
| 354 this->setCoverage(drawState, coverage, sharedState); | 219 this->setCoverage(drawState, coverage, sharedState); |
| 355 this->setMatrixAndRenderTargetHeight(drawState); | 220 this->setMatrixAndRenderTargetHeight(drawState); |
| 356 | 221 |
| 357 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary | |
| 358 if (fUniformHandles.fColorFilterUni.isValid() && | |
| 359 fColorFilterColor != drawState.getColorFilterColor()) { | |
| 360 GrGLfloat c[4]; | |
| 361 GrColorToRGBAFloat(drawState.getColorFilterColor(), c); | |
| 362 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c); | |
| 363 fColorFilterColor = drawState.getColorFilterColor(); | |
| 364 } | |
| 365 | |
| 366 if (NULL != dstCopy) { | 222 if (NULL != dstCopy) { |
| 367 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { | 223 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { |
| 368 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, | 224 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, |
| 369 static_cast<GrGLfloat>(dstCopy->offset().fX), | 225 static_cast<GrGLfloat>(dstCopy->offset().fX), |
| 370 static_cast<GrGLfloat>(dstCopy->offset().fY)); | 226 static_cast<GrGLfloat>(dstCopy->offset().fY)); |
| 371 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, | 227 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, |
| 372 1.f / dstCopy->texture()->width(), | 228 1.f / dstCopy->texture()->width(), |
| 373 1.f / dstCopy->texture()->height()); | 229 1.f / dstCopy->texture()->height()); |
| 374 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture())
; | 230 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture())
; |
| 375 static GrTextureParams kParams; // the default is clamp, nearest fil
tering. | 231 static GrTextureParams kParams; // the default is clamp, nearest fil
tering. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 404 sharedState->fConstAttribColorIndex != header.fColorAttribut
eIndex) { | 260 sharedState->fConstAttribColorIndex != header.fColorAttribut
eIndex) { |
| 405 // OpenGL ES only supports the float varieties of glVertexAt
trib | 261 // OpenGL ES only supports the float varieties of glVertexAt
trib |
| 406 GrGLfloat c[4]; | 262 GrGLfloat c[4]; |
| 407 GrColorToRGBAFloat(color, c); | 263 GrColorToRGBAFloat(color, c); |
| 408 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); | 264 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); |
| 409 sharedState->fConstAttribColor = color; | 265 sharedState->fConstAttribColor = color; |
| 410 sharedState->fConstAttribColorIndex = header.fColorAttribute
Index; | 266 sharedState->fConstAttribColorIndex = header.fColorAttribute
Index; |
| 411 } | 267 } |
| 412 break; | 268 break; |
| 413 case GrGLProgramDesc::kUniform_ColorInput: | 269 case GrGLProgramDesc::kUniform_ColorInput: |
| 414 if (fColor != color) { | 270 if (fColor != color && fUniformHandles.fColorUni.isValid()) { |
| 415 // OpenGL ES doesn't support unsigned byte varieties of glUn
iform | 271 // OpenGL ES doesn't support unsigned byte varieties of glUn
iform |
| 416 GrGLfloat c[4]; | 272 GrGLfloat c[4]; |
| 417 GrColorToRGBAFloat(color, c); | 273 GrColorToRGBAFloat(color, c); |
| 418 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); | 274 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); |
| 419 fColor = color; | 275 fColor = color; |
| 420 } | 276 } |
| 421 sharedState->fConstAttribColorIndex = -1; | 277 sharedState->fConstAttribColorIndex = -1; |
| 422 break; | 278 break; |
| 423 case GrGLProgramDesc::kSolidWhite_ColorInput: | 279 case GrGLProgramDesc::kSolidWhite_ColorInput: |
| 424 case GrGLProgramDesc::kTransBlack_ColorInput: | 280 case GrGLProgramDesc::kTransBlack_ColorInput: |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 | 348 |
| 493 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 349 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
| 494 fMatrixState.fRenderTargetSize = size; | 350 fMatrixState.fRenderTargetSize = size; |
| 495 fMatrixState.fRenderTargetOrigin = rt->origin(); | 351 fMatrixState.fRenderTargetOrigin = rt->origin(); |
| 496 | 352 |
| 497 GrGLfloat viewMatrix[3 * 3]; | 353 GrGLfloat viewMatrix[3 * 3]; |
| 498 fMatrixState.getGLMatrix<3>(viewMatrix); | 354 fMatrixState.getGLMatrix<3>(viewMatrix); |
| 499 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); | 355 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); |
| 500 } | 356 } |
| 501 } | 357 } |
| OLD | NEW |