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 14 matching lines...) Expand all Loading... |
25 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou
rce color's alpha | 25 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou
rce color's alpha |
26 we're replacing S with S'=fS. It's obvious that that first term will always
be ok. The second | 26 we're replacing S with S'=fS. It's obvious that that first term will always
be ok. The second |
27 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss
ibilities for Cd we | 27 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss
ibilities for Cd we |
28 find that only 1, ISA, and ISC produce the correct destination when applied
to S' and D. | 28 find that only 1, ISA, and ISC produce the correct destination when applied
to S' and D. |
29 */ | 29 */ |
30 return kOne_GrBlendCoeff == dstCoeff || | 30 return kOne_GrBlendCoeff == dstCoeff || |
31 kISA_GrBlendCoeff == dstCoeff || | 31 kISA_GrBlendCoeff == dstCoeff || |
32 kISC_GrBlendCoeff == dstCoeff; | 32 kISC_GrBlendCoeff == dstCoeff; |
33 } | 33 } |
34 | 34 |
35 class GrGLPorterDuffXferProcessor : public GrGLXferProcessor { | 35 class PorterDuffXferProcessor : public GrXferProcessor { |
36 public: | 36 public: |
37 GrGLPorterDuffXferProcessor(const GrProcessor&) {} | 37 static GrXferProcessor* Create(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, |
| 38 GrColor constant, const GrDeviceCoordTexture*
dstCopy, |
| 39 bool willReadDstColor) { |
| 40 return SkNEW_ARGS(PorterDuffXferProcessor, (srcBlend, dstBlend, constant
, dstCopy, |
| 41 willReadDstColor)); |
| 42 } |
38 | 43 |
39 virtual ~GrGLPorterDuffXferProcessor() {} | 44 ~PorterDuffXferProcessor() SK_OVERRIDE; |
| 45 |
| 46 const char* name() const SK_OVERRIDE { return "Porter Duff"; } |
| 47 |
| 48 GrGLXferProcessor* createGLInstance() const SK_OVERRIDE; |
| 49 |
| 50 bool hasSecondaryOutput() const SK_OVERRIDE; |
| 51 |
| 52 /////////////////////////////////////////////////////////////////////////// |
| 53 /// @name Stage Output Types |
| 54 //// |
| 55 |
| 56 enum PrimaryOutputType { |
| 57 kNone_PrimaryOutputType, |
| 58 kColor_PrimaryOutputType, |
| 59 kCoverage_PrimaryOutputType, |
| 60 // Modulate color and coverage, write result as the color output. |
| 61 kModulate_PrimaryOutputType, |
| 62 }; |
| 63 |
| 64 enum SecondaryOutputType { |
| 65 // There is no secondary output |
| 66 kNone_SecondaryOutputType, |
| 67 // Writes coverage as the secondary output. Only set if dual source blen
ding is supported |
| 68 // and primary output is kModulate. |
| 69 kCoverage_SecondaryOutputType, |
| 70 // Writes coverage * (1 - colorA) as the secondary output. Only set if d
ual source blending |
| 71 // is supported and primary output is kModulate. |
| 72 kCoverageISA_SecondaryOutputType, |
| 73 // Writes coverage * (1 - colorRGBA) as the secondary output. Only set i
f dual source |
| 74 // blending is supported and primary output is kModulate. |
| 75 kCoverageISC_SecondaryOutputType, |
| 76 |
| 77 kSecondaryOutputTypeCnt, |
| 78 }; |
| 79 |
| 80 PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; } |
| 81 SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputTyp
e; } |
| 82 |
| 83 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, |
| 84 const GrProcOptInfo& coveragePOI, |
| 85 bool doesStencilWrite, |
| 86 GrColor* overrideColor, |
| 87 const GrDrawTargetCaps& caps) SK_
OVERRIDE; |
| 88 |
| 89 void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE { |
| 90 blendInfo->fSrcBlend = fSrcBlend; |
| 91 blendInfo->fDstBlend = fDstBlend; |
| 92 blendInfo->fBlendConstant = fBlendConstant; |
| 93 } |
| 94 |
| 95 private: |
| 96 PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColo
r constant, |
| 97 const GrDeviceCoordTexture* dstCopy, bool willReadDs
tColor); |
| 98 |
| 99 void onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) con
st SK_OVERRIDE; |
| 100 |
| 101 bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE { |
| 102 const PorterDuffXferProcessor& xp = xpBase.cast<PorterDuffXferProcessor>
(); |
| 103 if (fSrcBlend != xp.fSrcBlend || |
| 104 fDstBlend != xp.fDstBlend || |
| 105 fBlendConstant != xp.fBlendConstant || |
| 106 fPrimaryOutputType != xp.fPrimaryOutputType || |
| 107 fSecondaryOutputType != xp.fSecondaryOutputType) { |
| 108 return false; |
| 109 } |
| 110 return true; |
| 111 } |
| 112 |
| 113 GrXferProcessor::OptFlags internalGetOptimizations(const GrProcOptInfo& colo
rPOI, |
| 114 const GrProcOptInfo& cove
ragePOI, |
| 115 bool doesStencilWrite); |
| 116 |
| 117 void calcOutputTypes(GrXferProcessor::OptFlags blendOpts, const GrDrawTarget
Caps& caps, |
| 118 bool hasSolidCoverage); |
| 119 |
| 120 GrBlendCoeff fSrcBlend; |
| 121 GrBlendCoeff fDstBlend; |
| 122 GrColor fBlendConstant; |
| 123 PrimaryOutputType fPrimaryOutputType; |
| 124 SecondaryOutputType fSecondaryOutputType; |
| 125 |
| 126 typedef GrXferProcessor INHERITED; |
| 127 }; |
| 128 |
| 129 /////////////////////////////////////////////////////////////////////////////// |
| 130 |
| 131 class GLPorterDuffXferProcessor : public GrGLXferProcessor { |
| 132 public: |
| 133 GLPorterDuffXferProcessor(const GrProcessor&) {} |
| 134 |
| 135 virtual ~GLPorterDuffXferProcessor() {} |
40 | 136 |
41 static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, | 137 static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, |
42 GrProcessorKeyBuilder* b) { | 138 GrProcessorKeyBuilder* b) { |
43 const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferPro
cessor>(); | 139 const PorterDuffXferProcessor& xp = processor.cast<PorterDuffXferProcess
or>(); |
44 b->add32(xp.primaryOutputType()); | 140 b->add32(xp.primaryOutputType()); |
45 b->add32(xp.secondaryOutputType()); | 141 b->add32(xp.secondaryOutputType()); |
46 }; | 142 }; |
47 | 143 |
48 private: | 144 private: |
49 void onEmitCode(const EmitArgs& args) SK_OVERRIDE { | 145 void onEmitCode(const EmitArgs& args) SK_OVERRIDE { |
50 const GrPorterDuffXferProcessor& xp = args.fXP.cast<GrPorterDuffXferProc
essor>(); | 146 const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcesso
r>(); |
51 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 147 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
52 if (xp.hasSecondaryOutput()) { | 148 if (xp.hasSecondaryOutput()) { |
53 switch(xp.secondaryOutputType()) { | 149 switch(xp.secondaryOutputType()) { |
54 case GrPorterDuffXferProcessor::kCoverage_SecondaryOutputType: | 150 case PorterDuffXferProcessor::kCoverage_SecondaryOutputType: |
55 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, ar
gs.fInputCoverage); | 151 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, ar
gs.fInputCoverage); |
56 break; | 152 break; |
57 case GrPorterDuffXferProcessor::kCoverageISA_SecondaryOutputType
: | 153 case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType: |
58 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", | 154 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", |
59 args.fOutputSecondary, args.fInputCol
or, | 155 args.fOutputSecondary, args.fInputCol
or, |
60 args.fInputCoverage); | 156 args.fInputCoverage); |
61 break; | 157 break; |
62 case GrPorterDuffXferProcessor::kCoverageISC_SecondaryOutputType
: | 158 case PorterDuffXferProcessor::kCoverageISC_SecondaryOutputType: |
63 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", | 159 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", |
64 args.fOutputSecondary, args.fInputCol
or, | 160 args.fOutputSecondary, args.fInputCol
or, |
65 args.fInputCoverage); | 161 args.fInputCoverage); |
66 break; | 162 break; |
67 default: | 163 default: |
68 SkFAIL("Unexpected Secondary Output"); | 164 SkFAIL("Unexpected Secondary Output"); |
69 } | 165 } |
70 } | 166 } |
71 | 167 |
72 switch (xp.primaryOutputType()) { | 168 switch (xp.primaryOutputType()) { |
73 case GrPorterDuffXferProcessor::kNone_PrimaryOutputType: | 169 case PorterDuffXferProcessor::kNone_PrimaryOutputType: |
74 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); | 170 fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); |
75 break; | 171 break; |
76 case GrPorterDuffXferProcessor::kColor_PrimaryOutputType: | 172 case PorterDuffXferProcessor::kColor_PrimaryOutputType: |
77 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn
putColor); | 173 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn
putColor); |
78 break; | 174 break; |
79 case GrPorterDuffXferProcessor::kCoverage_PrimaryOutputType: | 175 case PorterDuffXferProcessor::kCoverage_PrimaryOutputType: |
80 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn
putCoverage); | 176 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn
putCoverage); |
81 break; | 177 break; |
82 case GrPorterDuffXferProcessor::kModulate_PrimaryOutputType: | 178 case PorterDuffXferProcessor::kModulate_PrimaryOutputType: |
83 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, arg
s.fInputColor, | 179 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, arg
s.fInputColor, |
84 args.fInputCoverage); | 180 args.fInputCoverage); |
85 break; | 181 break; |
86 default: | 182 default: |
87 SkFAIL("Unexpected Primary Output"); | 183 SkFAIL("Unexpected Primary Output"); |
88 } | 184 } |
89 } | 185 } |
90 | 186 |
91 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVE
RRIDE {}; | 187 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVE
RRIDE {}; |
92 | 188 |
93 typedef GrGLXferProcessor INHERITED; | 189 typedef GrGLXferProcessor INHERITED; |
94 }; | 190 }; |
95 | 191 |
96 /////////////////////////////////////////////////////////////////////////////// | 192 /////////////////////////////////////////////////////////////////////////////// |
97 | 193 |
98 GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, | 194 PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend, |
99 GrBlendCoeff dstBlend, | 195 GrBlendCoeff dstBlend, |
100 GrColor constant, | 196 GrColor constant, |
101 const GrDeviceCoordTexture*
dstCopy, | 197 const GrDeviceCoordTexture* dst
Copy, |
102 bool willReadDstColor) | 198 bool willReadDstColor) |
103 : fSrcBlend(srcBlend) | 199 : fSrcBlend(srcBlend) |
104 , fDstBlend(dstBlend) | 200 , fDstBlend(dstBlend) |
105 , fBlendConstant(constant) | 201 , fBlendConstant(constant) |
106 , fPrimaryOutputType(kModulate_PrimaryOutputType) | 202 , fPrimaryOutputType(kModulate_PrimaryOutputType) |
107 , fSecondaryOutputType(kNone_SecondaryOutputType) { | 203 , fSecondaryOutputType(kNone_SecondaryOutputType) { |
108 this->initClassID<GrPorterDuffXferProcessor>(); | 204 this->initClassID<PorterDuffXferProcessor>(); |
109 } | 205 } |
110 | 206 |
111 GrPorterDuffXferProcessor::~GrPorterDuffXferProcessor() { | 207 PorterDuffXferProcessor::~PorterDuffXferProcessor() { |
112 } | 208 } |
113 | 209 |
114 void GrPorterDuffXferProcessor::onGetGLProcessorKey(const GrGLCaps& caps, | 210 void PorterDuffXferProcessor::onGetGLProcessorKey(const GrGLCaps& caps, |
115 GrProcessorKeyBuilder* b) co
nst { | 211 GrProcessorKeyBuilder* b) cons
t { |
116 GrGLPorterDuffXferProcessor::GenKey(*this, caps, b); | 212 GLPorterDuffXferProcessor::GenKey(*this, caps, b); |
117 } | 213 } |
118 | 214 |
119 GrGLXferProcessor* GrPorterDuffXferProcessor::createGLInstance() const { | 215 GrGLXferProcessor* PorterDuffXferProcessor::createGLInstance() const { |
120 return SkNEW_ARGS(GrGLPorterDuffXferProcessor, (*this)); | 216 return SkNEW_ARGS(GLPorterDuffXferProcessor, (*this)); |
121 } | 217 } |
122 | 218 |
123 GrXferProcessor::OptFlags | 219 GrXferProcessor::OptFlags |
124 GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, | 220 PorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, |
125 const GrProcOptInfo& coveragePOI, | 221 const GrProcOptInfo& coveragePOI, |
126 bool doesStencilWrite, | 222 bool doesStencilWrite, |
127 GrColor* overrideColor, | 223 GrColor* overrideColor, |
128 const GrDrawTargetCaps& caps) { | 224 const GrDrawTargetCaps& caps) { |
129 GrXferProcessor::OptFlags optFlags; | 225 GrXferProcessor::OptFlags optFlags; |
130 // Optimizations when doing RGB Coverage | 226 // Optimizations when doing RGB Coverage |
131 if (coveragePOI.isFourChannelOutput()) { | 227 if (coveragePOI.isFourChannelOutput()) { |
132 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha | 228 // We want to force our primary output to be alpha * Coverage, where alp
ha is the alpha |
133 // value of the blend the constant. We should already have valid blend c
oeff's if we are at | 229 // value of the blend the constant. We should already have valid blend c
oeff's if we are at |
134 // a point where we have RGB coverage. We don't need any color stages si
nce the known color | 230 // a point where we have RGB coverage. We don't need any color stages si
nce the known color |
135 // output is already baked into the blendConstant. | 231 // output is already baked into the blendConstant. |
136 uint8_t alpha = GrColorUnpackA(fBlendConstant); | 232 uint8_t alpha = GrColorUnpackA(fBlendConstant); |
137 *overrideColor = GrColorPackRGBA(alpha, alpha, alpha, alpha); | 233 *overrideColor = GrColorPackRGBA(alpha, alpha, alpha, alpha); |
138 optFlags = GrXferProcessor::kOverrideColor_OptFlag; | 234 optFlags = GrXferProcessor::kOverrideColor_OptFlag; |
139 } else { | 235 } else { |
140 optFlags = this->internalGetOptimizations(colorPOI, | 236 optFlags = this->internalGetOptimizations(colorPOI, |
141 coveragePOI, | 237 coveragePOI, |
142 doesStencilWrite); | 238 doesStencilWrite); |
143 } | 239 } |
144 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite()); | 240 this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite()); |
145 return optFlags; | 241 return optFlags; |
146 } | 242 } |
147 | 243 |
148 void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFla
gs, | 244 void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags
, |
149 const GrDrawTargetCaps& caps, | 245 const GrDrawTargetCaps& caps, |
150 bool hasSolidCoverage) { | 246 bool hasSolidCoverage) { |
151 if (optFlags & kIgnoreColor_OptFlag) { | 247 if (optFlags & kIgnoreColor_OptFlag) { |
152 if (optFlags & kIgnoreCoverage_OptFlag) { | 248 if (optFlags & kIgnoreCoverage_OptFlag) { |
153 fPrimaryOutputType = kNone_PrimaryOutputType; | 249 fPrimaryOutputType = kNone_PrimaryOutputType; |
154 return; | 250 return; |
155 } else { | 251 } else { |
156 fPrimaryOutputType = kCoverage_PrimaryOutputType; | 252 fPrimaryOutputType = kCoverage_PrimaryOutputType; |
157 return; | 253 return; |
158 } | 254 } |
159 } else if (optFlags & kIgnoreCoverage_OptFlag) { | 255 } else if (optFlags & kIgnoreCoverage_OptFlag) { |
160 fPrimaryOutputType = kColor_PrimaryOutputType; | 256 fPrimaryOutputType = kColor_PrimaryOutputType; |
(...skipping 17 matching lines...) Expand all Loading... |
178 } else if (kSC_GrBlendCoeff == fDstBlend) { | 274 } else if (kSC_GrBlendCoeff == fDstBlend) { |
179 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. | 275 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially
covered. |
180 fSecondaryOutputType = kCoverageISC_SecondaryOutputType; | 276 fSecondaryOutputType = kCoverageISC_SecondaryOutputType; |
181 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; | 277 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; |
182 } | 278 } |
183 } | 279 } |
184 } | 280 } |
185 } | 281 } |
186 | 282 |
187 GrXferProcessor::OptFlags | 283 GrXferProcessor::OptFlags |
188 GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
I, | 284 PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI, |
189 const GrProcOptInfo& coverag
ePOI, | 285 const GrProcOptInfo& coverageP
OI, |
190 bool doesStencilWrite) { | 286 bool doesStencilWrite) { |
191 bool srcAIsOne; | 287 bool srcAIsOne; |
192 bool hasCoverage; | 288 bool hasCoverage; |
193 | 289 |
194 srcAIsOne = colorPOI.isOpaque(); | 290 srcAIsOne = colorPOI.isOpaque(); |
195 hasCoverage = !coveragePOI.isSolidWhite(); | 291 hasCoverage = !coveragePOI.isSolidWhite(); |
196 | 292 |
197 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend || | 293 bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend || |
198 (kSA_GrBlendCoeff == fDstBlend && srcAIsOne); | 294 (kSA_GrBlendCoeff == fDstBlend && srcAIsOne); |
199 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend || | 295 bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend || |
200 (kISA_GrBlendCoeff == fDstBlend && srcAIsOne); | 296 (kISA_GrBlendCoeff == fDstBlend && srcAIsOne); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 // the dst coeff is effectively one so blend works out to: | 352 // the dst coeff is effectively one so blend works out to: |
257 // cS + (c)(1)D + (1-c)D = cS + D. | 353 // cS + (c)(1)D + (1-c)D = cS + D. |
258 fDstBlend = kOne_GrBlendCoeff; | 354 fDstBlend = kOne_GrBlendCoeff; |
259 return GrXferProcessor::kSetCoverageDrawing_OptFlag; | 355 return GrXferProcessor::kSetCoverageDrawing_OptFlag; |
260 } | 356 } |
261 } | 357 } |
262 | 358 |
263 return GrXferProcessor::kNone_Opt; | 359 return GrXferProcessor::kNone_Opt; |
264 } | 360 } |
265 | 361 |
266 bool GrPorterDuffXferProcessor::hasSecondaryOutput() const { | 362 bool PorterDuffXferProcessor::hasSecondaryOutput() const { |
267 return kNone_SecondaryOutputType != fSecondaryOutputType; | 363 return kNone_SecondaryOutputType != fSecondaryOutputType; |
268 } | 364 } |
269 | 365 |
270 /////////////////////////////////////////////////////////////////////////////// | 366 /////////////////////////////////////////////////////////////////////////////// |
271 | 367 |
272 GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst) | 368 GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst) |
273 : fSrcCoeff(src), fDstCoeff(dst) { | 369 : fSrcCoeff(src), fDstCoeff(dst) { |
274 this->initClassID<GrPorterDuffXPFactory>(); | 370 this->initClassID<GrPorterDuffXPFactory>(); |
275 } | 371 } |
276 | 372 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 default: | 450 default: |
355 return NULL; | 451 return NULL; |
356 } | 452 } |
357 } | 453 } |
358 | 454 |
359 GrXferProcessor* | 455 GrXferProcessor* |
360 GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, | 456 GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, |
361 const GrProcOptInfo& covPOI, | 457 const GrProcOptInfo& covPOI, |
362 const GrDeviceCoordTexture* dstCopy
) const { | 458 const GrDeviceCoordTexture* dstCopy
) const { |
363 if (!covPOI.isFourChannelOutput()) { | 459 if (!covPOI.isFourChannelOutput()) { |
364 return GrPorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCop
y, | 460 return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, |
365 this->willReadDstColor()); | 461 this->willReadDstColor()); |
366 } else { | 462 } else { |
367 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags()))
{ | 463 if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags()))
{ |
368 SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); | 464 SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); |
369 GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); | 465 GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); |
370 return GrPorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_
GrBlendCoeff, | 466 return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_Gr
BlendCoeff, |
371 blendConstant, dstCopy, | 467 blendConstant, dstCopy, |
372 this->willReadDstColor()); | 468 this->willReadDstColor()); |
373 } else { | 469 } else { |
374 return NULL; | 470 return NULL; |
375 } | 471 } |
376 } | 472 } |
377 } | 473 } |
378 | 474 |
379 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, | 475 bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, |
380 uint32_t knownColorFlags) const
{ | 476 uint32_t knownColorFlags) const
{ |
381 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff && | 477 if (kOne_GrBlendCoeff == fSrcCoeff && kISA_GrBlendCoeff == fDstCoeff && |
382 kRGBA_GrColorComponentFlags == knownColorFlags) { | 478 kRGBA_GrColorComponentFlags == knownColorFlags) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 } while (GrBlendCoeffRefsSrc(src)); | 603 } while (GrBlendCoeffRefsSrc(src)); |
508 | 604 |
509 GrBlendCoeff dst; | 605 GrBlendCoeff dst; |
510 do { | 606 do { |
511 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub
licGrBlendCoeff)); | 607 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub
licGrBlendCoeff)); |
512 } while (GrBlendCoeffRefsDst(dst)); | 608 } while (GrBlendCoeffRefsDst(dst)); |
513 | 609 |
514 return GrPorterDuffXPFactory::Create(src, dst); | 610 return GrPorterDuffXPFactory::Create(src, dst); |
515 } | 611 } |
516 | 612 |
OLD | NEW |