| 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->shouldUseFixedFunctionTexturing()) { | 53 !fGpu->shouldUseFixedFunctionTexturing()) { |
| 55 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); | 54 GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); |
| 56 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { | 55 if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { |
| 57 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); | 56 fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); |
| 58 fHasVertexShader = true; | 57 fHasVertexShader = true; |
| 59 } | 58 } |
| 60 } else { | 59 } else { |
| 61 GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(fGpu, fUniformManager,
fDesc); | 60 GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(fGpu, fUniformManager,
fDesc); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 90 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: | 89 case GrGLProgramDesc::kCombineWithDst_CoverageOutput: |
| 91 // We should only have set this if the blend was specified as (1, 0) | 90 // We should only have set this if the blend was specified as (1, 0) |
| 92 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds
tCoeff); | 91 SkASSERT(kOne_GrBlendCoeff == *srcCoeff && kZero_GrBlendCoeff == *ds
tCoeff); |
| 93 break; | 92 break; |
| 94 default: | 93 default: |
| 95 GrCrash("Unexpected coverage output"); | 94 GrCrash("Unexpected coverage output"); |
| 96 break; | 95 break; |
| 97 } | 96 } |
| 98 } | 97 } |
| 99 | 98 |
| 100 namespace { | |
| 101 // given two blend coefficients determine whether the src | |
| 102 // and/or dst computation can be omitted. | |
| 103 inline void need_blend_inputs(SkXfermode::Coeff srcCoeff, | |
| 104 SkXfermode::Coeff dstCoeff, | |
| 105 bool* needSrcValue, | |
| 106 bool* needDstValue) { | |
| 107 if (SkXfermode::kZero_Coeff == srcCoeff) { | |
| 108 switch (dstCoeff) { | |
| 109 // these all read the src | |
| 110 case SkXfermode::kSC_Coeff: | |
| 111 case SkXfermode::kISC_Coeff: | |
| 112 case SkXfermode::kSA_Coeff: | |
| 113 case SkXfermode::kISA_Coeff: | |
| 114 *needSrcValue = true; | |
| 115 break; | |
| 116 default: | |
| 117 *needSrcValue = false; | |
| 118 break; | |
| 119 } | |
| 120 } else { | |
| 121 *needSrcValue = true; | |
| 122 } | |
| 123 if (SkXfermode::kZero_Coeff == dstCoeff) { | |
| 124 switch (srcCoeff) { | |
| 125 // these all read the dst | |
| 126 case SkXfermode::kDC_Coeff: | |
| 127 case SkXfermode::kIDC_Coeff: | |
| 128 case SkXfermode::kDA_Coeff: | |
| 129 case SkXfermode::kIDA_Coeff: | |
| 130 *needDstValue = true; | |
| 131 break; | |
| 132 default: | |
| 133 *needDstValue = false; | |
| 134 break; | |
| 135 } | |
| 136 } else { | |
| 137 *needDstValue = true; | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 /** | |
| 142 * Create a blend_coeff * value string to be used in shader code. Sets empty | |
| 143 * string if result is trivially zero. | |
| 144 */ | |
| 145 inline void blend_term_string(SkString* str, SkXfermode::Coeff coeff, | |
| 146 const char* src, const char* dst, | |
| 147 const char* value) { | |
| 148 switch (coeff) { | |
| 149 case SkXfermode::kZero_Coeff: /** 0 */ | |
| 150 *str = ""; | |
| 151 break; | |
| 152 case SkXfermode::kOne_Coeff: /** 1 */ | |
| 153 *str = value; | |
| 154 break; | |
| 155 case SkXfermode::kSC_Coeff: | |
| 156 str->printf("(%s * %s)", src, value); | |
| 157 break; | |
| 158 case SkXfermode::kISC_Coeff: | |
| 159 str->printf("((vec4(1) - %s) * %s)", src, value); | |
| 160 break; | |
| 161 case SkXfermode::kDC_Coeff: | |
| 162 str->printf("(%s * %s)", dst, value); | |
| 163 break; | |
| 164 case SkXfermode::kIDC_Coeff: | |
| 165 str->printf("((vec4(1) - %s) * %s)", dst, value); | |
| 166 break; | |
| 167 case SkXfermode::kSA_Coeff: /** src alpha */ | |
| 168 str->printf("(%s.a * %s)", src, value); | |
| 169 break; | |
| 170 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ | |
| 171 str->printf("((1.0 - %s.a) * %s)", src, value); | |
| 172 break; | |
| 173 case SkXfermode::kDA_Coeff: /** dst alpha */ | |
| 174 str->printf("(%s.a * %s)", dst, value); | |
| 175 break; | |
| 176 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ | |
| 177 str->printf("((1.0 - %s.a) * %s)", dst, value); | |
| 178 break; | |
| 179 default: | |
| 180 GrCrash("Unexpected xfer coeff."); | |
| 181 break; | |
| 182 } | |
| 183 } | |
| 184 /** | |
| 185 * Adds a line to the fragment shader code which modifies the color by | |
| 186 * the specified color filter. | |
| 187 */ | |
| 188 void add_color_filter(GrGLShaderBuilder* builder, | |
| 189 const char * outputVar, | |
| 190 SkXfermode::Coeff uniformCoeff, | |
| 191 SkXfermode::Coeff colorCoeff, | |
| 192 const char* filterColor, | |
| 193 const char* inColor) { | |
| 194 SkString colorStr, constStr; | |
| 195 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); | |
| 196 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); | |
| 197 GrGLSLExpr<4> sum; | |
| 198 if (colorStr.isEmpty() && constStr.isEmpty()) { | |
| 199 sum = GrGLSLExpr<4>(0); | |
| 200 } else if (colorStr.isEmpty()) { | |
| 201 sum = constStr; | |
| 202 } else if (constStr.isEmpty()) { | |
| 203 sum = colorStr; | |
| 204 } else { | |
| 205 sum = GrGLSLExpr<4>(colorStr) + GrGLSLExpr<4>(constStr); | |
| 206 } | |
| 207 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, | 99 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, |
| 212 const GrEffectStage* colorStages[], | 100 const GrEffectStage* colorStages[], |
| 213 const GrEffectStage* coverageStages[]) { | 101 const GrEffectStage* coverageStages[]) { |
| 214 SkASSERT(0 == fProgramID); | 102 SkASSERT(0 == fProgramID); |
| 215 | 103 |
| 216 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 104 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
| 217 | 105 |
| 218 // incoming color to current stage being processed. | 106 // incoming color to current stage being processed. |
| 219 GrGLSLExpr<4> inColor = builder->getInputColor(); | 107 GrGLSLExpr4 inColor = builder->getInputColor(); |
| 220 | |
| 221 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. | |
| 222 SkXfermode::Coeff colorCoeff; | |
| 223 SkXfermode::Coeff filterColorCoeff; | |
| 224 SkAssertResult( | |
| 225 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, | |
| 226 &filterColorCoeff, | |
| 227 &colorCoeff)); | |
| 228 bool needColor, needFilterColor; | |
| 229 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); | |
| 230 | 108 |
| 231 fColorEffects.reset( | 109 fColorEffects.reset( |
| 232 builder->createAndEmitEffects(colorStages, | 110 builder->createAndEmitEffects(colorStages, |
| 233 fDesc.effectKeys(), | 111 fDesc.effectKeys(), |
| 234 needColor ? fDesc.numColorEffects() : 0, | 112 fDesc.numColorEffects(), |
| 235 &inColor)); | 113 &inColor)); |
| 236 | 114 |
| 237 // Insert the color filter. This will soon be replaced by a color effect. | |
| 238 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { | |
| 239 const char* colorFilterColorUniName = NULL; | |
| 240 fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder:
:kFragment_Visibility, | |
| 241 kVec4f_GrSLType, "
FilterColor", | |
| 242 &colorFilterColorU
niName); | |
| 243 | |
| 244 builder->fsCodeAppend("\tvec4 filteredColor;\n"); | |
| 245 add_color_filter(builder, "filteredColor", filterColorCoeff, | |
| 246 colorCoeff, colorFilterColorUniName, inColor.c_str()); | |
| 247 inColor = "filteredColor"; | |
| 248 } | |
| 249 | |
| 250 /////////////////////////////////////////////////////////////////////////// | 115 /////////////////////////////////////////////////////////////////////////// |
| 251 // compute the partial coverage | 116 // compute the partial coverage |
| 252 GrGLSLExpr<4> inCoverage = builder->getInputCoverage(); | 117 GrGLSLExpr4 inCoverage = builder->getInputCoverage(); |
| 253 | 118 |
| 254 fCoverageEffects.reset( | 119 fCoverageEffects.reset( |
| 255 builder->createAndEmitEffects(coverageStages, | 120 builder->createAndEmitEffects(coverageStages, |
| 256 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), | 121 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), |
| 257 fDesc.numCoverageEffects(), | 122 fDesc.numCoverageEffects(), |
| 258 &inCoverage)); | 123 &inCoverage)); |
| 259 | 124 |
| 260 // discard if coverage is zero | 125 // discard if coverage is zero |
| 261 if (header.fDiscardIfZeroCoverage && !inCoverage.isOnes()) { | 126 if (header.fDiscardIfZeroCoverage && !inCoverage.isOnes()) { |
| 262 if (inCoverage.isZeros()) { | 127 if (inCoverage.isZeros()) { |
| 263 // This is unfortunate. | 128 // This is unfortunate. |
| 264 builder->fsCodeAppend("\tdiscard;\n"); | 129 builder->fsCodeAppend("\tdiscard;\n"); |
| 265 } else { | 130 } else { |
| 266 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n
\t\tdiscard;\n\t}\n", | 131 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n
\t\tdiscard;\n\t}\n", |
| 267 inCoverage.c_str()); | 132 inCoverage.c_str()); |
| 268 } | 133 } |
| 269 } | 134 } |
| 270 | 135 |
| 271 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { | 136 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { |
| 272 const char* secondaryOutputName = builder->enableSecondaryOutput(); | 137 const char* secondaryOutputName = builder->enableSecondaryOutput(); |
| 273 | 138 |
| 274 // default coeff to ones for kCoverage_DualSrcOutput | 139 // default coeff to ones for kCoverage_DualSrcOutput |
| 275 GrGLSLExpr<4> coeff(1); | 140 GrGLSLExpr4 coeff(1); |
| 276 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { | 141 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { |
| 277 // Get (1-A) into coeff | 142 // Get (1-A) into coeff |
| 278 coeff = GrGLSLExprCast4(GrGLSLExpr<1>(1) - GrGLSLExprExtractAlpha(in
Color)); | 143 coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inColor.a()); |
| 279 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == head
er.fCoverageOutput) { | 144 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == head
er.fCoverageOutput) { |
| 280 // Get (1-RGBA) into coeff | 145 // Get (1-RGBA) into coeff |
| 281 coeff = GrGLSLExpr<4>(1) - inColor; | 146 coeff = GrGLSLExpr4(1) - inColor; |
| 282 } | 147 } |
| 283 // Get coeff * coverage into modulate and then write that to the dual so
urce output. | 148 // Get coeff * coverage into modulate and then write that to the dual so
urce output. |
| 284 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inC
overage).c_str()); | 149 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inC
overage).c_str()); |
| 285 } | 150 } |
| 286 | 151 |
| 287 /////////////////////////////////////////////////////////////////////////// | 152 /////////////////////////////////////////////////////////////////////////// |
| 288 // combine color and coverage as frag color | 153 // combine color and coverage as frag color |
| 289 | 154 |
| 290 // Get "color * coverage" into fragColor | 155 // Get "color * coverage" into fragColor |
| 291 GrGLSLExpr<4> fragColor = inColor * inCoverage; | 156 GrGLSLExpr4 fragColor = inColor * inCoverage; |
| 292 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do
so. | 157 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do
so. |
| 293 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu
t) { | 158 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu
t) { |
| 294 GrGLSLExpr<4> dstCoeff = GrGLSLExpr<4>(1) - inCoverage; | 159 GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inCoverage; |
| 295 | 160 |
| 296 GrGLSLExpr<4> dstContribution = dstCoeff * GrGLSLExpr<4>(builder->dstCol
or()); | 161 GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(builder->dstColor()
); |
| 297 | 162 |
| 298 fragColor = fragColor + dstContribution; | 163 fragColor = fragColor + dstContribution; |
| 299 } | 164 } |
| 300 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragCo
lor.c_str()); | 165 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragCo
lor.c_str()); |
| 301 | 166 |
| 302 if (!builder->finish(&fProgramID)) { | 167 if (!builder->finish(&fProgramID)) { |
| 303 return false; | 168 return false; |
| 304 } | 169 } |
| 305 | 170 |
| 306 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform(); | 171 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 coverage = drawState.getCoverage(); | 210 coverage = drawState.getCoverage(); |
| 346 } else { | 211 } else { |
| 347 color = drawState.getColor(); | 212 color = drawState.getColor(); |
| 348 coverage = drawState.getCoverage(); | 213 coverage = drawState.getCoverage(); |
| 349 } | 214 } |
| 350 | 215 |
| 351 this->setColor(drawState, color, sharedState); | 216 this->setColor(drawState, color, sharedState); |
| 352 this->setCoverage(drawState, coverage, sharedState); | 217 this->setCoverage(drawState, coverage, sharedState); |
| 353 this->setMatrixAndRenderTargetHeight(drawState); | 218 this->setMatrixAndRenderTargetHeight(drawState); |
| 354 | 219 |
| 355 // Setup the SkXfermode::Mode-based colorfilter uniform if necessary | |
| 356 if (fUniformHandles.fColorFilterUni.isValid() && | |
| 357 fColorFilterColor != drawState.getColorFilterColor()) { | |
| 358 GrGLfloat c[4]; | |
| 359 GrColorToRGBAFloat(drawState.getColorFilterColor(), c); | |
| 360 fUniformManager.set4fv(fUniformHandles.fColorFilterUni, 0, 1, c); | |
| 361 fColorFilterColor = drawState.getColorFilterColor(); | |
| 362 } | |
| 363 | |
| 364 if (NULL != dstCopy) { | 220 if (NULL != dstCopy) { |
| 365 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { | 221 if (fUniformHandles.fDstCopyTopLeftUni.isValid()) { |
| 366 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, | 222 fUniformManager.set2f(fUniformHandles.fDstCopyTopLeftUni, |
| 367 static_cast<GrGLfloat>(dstCopy->offset().fX), | 223 static_cast<GrGLfloat>(dstCopy->offset().fX), |
| 368 static_cast<GrGLfloat>(dstCopy->offset().fY)); | 224 static_cast<GrGLfloat>(dstCopy->offset().fY)); |
| 369 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, | 225 fUniformManager.set2f(fUniformHandles.fDstCopyScaleUni, |
| 370 1.f / dstCopy->texture()->width(), | 226 1.f / dstCopy->texture()->width(), |
| 371 1.f / dstCopy->texture()->height()); | 227 1.f / dstCopy->texture()->height()); |
| 372 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture())
; | 228 GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture())
; |
| 373 static GrTextureParams kParams; // the default is clamp, nearest fil
tering. | 229 static GrTextureParams kParams; // the default is clamp, nearest fil
tering. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 402 sharedState->fConstAttribColorIndex != header.fColorAttribut
eIndex) { | 258 sharedState->fConstAttribColorIndex != header.fColorAttribut
eIndex) { |
| 403 // OpenGL ES only supports the float varieties of glVertexAt
trib | 259 // OpenGL ES only supports the float varieties of glVertexAt
trib |
| 404 GrGLfloat c[4]; | 260 GrGLfloat c[4]; |
| 405 GrColorToRGBAFloat(color, c); | 261 GrColorToRGBAFloat(color, c); |
| 406 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); | 262 GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); |
| 407 sharedState->fConstAttribColor = color; | 263 sharedState->fConstAttribColor = color; |
| 408 sharedState->fConstAttribColorIndex = header.fColorAttribute
Index; | 264 sharedState->fConstAttribColorIndex = header.fColorAttribute
Index; |
| 409 } | 265 } |
| 410 break; | 266 break; |
| 411 case GrGLProgramDesc::kUniform_ColorInput: | 267 case GrGLProgramDesc::kUniform_ColorInput: |
| 412 if (fColor != color) { | 268 if (fColor != color && fUniformHandles.fColorUni.isValid()) { |
| 413 // OpenGL ES doesn't support unsigned byte varieties of glUn
iform | 269 // OpenGL ES doesn't support unsigned byte varieties of glUn
iform |
| 414 GrGLfloat c[4]; | 270 GrGLfloat c[4]; |
| 415 GrColorToRGBAFloat(color, c); | 271 GrColorToRGBAFloat(color, c); |
| 416 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); | 272 fUniformManager.set4fv(fUniformHandles.fColorUni, 0, 1, c); |
| 417 fColor = color; | 273 fColor = color; |
| 418 } | 274 } |
| 419 sharedState->fConstAttribColorIndex = -1; | 275 sharedState->fConstAttribColorIndex = -1; |
| 420 break; | 276 break; |
| 421 case GrGLProgramDesc::kSolidWhite_ColorInput: | 277 case GrGLProgramDesc::kSolidWhite_ColorInput: |
| 422 case GrGLProgramDesc::kTransBlack_ColorInput: | 278 case GrGLProgramDesc::kTransBlack_ColorInput: |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 | 346 |
| 491 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 347 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
| 492 fMatrixState.fRenderTargetSize = size; | 348 fMatrixState.fRenderTargetSize = size; |
| 493 fMatrixState.fRenderTargetOrigin = rt->origin(); | 349 fMatrixState.fRenderTargetOrigin = rt->origin(); |
| 494 | 350 |
| 495 GrGLfloat viewMatrix[3 * 3]; | 351 GrGLfloat viewMatrix[3 * 3]; |
| 496 fMatrixState.getGLMatrix<3>(viewMatrix); | 352 fMatrixState.getGLMatrix<3>(viewMatrix); |
| 497 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); | 353 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); |
| 498 } | 354 } |
| 499 } | 355 } |
| OLD | NEW |