Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Side by Side Diff: src/gpu/effects/GrPorterDuffXferProcessor.cpp

Issue 914003003: Use dst copies in porter duffer XP to correctly render certain blends. (Closed) Base URL: https://skia.googlesource.com/skia.git@prePDDstCopy
Patch Set: Rebase Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/effects/GrDisableColorXP.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 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 "effects/GrPorterDuffXferProcessor.h" 8 #include "effects/GrPorterDuffXferProcessor.h"
9 9
10 #include "GrBlend.h" 10 #include "GrBlend.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 /////////////////////////////////////////////////////////////////////////// 52 ///////////////////////////////////////////////////////////////////////////
53 /// @name Stage Output Types 53 /// @name Stage Output Types
54 //// 54 ////
55 55
56 enum PrimaryOutputType { 56 enum PrimaryOutputType {
57 kNone_PrimaryOutputType, 57 kNone_PrimaryOutputType,
58 kColor_PrimaryOutputType, 58 kColor_PrimaryOutputType,
59 kCoverage_PrimaryOutputType, 59 kCoverage_PrimaryOutputType,
60 // Modulate color and coverage, write result as the color output. 60 // Modulate color and coverage, write result as the color output.
61 kModulate_PrimaryOutputType, 61 kModulate_PrimaryOutputType,
62 // Custom Porter-Duff output, used for when we explictly are reading the dst and blending
63 // in the shader. Secondary Output must be none if you use this. The cus tom blend uses the
64 // equation: cov * (coeffS * S + coeffD * D) + (1 - cov) * D
65 kCustom_PrimaryOutputType
62 }; 66 };
63 67
64 enum SecondaryOutputType { 68 enum SecondaryOutputType {
65 // There is no secondary output 69 // There is no secondary output
66 kNone_SecondaryOutputType, 70 kNone_SecondaryOutputType,
67 // Writes coverage as the secondary output. Only set if dual source blen ding is supported 71 // Writes coverage as the secondary output. Only set if dual source blen ding is supported
68 // and primary output is kModulate. 72 // and primary output is kModulate.
69 kCoverage_SecondaryOutputType, 73 kCoverage_SecondaryOutputType,
70 // Writes coverage * (1 - colorA) as the secondary output. Only set if d ual source blending 74 // Writes coverage * (1 - colorA) as the secondary output. Only set if d ual source blending
71 // is supported and primary output is kModulate. 75 // is supported and primary output is kModulate.
72 kCoverageISA_SecondaryOutputType, 76 kCoverageISA_SecondaryOutputType,
73 // Writes coverage * (1 - colorRGBA) as the secondary output. Only set i f dual source 77 // Writes coverage * (1 - colorRGBA) as the secondary output. Only set i f dual source
74 // blending is supported and primary output is kModulate. 78 // blending is supported and primary output is kModulate.
75 kCoverageISC_SecondaryOutputType, 79 kCoverageISC_SecondaryOutputType,
76 80
77 kSecondaryOutputTypeCnt, 81 kSecondaryOutputTypeCnt,
78 }; 82 };
79 83
80 PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; } 84 PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; }
81 SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputTyp e; } 85 SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputTyp e; }
82 86
83 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, 87 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
84 const GrProcOptInfo& coveragePOI, 88 const GrProcOptInfo& coveragePOI,
85 bool doesStencilWrite, 89 bool doesStencilWrite,
86 GrColor* overrideColor, 90 GrColor* overrideColor,
87 const GrDrawTargetCaps& caps) SK_ OVERRIDE; 91 const GrDrawTargetCaps& caps) SK_ OVERRIDE;
88 92
89 void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE { 93 void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE {
90 blendInfo->fSrcBlend = fSrcBlend; 94 if (!this->willReadDstColor()) {
91 blendInfo->fDstBlend = fDstBlend; 95 blendInfo->fSrcBlend = fSrcBlend;
96 blendInfo->fDstBlend = fDstBlend;
97 } else {
98 blendInfo->fSrcBlend = kOne_GrBlendCoeff;
99 blendInfo->fDstBlend = kZero_GrBlendCoeff;
100 }
92 blendInfo->fBlendConstant = fBlendConstant; 101 blendInfo->fBlendConstant = fBlendConstant;
93 } 102 }
94 103
104 GrBlendCoeff getSrcBlend() const { return fSrcBlend; }
105 GrBlendCoeff getDstBlend() const { return fDstBlend; }
106
95 private: 107 private:
96 PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColo r constant, 108 PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColo r constant,
97 const GrDeviceCoordTexture* dstCopy, bool willReadDs tColor); 109 const GrDeviceCoordTexture* dstCopy, bool willReadDs tColor);
98 110
99 void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) con st SK_OVERRIDE; 111 void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) con st SK_OVERRIDE;
100 112
101 bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { 113 bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
102 const PorterDuffXferProcessor& xp = xpBase.cast<PorterDuffXferProcessor> (); 114 const PorterDuffXferProcessor& xp = xpBase.cast<PorterDuffXferProcessor> ();
103 if (fSrcBlend != xp.fSrcBlend || 115 if (fSrcBlend != xp.fSrcBlend ||
104 fDstBlend != xp.fDstBlend || 116 fDstBlend != xp.fDstBlend ||
(...skipping 16 matching lines...) Expand all
121 GrBlendCoeff fDstBlend; 133 GrBlendCoeff fDstBlend;
122 GrColor fBlendConstant; 134 GrColor fBlendConstant;
123 PrimaryOutputType fPrimaryOutputType; 135 PrimaryOutputType fPrimaryOutputType;
124 SecondaryOutputType fSecondaryOutputType; 136 SecondaryOutputType fSecondaryOutputType;
125 137
126 typedef GrXferProcessor INHERITED; 138 typedef GrXferProcessor INHERITED;
127 }; 139 };
128 140
129 /////////////////////////////////////////////////////////////////////////////// 141 ///////////////////////////////////////////////////////////////////////////////
130 142
143 bool append_porterduff_term(GrGLFPFragmentBuilder* fsBuilder, GrBlendCoeff coeff ,
144 const char* colorName, const char* srcColorName,
145 const char* dstColorName, bool hasPrevious) {
146 if (kZero_GrBlendCoeff == coeff) {
147 return hasPrevious;
148 } else {
149 if (hasPrevious) {
150 fsBuilder->codeAppend(" + ");
151 }
152 fsBuilder->codeAppendf("%s", colorName);
153 switch (coeff) {
154 case kOne_GrBlendCoeff:
155 break;
156 case kSC_GrBlendCoeff:
157 fsBuilder->codeAppendf(" * %s", srcColorName);
158 break;
159 case kISC_GrBlendCoeff:
160 fsBuilder->codeAppendf(" * (vec4(1.0) - %s)", srcColorName);
161 break;
162 case kDC_GrBlendCoeff:
163 fsBuilder->codeAppendf(" * %s", dstColorName);
164 break;
165 case kIDC_GrBlendCoeff:
166 fsBuilder->codeAppendf(" * (vec4(1.0) - %s)", dstColorName);
167 break;
168 case kSA_GrBlendCoeff:
169 fsBuilder->codeAppendf(" * %s.a", srcColorName);
170 break;
171 case kISA_GrBlendCoeff:
172 fsBuilder->codeAppendf(" * (1.0 - %s.a)", srcColorName);
173 break;
174 case kDA_GrBlendCoeff:
175 fsBuilder->codeAppendf(" * %s.a", dstColorName);
176 break;
177 case kIDA_GrBlendCoeff:
178 fsBuilder->codeAppendf(" * (1.0 - %s.a)", dstColorName);
179 break;
180 default:
181 SkFAIL("Unsupported Blend Coeff");
182 }
183 return true;
184 }
185 }
186
131 class GLPorterDuffXferProcessor : public GrGLXferProcessor { 187 class GLPorterDuffXferProcessor : public GrGLXferProcessor {
132 public: 188 public:
133 GLPorterDuffXferProcessor(const GrProcessor&) {} 189 GLPorterDuffXferProcessor(const GrProcessor&) {}
134 190
135 virtual ~GLPorterDuffXferProcessor() {} 191 virtual ~GLPorterDuffXferProcessor() {}
136 192
137 static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, 193 static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
138 GrProcessorKeyBuilder* b) { 194 GrProcessorKeyBuilder* b) {
139 const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcess or>(); 195 const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcess or>();
140 b->add32(xp.primaryOutputType()); 196 b->add32(xp.primaryOutputType());
141 b->add32(xp.secondaryOutputType()); 197 b->add32(xp.secondaryOutputType());
198 if (xp.willReadDstColor()) {
199 b->add32(xp.getSrcBlend());
200 b->add32(xp.getDstBlend());
201 }
142 }; 202 };
143 203
144 private: 204 private:
145 void onEmitCode(const EmitArgs& args) SK_OVERRIDE { 205 void onEmitCode(const EmitArgs& args) SK_OVERRIDE {
146 const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcesso r>(); 206 const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcesso r>();
147 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 207 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
148 if (xp.hasSecondaryOutput()) { 208 if (PorterDuffXferProcessor::kCustom_PrimaryOutputType != xp.primaryOutp utType()) {
209 SkASSERT(!xp.willReadDstColor());
149 switch(xp.secondaryOutputType()) { 210 switch(xp.secondaryOutputType()) {
211 case PorterDuffXferProcessor::kNone_SecondaryOutputType:
212 break;
150 case PorterDuffXferProcessor::kCoverage_SecondaryOutputType: 213 case PorterDuffXferProcessor::kCoverage_SecondaryOutputType:
151 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, ar gs.fInputCoverage); 214 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary,
215 args.fInputCoverage);
152 break; 216 break;
153 case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType: 217 case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType:
154 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", 218 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
155 args.fOutputSecondary, args.fInputCol or, 219 args.fOutputSecondary, args.fInputCol or,
156 args.fInputCoverage); 220 args.fInputCoverage);
157 break; 221 break;
158 case PorterDuffXferProcessor::kCoverageISC_SecondaryOutputType: 222 case PorterDuffXferProcessor::kCoverageISC_SecondaryOutputType:
159 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", 223 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;",
160 args.fOutputSecondary, args.fInputCol or, 224 args.fOutputSecondary, args.fInputCol or,
161 args.fInputCoverage); 225 args.fInputCoverage);
162 break; 226 break;
163 default: 227 default:
164 SkFAIL("Unexpected Secondary Output"); 228 SkFAIL("Unexpected Secondary Output");
165 } 229 }
166 } 230
167 231 switch (xp.primaryOutputType()) {
168 switch (xp.primaryOutputType()) { 232 case PorterDuffXferProcessor::kNone_PrimaryOutputType:
169 case PorterDuffXferProcessor::kNone_PrimaryOutputType: 233 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary) ;
170 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); 234 break;
171 break; 235 case PorterDuffXferProcessor::kColor_PrimaryOutputType:
172 case PorterDuffXferProcessor::kColor_PrimaryOutputType: 236 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args .fInputColor);
173 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn putColor); 237 break;
174 break; 238 case PorterDuffXferProcessor::kCoverage_PrimaryOutputType:
175 case PorterDuffXferProcessor::kCoverage_PrimaryOutputType: 239 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args .fInputCoverage);
176 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn putCoverage); 240 break;
177 break; 241 case PorterDuffXferProcessor::kModulate_PrimaryOutputType:
178 case PorterDuffXferProcessor::kModulate_PrimaryOutputType: 242 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
179 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, arg s.fInputColor, 243 args.fInputCoverage);
180 args.fInputCoverage); 244 break;
181 break; 245 default:
182 default: 246 SkFAIL("Unexpected Primary Output");
183 SkFAIL("Unexpected Primary Output"); 247 }
248 } else {
249 SkASSERT(xp.willReadDstColor());
250
251 const char* dstColor = fsBuilder->dstColor();
252
253 fsBuilder->codeAppend("vec4 colorBlend =");
254 // append src blend
255 bool didAppend = append_porterduff_term(fsBuilder, xp.getSrcBlend(),
256 args.fInputColor, args.fInpu tColor,
257 dstColor, false);
258 // append dst blend
259 SkAssertResult(append_porterduff_term(fsBuilder, xp.getDstBlend(),
260 dstColor, args.fInputColor,
261 dstColor, didAppend));
262 fsBuilder->codeAppend(";");
263
264 fsBuilder->codeAppendf("%s = %s * colorBlend + (vec4(1.0) - %s) * %s ;",
265 args.fOutputPrimary, args.fInputCoverage, arg s.fInputCoverage,
266 dstColor);
184 } 267 }
185 } 268 }
186 269
187 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVE RRIDE {}; 270 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVE RRIDE {};
188 271
189 typedef GrGLXferProcessor INHERITED; 272 typedef GrGLXferProcessor INHERITED;
190 }; 273 };
191 274
192 /////////////////////////////////////////////////////////////////////////////// 275 ///////////////////////////////////////////////////////////////////////////////
193 276
194 PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend, 277 PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend,
195 GrBlendCoeff dstBlend, 278 GrBlendCoeff dstBlend,
196 GrColor constant, 279 GrColor constant,
197 const GrDeviceCoordTexture* dst Copy, 280 const GrDeviceCoordTexture* dst Copy,
198 bool willReadDstColor) 281 bool willReadDstColor)
199 : fSrcBlend(srcBlend) 282 : INHERITED(dstCopy, willReadDstColor)
283 , fSrcBlend(srcBlend)
200 , fDstBlend(dstBlend) 284 , fDstBlend(dstBlend)
201 , fBlendConstant(constant) 285 , fBlendConstant(constant)
202 , fPrimaryOutputType(kModulate_PrimaryOutputType) 286 , fPrimaryOutputType(kModulate_PrimaryOutputType)
203 , fSecondaryOutputType(kNone_SecondaryOutputType) { 287 , fSecondaryOutputType(kNone_SecondaryOutputType) {
204 this->initClassID<PorterDuffXferProcessor>(); 288 this->initClassID<PorterDuffXferProcessor>();
205 } 289 }
206 290
207 PorterDuffXferProcessor::~PorterDuffXferProcessor() { 291 PorterDuffXferProcessor::~PorterDuffXferProcessor() {
208 } 292 }
209 293
(...skipping 27 matching lines...) Expand all
237 coveragePOI, 321 coveragePOI,
238 doesStencilWrite); 322 doesStencilWrite);
239 } 323 }
240 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite()); 324 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite());
241 return optFlags; 325 return optFlags;
242 } 326 }
243 327
244 void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags , 328 void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags ,
245 const GrDrawTargetCaps& caps, 329 const GrDrawTargetCaps& caps,
246 bool hasSolidCoverage) { 330 bool hasSolidCoverage) {
331 if (this->willReadDstColor()) {
332 fPrimaryOutputType = kCustom_PrimaryOutputType;
333 return;
334 }
335
247 if (optFlags & kIgnoreColor_OptFlag) { 336 if (optFlags & kIgnoreColor_OptFlag) {
248 if (optFlags & kIgnoreCoverage_OptFlag) { 337 if (optFlags & kIgnoreCoverage_OptFlag) {
249 fPrimaryOutputType = kNone_PrimaryOutputType; 338 fPrimaryOutputType = kNone_PrimaryOutputType;
250 return; 339 return;
251 } else { 340 } else {
252 fPrimaryOutputType = kCoverage_PrimaryOutputType; 341 fPrimaryOutputType = kCoverage_PrimaryOutputType;
253 return; 342 return;
254 } 343 }
255 } else if (optFlags & kIgnoreCoverage_OptFlag) { 344 } else if (optFlags & kIgnoreCoverage_OptFlag) {
256 fPrimaryOutputType = kColor_PrimaryOutputType; 345 fPrimaryOutputType = kColor_PrimaryOutputType;
(...skipping 20 matching lines...) Expand all
277 fDstBlend = kIS2C_GrBlendCoeff; 366 fDstBlend = kIS2C_GrBlendCoeff;
278 } 367 }
279 } 368 }
280 } 369 }
281 } 370 }
282 371
283 GrXferProcessor::OptFlags 372 GrXferProcessor::OptFlags
284 PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI, 373 PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI,
285 const GrProcOptInfo& coverageP OI, 374 const GrProcOptInfo& coverageP OI,
286 bool doesStencilWrite) { 375 bool doesStencilWrite) {
287 bool srcAIsOne; 376 if (this->willReadDstColor()) {
288 bool hasCoverage; 377 return GrXferProcessor::kNone_Opt;
378 }
289 379
290 srcAIsOne = colorPOI.isOpaque(); 380 bool srcAIsOne = colorPOI.isOpaque();
291 hasCoverage = !coveragePOI.isSolidWhite(); 381 bool hasCoverage = !coveragePOI.isSolidWhite();
292 382
293 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend || 383 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend ||
294 (kSA_GrBlendCoeff == fDstBlend && srcAIsOne); 384 (kSA_GrBlendCoeff == fDstBlend && srcAIsOne);
295 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend || 385 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend ||
296 (kISA_GrBlendCoeff == fDstBlend && srcAIsOne); 386 (kISA_GrBlendCoeff == fDstBlend && srcAIsOne);
297 387
298 // When coeffs are (0,1) there is no reason to draw at all, unless 388 // When coeffs are (0,1) there is no reason to draw at all, unless
299 // stenciling is enabled. Having color writes disabled is effectively 389 // stenciling is enabled. Having color writes disabled is effectively
300 // (0,1). 390 // (0,1).
301 if ((kZero_GrBlendCoeff == fSrcBlend && dstCoeffIsOne)) { 391 if ((kZero_GrBlendCoeff == fSrcBlend && dstCoeffIsOne)) {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 static GrPorterDuffXPFactory gScreenPDXPF(kOne_GrBlendCoeff, kISC_Gr BlendCoeff); 555 static GrPorterDuffXPFactory gScreenPDXPF(kOne_GrBlendCoeff, kISC_Gr BlendCoeff);
466 return SkRef(&gScreenPDXPF); 556 return SkRef(&gScreenPDXPF);
467 break; 557 break;
468 } 558 }
469 default: 559 default:
470 return NULL; 560 return NULL;
471 } 561 }
472 } 562 }
473 563
474 GrXferProcessor* 564 GrXferProcessor*
475 GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, 565 GrPorterDuffXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
566 const GrProcOptInfo& colorPOI,
476 const GrProcOptInfo& covPOI, 567 const GrProcOptInfo& covPOI,
477 const GrDeviceCoordTexture* dstCopy ) const { 568 const GrDeviceCoordTexture* dstCopy ) const {
478 if (!covPOI.isFourChannelOutput()) { 569 if (!covPOI.isFourChannelOutput()) {
479 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, 570 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy,
480 this->willReadDstColor(colorPOI, covPOI)); 571 this->willReadDstColor(caps, colo rPOI, covPOI));
481 } else { 572 } else {
482 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) { 573 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) {
483 SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); 574 SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags());
484 GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); 575 GrColor blendConstant = GrUnPreMulColor(colorPOI.color());
485 return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_Gr BlendCoeff, 576 return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_Gr BlendCoeff,
486 blendConstant, dstCopy, 577 blendConstant, dstCopy,
487 this->willReadDstColor(colorP OI, covPOI)); 578 this->willReadDstColor(caps, colorPOI, covPOI));
488 } else { 579 } else {
489 return NULL; 580 return NULL;
490 } 581 }
491 } 582 }
492 } 583 }
493 584
494 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, 585 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/,
495 uint32_t knownColorFlags) const { 586 uint32_t knownColorFlags) const {
496 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff && 587 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff &&
497 kRGBA_GrColorComponentFlags == knownColorFlags) { 588 kRGBA_GrColorComponentFlags == knownColorFlags) {
498 return true; 589 return true;
499 } 590 }
500 return false; 591 return false;
501 } 592 }
502 593
503 bool GrPorterDuffXPFactory::canApplyCoverage(const GrProcOptInfo& colorPOI,
504 const GrProcOptInfo& coveragePOI) c onst {
505 bool srcAIsOne = colorPOI.isOpaque();
506
507 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstCoeff ||
508 (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne);
509 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstCoeff ||
510 (kISA_GrBlendCoeff == fDstCoeff && srcAIsOne);
511
512 if ((kZero_GrBlendCoeff == fSrcCoeff && dstCoeffIsOne)) {
513 return true;
514 }
515
516 // if we don't have coverage we can check whether the dst
517 // has to read at all.
518 // check whether coverage can be safely rolled into alpha
519 // of if we can skip color computation and just emit coverage
520 if (this->canTweakAlphaForCoverage()) {
521 return true;
522 }
523 if (dstCoeffIsZero) {
524 if (kZero_GrBlendCoeff == fSrcCoeff) {
525 return true;
526 } else if (srcAIsOne) {
527 return true;
528 }
529 } else if (dstCoeffIsOne) {
530 return true;
531 }
532
533 return false;
534 }
535
536 bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const { 594 bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const {
537 return can_tweak_alpha_for_coverage(fDstCoeff); 595 return can_tweak_alpha_for_coverage(fDstCoeff);
538 } 596 }
539 597
540 void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, 598 void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI,
541 const GrProcOptInfo& coveragePOI, 599 const GrProcOptInfo& coveragePOI,
542 GrXPFactory::InvariantOutput* out put) const { 600 GrXPFactory::InvariantOutput* out put) const {
543 if (!coveragePOI.isSolidWhite()) { 601 if (!coveragePOI.isSolidWhite()) {
544 output->fWillBlendWithDst = true; 602 output->fWillBlendWithDst = true;
545 output->fBlendedColorFlags = 0; 603 output->fBlendedColorFlags = 0;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 case kIConstC_GrBlendCoeff: 657 case kIConstC_GrBlendCoeff:
600 case kConstA_GrBlendCoeff: 658 case kConstA_GrBlendCoeff:
601 case kIConstA_GrBlendCoeff: 659 case kIConstA_GrBlendCoeff:
602 output->fBlendedColorFlags = 0; 660 output->fBlendedColorFlags = 0;
603 break; 661 break;
604 } 662 }
605 663
606 output->fWillBlendWithDst = false; 664 output->fWillBlendWithDst = false;
607 } 665 }
608 666
609 bool GrPorterDuffXPFactory::willReadDstColor(const GrProcOptInfo& colorPOI, 667 bool GrPorterDuffXPFactory::willReadDstColor(const GrDrawTargetCaps& caps,
668 const GrProcOptInfo& colorPOI,
610 const GrProcOptInfo& coveragePOI) c onst { 669 const GrProcOptInfo& coveragePOI) c onst {
611 return false; 670 // We can always blend correctly if we have dual source blending.
671 if (caps.dualSourceBlendingSupport()) {
672 return false;
673 }
674
675 if (this->canTweakAlphaForCoverage()) {
676 return false;
677 }
678
679 bool srcAIsOne = colorPOI.isOpaque();
680
681 if (kZero_GrBlendCoeff == fDstCoeff) {
682 if (kZero_GrBlendCoeff == fSrcCoeff || srcAIsOne) {
683 return false;
684 }
685 }
686
687 // Reduces to: coeffS * (Cov*S) + D
688 if (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne) {
689 return false;
690 }
691
692 // We can always blend correctly if we have solid coverage.
693 if (coveragePOI.isSolidWhite()) {
694 return false;
695 }
696
697 return true;
612 } 698 }
613 699
614 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); 700 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
615 701
616 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, 702 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
617 GrContext*, 703 GrContext*,
618 const GrDrawTargetCaps&, 704 const GrDrawTargetCaps&,
619 GrTexture*[]) { 705 GrTexture*[]) {
620 SkXfermode::Mode mode = SkXfermode::Mode(random->nextULessThan(SkXfermode::k LastCoeffMode)); 706 SkXfermode::Mode mode = SkXfermode::Mode(random->nextULessThan(SkXfermode::k LastCoeffMode));
621 return GrPorterDuffXPFactory::Create(mode); 707 return GrPorterDuffXPFactory::Create(mode);
622 } 708 }
623 709
OLDNEW
« no previous file with comments | « src/gpu/effects/GrDisableColorXP.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698