OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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/GrCustomXfermode.h" | 8 #include "effects/GrCustomXfermode.h" |
9 | 9 |
10 #include "GrCoordTransform.h" | 10 #include "GrCoordTransform.h" |
11 #include "GrContext.h" | 11 #include "GrContext.h" |
12 #include "GrFragmentProcessor.h" | 12 #include "GrFragmentProcessor.h" |
13 #include "GrInvariantOutput.h" | 13 #include "GrInvariantOutput.h" |
| 14 #include "GrPipeline.h" |
14 #include "GrProcessor.h" | 15 #include "GrProcessor.h" |
15 #include "GrTexture.h" | 16 #include "GrTexture.h" |
16 #include "GrTextureAccess.h" | 17 #include "GrTextureAccess.h" |
17 #include "SkXfermode.h" | 18 #include "SkXfermode.h" |
18 #include "glsl/GrGLSLBlend.h" | 19 #include "glsl/GrGLSLBlend.h" |
19 #include "glsl/GrGLSLCaps.h" | 20 #include "glsl/GrGLSLCaps.h" |
20 #include "glsl/GrGLSLFragmentProcessor.h" | 21 #include "glsl/GrGLSLFragmentProcessor.h" |
21 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 22 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
22 #include "glsl/GrGLSLProgramBuilder.h" | 23 #include "glsl/GrGLSLProgramBuilder.h" |
23 #include "glsl/GrGLSLProgramDataManager.h" | 24 #include "glsl/GrGLSLProgramDataManager.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 | 93 |
93 SkXfermode::Mode mode() const { return fMode; } | 94 SkXfermode::Mode mode() const { return fMode; } |
94 bool hasHWBlendEquation() const { return -1 != static_cast<int>(fHWBlendEqua
tion); } | 95 bool hasHWBlendEquation() const { return -1 != static_cast<int>(fHWBlendEqua
tion); } |
95 | 96 |
96 GrBlendEquation hwBlendEquation() const { | 97 GrBlendEquation hwBlendEquation() const { |
97 SkASSERT(this->hasHWBlendEquation()); | 98 SkASSERT(this->hasHWBlendEquation()); |
98 return fHWBlendEquation; | 99 return fHWBlendEquation; |
99 } | 100 } |
100 | 101 |
101 private: | 102 private: |
102 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, | 103 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&
optimizations, |
103 const GrProcOptInfo& coveragePO
I, | |
104 bool doesStencilWrite, | 104 bool doesStencilWrite, |
105 GrColor* overrideColor, | 105 GrColor* overrideColor, |
106 const GrCaps& caps) override; | 106 const GrCaps& caps) override; |
107 | 107 |
108 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; | 108 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; |
109 | 109 |
110 GrXferBarrierType onXferBarrier(const GrRenderTarget*, const GrCaps&) const
override; | 110 GrXferBarrierType onXferBarrier(const GrRenderTarget*, const GrCaps&) const
override; |
111 | 111 |
112 void onGetBlendInfo(BlendInfo*) const override; | 112 void onGetBlendInfo(BlendInfo*) const override; |
113 | 113 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 GrGLSLXferProcessor* CustomXP::createGLSLInstance() const { | 185 GrGLSLXferProcessor* CustomXP::createGLSLInstance() const { |
186 SkASSERT(this->willReadDstColor() != this->hasHWBlendEquation()); | 186 SkASSERT(this->willReadDstColor() != this->hasHWBlendEquation()); |
187 return new GLCustomXP(*this); | 187 return new GLCustomXP(*this); |
188 } | 188 } |
189 | 189 |
190 bool CustomXP::onIsEqual(const GrXferProcessor& other) const { | 190 bool CustomXP::onIsEqual(const GrXferProcessor& other) const { |
191 const CustomXP& s = other.cast<CustomXP>(); | 191 const CustomXP& s = other.cast<CustomXP>(); |
192 return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation; | 192 return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation; |
193 } | 193 } |
194 | 194 |
195 GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrProcOptInfo& colo
rPOI, | 195 GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrPipelineOptimizat
ions& optimizations, |
196 const GrProcOptInfo& cove
ragePOI, | |
197 bool doesStencilWrite, | 196 bool doesStencilWrite, |
198 GrColor* overrideColor, | 197 GrColor* overrideColor, |
199 const GrCaps& caps) { | 198 const GrCaps& caps) { |
200 /* | 199 /* |
201 Most the optimizations we do here are based on tweaking alpha for coverage. | 200 Most the optimizations we do here are based on tweaking alpha for coverage. |
202 | 201 |
203 The general SVG blend equation is defined in the spec as follows: | 202 The general SVG blend equation is defined in the spec as follows: |
204 | 203 |
205 Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa) | 204 Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa) |
206 Da' = X * Sa * Da + Y * Sa * (1-Da) + Z * Da * (1-Sa) | 205 Da' = X * Sa * Da + Y * Sa * (1-Da) + Z * Da * (1-Sa) |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 | 286 |
288 f * blend(Sa, Da) + (1-f) * Da | 287 f * blend(Sa, Da) + (1-f) * Da |
289 = f * (Sa + Da - Sa * Da) + (1-f) * Da | 288 = f * (Sa + Da - Sa * Da) + (1-f) * Da |
290 = f*Sa + f*Da - f*Sa * Da + Da - f*Da | 289 = f*Sa + f*Da - f*Sa * Da + Da - f*Da |
291 = f*Sa - f*Sa * Da + Da | 290 = f*Sa - f*Sa * Da + Da |
292 = f*Sa + Da - f*Sa * Da | 291 = f*Sa + Da - f*Sa * Da |
293 = blend(f*Sa, Da) | 292 = blend(f*Sa, Da) |
294 */ | 293 */ |
295 | 294 |
296 OptFlags flags = kNone_OptFlags; | 295 OptFlags flags = kNone_OptFlags; |
297 if (colorPOI.allStagesMultiplyInput()) { | 296 if (optimizations.fColorPOI.allStagesMultiplyInput()) { |
298 flags |= kCanTweakAlphaForCoverage_OptFlag; | 297 flags |= kCanTweakAlphaForCoverage_OptFlag; |
299 } | 298 } |
300 if (this->hasHWBlendEquation() && coveragePOI.isSolidWhite()) { | 299 if (this->hasHWBlendEquation() && optimizations.fCoveragePOI.isSolidWhite())
{ |
301 flags |= kIgnoreCoverage_OptFlag; | 300 flags |= kIgnoreCoverage_OptFlag; |
302 } | 301 } |
303 return flags; | 302 return flags; |
304 } | 303 } |
305 | 304 |
306 GrXferBarrierType CustomXP::onXferBarrier(const GrRenderTarget* rt, const GrCaps
& caps) const { | 305 GrXferBarrierType CustomXP::onXferBarrier(const GrRenderTarget* rt, const GrCaps
& caps) const { |
307 if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport
()) { | 306 if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport
()) { |
308 return kBlend_GrXferBarrierType; | 307 return kBlend_GrXferBarrierType; |
309 } | 308 } |
310 return kNone_GrXferBarrierType; | 309 return kNone_GrXferBarrierType; |
311 } | 310 } |
312 | 311 |
313 void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const { | 312 void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const { |
314 if (this->hasHWBlendEquation()) { | 313 if (this->hasHWBlendEquation()) { |
315 blendInfo->fEquation = this->hwBlendEquation(); | 314 blendInfo->fEquation = this->hwBlendEquation(); |
316 } | 315 } |
317 } | 316 } |
318 | 317 |
319 /////////////////////////////////////////////////////////////////////////////// | 318 /////////////////////////////////////////////////////////////////////////////// |
320 class CustomXPFactory : public GrXPFactory { | 319 class CustomXPFactory : public GrXPFactory { |
321 public: | 320 public: |
322 CustomXPFactory(SkXfermode::Mode mode); | 321 CustomXPFactory(SkXfermode::Mode mode); |
323 | 322 |
324 void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, | 323 void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, |
325 GrXPFactory::InvariantBlendedColor*) const ove
rride; | 324 GrXPFactory::InvariantBlendedColor*) const ove
rride; |
326 | 325 |
327 private: | 326 private: |
328 GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, | 327 GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, |
329 const GrProcOptInfo& colorPOI, | 328 const GrPipelineOptimizations& optimi
zations, |
330 const GrProcOptInfo& coveragePOI, | |
331 bool hasMixedSamples, | 329 bool hasMixedSamples, |
332 const DstTexture*) const override; | 330 const DstTexture*) const override; |
333 | 331 |
334 bool willReadDstColor(const GrCaps& caps, | 332 bool willReadDstColor(const GrCaps& caps, |
335 const GrProcOptInfo& colorPOI, | 333 const GrPipelineOptimizations& optimizations, |
336 const GrProcOptInfo& coveragePOI, | |
337 bool hasMixedSamples) const override; | 334 bool hasMixedSamples) const override; |
338 | 335 |
339 bool onIsEqual(const GrXPFactory& xpfBase) const override { | 336 bool onIsEqual(const GrXPFactory& xpfBase) const override { |
340 const CustomXPFactory& xpf = xpfBase.cast<CustomXPFactory>(); | 337 const CustomXPFactory& xpf = xpfBase.cast<CustomXPFactory>(); |
341 return fMode == xpf.fMode; | 338 return fMode == xpf.fMode; |
342 } | 339 } |
343 | 340 |
344 GR_DECLARE_XP_FACTORY_TEST; | 341 GR_DECLARE_XP_FACTORY_TEST; |
345 | 342 |
346 SkXfermode::Mode fMode; | 343 SkXfermode::Mode fMode; |
347 GrBlendEquation fHWBlendEquation; | 344 GrBlendEquation fHWBlendEquation; |
348 | 345 |
349 typedef GrXPFactory INHERITED; | 346 typedef GrXPFactory INHERITED; |
350 }; | 347 }; |
351 | 348 |
352 CustomXPFactory::CustomXPFactory(SkXfermode::Mode mode) | 349 CustomXPFactory::CustomXPFactory(SkXfermode::Mode mode) |
353 : fMode(mode), | 350 : fMode(mode), |
354 fHWBlendEquation(hw_blend_equation(mode)) { | 351 fHWBlendEquation(hw_blend_equation(mode)) { |
355 SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); | 352 SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); |
356 this->initClassID<CustomXPFactory>(); | 353 this->initClassID<CustomXPFactory>(); |
357 } | 354 } |
358 | 355 |
359 GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps, | 356 GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps, |
360 const GrProcOptInfo& col
orPOI, | 357 const GrPipelineOptimiza
tions& opt, |
361 const GrProcOptInfo& cov
eragePOI, | |
362 bool hasMixedSamples, | 358 bool hasMixedSamples, |
363 const DstTexture* dstTex
ture) const { | 359 const DstTexture* dstTex
ture) const { |
364 if (can_use_hw_blend_equation(fHWBlendEquation, coveragePOI, caps)) { | 360 if (can_use_hw_blend_equation(fHWBlendEquation, opt.fCoveragePOI, caps)) { |
365 SkASSERT(!dstTexture || !dstTexture->texture()); | 361 SkASSERT(!dstTexture || !dstTexture->texture()); |
366 return new CustomXP(fMode, fHWBlendEquation); | 362 return new CustomXP(fMode, fHWBlendEquation); |
367 } | 363 } |
368 return new CustomXP(dstTexture, hasMixedSamples, fMode); | 364 return new CustomXP(dstTexture, hasMixedSamples, fMode); |
369 } | 365 } |
370 | 366 |
371 bool CustomXPFactory::willReadDstColor(const GrCaps& caps, | 367 bool CustomXPFactory::willReadDstColor(const GrCaps& caps, |
372 const GrProcOptInfo& colorPOI, | 368 const GrPipelineOptimizations& optimizati
ons, |
373 const GrProcOptInfo& coveragePOI, | |
374 bool hasMixedSamples) const { | 369 bool hasMixedSamples) const { |
375 return !can_use_hw_blend_equation(fHWBlendEquation, coveragePOI, caps); | 370 return !can_use_hw_blend_equation(fHWBlendEquation, optimizations.fCoverageP
OI, caps); |
376 } | 371 } |
377 | 372 |
378 void CustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, | 373 void CustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, |
379 InvariantBlendedColor* blendedCol
or) const { | 374 InvariantBlendedColor* blendedCol
or) const { |
380 blendedColor->fWillBlendWithDst = true; | 375 blendedColor->fWillBlendWithDst = true; |
381 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; | 376 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; |
382 } | 377 } |
383 | 378 |
384 GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory); | 379 GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory); |
385 const GrXPFactory* CustomXPFactory::TestCreate(GrProcessorTestData* d) { | 380 const GrXPFactory* CustomXPFactory::TestCreate(GrProcessorTestData* d) { |
386 int mode = d->fRandom->nextRangeU(SkXfermode::kLastCoeffMode + 1, | 381 int mode = d->fRandom->nextRangeU(SkXfermode::kLastCoeffMode + 1, |
387 SkXfermode::kLastSeparableMode); | 382 SkXfermode::kLastSeparableMode); |
388 | 383 |
389 return new CustomXPFactory(static_cast<SkXfermode::Mode>(mode)); | 384 return new CustomXPFactory(static_cast<SkXfermode::Mode>(mode)); |
390 } | 385 } |
391 | 386 |
392 /////////////////////////////////////////////////////////////////////////////// | 387 /////////////////////////////////////////////////////////////////////////////// |
393 | 388 |
394 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) { | 389 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) { |
395 if (!GrCustomXfermode::IsSupportedMode(mode)) { | 390 if (!GrCustomXfermode::IsSupportedMode(mode)) { |
396 return nullptr; | 391 return nullptr; |
397 } else { | 392 } else { |
398 return new CustomXPFactory(mode); | 393 return new CustomXPFactory(mode); |
399 } | 394 } |
400 } | 395 } |
OLD | NEW |