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

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

Issue 1124373002: Implement Porter Duff XP with a blend table (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 5 years, 7 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 | « no previous file | 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 const char* name() const override { return "Porter Duff"; } 46 const char* name() const override { return "Porter Duff"; }
47 47
48 GrGLXferProcessor* createGLInstance() const override; 48 GrGLXferProcessor* createGLInstance() const override;
49 49
50 bool hasSecondaryOutput() const override; 50 bool hasSecondaryOutput() const override;
51 51
52 /////////////////////////////////////////////////////////////////////////// 52 ///////////////////////////////////////////////////////////////////////////
53 /// @name Stage Output Types 53 /// @name Stage Output Types
54 //// 54 ////
55 55
56 enum PrimaryOutputType { 56 enum OutputType {
57 kNone_PrimaryOutputType, 57 kNone_OutputType,
58 kColor_PrimaryOutputType, 58 kColor_OutputType,
59 kCoverage_PrimaryOutputType, 59 kCoverage_OutputType,
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_OutputType,
62 // Write coverage * (1 - colorA) as the color output.
63 kCoverageISA_OutputType,
64 // Write coverage * (1 - colorRGBA) as the color output.
65 kCoverageISC_OutputType,
62 // Custom Porter-Duff output, used for when we explictly are reading the dst and blending 66 // 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 67 // in the shader. This is only vaid for the primary output, and secondar y output is ignored
64 // equation: cov * (coeffS * S + coeffD * D) + (1 - cov) * D 68 // if you use this. Uses the equation: cov * (coeffS * S + coeffD * D) + (1 - cov) * D
65 kCustom_PrimaryOutputType 69 kCustom_OutputType
66 }; 70 };
67 71
68 enum SecondaryOutputType { 72 OutputType primaryOutputType() const { return fPrimaryOutputType; }
69 // There is no secondary output 73 OutputType secondaryOutputType() const { return fSecondaryOutputType; }
70 kNone_SecondaryOutputType,
71 // Writes coverage as the secondary output. Only set if dual source blen ding is supported
72 // and primary output is kModulate.
73 kCoverage_SecondaryOutputType,
74 // Writes coverage * (1 - colorA) as the secondary output. Only set if d ual source blending
75 // is supported and primary output is kModulate.
76 kCoverageISA_SecondaryOutputType,
77 // Writes coverage * (1 - colorRGBA) as the secondary output. Only set i f dual source
78 // blending is supported and primary output is kModulate.
79 kCoverageISC_SecondaryOutputType,
80 74
81 kSecondaryOutputTypeCnt, 75 GrBlendEquation getBlendEquation() const { return fBlendEquation; }
82 };
83
84 PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; }
85 SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputTyp e; }
86
87 GrBlendCoeff getSrcBlend() const { return fSrcBlend; } 76 GrBlendCoeff getSrcBlend() const { return fSrcBlend; }
88 GrBlendCoeff getDstBlend() const { return fDstBlend; } 77 GrBlendCoeff getDstBlend() const { return fDstBlend; }
89 78
90 private: 79 private:
91 PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColo r constant, 80 PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColo r constant,
92 const GrDeviceCoordTexture* dstCopy, bool willReadDs tColor); 81 const GrDeviceCoordTexture* dstCopy, bool willReadDs tColor);
93 82
94 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, 83 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
95 const GrProcOptInfo& coveragePO I, 84 const GrProcOptInfo& coveragePO I,
96 bool doesStencilWrite, 85 bool doesStencilWrite,
97 GrColor* overrideColor, 86 GrColor* overrideColor,
98 const GrDrawTargetCaps& caps) o verride; 87 const GrDrawTargetCaps& caps) o verride;
99 88
100 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override; 89 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override;
101 90
102 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { 91 void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override {
103 if (!this->willReadDstColor()) { 92 if (!this->willReadDstColor()) {
93 blendInfo->fEquation = fBlendEquation;
104 blendInfo->fSrcBlend = fSrcBlend; 94 blendInfo->fSrcBlend = fSrcBlend;
105 blendInfo->fDstBlend = fDstBlend; 95 blendInfo->fDstBlend = fDstBlend;
106 } else {
107 blendInfo->fSrcBlend = kOne_GrBlendCoeff;
108 blendInfo->fDstBlend = kZero_GrBlendCoeff;
109 } 96 }
110 blendInfo->fBlendConstant = fBlendConstant; 97 blendInfo->fBlendConstant = fBlendConstant;
111 } 98 }
112 99
113 bool onIsEqual(const GrXferProcessor& xpBase) const override { 100 bool onIsEqual(const GrXferProcessor& xpBase) const override {
114 const PorterDuffXferProcessor& xp = xpBase.cast<PorterDuffXferProcessor> (); 101 const PorterDuffXferProcessor& xp = xpBase.cast<PorterDuffXferProcessor> ();
115 if (fSrcBlend != xp.fSrcBlend || 102 if (fBlendEquation != xp.fBlendEquation ||
103 fSrcBlend != xp.fSrcBlend ||
116 fDstBlend != xp.fDstBlend || 104 fDstBlend != xp.fDstBlend ||
117 fBlendConstant != xp.fBlendConstant || 105 fBlendConstant != xp.fBlendConstant ||
118 fPrimaryOutputType != xp.fPrimaryOutputType || 106 fPrimaryOutputType != xp.fPrimaryOutputType ||
119 fSecondaryOutputType != xp.fSecondaryOutputType) { 107 fSecondaryOutputType != xp.fSecondaryOutputType) {
120 return false; 108 return false;
121 } 109 }
122 return true; 110 return true;
123 } 111 }
124 112
125 GrXferProcessor::OptFlags internalGetOptimizations(const GrProcOptInfo& colo rPOI, 113 GrXferProcessor::OptFlags internalGetOptimizations(const GrProcOptInfo& colo rPOI,
126 const GrProcOptInfo& cove ragePOI, 114 const GrProcOptInfo& cove ragePOI,
127 bool doesStencilWrite); 115 bool doesStencilWrite);
128 116
129 void calcOutputTypes(GrXferProcessor::OptFlags blendOpts, const GrDrawTarget Caps& caps, 117 void calcOutputTypes(GrXferProcessor::OptFlags blendOpts, const GrDrawTarget Caps& caps,
130 bool hasSolidCoverage); 118 bool hasSolidCoverage);
131 119
132 GrBlendCoeff fSrcBlend; 120 GrBlendEquation fBlendEquation;
133 GrBlendCoeff fDstBlend; 121 GrBlendCoeff fSrcBlend;
134 GrColor fBlendConstant; 122 GrBlendCoeff fDstBlend;
135 PrimaryOutputType fPrimaryOutputType; 123 GrColor fBlendConstant;
136 SecondaryOutputType fSecondaryOutputType; 124 OutputType fPrimaryOutputType;
125 OutputType fSecondaryOutputType;
137 126
138 typedef GrXferProcessor INHERITED; 127 typedef GrXferProcessor INHERITED;
139 }; 128 };
140 129
141 /////////////////////////////////////////////////////////////////////////////// 130 ///////////////////////////////////////////////////////////////////////////////
142 131
132 static void append_color_output(GrGLXPFragmentBuilder* fsBuilder,
133 PorterDuffXferProcessor::OutputType outputType,
134 const char* outputName, const char* inputColor,
135 const char* inputCoverage) {
136 switch (outputType) {
137 case PorterDuffXferProcessor::kNone_OutputType:
138 fsBuilder->codeAppendf("%s = vec4(0);", outputName);
139 break;
140 case PorterDuffXferProcessor::kColor_OutputType:
141 fsBuilder->codeAppendf("%s = %s;", outputName, inputColor);
142 break;
143 case PorterDuffXferProcessor::kCoverage_OutputType:
144 fsBuilder->codeAppendf("%s = %s;", outputName, inputCoverage);
145 break;
146 case PorterDuffXferProcessor::kModulate_OutputType:
147 fsBuilder->codeAppendf("%s = %s * %s;", outputName, inputColor, inpu tCoverage);
148 break;
149 case PorterDuffXferProcessor::kCoverageISA_OutputType:
150 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
151 outputName, inputColor, inputCoverage);
152 break;
153 case PorterDuffXferProcessor::kCoverageISC_OutputType:
154 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;",
155 outputName, inputColor, inputCoverage);
156 break;
157 default:
158 SkFAIL("Unexpected Output");
159 }
160 }
161
143 bool append_porterduff_term(GrGLXPFragmentBuilder* fsBuilder, GrBlendCoeff coeff , 162 bool append_porterduff_term(GrGLXPFragmentBuilder* fsBuilder, GrBlendCoeff coeff ,
144 const char* colorName, const char* srcColorName, 163 const char* colorName, const char* srcColorName,
145 const char* dstColorName, bool hasPrevious) { 164 const char* dstColorName, bool hasPrevious) {
146 if (kZero_GrBlendCoeff == coeff) { 165 if (kZero_GrBlendCoeff == coeff) {
147 return hasPrevious; 166 return hasPrevious;
148 } else { 167 } else {
149 if (hasPrevious) { 168 if (hasPrevious) {
150 fsBuilder->codeAppend(" + "); 169 fsBuilder->codeAppend(" + ");
151 } 170 }
152 fsBuilder->codeAppendf("%s", colorName); 171 fsBuilder->codeAppendf("%s", colorName);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 if (xp.willReadDstColor()) { 217 if (xp.willReadDstColor()) {
199 b->add32(xp.getSrcBlend()); 218 b->add32(xp.getSrcBlend());
200 b->add32(xp.getDstBlend()); 219 b->add32(xp.getDstBlend());
201 } 220 }
202 }; 221 };
203 222
204 private: 223 private:
205 void onEmitCode(const EmitArgs& args) override { 224 void onEmitCode(const EmitArgs& args) override {
206 const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcesso r>(); 225 const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcesso r>();
207 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 226 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
208 if (PorterDuffXferProcessor::kCustom_PrimaryOutputType != xp.primaryOutp utType()) { 227 if (PorterDuffXferProcessor::kCustom_OutputType != xp.primaryOutputType( )) {
209 SkASSERT(!xp.willReadDstColor()); 228 SkASSERT(!xp.willReadDstColor());
210 switch(xp.secondaryOutputType()) { 229 if (PorterDuffXferProcessor::kNone_OutputType != xp.secondaryOutputT ype()) {
211 case PorterDuffXferProcessor::kNone_SecondaryOutputType: 230 append_color_output(fsBuilder, xp.secondaryOutputType(), args.fO utputSecondary,
212 break; 231 args.fInputColor, args.fInputCoverage);
213 case PorterDuffXferProcessor::kCoverage_SecondaryOutputType:
214 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary,
215 args.fInputCoverage);
216 break;
217 case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType:
218 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
219 args.fOutputSecondary, args.fInputCol or,
220 args.fInputCoverage);
221 break;
222 case PorterDuffXferProcessor::kCoverageISC_SecondaryOutputType:
223 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;",
224 args.fOutputSecondary, args.fInputCol or,
225 args.fInputCoverage);
226 break;
227 default:
228 SkFAIL("Unexpected Secondary Output");
229 } 232 }
230 233 append_color_output(fsBuilder, xp.primaryOutputType(), args.fOutputP rimary,
231 switch (xp.primaryOutputType()) { 234 args.fInputColor, args.fInputCoverage);
232 case PorterDuffXferProcessor::kNone_PrimaryOutputType:
233 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary) ;
234 break;
235 case PorterDuffXferProcessor::kColor_PrimaryOutputType:
236 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args .fInputColor);
237 break;
238 case PorterDuffXferProcessor::kCoverage_PrimaryOutputType:
239 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args .fInputCoverage);
240 break;
241 case PorterDuffXferProcessor::kModulate_PrimaryOutputType:
242 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
243 args.fInputCoverage);
244 break;
245 default:
246 SkFAIL("Unexpected Primary Output");
247 }
248 } else { 235 } else {
249 SkASSERT(xp.willReadDstColor()); 236 SkASSERT(xp.willReadDstColor());
250 237
251 const char* dstColor = fsBuilder->dstColor(); 238 const char* dstColor = fsBuilder->dstColor();
252 239
253 fsBuilder->codeAppend("vec4 colorBlend ="); 240 fsBuilder->codeAppend("vec4 colorBlend =");
254 // append src blend 241 // append src blend
255 bool didAppend = append_porterduff_term(fsBuilder, xp.getSrcBlend(), 242 bool didAppend = append_porterduff_term(fsBuilder, xp.getSrcBlend(),
256 args.fInputColor, args.fInpu tColor, 243 args.fInputColor, args.fInpu tColor,
257 dstColor, false); 244 dstColor, false);
(...skipping 15 matching lines...) Expand all
273 }; 260 };
274 261
275 /////////////////////////////////////////////////////////////////////////////// 262 ///////////////////////////////////////////////////////////////////////////////
276 263
277 PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend, 264 PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend,
278 GrBlendCoeff dstBlend, 265 GrBlendCoeff dstBlend,
279 GrColor constant, 266 GrColor constant,
280 const GrDeviceCoordTexture* dst Copy, 267 const GrDeviceCoordTexture* dst Copy,
281 bool willReadDstColor) 268 bool willReadDstColor)
282 : INHERITED(dstCopy, willReadDstColor) 269 : INHERITED(dstCopy, willReadDstColor)
270 , fBlendEquation(kAdd_GrBlendEquation)
283 , fSrcBlend(srcBlend) 271 , fSrcBlend(srcBlend)
284 , fDstBlend(dstBlend) 272 , fDstBlend(dstBlend)
285 , fBlendConstant(constant) 273 , fBlendConstant(constant)
286 , fPrimaryOutputType(kModulate_PrimaryOutputType) 274 , fPrimaryOutputType(kModulate_OutputType)
287 , fSecondaryOutputType(kNone_SecondaryOutputType) { 275 , fSecondaryOutputType(kNone_OutputType) {
288 this->initClassID<PorterDuffXferProcessor>(); 276 this->initClassID<PorterDuffXferProcessor>();
289 } 277 }
290 278
291 PorterDuffXferProcessor::~PorterDuffXferProcessor() { 279 PorterDuffXferProcessor::~PorterDuffXferProcessor() {
292 } 280 }
293 281
294 void PorterDuffXferProcessor::onGetGLProcessorKey(const GrGLSLCaps& caps, 282 void PorterDuffXferProcessor::onGetGLProcessorKey(const GrGLSLCaps& caps,
295 GrProcessorKeyBuilder* b) cons t { 283 GrProcessorKeyBuilder* b) cons t {
296 GLPorterDuffXferProcessor::GenKey(*this, caps, b); 284 GLPorterDuffXferProcessor::GenKey(*this, caps, b);
297 } 285 }
(...skipping 12 matching lines...) Expand all
310 coverage POI, 298 coverage POI,
311 doesSten cilWrite); 299 doesSten cilWrite);
312 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite()); 300 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite());
313 return optFlags; 301 return optFlags;
314 } 302 }
315 303
316 void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags , 304 void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags ,
317 const GrDrawTargetCaps& caps, 305 const GrDrawTargetCaps& caps,
318 bool hasSolidCoverage) { 306 bool hasSolidCoverage) {
319 if (this->willReadDstColor()) { 307 if (this->willReadDstColor()) {
320 fPrimaryOutputType = kCustom_PrimaryOutputType; 308 fPrimaryOutputType = kCustom_OutputType;
321 return; 309 return;
322 } 310 }
323 311
324 if (optFlags & kIgnoreColor_OptFlag) { 312 if (optFlags & kIgnoreColor_OptFlag) {
325 if (optFlags & kIgnoreCoverage_OptFlag) { 313 if (optFlags & kIgnoreCoverage_OptFlag) {
326 fPrimaryOutputType = kNone_PrimaryOutputType; 314 fPrimaryOutputType = kNone_OutputType;
327 return; 315 return;
328 } else { 316 } else {
329 fPrimaryOutputType = kCoverage_PrimaryOutputType; 317 fPrimaryOutputType = kCoverage_OutputType;
330 return; 318 return;
331 } 319 }
332 } else if (optFlags & kIgnoreCoverage_OptFlag) { 320 } else if (optFlags & kIgnoreCoverage_OptFlag) {
333 fPrimaryOutputType = kColor_PrimaryOutputType; 321 fPrimaryOutputType = kColor_OutputType;
334 return; 322 return;
335 } 323 }
336 324
337 // If we do have coverage determine whether it matters. Dual source blendin g is expensive so 325 // If we do have coverage determine whether it matters. Coverage drawing mod e "just works",
338 // we don't do it if we are doing coverage drawing. If we aren't then We al ways do dual source 326 // without the need for special handling. (We get coverage when there are an y effective coverage
339 // blending if we have any effective coverage stages OR the geometry process or doesn't emits 327 // stages OR the geometry processor doesn't emit solid coverage.)
340 // solid coverage.
341 if (!(optFlags & kSetCoverageDrawing_OptFlag) && !hasSolidCoverage) { 328 if (!(optFlags & kSetCoverageDrawing_OptFlag) && !hasSolidCoverage) {
329 // Try to handle coverage using an alternate blend equation. Dual source blending is
330 // expensive and not supported on all platforms.
331 if (kZero_GrBlendCoeff == fSrcBlend) {
egdaniel 2015/05/15 14:58:03 I wonder if it is time to merge getInternalOptimiz
332 if (kSA_GrBlendCoeff == fDstBlend) {
333 // The formula with f=coverage is: f * D * Sa + (1-f) * D
334 // This can be rewritten as: D - [f * (1-Sa)] * D
335 fBlendEquation = kReverseSubtract_GrBlendEquation;
336 fDstBlend = kOne_GrBlendCoeff;
337 fSrcBlend = kDC_GrBlendCoeff;
338 fPrimaryOutputType = kCoverageISA_OutputType;
339 return;
340 } else if (kSC_GrBlendCoeff == fDstBlend) {
341 // The formula with f=coverage is: f * D * S + (1-f) * D
342 // This can be rewritten as: D - [f * (1-S)] * D
343 fBlendEquation = kReverseSubtract_GrBlendEquation;
344 fDstBlend = kOne_GrBlendCoeff;
345 fSrcBlend = kDC_GrBlendCoeff;
346 fPrimaryOutputType = kCoverageISC_OutputType;
347 return;
348 }
349 }
342 if (caps.shaderCaps()->dualSourceBlendingSupport()) { 350 if (caps.shaderCaps()->dualSourceBlendingSupport()) {
343 if (kZero_GrBlendCoeff == fDstBlend) { 351 if (kZero_GrBlendCoeff == fDstBlend) {
344 // write the coverage value to second color 352 // write the coverage value to second color
345 fSecondaryOutputType = kCoverage_SecondaryOutputType; 353 fSecondaryOutputType = kCoverage_OutputType;
346 fDstBlend = kIS2C_GrBlendCoeff; 354 fDstBlend = kIS2C_GrBlendCoeff;
355 return;
347 } else if (kSA_GrBlendCoeff == fDstBlend) { 356 } else if (kSA_GrBlendCoeff == fDstBlend) {
348 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. 357 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
349 fSecondaryOutputType = kCoverageISA_SecondaryOutputType; 358 fSecondaryOutputType = kCoverageISA_OutputType;
350 fDstBlend = kIS2C_GrBlendCoeff; 359 fDstBlend = kIS2C_GrBlendCoeff;
351 } else if (kSC_GrBlendCoeff == fDstBlend) { 360 return;
352 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
353 fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
354 fDstBlend = kIS2C_GrBlendCoeff;
355 } 361 }
356 } 362 }
357 } 363 }
358 } 364 }
359 365
360 GrXferProcessor::OptFlags 366 GrXferProcessor::OptFlags
361 PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI, 367 PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI,
362 const GrProcOptInfo& coverageP OI, 368 const GrProcOptInfo& coverageP OI,
363 bool doesStencilWrite) { 369 bool doesStencilWrite) {
364 if (this->willReadDstColor()) { 370 if (this->willReadDstColor()) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 return GrXferProcessor::kSetCoverageDrawing_OptFlag; 458 return GrXferProcessor::kSetCoverageDrawing_OptFlag;
453 459
454 } 460 }
455 return GrXferProcessor::kSetCoverageDrawing_OptFlag; 461 return GrXferProcessor::kSetCoverageDrawing_OptFlag;
456 } 462 }
457 463
458 return GrXferProcessor::kNone_Opt; 464 return GrXferProcessor::kNone_Opt;
459 } 465 }
460 466
461 bool PorterDuffXferProcessor::hasSecondaryOutput() const { 467 bool PorterDuffXferProcessor::hasSecondaryOutput() const {
462 return kNone_SecondaryOutputType != fSecondaryOutputType; 468 return kNone_OutputType != fSecondaryOutputType;
463 } 469 }
464 470
465 /////////////////////////////////////////////////////////////////////////////// 471 ///////////////////////////////////////////////////////////////////////////////
466 472
467 class PDLCDXferProcessor : public GrXferProcessor { 473 class PDLCDXferProcessor : public GrXferProcessor {
468 public: 474 public:
469 static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, 475 static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend,
470 const GrProcOptInfo& colorPOI); 476 const GrProcOptInfo& colorPOI);
471 477
472 ~PDLCDXferProcessor() override; 478 ~PDLCDXferProcessor() override;
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 if (caps.shaderCaps()->dualSourceBlendingSupport()) { 776 if (caps.shaderCaps()->dualSourceBlendingSupport()) {
771 return false; 777 return false;
772 } 778 }
773 779
774 if (can_tweak_alpha_for_coverage(fDstCoeff)) { 780 if (can_tweak_alpha_for_coverage(fDstCoeff)) {
775 return false; 781 return false;
776 } 782 }
777 783
778 bool srcAIsOne = colorPOI.isOpaque(); 784 bool srcAIsOne = colorPOI.isOpaque();
779 785
780 if (kZero_GrBlendCoeff == fDstCoeff) { 786 switch (fDstCoeff) {
781 if (kZero_GrBlendCoeff == fSrcCoeff || srcAIsOne) { 787 case kZero_GrBlendCoeff:
782 return false; 788 if (kZero_GrBlendCoeff == fSrcCoeff || srcAIsOne) {
783 } 789 return false;
784 } 790 }
785 791 break;
786 // Reduces to: coeffS * (Cov*S) + D 792 case kSA_GrBlendCoeff:
787 if (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne) { 793 // Reduces to: coeffS * (Cov*S) + D
788 return false; 794 if (srcAIsOne) {
795 return false;
796 }
797 // fallthrough
798 case kSC_GrBlendCoeff:
799 // Can be implemented with kReverseSubtract_GrBlendEquation.
800 if (kZero_GrBlendCoeff == fSrcCoeff) {
801 return false;
802 }
803 break;
804 default: break;
789 } 805 }
790 806
791 // We can always blend correctly if we have solid coverage. 807 // We can always blend correctly if we have solid coverage.
792 if (coveragePOI.isSolidWhite()) { 808 if (coveragePOI.isSolidWhite()) {
793 return false; 809 return false;
794 } 810 }
795 811
796 return true; 812 return true;
797 } 813 }
798 814
799 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); 815 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
800 816
801 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random, 817 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
802 GrContext*, 818 GrContext*,
803 const GrDrawTargetCaps&, 819 const GrDrawTargetCaps&,
804 GrTexture*[]) { 820 GrTexture*[]) {
805 SkXfermode::Mode mode = SkXfermode::Mode(random->nextULessThan(SkXfermode::k LastCoeffMode)); 821 SkXfermode::Mode mode = SkXfermode::Mode(random->nextULessThan(SkXfermode::k LastCoeffMode));
806 return GrPorterDuffXPFactory::Create(mode); 822 return GrPorterDuffXPFactory::Create(mode);
807 } 823 }
808 824
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698