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

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

Issue 923153003: Revert of 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
66 }; 62 };
67 63
68 enum SecondaryOutputType { 64 enum SecondaryOutputType {
69 // There is no secondary output 65 // There is no secondary output
70 kNone_SecondaryOutputType, 66 kNone_SecondaryOutputType,
71 // Writes coverage as the secondary output. Only set if dual source blen ding is supported 67 // Writes coverage as the secondary output. Only set if dual source blen ding is supported
72 // and primary output is kModulate. 68 // and primary output is kModulate.
73 kCoverage_SecondaryOutputType, 69 kCoverage_SecondaryOutputType,
74 // Writes coverage * (1 - colorA) as the secondary output. Only set if d ual source blending 70 // Writes coverage * (1 - colorA) as the secondary output. Only set if d ual source blending
75 // is supported and primary output is kModulate. 71 // is supported and primary output is kModulate.
76 kCoverageISA_SecondaryOutputType, 72 kCoverageISA_SecondaryOutputType,
77 // Writes coverage * (1 - colorRGBA) as the secondary output. Only set i f dual source 73 // Writes coverage * (1 - colorRGBA) as the secondary output. Only set i f dual source
78 // blending is supported and primary output is kModulate. 74 // blending is supported and primary output is kModulate.
79 kCoverageISC_SecondaryOutputType, 75 kCoverageISC_SecondaryOutputType,
80 76
81 kSecondaryOutputTypeCnt, 77 kSecondaryOutputTypeCnt,
82 }; 78 };
83 79
84 PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; } 80 PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; }
85 SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputTyp e; } 81 SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputTyp e; }
86 82
87 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, 83 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
88 const GrProcOptInfo& coveragePOI, 84 const GrProcOptInfo& coveragePOI,
89 bool doesStencilWrite, 85 bool doesStencilWrite,
90 GrColor* overrideColor, 86 GrColor* overrideColor,
91 const GrDrawTargetCaps& caps) SK_ OVERRIDE; 87 const GrDrawTargetCaps& caps) SK_ OVERRIDE;
92 88
93 void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE { 89 void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE {
94 if (!this->willReadDstColor()) { 90 blendInfo->fSrcBlend = fSrcBlend;
95 blendInfo->fSrcBlend = fSrcBlend; 91 blendInfo->fDstBlend = fDstBlend;
96 blendInfo->fDstBlend = fDstBlend;
97 } else {
98 blendInfo->fSrcBlend = kOne_GrBlendCoeff;
99 blendInfo->fDstBlend = kZero_GrBlendCoeff;
100 }
101 blendInfo->fBlendConstant = fBlendConstant; 92 blendInfo->fBlendConstant = fBlendConstant;
102 } 93 }
103 94
104 GrBlendCoeff getSrcBlend() const { return fSrcBlend; }
105 GrBlendCoeff getDstBlend() const { return fDstBlend; }
106
107 private: 95 private:
108 PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColo r constant, 96 PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColo r constant,
109 const GrDeviceCoordTexture* dstCopy, bool willReadDs tColor); 97 const GrDeviceCoordTexture* dstCopy, bool willReadDs tColor);
110 98
111 void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) con st SK_OVERRIDE; 99 void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) con st SK_OVERRIDE;
112 100
113 bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { 101 bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
114 const PorterDuffXferProcessor& xp = xpBase.cast<PorterDuffXferProcessor> (); 102 const PorterDuffXferProcessor& xp = xpBase.cast<PorterDuffXferProcessor> ();
115 if (fSrcBlend != xp.fSrcBlend || 103 if (fSrcBlend != xp.fSrcBlend ||
116 fDstBlend != xp.fDstBlend || 104 fDstBlend != xp.fDstBlend ||
(...skipping 16 matching lines...) Expand all
133 GrBlendCoeff fDstBlend; 121 GrBlendCoeff fDstBlend;
134 GrColor fBlendConstant; 122 GrColor fBlendConstant;
135 PrimaryOutputType fPrimaryOutputType; 123 PrimaryOutputType fPrimaryOutputType;
136 SecondaryOutputType fSecondaryOutputType; 124 SecondaryOutputType fSecondaryOutputType;
137 125
138 typedef GrXferProcessor INHERITED; 126 typedef GrXferProcessor INHERITED;
139 }; 127 };
140 128
141 /////////////////////////////////////////////////////////////////////////////// 129 ///////////////////////////////////////////////////////////////////////////////
142 130
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
187 class GLPorterDuffXferProcessor : public GrGLXferProcessor { 131 class GLPorterDuffXferProcessor : public GrGLXferProcessor {
188 public: 132 public:
189 GLPorterDuffXferProcessor(const GrProcessor&) {} 133 GLPorterDuffXferProcessor(const GrProcessor&) {}
190 134
191 virtual ~GLPorterDuffXferProcessor() {} 135 virtual ~GLPorterDuffXferProcessor() {}
192 136
193 static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, 137 static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
194 GrProcessorKeyBuilder* b) { 138 GrProcessorKeyBuilder* b) {
195 const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcess or>(); 139 const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcess or>();
196 b->add32(xp.primaryOutputType()); 140 b->add32(xp.primaryOutputType());
197 b->add32(xp.secondaryOutputType()); 141 b->add32(xp.secondaryOutputType());
198 if (xp.willReadDstColor()) {
199 b->add32(xp.getSrcBlend());
200 b->add32(xp.getDstBlend());
201 }
202 }; 142 };
203 143
204 private: 144 private:
205 void onEmitCode(const EmitArgs& args) SK_OVERRIDE { 145 void onEmitCode(const EmitArgs& args) SK_OVERRIDE {
206 const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcesso r>(); 146 const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcesso r>();
207 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 147 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
208 if (PorterDuffXferProcessor::kCustom_PrimaryOutputType != xp.primaryOutp utType()) { 148 if (xp.hasSecondaryOutput()) {
209 SkASSERT(!xp.willReadDstColor());
210 switch(xp.secondaryOutputType()) { 149 switch(xp.secondaryOutputType()) {
211 case PorterDuffXferProcessor::kNone_SecondaryOutputType:
212 break;
213 case PorterDuffXferProcessor::kCoverage_SecondaryOutputType: 150 case PorterDuffXferProcessor::kCoverage_SecondaryOutputType:
214 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, 151 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, ar gs.fInputCoverage);
215 args.fInputCoverage);
216 break; 152 break;
217 case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType: 153 case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType:
218 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", 154 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
219 args.fOutputSecondary, args.fInputCol or, 155 args.fOutputSecondary, args.fInputCol or,
220 args.fInputCoverage); 156 args.fInputCoverage);
221 break; 157 break;
222 case PorterDuffXferProcessor::kCoverageISC_SecondaryOutputType: 158 case PorterDuffXferProcessor::kCoverageISC_SecondaryOutputType:
223 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", 159 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;",
224 args.fOutputSecondary, args.fInputCol or, 160 args.fOutputSecondary, args.fInputCol or,
225 args.fInputCoverage); 161 args.fInputCoverage);
226 break; 162 break;
227 default: 163 default:
228 SkFAIL("Unexpected Secondary Output"); 164 SkFAIL("Unexpected Secondary Output");
229 } 165 }
230 166 }
231 switch (xp.primaryOutputType()) { 167
232 case PorterDuffXferProcessor::kNone_PrimaryOutputType: 168 switch (xp.primaryOutputType()) {
233 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary) ; 169 case PorterDuffXferProcessor::kNone_PrimaryOutputType:
234 break; 170 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary);
235 case PorterDuffXferProcessor::kColor_PrimaryOutputType: 171 break;
236 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args .fInputColor); 172 case PorterDuffXferProcessor::kColor_PrimaryOutputType:
237 break; 173 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn putColor);
238 case PorterDuffXferProcessor::kCoverage_PrimaryOutputType: 174 break;
239 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args .fInputCoverage); 175 case PorterDuffXferProcessor::kCoverage_PrimaryOutputType:
240 break; 176 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn putCoverage);
241 case PorterDuffXferProcessor::kModulate_PrimaryOutputType: 177 break;
242 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor, 178 case PorterDuffXferProcessor::kModulate_PrimaryOutputType:
243 args.fInputCoverage); 179 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, arg s.fInputColor,
244 break; 180 args.fInputCoverage);
245 default: 181 break;
246 SkFAIL("Unexpected Primary Output"); 182 default:
247 } 183 SkFAIL("Unexpected Primary Output");
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);
267 } 184 }
268 } 185 }
269 186
270 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVE RRIDE {}; 187 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVE RRIDE {};
271 188
272 typedef GrGLXferProcessor INHERITED; 189 typedef GrGLXferProcessor INHERITED;
273 }; 190 };
274 191
275 /////////////////////////////////////////////////////////////////////////////// 192 ///////////////////////////////////////////////////////////////////////////////
276 193
277 PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend, 194 PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend,
278 GrBlendCoeff dstBlend, 195 GrBlendCoeff dstBlend,
279 GrColor constant, 196 GrColor constant,
280 const GrDeviceCoordTexture* dst Copy, 197 const GrDeviceCoordTexture* dst Copy,
281 bool willReadDstColor) 198 bool willReadDstColor)
282 : INHERITED(dstCopy, willReadDstColor) 199 : fSrcBlend(srcBlend)
283 , fSrcBlend(srcBlend)
284 , fDstBlend(dstBlend) 200 , fDstBlend(dstBlend)
285 , fBlendConstant(constant) 201 , fBlendConstant(constant)
286 , fPrimaryOutputType(kModulate_PrimaryOutputType) 202 , fPrimaryOutputType(kModulate_PrimaryOutputType)
287 , fSecondaryOutputType(kNone_SecondaryOutputType) { 203 , fSecondaryOutputType(kNone_SecondaryOutputType) {
288 this->initClassID<PorterDuffXferProcessor>(); 204 this->initClassID<PorterDuffXferProcessor>();
289 } 205 }
290 206
291 PorterDuffXferProcessor::~PorterDuffXferProcessor() { 207 PorterDuffXferProcessor::~PorterDuffXferProcessor() {
292 } 208 }
293 209
(...skipping 27 matching lines...) Expand all
321 coveragePOI, 237 coveragePOI,
322 doesStencilWrite); 238 doesStencilWrite);
323 } 239 }
324 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite()); 240 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite());
325 return optFlags; 241 return optFlags;
326 } 242 }
327 243
328 void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags , 244 void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags ,
329 const GrDrawTargetCaps& caps, 245 const GrDrawTargetCaps& caps,
330 bool hasSolidCoverage) { 246 bool hasSolidCoverage) {
331 if (this->willReadDstColor()) {
332 fPrimaryOutputType = kCustom_PrimaryOutputType;
333 return;
334 }
335
336 if (optFlags & kIgnoreColor_OptFlag) { 247 if (optFlags & kIgnoreColor_OptFlag) {
337 if (optFlags & kIgnoreCoverage_OptFlag) { 248 if (optFlags & kIgnoreCoverage_OptFlag) {
338 fPrimaryOutputType = kNone_PrimaryOutputType; 249 fPrimaryOutputType = kNone_PrimaryOutputType;
339 return; 250 return;
340 } else { 251 } else {
341 fPrimaryOutputType = kCoverage_PrimaryOutputType; 252 fPrimaryOutputType = kCoverage_PrimaryOutputType;
342 return; 253 return;
343 } 254 }
344 } else if (optFlags & kIgnoreCoverage_OptFlag) { 255 } else if (optFlags & kIgnoreCoverage_OptFlag) {
345 fPrimaryOutputType = kColor_PrimaryOutputType; 256 fPrimaryOutputType = kColor_PrimaryOutputType;
(...skipping 20 matching lines...) Expand all
366 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; 277 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
367 } 278 }
368 } 279 }
369 } 280 }
370 } 281 }
371 282
372 GrXferProcessor::OptFlags 283 GrXferProcessor::OptFlags
373 PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI, 284 PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI,
374 const GrProcOptInfo& coverageP OI, 285 const GrProcOptInfo& coverageP OI,
375 bool doesStencilWrite) { 286 bool doesStencilWrite) {
376 if (this->willReadDstColor()) { 287 bool srcAIsOne;
377 return GrXferProcessor::kNone_Opt; 288 bool hasCoverage;
378 }
379 289
380 bool srcAIsOne = colorPOI.isOpaque(); 290 srcAIsOne = colorPOI.isOpaque();
381 bool hasCoverage = !coveragePOI.isSolidWhite(); 291 hasCoverage = !coveragePOI.isSolidWhite();
382 292
383 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend || 293 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend ||
384 (kSA_GrBlendCoeff == fDstBlend && srcAIsOne); 294 (kSA_GrBlendCoeff == fDstBlend && srcAIsOne);
385 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend || 295 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend ||
386 (kISA_GrBlendCoeff == fDstBlend && srcAIsOne); 296 (kISA_GrBlendCoeff == fDstBlend && srcAIsOne);
387 297
388 // When coeffs are (0,1) there is no reason to draw at all, unless 298 // When coeffs are (0,1) there is no reason to draw at all, unless
389 // stenciling is enabled. Having color writes disabled is effectively 299 // stenciling is enabled. Having color writes disabled is effectively
390 // (0,1). 300 // (0,1).
391 if ((kZero_GrBlendCoeff == fSrcBlend && dstCoeffIsOne)) { 301 if ((kZero_GrBlendCoeff == fSrcBlend && dstCoeffIsOne)) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 static GrPorterDuffXPFactory gScreenPDXPF(kOne_GrBlendCoeff, kISC_Gr BlendCoeff); 446 static GrPorterDuffXPFactory gScreenPDXPF(kOne_GrBlendCoeff, kISC_Gr BlendCoeff);
537 return SkRef(&gScreenPDXPF); 447 return SkRef(&gScreenPDXPF);
538 break; 448 break;
539 } 449 }
540 default: 450 default:
541 return NULL; 451 return NULL;
542 } 452 }
543 } 453 }
544 454
545 GrXferProcessor* 455 GrXferProcessor*
546 GrPorterDuffXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, 456 GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
547 const GrProcOptInfo& colorPOI,
548 const GrProcOptInfo& covPOI, 457 const GrProcOptInfo& covPOI,
549 const GrDeviceCoordTexture* dstCopy ) const { 458 const GrDeviceCoordTexture* dstCopy ) const {
550 if (!covPOI.isFourChannelOutput()) { 459 if (!covPOI.isFourChannelOutput()) {
551 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, 460 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy,
552 this->willReadDstColor(caps, colo rPOI, covPOI)); 461 this->willReadDstColor(colorPOI, covPOI));
553 } else { 462 } else {
554 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) { 463 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) {
555 SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); 464 SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags());
556 GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); 465 GrColor blendConstant = GrUnPreMulColor(colorPOI.color());
557 return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_Gr BlendCoeff, 466 return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_Gr BlendCoeff,
558 blendConstant, dstCopy, 467 blendConstant, dstCopy,
559 this->willReadDstColor(caps, colorPOI, covPOI)); 468 this->willReadDstColor(colorP OI, covPOI));
560 } else { 469 } else {
561 return NULL; 470 return NULL;
562 } 471 }
563 } 472 }
564 } 473 }
565 474
566 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, 475 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/,
567 uint32_t knownColorFlags) const { 476 uint32_t knownColorFlags) const {
568 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff && 477 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff &&
569 kRGBA_GrColorComponentFlags == knownColorFlags) { 478 kRGBA_GrColorComponentFlags == knownColorFlags) {
570 return true; 479 return true;
571 } 480 }
572 return false; 481 return false;
573 } 482 }
574 483
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
575 bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const { 517 bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const {
576 return can_tweak_alpha_for_coverage(fDstCoeff); 518 return can_tweak_alpha_for_coverage(fDstCoeff);
577 } 519 }
578 520
579 void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, 521 void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI,
580 const GrProcOptInfo& coveragePOI, 522 const GrProcOptInfo& coveragePOI,
581 GrXPFactory::InvariantOutput* out put) const { 523 GrXPFactory::InvariantOutput* out put) const {
582 if (!coveragePOI.isSolidWhite()) { 524 if (!coveragePOI.isSolidWhite()) {
583 output->fWillBlendWithDst = true; 525 output->fWillBlendWithDst = true;
584 output->fBlendedColorFlags = 0; 526 output->fBlendedColorFlags = 0;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 case kIConstC_GrBlendCoeff: 580 case kIConstC_GrBlendCoeff:
639 case kConstA_GrBlendCoeff: 581 case kConstA_GrBlendCoeff:
640 case kIConstA_GrBlendCoeff: 582 case kIConstA_GrBlendCoeff:
641 output->fBlendedColorFlags = 0; 583 output->fBlendedColorFlags = 0;
642 break; 584 break;
643 } 585 }
644 586
645 output->fWillBlendWithDst = false; 587 output->fWillBlendWithDst = false;
646 } 588 }
647 589
648 bool GrPorterDuffXPFactory::willReadDstColor(const GrDrawTargetCaps& caps, 590 bool GrPorterDuffXPFactory::willReadDstColor(const GrProcOptInfo& colorPOI,
649 const GrProcOptInfo& colorPOI,
650 const GrProcOptInfo& coveragePOI) c onst { 591 const GrProcOptInfo& coveragePOI) c onst {
651 // We can always blend correctly if we have dual source blending. 592 return false;
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;
679 } 593 }
680 594
681 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); 595 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
682 596
683 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, 597 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
684 GrContext*, 598 GrContext*,
685 const GrDrawTargetCaps&, 599 const GrDrawTargetCaps&,
686 GrTexture*[]) { 600 GrTexture*[]) {
687 GrBlendCoeff src; 601 GrBlendCoeff src;
688 do { 602 do {
689 src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff)); 603 src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
690 } while (GrBlendCoeffRefsSrc(src)); 604 } while (GrBlendCoeffRefsSrc(src));
691 605
692 GrBlendCoeff dst; 606 GrBlendCoeff dst;
693 do { 607 do {
694 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff)); 608 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
695 } while (GrBlendCoeffRefsDst(dst)); 609 } while (GrBlendCoeffRefsDst(dst));
696 610
697 return GrPorterDuffXPFactory::Create(src, dst); 611 return GrPorterDuffXPFactory::Create(src, dst);
698 } 612 }
699 613
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