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

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: 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_blend(GrGLFPFragmentBuilder* fsBuilder, GrBlendCoeff coef f,
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()) {
149 switch(xp.secondaryOutputType()) { 209 SkASSERT(!xp.willReadDstColor());
150 case PorterDuffXferProcessor::kCoverage_SecondaryOutputType: 210 if (xp.hasSecondaryOutput()) {
bsalomon 2015/02/11 15:53:31 can we skip the vcall/extra branch here since seco
151 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, ar gs.fInputCoverage); 211 switch(xp.secondaryOutputType()) {
212 case PorterDuffXferProcessor::kCoverage_SecondaryOutputType:
213 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary ,
214 args.fInputCoverage);
215 break;
216 case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputTy pe:
217 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
218 args.fOutputSecondary, args.fInpu tColor,
219 args.fInputCoverage);
220 break;
221 case PorterDuffXferProcessor::kCoverageISC_SecondaryOutputTy pe:
222 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;",
223 args.fOutputSecondary, args.fInpu tColor,
224 args.fInputCoverage);
225 break;
226 default:
227 SkFAIL("Unexpected Secondary Output");
228 }
229 }
230
231 switch (xp.primaryOutputType()) {
232 case PorterDuffXferProcessor::kNone_PrimaryOutputType:
233 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary) ;
152 break; 234 break;
153 case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType: 235 case PorterDuffXferProcessor::kColor_PrimaryOutputType:
154 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", 236 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args .fInputColor);
155 args.fOutputSecondary, args.fInputCol or,
156 args.fInputCoverage);
157 break; 237 break;
158 case PorterDuffXferProcessor::kCoverageISC_SecondaryOutputType: 238 case PorterDuffXferProcessor::kCoverage_PrimaryOutputType:
159 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", 239 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args .fInputCoverage);
160 args.fOutputSecondary, args.fInputCol or, 240 break;
241 case PorterDuffXferProcessor::kModulate_PrimaryOutputType:
242 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
161 args.fInputCoverage); 243 args.fInputCoverage);
162 break; 244 break;
163 default: 245 default:
164 SkFAIL("Unexpected Secondary Output"); 246 SkFAIL("Unexpected Primary Output");
165 } 247 }
166 } 248 } else {
167 249 SkASSERT(xp.willReadDstColor());
168 switch (xp.primaryOutputType()) { 250
169 case PorterDuffXferProcessor::kNone_PrimaryOutputType: 251 const char* dstColor = fsBuilder->dstColor();
170 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); 252
171 break; 253 fsBuilder->codeAppend("vec4 colorBlend =");
172 case PorterDuffXferProcessor::kColor_PrimaryOutputType: 254 // append src blend
173 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn putColor); 255 bool didAppend = append_porterduff_blend(fsBuilder, xp.getSrcBlend() ,
bsalomon 2015/02/11 15:53:31 maybe append_porterduff_term?
174 break; 256 args.fInputColor, args.fInp utColor,
175 case PorterDuffXferProcessor::kCoverage_PrimaryOutputType: 257 dstColor, false);
176 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn putCoverage); 258 // append dst blend
177 break; 259 SkAssertResult(append_porterduff_blend(fsBuilder, xp.getDstBlend(),
178 case PorterDuffXferProcessor::kModulate_PrimaryOutputType: 260 dstColor, args.fInputColor,
179 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, arg s.fInputColor, 261 dstColor, didAppend));
180 args.fInputCoverage); 262 fsBuilder->codeAppend(";");
181 break; 263
182 default: 264 fsBuilder->codeAppendf("%s = %s * colorBlend + (vec4(1.0) - %s) * %s ;",
bsalomon 2015/02/11 15:53:31 do we know if cov is 4 chan here? can we treat it
egdaniel 2015/02/13 14:19:14 In our current system we know that cov will be 4 c
183 SkFAIL("Unexpected Primary Output"); 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 = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; 366 fDstBlend = (GrBlendCoeff)GrGpu::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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 static GrPorterDuffXPFactory gScreenPDXPF(kOne_GrBlendCoeff, kISC_Gr BlendCoeff); 536 static GrPorterDuffXPFactory gScreenPDXPF(kOne_GrBlendCoeff, kISC_Gr BlendCoeff);
447 return SkRef(&gScreenPDXPF); 537 return SkRef(&gScreenPDXPF);
448 break; 538 break;
449 } 539 }
450 default: 540 default:
451 return NULL; 541 return NULL;
452 } 542 }
453 } 543 }
454 544
455 GrXferProcessor* 545 GrXferProcessor*
456 GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, 546 GrPorterDuffXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
547 const GrProcOptInfo& colorPOI,
457 const GrProcOptInfo& covPOI, 548 const GrProcOptInfo& covPOI,
458 const GrDeviceCoordTexture* dstCopy ) const { 549 const GrDeviceCoordTexture* dstCopy ) const {
459 if (!covPOI.isFourChannelOutput()) { 550 if (!covPOI.isFourChannelOutput()) {
460 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, 551 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy,
461 this->willReadDstColor(colorPOI, covPOI)); 552 this->willReadDstColor(caps, colo rPOI, covPOI));
462 } else { 553 } else {
463 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) { 554 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) {
464 SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); 555 SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags());
465 GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); 556 GrColor blendConstant = GrUnPreMulColor(colorPOI.color());
466 return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_Gr BlendCoeff, 557 return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_Gr BlendCoeff,
467 blendConstant, dstCopy, 558 blendConstant, dstCopy,
468 this->willReadDstColor(colorP OI, covPOI)); 559 this->willReadDstColor(caps, colorPOI, covPOI));
469 } else { 560 } else {
470 return NULL; 561 return NULL;
471 } 562 }
472 } 563 }
473 } 564 }
474 565
475 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, 566 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/,
476 uint32_t knownColorFlags) const { 567 uint32_t knownColorFlags) const {
477 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff && 568 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff &&
478 kRGBA_GrColorComponentFlags == knownColorFlags) { 569 kRGBA_GrColorComponentFlags == knownColorFlags) {
479 return true; 570 return true;
480 } 571 }
481 return false; 572 return false;
482 } 573 }
483 574
484 bool GrPorterDuffXPFactory::canApplyCoverage(const GrProcOptInfo& colorPOI,
485 const GrProcOptInfo& coveragePOI) c onst {
486 bool srcAIsOne = colorPOI.isOpaque();
487
488 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstCoeff ||
489 (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne);
490 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstCoeff ||
491 (kISA_GrBlendCoeff == fDstCoeff && srcAIsOne);
492
493 if ((kZero_GrBlendCoeff == fSrcCoeff && dstCoeffIsOne)) {
494 return true;
495 }
496
497 // if we don't have coverage we can check whether the dst
498 // has to read at all.
499 // check whether coverage can be safely rolled into alpha
500 // of if we can skip color computation and just emit coverage
501 if (this->canTweakAlphaForCoverage()) {
502 return true;
503 }
504 if (dstCoeffIsZero) {
505 if (kZero_GrBlendCoeff == fSrcCoeff) {
506 return true;
507 } else if (srcAIsOne) {
508 return true;
509 }
510 } else if (dstCoeffIsOne) {
511 return true;
512 }
513
514 return false;
515 }
516
517 bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const { 575 bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const {
518 return can_tweak_alpha_for_coverage(fDstCoeff); 576 return can_tweak_alpha_for_coverage(fDstCoeff);
519 } 577 }
520 578
521 void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, 579 void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI,
522 const GrProcOptInfo& coveragePOI, 580 const GrProcOptInfo& coveragePOI,
523 GrXPFactory::InvariantOutput* out put) const { 581 GrXPFactory::InvariantOutput* out put) const {
524 if (!coveragePOI.isSolidWhite()) { 582 if (!coveragePOI.isSolidWhite()) {
525 output->fWillBlendWithDst = true; 583 output->fWillBlendWithDst = true;
526 output->fBlendedColorFlags = 0; 584 output->fBlendedColorFlags = 0;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 case kIConstC_GrBlendCoeff: 638 case kIConstC_GrBlendCoeff:
581 case kConstA_GrBlendCoeff: 639 case kConstA_GrBlendCoeff:
582 case kIConstA_GrBlendCoeff: 640 case kIConstA_GrBlendCoeff:
583 output->fBlendedColorFlags = 0; 641 output->fBlendedColorFlags = 0;
584 break; 642 break;
585 } 643 }
586 644
587 output->fWillBlendWithDst = false; 645 output->fWillBlendWithDst = false;
588 } 646 }
589 647
590 bool GrPorterDuffXPFactory::willReadDstColor(const GrProcOptInfo& colorPOI, 648 bool GrPorterDuffXPFactory::willReadDstColor(const GrDrawTargetCaps& caps,
649 const GrProcOptInfo& colorPOI,
591 const GrProcOptInfo& coveragePOI) c onst { 650 const GrProcOptInfo& coveragePOI) c onst {
592 return false; 651 // We can always blend correctly if we have dual source blending.
652 if (caps.dualSourceBlendingSupport()) {
653 return false;
654 }
655
656 if (this->canTweakAlphaForCoverage()) {
657 return false;
658 }
659
660 bool srcAIsOne = colorPOI.isOpaque();
661
662 if (kZero_GrBlendCoeff == fDstCoeff) {
663 if (kZero_GrBlendCoeff == fSrcCoeff || srcAIsOne) {
664 return false;
665 }
666 }
667
668 // Reduces to: coeffS * (Cov*S) + D
669 if (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne) {
670 return false;
671 }
672
673 // We can always blend correctly if we have solid coverage.
674 if (coveragePOI.isSolidWhite()) {
675 return false;
676 }
677
678 return true;
593 } 679 }
594 680
595 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); 681 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
596 682
597 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, 683 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
598 GrContext*, 684 GrContext*,
599 const GrDrawTargetCaps&, 685 const GrDrawTargetCaps&,
600 GrTexture*[]) { 686 GrTexture*[]) {
601 GrBlendCoeff src; 687 GrBlendCoeff src;
602 do { 688 do {
603 src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff)); 689 src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
604 } while (GrBlendCoeffRefsSrc(src)); 690 } while (GrBlendCoeffRefsSrc(src));
605 691
606 GrBlendCoeff dst; 692 GrBlendCoeff dst;
607 do { 693 do {
608 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff)); 694 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
609 } while (GrBlendCoeffRefsDst(dst)); 695 } while (GrBlendCoeffRefsDst(dst));
610 696
611 return GrPorterDuffXPFactory::Create(src, dst); 697 return GrPorterDuffXPFactory::Create(src, dst);
612 } 698 }
613 699
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