| 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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 case SkXfermode::kZero_Coeff: /** 0 */ | 151 case SkXfermode::kZero_Coeff: /** 0 */ |
| 152 *str = ""; | 152 *str = ""; |
| 153 break; | 153 break; |
| 154 case SkXfermode::kOne_Coeff: /** 1 */ | 154 case SkXfermode::kOne_Coeff: /** 1 */ |
| 155 *str = value; | 155 *str = value; |
| 156 break; | 156 break; |
| 157 case SkXfermode::kSC_Coeff: | 157 case SkXfermode::kSC_Coeff: |
| 158 str->printf("(%s * %s)", src, value); | 158 str->printf("(%s * %s)", src, value); |
| 159 break; | 159 break; |
| 160 case SkXfermode::kISC_Coeff: | 160 case SkXfermode::kISC_Coeff: |
| 161 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value); | 161 str->printf("((vec4(1) - %s) * %s)", src, value); |
| 162 break; | 162 break; |
| 163 case SkXfermode::kDC_Coeff: | 163 case SkXfermode::kDC_Coeff: |
| 164 str->printf("(%s * %s)", dst, value); | 164 str->printf("(%s * %s)", dst, value); |
| 165 break; | 165 break; |
| 166 case SkXfermode::kIDC_Coeff: | 166 case SkXfermode::kIDC_Coeff: |
| 167 str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value); | 167 str->printf("((vec4(1) - %s) * %s)", dst, value); |
| 168 break; | 168 break; |
| 169 case SkXfermode::kSA_Coeff: /** src alpha */ | 169 case SkXfermode::kSA_Coeff: /** src alpha */ |
| 170 str->printf("(%s.a * %s)", src, value); | 170 str->printf("(%s.a * %s)", src, value); |
| 171 break; | 171 break; |
| 172 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ | 172 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ |
| 173 str->printf("((1.0 - %s.a) * %s)", src, value); | 173 str->printf("((1.0 - %s.a) * %s)", src, value); |
| 174 break; | 174 break; |
| 175 case SkXfermode::kDA_Coeff: /** dst alpha */ | 175 case SkXfermode::kDA_Coeff: /** dst alpha */ |
| 176 str->printf("(%s.a * %s)", dst, value); | 176 str->printf("(%s.a * %s)", dst, value); |
| 177 break; | 177 break; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 189 */ | 189 */ |
| 190 void add_color_filter(GrGLShaderBuilder* builder, | 190 void add_color_filter(GrGLShaderBuilder* builder, |
| 191 const char * outputVar, | 191 const char * outputVar, |
| 192 SkXfermode::Coeff uniformCoeff, | 192 SkXfermode::Coeff uniformCoeff, |
| 193 SkXfermode::Coeff colorCoeff, | 193 SkXfermode::Coeff colorCoeff, |
| 194 const char* filterColor, | 194 const char* filterColor, |
| 195 const char* inColor) { | 195 const char* inColor) { |
| 196 SkString colorStr, constStr; | 196 SkString colorStr, constStr; |
| 197 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); | 197 blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); |
| 198 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); | 198 blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor
); |
| 199 | 199 GrGLSLExpr<4> sum; |
| 200 SkString sum; | 200 if (colorStr.isEmpty() && constStr.isEmpty()) { |
| 201 GrGLSLAddf<4>(&sum, colorStr.c_str(), constStr.c_str()); | 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 } |
| 202 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); | 209 builder->fsCodeAppendf("\t%s = %s;\n", outputVar, sum.c_str()); |
| 203 } | 210 } |
| 204 } | 211 } |
| 205 | 212 |
| 206 namespace { | |
| 207 | |
| 208 void expand_known_value4f(SkString* string, GrSLConstantVec vec) { | |
| 209 SkASSERT(string->isEmpty() == (vec != kNone_GrSLConstantVec)); | |
| 210 switch (vec) { | |
| 211 case kNone_GrSLConstantVec: | |
| 212 break; | |
| 213 case kZeros_GrSLConstantVec: | |
| 214 *string = GrGLSLZerosVecf(4); | |
| 215 break; | |
| 216 case kOnes_GrSLConstantVec: | |
| 217 *string = GrGLSLOnesVecf(4); | |
| 218 break; | |
| 219 } | |
| 220 } | |
| 221 | |
| 222 } | |
| 223 | |
| 224 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, | 213 bool GrGLProgram::genProgram(GrGLShaderBuilder* builder, |
| 225 const GrEffectStage* colorStages[], | 214 const GrEffectStage* colorStages[], |
| 226 const GrEffectStage* coverageStages[]) { | 215 const GrEffectStage* coverageStages[]) { |
| 227 SkASSERT(0 == fProgramID); | 216 SkASSERT(0 == fProgramID); |
| 228 | 217 |
| 229 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); | 218 const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); |
| 230 | 219 |
| 231 // incoming color to current stage being processed. | 220 // incoming color to current stage being processed. |
| 232 SkString inColor = builder->getInputColor(); | 221 GrGLSLExpr<4> inColor = builder->getInputColor(); |
| 233 GrSLConstantVec knownColorValue = builder->getKnownColorValue(); | |
| 234 | 222 |
| 235 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. | 223 // Get the coeffs for the Mode-based color filter, determine if color is nee
ded. |
| 236 SkXfermode::Coeff colorCoeff; | 224 SkXfermode::Coeff colorCoeff; |
| 237 SkXfermode::Coeff filterColorCoeff; | 225 SkXfermode::Coeff filterColorCoeff; |
| 238 SkAssertResult( | 226 SkAssertResult( |
| 239 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, | 227 SkXfermode::ModeAsCoeff(header.fColorFilterXfermode, |
| 240 &filterColorCoeff, | 228 &filterColorCoeff, |
| 241 &colorCoeff)); | 229 &colorCoeff)); |
| 242 bool needColor, needFilterColor; | 230 bool needColor, needFilterColor; |
| 243 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); | 231 need_blend_inputs(filterColorCoeff, colorCoeff, &needFilterColor, &needColor
); |
| 244 | 232 |
| 245 fColorEffects.reset( | 233 fColorEffects.reset( |
| 246 builder->createAndEmitEffects(colorStages, | 234 builder->createAndEmitEffects(colorStages, |
| 247 fDesc.effectKeys(), | 235 fDesc.effectKeys(), |
| 248 needColor ? fDesc.numColorEffects() : 0, | 236 needColor ? fDesc.numColorEffects() : 0, |
| 249 &inColor, | 237 &inColor)); |
| 250 &knownColorValue)); | |
| 251 | 238 |
| 252 // Insert the color filter. This will soon be replaced by a color effect. | 239 // Insert the color filter. This will soon be replaced by a color effect. |
| 253 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { | 240 if (SkXfermode::kDst_Mode != header.fColorFilterXfermode) { |
| 254 const char* colorFilterColorUniName = NULL; | 241 const char* colorFilterColorUniName = NULL; |
| 255 fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder:
:kFragment_Visibility, | 242 fUniformHandles.fColorFilterUni = builder->addUniform(GrGLShaderBuilder:
:kFragment_Visibility, |
| 256 kVec4f_GrSLType, "
FilterColor", | 243 kVec4f_GrSLType, "
FilterColor", |
| 257 &colorFilterColorU
niName); | 244 &colorFilterColorU
niName); |
| 258 | 245 |
| 259 builder->fsCodeAppend("\tvec4 filteredColor;\n"); | 246 builder->fsCodeAppend("\tvec4 filteredColor;\n"); |
| 260 const char* color; | |
| 261 // add_color_filter requires a real input string. | |
| 262 if (knownColorValue == kOnes_GrSLConstantVec) { | |
| 263 color = GrGLSLOnesVecf(4); | |
| 264 } else if (knownColorValue == kZeros_GrSLConstantVec) { | |
| 265 color = GrGLSLZerosVecf(4); | |
| 266 } else { | |
| 267 color = inColor.c_str(); | |
| 268 } | |
| 269 add_color_filter(builder, "filteredColor", filterColorCoeff, | 247 add_color_filter(builder, "filteredColor", filterColorCoeff, |
| 270 colorCoeff, colorFilterColorUniName, color); | 248 colorCoeff, colorFilterColorUniName, inColor.c_str()); |
| 271 inColor = "filteredColor"; | 249 inColor = "filteredColor"; |
| 272 } | 250 } |
| 273 | 251 |
| 274 /////////////////////////////////////////////////////////////////////////// | 252 /////////////////////////////////////////////////////////////////////////// |
| 275 // compute the partial coverage | 253 // compute the partial coverage |
| 276 SkString inCoverage = builder->getInputCoverage(); | 254 GrGLSLExpr<4> inCoverage = builder->getInputCoverage(); |
| 277 GrSLConstantVec knownCoverageValue = builder->getKnownCoverageValue(); | |
| 278 | 255 |
| 279 fCoverageEffects.reset( | 256 fCoverageEffects.reset( |
| 280 builder->createAndEmitEffects(coverageStages, | 257 builder->createAndEmitEffects(coverageStages, |
| 281 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), | 258 fDesc.getEffectKeys() + fDesc.numColorEffe
cts(), |
| 282 fDesc.numCoverageEffects(), | 259 fDesc.numCoverageEffects(), |
| 283 &inCoverage, | 260 &inCoverage)); |
| 284 &knownCoverageValue)); | |
| 285 | 261 |
| 286 // discard if coverage is zero | 262 // discard if coverage is zero |
| 287 if (header.fDiscardIfZeroCoverage && kOnes_GrSLConstantVec != knownCoverageV
alue) { | 263 if (header.fDiscardIfZeroCoverage && !inCoverage.isOnes()) { |
| 288 if (kZeros_GrSLConstantVec == knownCoverageValue) { | 264 if (inCoverage.isZeros()) { |
| 289 // This is unfortunate. | 265 // This is unfortunate. |
| 290 builder->fsCodeAppend("\tdiscard;\n"); | 266 builder->fsCodeAppend("\tdiscard;\n"); |
| 291 } else { | 267 } else { |
| 292 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n
\t\tdiscard;\n\t}\n", | 268 builder->fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n
\t\tdiscard;\n\t}\n", |
| 293 inCoverage.c_str()); | 269 inCoverage.c_str()); |
| 294 } | 270 } |
| 295 } | 271 } |
| 296 | 272 |
| 297 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { | 273 if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutpu
t)) { |
| 298 const char* secondaryOutputName = builder->enableSecondaryOutput(); | 274 const char* secondaryOutputName = builder->enableSecondaryOutput(); |
| 299 | 275 |
| 300 // default coeff to ones for kCoverage_DualSrcOutput | 276 // default coeff to ones for kCoverage_DualSrcOutput |
| 301 SkString coeff; | 277 GrGLSLExpr<4> coeff(1); |
| 302 GrSLConstantVec knownCoeffValue = kOnes_GrSLConstantVec; | |
| 303 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { | 278 if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCov
erageOutput) { |
| 304 // Get (1-A) into coeff | 279 // Get (1-A) into coeff |
| 305 SkString inColorAlpha; | 280 coeff = GrGLSLExprCast4(GrGLSLExpr<1>(1) - GrGLSLExprExtractAlpha(in
Color)); |
| 306 GrGLSLGetComponent4f(&inColorAlpha, | |
| 307 inColor.c_str(), | |
| 308 kA_GrColorComponentFlag, | |
| 309 knownColorValue, | |
| 310 true); | |
| 311 knownCoeffValue = GrGLSLSubtractf<1>(&coeff, | |
| 312 NULL, | |
| 313 inColorAlpha.c_str(), | |
| 314 kOnes_GrSLConstantVec, | |
| 315 knownColorValue, | |
| 316 true); | |
| 317 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == head
er.fCoverageOutput) { | 281 } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == head
er.fCoverageOutput) { |
| 318 // Get (1-RGBA) into coeff | 282 // Get (1-RGBA) into coeff |
| 319 knownCoeffValue = GrGLSLSubtractf<4>(&coeff, | 283 coeff = GrGLSLExpr<4>(1) - inColor; |
| 320 NULL, | |
| 321 inColor.c_str(), | |
| 322 kOnes_GrSLConstantVec, | |
| 323 knownColorValue, | |
| 324 true); | |
| 325 } | 284 } |
| 326 // Get coeff * coverage into modulate and then write that to the dual so
urce output. | 285 // Get coeff * coverage into modulate and then write that to the dual so
urce output. |
| 327 SkString modulate; | 286 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inC
overage).c_str()); |
| 328 GrGLSLModulatef<4>(&modulate, | |
| 329 coeff.c_str(), | |
| 330 inCoverage.c_str(), | |
| 331 knownCoeffValue, | |
| 332 knownCoverageValue, | |
| 333 false); | |
| 334 builder->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, modulate.c_s
tr()); | |
| 335 } | 287 } |
| 336 | 288 |
| 337 /////////////////////////////////////////////////////////////////////////// | 289 /////////////////////////////////////////////////////////////////////////// |
| 338 // combine color and coverage as frag color | 290 // combine color and coverage as frag color |
| 339 | 291 |
| 340 // Get "color * coverage" into fragColor | 292 // Get "color * coverage" into fragColor |
| 341 SkString fragColor; | 293 GrGLSLExpr<4> fragColor = inColor * inCoverage; |
| 342 GrSLConstantVec knownFragColorValue = GrGLSLModulatef<4>(&fragColor, | |
| 343 inColor.c_str(), | |
| 344 inCoverage.c_str(), | |
| 345 knownColorValue, | |
| 346 knownCoverageValue, | |
| 347 true); | |
| 348 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do
so. | 294 // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do
so. |
| 349 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu
t) { | 295 if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutpu
t) { |
| 350 SkString dstCoeff; | 296 GrGLSLExpr<4> dstCoeff = GrGLSLExpr<4>(1) - inCoverage; |
| 351 GrSLConstantVec knownDstCoeffValue = GrGLSLSubtractf<4>(&dstCoeff, | 297 |
| 352 NULL, | 298 GrGLSLExpr<4> dstContribution = dstCoeff * GrGLSLExpr<4>(builder->dstCol
or()); |
| 353 inCoverage.c_str
(), | 299 |
| 354 kOnes_GrSLConsta
ntVec, | 300 fragColor = fragColor + dstContribution; |
| 355 knownCoverageVal
ue, | |
| 356 true); | |
| 357 SkString dstContribution; | |
| 358 GrSLConstantVec knownDstContributionValue = GrGLSLModulatef<4>(&dstContr
ibution, | |
| 359 dstCoeff.
c_str(), | |
| 360 builder->
dstColor(), | |
| 361 knownDstC
oeffValue, | |
| 362 kNone_GrS
LConstantVec, | |
| 363 true); | |
| 364 SkString oldFragColor = fragColor; | |
| 365 fragColor.reset(); | |
| 366 GrGLSLAddf<4>(&fragColor, | |
| 367 oldFragColor.c_str(), | |
| 368 dstContribution.c_str(), | |
| 369 knownFragColorValue, | |
| 370 knownDstContributionValue, | |
| 371 false); | |
| 372 } else { | |
| 373 expand_known_value4f(&fragColor, knownFragColorValue); | |
| 374 } | 301 } |
| 375 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragCo
lor.c_str()); | 302 builder->fsCodeAppendf("\t%s = %s;\n", builder->getColorOutputName(), fragCo
lor.c_str()); |
| 376 | 303 |
| 377 if (!builder->finish(&fProgramID)) { | 304 if (!builder->finish(&fProgramID)) { |
| 378 return false; | 305 return false; |
| 379 } | 306 } |
| 380 | 307 |
| 381 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform(); | 308 fUniformHandles.fRTHeightUni = builder->getRTHeightUniform(); |
| 382 fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform(); | 309 fUniformHandles.fDstCopyTopLeftUni = builder->getDstCopyTopLeftUniform(); |
| 383 fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform(); | 310 fUniformHandles.fDstCopyScaleUni = builder->getDstCopyScaleUniform(); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 | 492 |
| 566 fMatrixState.fViewMatrix = drawState.getViewMatrix(); | 493 fMatrixState.fViewMatrix = drawState.getViewMatrix(); |
| 567 fMatrixState.fRenderTargetSize = size; | 494 fMatrixState.fRenderTargetSize = size; |
| 568 fMatrixState.fRenderTargetOrigin = rt->origin(); | 495 fMatrixState.fRenderTargetOrigin = rt->origin(); |
| 569 | 496 |
| 570 GrGLfloat viewMatrix[3 * 3]; | 497 GrGLfloat viewMatrix[3 * 3]; |
| 571 fMatrixState.getGLMatrix<3>(viewMatrix); | 498 fMatrixState.getGLMatrix<3>(viewMatrix); |
| 572 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); | 499 fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, viewMatrix); |
| 573 } | 500 } |
| 574 } | 501 } |
| OLD | NEW |