LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu/effects - GrCustomXfermode.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 106 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 26 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2015 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #include "effects/GrCustomXfermode.h"
       9             : 
      10             : #include "GrCaps.h"
      11             : #include "GrCoordTransform.h"
      12             : #include "GrFragmentProcessor.h"
      13             : #include "GrPipeline.h"
      14             : #include "GrProcessor.h"
      15             : #include "GrShaderCaps.h"
      16             : #include "GrTexture.h"
      17             : #include "glsl/GrGLSLBlend.h"
      18             : #include "glsl/GrGLSLFragmentProcessor.h"
      19             : #include "glsl/GrGLSLFragmentShaderBuilder.h"
      20             : #include "glsl/GrGLSLProgramDataManager.h"
      21             : #include "glsl/GrGLSLUniformHandler.h"
      22             : #include "glsl/GrGLSLXferProcessor.h"
      23             : 
      24           0 : bool GrCustomXfermode::IsSupportedMode(SkBlendMode mode) {
      25           0 :     return (int)mode  > (int)SkBlendMode::kLastCoeffMode &&
      26           0 :            (int)mode <= (int)SkBlendMode::kLastMode;
      27             : }
      28             : 
      29             : ///////////////////////////////////////////////////////////////////////////////
      30             : // Static helpers
      31             : ///////////////////////////////////////////////////////////////////////////////
      32             : 
      33             : static constexpr GrBlendEquation hw_blend_equation(SkBlendMode mode) {
      34             : // In C++14 this could be a constexpr int variable.
      35             : #define EQ_OFFSET (kOverlay_GrBlendEquation - (int)SkBlendMode::kOverlay)
      36             :     GR_STATIC_ASSERT(kOverlay_GrBlendEquation == (int)SkBlendMode::kOverlay + EQ_OFFSET);
      37             :     GR_STATIC_ASSERT(kDarken_GrBlendEquation == (int)SkBlendMode::kDarken + EQ_OFFSET);
      38             :     GR_STATIC_ASSERT(kLighten_GrBlendEquation == (int)SkBlendMode::kLighten + EQ_OFFSET);
      39             :     GR_STATIC_ASSERT(kColorDodge_GrBlendEquation == (int)SkBlendMode::kColorDodge + EQ_OFFSET);
      40             :     GR_STATIC_ASSERT(kColorBurn_GrBlendEquation == (int)SkBlendMode::kColorBurn + EQ_OFFSET);
      41             :     GR_STATIC_ASSERT(kHardLight_GrBlendEquation == (int)SkBlendMode::kHardLight + EQ_OFFSET);
      42             :     GR_STATIC_ASSERT(kSoftLight_GrBlendEquation == (int)SkBlendMode::kSoftLight + EQ_OFFSET);
      43             :     GR_STATIC_ASSERT(kDifference_GrBlendEquation == (int)SkBlendMode::kDifference + EQ_OFFSET);
      44             :     GR_STATIC_ASSERT(kExclusion_GrBlendEquation == (int)SkBlendMode::kExclusion + EQ_OFFSET);
      45             :     GR_STATIC_ASSERT(kMultiply_GrBlendEquation == (int)SkBlendMode::kMultiply + EQ_OFFSET);
      46             :     GR_STATIC_ASSERT(kHSLHue_GrBlendEquation == (int)SkBlendMode::kHue + EQ_OFFSET);
      47             :     GR_STATIC_ASSERT(kHSLSaturation_GrBlendEquation == (int)SkBlendMode::kSaturation + EQ_OFFSET);
      48             :     GR_STATIC_ASSERT(kHSLColor_GrBlendEquation == (int)SkBlendMode::kColor + EQ_OFFSET);
      49             :     GR_STATIC_ASSERT(kHSLLuminosity_GrBlendEquation == (int)SkBlendMode::kLuminosity + EQ_OFFSET);
      50             :     GR_STATIC_ASSERT(kGrBlendEquationCnt == (int)SkBlendMode::kLastMode + 1 + EQ_OFFSET);
      51             :     return static_cast<GrBlendEquation>((int)mode + EQ_OFFSET);
      52             : #undef EQ_OFFSET
      53             : }
      54             : 
      55           0 : static bool can_use_hw_blend_equation(GrBlendEquation equation,
      56             :                                       GrProcessorAnalysisCoverage coverage, const GrCaps& caps) {
      57           0 :     if (!caps.advancedBlendEquationSupport()) {
      58           0 :         return false;
      59             :     }
      60           0 :     if (GrProcessorAnalysisCoverage::kLCD == coverage) {
      61           0 :         return false; // LCD coverage must be applied after the blend equation.
      62             :     }
      63           0 :     if (caps.canUseAdvancedBlendEquation(equation)) {
      64           0 :         return false;
      65             :     }
      66           0 :     return true;
      67             : }
      68             : 
      69             : ///////////////////////////////////////////////////////////////////////////////
      70             : // Xfer Processor
      71             : ///////////////////////////////////////////////////////////////////////////////
      72             : 
      73           0 : class CustomXP : public GrXferProcessor {
      74             : public:
      75           0 :     CustomXP(SkBlendMode mode, GrBlendEquation hwBlendEquation)
      76           0 :         : fMode(mode),
      77           0 :           fHWBlendEquation(hwBlendEquation) {
      78           0 :         this->initClassID<CustomXP>();
      79           0 :     }
      80             : 
      81           0 :     CustomXP(bool hasMixedSamples, SkBlendMode mode)
      82           0 :             : INHERITED(true, hasMixedSamples)
      83             :             , fMode(mode)
      84           0 :             , fHWBlendEquation(static_cast<GrBlendEquation>(-1)) {
      85           0 :         this->initClassID<CustomXP>();
      86           0 :     }
      87             : 
      88           0 :     const char* name() const override { return "Custom Xfermode"; }
      89             : 
      90             :     GrGLSLXferProcessor* createGLSLInstance() const override;
      91             : 
      92           0 :     SkBlendMode mode() const { return fMode; }
      93           0 :     bool hasHWBlendEquation() const { return -1 != static_cast<int>(fHWBlendEquation); }
      94             : 
      95           0 :     GrBlendEquation hwBlendEquation() const {
      96           0 :         SkASSERT(this->hasHWBlendEquation());
      97           0 :         return fHWBlendEquation;
      98             :     }
      99             : 
     100             :     GrXferBarrierType xferBarrierType(const GrCaps&) const override;
     101             : 
     102             : private:
     103             :     void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
     104             : 
     105             :     void onGetBlendInfo(BlendInfo*) const override;
     106             : 
     107             :     bool onIsEqual(const GrXferProcessor& xpBase) const override;
     108             : 
     109             :     const SkBlendMode      fMode;
     110             :     const GrBlendEquation  fHWBlendEquation;
     111             : 
     112             :     typedef GrXferProcessor INHERITED;
     113             : };
     114             : 
     115             : ///////////////////////////////////////////////////////////////////////////////
     116             : 
     117             : class GLCustomXP : public GrGLSLXferProcessor {
     118             : public:
     119           0 :     GLCustomXP(const GrXferProcessor&) {}
     120           0 :     ~GLCustomXP() override {}
     121             : 
     122           0 :     static void GenKey(const GrXferProcessor& p, const GrShaderCaps& caps,
     123             :                        GrProcessorKeyBuilder* b) {
     124           0 :         const CustomXP& xp = p.cast<CustomXP>();
     125           0 :         uint32_t key = 0;
     126           0 :         if (xp.hasHWBlendEquation()) {
     127           0 :             SkASSERT(caps.advBlendEqInteraction() > 0);  // 0 will mean !xp.hasHWBlendEquation().
     128           0 :             key |= caps.advBlendEqInteraction();
     129             :             GR_STATIC_ASSERT(GrShaderCaps::kLast_AdvBlendEqInteraction < 4);
     130             :         }
     131           0 :         if (!xp.hasHWBlendEquation() || caps.mustEnableSpecificAdvBlendEqs()) {
     132           0 :             key |= (int)xp.mode() << 3;
     133             :         }
     134           0 :         b->add32(key);
     135           0 :     }
     136             : 
     137             : private:
     138           0 :     void emitOutputsForBlendState(const EmitArgs& args) override {
     139           0 :         const CustomXP& xp = args.fXP.cast<CustomXP>();
     140           0 :         SkASSERT(xp.hasHWBlendEquation());
     141             : 
     142           0 :         GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
     143           0 :         fragBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation());
     144             : 
     145             :         // Apply coverage by multiplying it into the src color before blending. Mixed samples will
     146             :         // "just work" automatically. (See onGetOptimizations())
     147           0 :         fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputCoverage,
     148           0 :                                  args.fInputColor);
     149           0 :     }
     150             : 
     151           0 :     void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder* fragBuilder,
     152             :                                  GrGLSLUniformHandler* uniformHandler,
     153             :                                  const char* srcColor,
     154             :                                  const char* srcCoverage,
     155             :                                  const char* dstColor,
     156             :                                  const char* outColor,
     157             :                                  const char* outColorSecondary,
     158             :                                  const GrXferProcessor& proc) override {
     159           0 :         const CustomXP& xp = proc.cast<CustomXP>();
     160           0 :         SkASSERT(!xp.hasHWBlendEquation());
     161             : 
     162           0 :         GrGLSLBlend::AppendMode(fragBuilder, srcColor, dstColor, outColor, xp.mode());
     163             : 
     164             :         // Apply coverage.
     165           0 :         INHERITED::DefaultCoverageModulation(fragBuilder, srcCoverage, dstColor, outColor,
     166           0 :                                              outColorSecondary, xp);
     167           0 :     }
     168             : 
     169           0 :     void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
     170             : 
     171             :     typedef GrGLSLXferProcessor INHERITED;
     172             : };
     173             : 
     174             : ///////////////////////////////////////////////////////////////////////////////
     175             : 
     176           0 : void CustomXP::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
     177           0 :     GLCustomXP::GenKey(*this, caps, b);
     178           0 : }
     179             : 
     180           0 : GrGLSLXferProcessor* CustomXP::createGLSLInstance() const {
     181           0 :     SkASSERT(this->willReadDstColor() != this->hasHWBlendEquation());
     182           0 :     return new GLCustomXP(*this);
     183             : }
     184             : 
     185           0 : bool CustomXP::onIsEqual(const GrXferProcessor& other) const {
     186           0 :     const CustomXP& s = other.cast<CustomXP>();
     187           0 :     return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation;
     188             : }
     189             : 
     190           0 : GrXferBarrierType CustomXP::xferBarrierType(const GrCaps& caps) const {
     191           0 :     if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport()) {
     192           0 :         return kBlend_GrXferBarrierType;
     193             :     }
     194           0 :     return kNone_GrXferBarrierType;
     195             : }
     196             : 
     197           0 : void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const {
     198           0 :     if (this->hasHWBlendEquation()) {
     199           0 :         blendInfo->fEquation = this->hwBlendEquation();
     200             :     }
     201           0 : }
     202             : 
     203             : ///////////////////////////////////////////////////////////////////////////////
     204             : 
     205             : // See the comment above GrXPFactory's definition about this warning suppression.
     206             : #if defined(__GNUC__) || defined(__clang)
     207             : #pragma GCC diagnostic push
     208             : #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
     209             : #endif
     210             : class CustomXPFactory : public GrXPFactory {
     211             : public:
     212             :     constexpr CustomXPFactory(SkBlendMode mode)
     213             :             : fMode(mode), fHWBlendEquation(hw_blend_equation(mode)) {}
     214             : 
     215             : private:
     216             :     sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
     217             :                                                    GrProcessorAnalysisCoverage,
     218             :                                                    bool hasMixedSamples,
     219             :                                                    const GrCaps&) const override;
     220             : 
     221             :     AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
     222             :                                           const GrProcessorAnalysisCoverage&,
     223             :                                           const GrCaps&) const override;
     224             : 
     225             :     GR_DECLARE_XP_FACTORY_TEST;
     226             : 
     227             :     SkBlendMode fMode;
     228             :     GrBlendEquation fHWBlendEquation;
     229             : 
     230             :     typedef GrXPFactory INHERITED;
     231             : };
     232             : #if defined(__GNUC__) || defined(__clang)
     233             : #pragma GCC diagnostic pop
     234             : #endif
     235             : 
     236           0 : sk_sp<const GrXferProcessor> CustomXPFactory::makeXferProcessor(
     237             :         const GrProcessorAnalysisColor&,
     238             :         GrProcessorAnalysisCoverage coverage,
     239             :         bool hasMixedSamples,
     240             :         const GrCaps& caps) const {
     241           0 :     SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
     242           0 :     if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) {
     243           0 :         return sk_sp<GrXferProcessor>(new CustomXP(fMode, fHWBlendEquation));
     244             :     }
     245           0 :     return sk_sp<GrXferProcessor>(new CustomXP(hasMixedSamples, fMode));
     246             : }
     247             : 
     248           0 : GrXPFactory::AnalysisProperties CustomXPFactory::analysisProperties(
     249             :         const GrProcessorAnalysisColor&, const GrProcessorAnalysisCoverage& coverage,
     250             :         const GrCaps& caps) const {
     251             :     /*
     252             :       The general SVG blend equation is defined in the spec as follows:
     253             : 
     254             :         Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa)
     255             :         Da'  = X * Sa * Da + Y * Sa * (1-Da) + Z * Da * (1-Sa)
     256             : 
     257             :       (Note that Sca, Dca indicate RGB vectors that are premultiplied by alpha,
     258             :        and that B(Sc, Dc) is a mode-specific function that accepts non-multiplied
     259             :        RGB colors.)
     260             : 
     261             :       For every blend mode supported by this class, i.e. the "advanced" blend
     262             :       modes, X=Y=Z=1 and this equation reduces to the PDF blend equation.
     263             : 
     264             :       It can be shown that when X=Y=Z=1, these equations can modulate alpha for
     265             :       coverage.
     266             : 
     267             : 
     268             :       == Color ==
     269             : 
     270             :       We substitute Y=Z=1 and define a blend() function that calculates Dca' in
     271             :       terms of premultiplied alpha only:
     272             : 
     273             :         blend(Sca, Dca, Sa, Da) = {Dca : if Sa == 0,
     274             :                                    Sca : if Da == 0,
     275             :                                    B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa) : if
     276             :       Sa,Da != 0}
     277             : 
     278             :       And for coverage modulation, we use a post blend src-over model:
     279             : 
     280             :         Dca'' = f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
     281             : 
     282             :       (Where f is the fractional coverage.)
     283             : 
     284             :       Next we show that canTweakAlphaForCoverage() is true by proving the
     285             :       following relationship:
     286             : 
     287             :         blend(f*Sca, Dca, f*Sa, Da) == f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
     288             : 
     289             :       General case (f,Sa,Da != 0):
     290             : 
     291             :         f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
     292             :           = f * (B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa)) + (1-f) * Dca  [Sa,Da !=
     293             :       0, definition of blend()]
     294             :           = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + f*Dca * (1-Sa) + Dca - f*Dca
     295             :           = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da + f*Dca - f*Dca * Sa + Dca - f*Dca
     296             :           = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da - f*Dca * Sa + Dca
     297             :           = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) - f*Dca * Sa + Dca
     298             :           = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa)
     299             :           = B(f*Sca/f*Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa)  [f!=0]
     300             :           = blend(f*Sca, Dca, f*Sa, Da)  [definition of blend()]
     301             : 
     302             :       Corner cases (Sa=0, Da=0, and f=0):
     303             : 
     304             :         Sa=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
     305             :                 = f * Dca + (1-f) * Dca  [Sa=0, definition of blend()]
     306             :                 = Dca
     307             :                 = blend(0, Dca, 0, Da)  [definition of blend()]
     308             :                 = blend(f*Sca, Dca, f*Sa, Da)  [Sa=0]
     309             : 
     310             :         Da=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
     311             :                 = f * Sca + (1-f) * Dca  [Da=0, definition of blend()]
     312             :                 = f * Sca  [Da=0]
     313             :                 = blend(f*Sca, 0, f*Sa, 0)  [definition of blend()]
     314             :                 = blend(f*Sca, Dca, f*Sa, Da)  [Da=0]
     315             : 
     316             :         f=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
     317             :                = Dca  [f=0]
     318             :                = blend(0, Dca, 0, Da)  [definition of blend()]
     319             :                = blend(f*Sca, Dca, f*Sa, Da)  [f=0]
     320             : 
     321             :       == Alpha ==
     322             : 
     323             :       We substitute X=Y=Z=1 and define a blend() function that calculates Da':
     324             : 
     325             :         blend(Sa, Da) = Sa * Da + Sa * (1-Da) + Da * (1-Sa)
     326             :                       = Sa * Da + Sa - Sa * Da + Da - Da * Sa
     327             :                       = Sa + Da - Sa * Da
     328             : 
     329             :       We use the same model for coverage modulation as we did with color:
     330             : 
     331             :         Da'' = f * blend(Sa, Da) + (1-f) * Da
     332             : 
     333             :       And show that canTweakAlphaForCoverage() is true by proving the following
     334             :       relationship:
     335             : 
     336             :         blend(f*Sa, Da) == f * blend(Sa, Da) + (1-f) * Da
     337             : 
     338             : 
     339             :         f * blend(Sa, Da) + (1-f) * Da
     340             :           = f * (Sa + Da - Sa * Da) + (1-f) * Da
     341             :           = f*Sa + f*Da - f*Sa * Da + Da - f*Da
     342             :           = f*Sa - f*Sa * Da + Da
     343             :           = f*Sa + Da - f*Sa * Da
     344             :           = blend(f*Sa, Da)
     345             :     */
     346           0 :     if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) {
     347           0 :         if (caps.blendEquationSupport() == GrCaps::kAdvancedCoherent_BlendEquationSupport) {
     348           0 :             return AnalysisProperties::kCompatibleWithAlphaAsCoverage;
     349             :         } else {
     350             :             return AnalysisProperties::kCompatibleWithAlphaAsCoverage |
     351           0 :                    AnalysisProperties::kRequiresBarrierBetweenOverlappingDraws;
     352             :         }
     353             :     }
     354             :     return AnalysisProperties::kCompatibleWithAlphaAsCoverage |
     355           0 :            AnalysisProperties::kReadsDstInShader;
     356             : }
     357             : 
     358             : GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory);
     359             : #if GR_TEST_UTILS
     360           0 : const GrXPFactory* CustomXPFactory::TestGet(GrProcessorTestData* d) {
     361           0 :     int mode = d->fRandom->nextRangeU((int)SkBlendMode::kLastCoeffMode + 1,
     362           0 :                                       (int)SkBlendMode::kLastSeparableMode);
     363             : 
     364           0 :     return GrCustomXfermode::Get((SkBlendMode)mode);
     365             : }
     366             : #endif
     367             : 
     368             : ///////////////////////////////////////////////////////////////////////////////
     369             : 
     370           0 : const GrXPFactory* GrCustomXfermode::Get(SkBlendMode mode) {
     371             :     // If these objects are constructed as static constexpr by cl.exe (2015 SP2) the vtables are
     372             :     // null.
     373             : #ifdef SK_BUILD_FOR_WIN
     374             : #define _CONSTEXPR_
     375             : #else
     376             : #define _CONSTEXPR_ constexpr
     377             : #endif
     378             :     static _CONSTEXPR_ const CustomXPFactory gOverlay(SkBlendMode::kOverlay);
     379             :     static _CONSTEXPR_ const CustomXPFactory gDarken(SkBlendMode::kDarken);
     380             :     static _CONSTEXPR_ const CustomXPFactory gLighten(SkBlendMode::kLighten);
     381             :     static _CONSTEXPR_ const CustomXPFactory gColorDodge(SkBlendMode::kColorDodge);
     382             :     static _CONSTEXPR_ const CustomXPFactory gColorBurn(SkBlendMode::kColorBurn);
     383             :     static _CONSTEXPR_ const CustomXPFactory gHardLight(SkBlendMode::kHardLight);
     384             :     static _CONSTEXPR_ const CustomXPFactory gSoftLight(SkBlendMode::kSoftLight);
     385             :     static _CONSTEXPR_ const CustomXPFactory gDifference(SkBlendMode::kDifference);
     386             :     static _CONSTEXPR_ const CustomXPFactory gExclusion(SkBlendMode::kExclusion);
     387             :     static _CONSTEXPR_ const CustomXPFactory gMultiply(SkBlendMode::kMultiply);
     388             :     static _CONSTEXPR_ const CustomXPFactory gHue(SkBlendMode::kHue);
     389             :     static _CONSTEXPR_ const CustomXPFactory gSaturation(SkBlendMode::kSaturation);
     390             :     static _CONSTEXPR_ const CustomXPFactory gColor(SkBlendMode::kColor);
     391             :     static _CONSTEXPR_ const CustomXPFactory gLuminosity(SkBlendMode::kLuminosity);
     392             : #undef _CONSTEXPR_
     393           0 :     switch (mode) {
     394             :         case SkBlendMode::kOverlay:
     395           0 :             return &gOverlay;
     396             :         case SkBlendMode::kDarken:
     397           0 :             return &gDarken;
     398             :         case SkBlendMode::kLighten:
     399           0 :             return &gLighten;
     400             :         case SkBlendMode::kColorDodge:
     401           0 :             return &gColorDodge;
     402             :         case SkBlendMode::kColorBurn:
     403           0 :             return &gColorBurn;
     404             :         case SkBlendMode::kHardLight:
     405           0 :             return &gHardLight;
     406             :         case SkBlendMode::kSoftLight:
     407           0 :             return &gSoftLight;
     408             :         case SkBlendMode::kDifference:
     409           0 :             return &gDifference;
     410             :         case SkBlendMode::kExclusion:
     411           0 :             return &gExclusion;
     412             :         case SkBlendMode::kMultiply:
     413           0 :             return &gMultiply;
     414             :         case SkBlendMode::kHue:
     415           0 :             return &gHue;
     416             :         case SkBlendMode::kSaturation:
     417           0 :             return &gSaturation;
     418             :         case SkBlendMode::kColor:
     419           0 :             return &gColor;
     420             :         case SkBlendMode::kLuminosity:
     421           0 :             return &gLuminosity;
     422             :         default:
     423           0 :             SkASSERT(!GrCustomXfermode::IsSupportedMode(mode));
     424           0 :             return nullptr;
     425             :     }
     426             : }

Generated by: LCOV version 1.13