OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |