• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 "src/gpu/effects/GrCoverageSetOpXP.h"
9 
10 #include "src/gpu/GrCaps.h"
11 #include "src/gpu/GrColor.h"
12 #include "src/gpu/GrPipeline.h"
13 #include "src/gpu/GrXferProcessor.h"
14 #include "src/gpu/glsl/GrGLSLBlend.h"
15 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
16 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
17 
18 class CoverageSetOpXP : public GrXferProcessor {
19 public:
CoverageSetOpXP(SkRegion::Op regionOp,bool invertCoverage)20     CoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage)
21             : INHERITED(kCoverageSetOpXP_ClassID)
22             , fRegionOp(regionOp)
23             , fInvertCoverage(invertCoverage) {}
24 
name() const25     const char* name() const override { return "Coverage Set Op"; }
26 
27     std::unique_ptr<ProgramImpl> makeProgramImpl() const override;
28 
29 private:
30     void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
31 
32     void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override;
33 
onIsEqual(const GrXferProcessor & xpBase) const34     bool onIsEqual(const GrXferProcessor& xpBase) const override {
35         const CoverageSetOpXP& xp = xpBase.cast<CoverageSetOpXP>();
36         return (fRegionOp == xp.fRegionOp &&
37                 fInvertCoverage == xp.fInvertCoverage);
38     }
39 
40     SkRegion::Op fRegionOp;
41     bool         fInvertCoverage;
42 
43     using INHERITED = GrXferProcessor;
44 };
45 
onAddToKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b) const46 void CoverageSetOpXP::onAddToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
47     b->addBool(fInvertCoverage, "invert coverage");
48 }
49 
makeProgramImpl() const50 std::unique_ptr<GrXferProcessor::ProgramImpl> CoverageSetOpXP::makeProgramImpl() const {
51     class Impl : public ProgramImpl {
52     private:
53         void emitOutputsForBlendState(const EmitArgs& args) override {
54             const CoverageSetOpXP& xp = args.fXP.cast<CoverageSetOpXP>();
55             GrGLSLXPFragmentBuilder* fb = args.fXPFragBuilder;
56             if (xp.fInvertCoverage) {
57                 fb->codeAppendf("%s = 1.0 - %s;", args.fOutputPrimary, args.fInputCoverage);
58             } else {
59                 fb->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage);
60             }
61         }
62     };
63     return std::make_unique<Impl>();
64 }
65 
onGetBlendInfo(GrXferProcessor::BlendInfo * blendInfo) const66 void CoverageSetOpXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const {
67     switch (fRegionOp) {
68         case SkRegion::kReplace_Op:
69             blendInfo->fSrcBlend = kOne_GrBlendCoeff;
70             blendInfo->fDstBlend = kZero_GrBlendCoeff;
71             break;
72         case SkRegion::kIntersect_Op:
73             blendInfo->fSrcBlend = kDC_GrBlendCoeff;
74             blendInfo->fDstBlend = kZero_GrBlendCoeff;
75             break;
76         case SkRegion::kUnion_Op:
77             blendInfo->fSrcBlend = kOne_GrBlendCoeff;
78             blendInfo->fDstBlend = kISC_GrBlendCoeff;
79             break;
80         case SkRegion::kXOR_Op:
81             blendInfo->fSrcBlend = kIDC_GrBlendCoeff;
82             blendInfo->fDstBlend = kISC_GrBlendCoeff;
83             break;
84         case SkRegion::kDifference_Op:
85             blendInfo->fSrcBlend = kZero_GrBlendCoeff;
86             blendInfo->fDstBlend = kISC_GrBlendCoeff;
87             break;
88         case SkRegion::kReverseDifference_Op:
89             blendInfo->fSrcBlend = kIDC_GrBlendCoeff;
90             blendInfo->fDstBlend = kZero_GrBlendCoeff;
91             break;
92     }
93     blendInfo->fBlendConstant = SK_PMColor4fTRANSPARENT;
94 }
95 
96 ///////////////////////////////////////////////////////////////////////////////
97 
GrCoverageSetOpXPFactory(SkRegion::Op regionOp,bool invertCoverage)98 constexpr GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp,
99                                                              bool invertCoverage)
100         : fRegionOp(regionOp), fInvertCoverage(invertCoverage) {}
101 
Get(SkRegion::Op regionOp,bool invertCoverage)102 const GrXPFactory* GrCoverageSetOpXPFactory::Get(SkRegion::Op regionOp, bool invertCoverage) {
103     switch (regionOp) {
104         case SkRegion::kReplace_Op: {
105             if (invertCoverage) {
106                 static constexpr const GrCoverageSetOpXPFactory gReplaceCDXPFI(
107                         SkRegion::kReplace_Op, true);
108                 return &gReplaceCDXPFI;
109             } else {
110                 static constexpr const GrCoverageSetOpXPFactory gReplaceCDXPF(SkRegion::kReplace_Op,
111                                                                               false);
112                 return &gReplaceCDXPF;
113             }
114         }
115         case SkRegion::kIntersect_Op: {
116             if (invertCoverage) {
117                 static constexpr const GrCoverageSetOpXPFactory gIntersectCDXPFI(
118                         SkRegion::kIntersect_Op, true);
119                 return &gIntersectCDXPFI;
120             } else {
121                 static constexpr const GrCoverageSetOpXPFactory gIntersectCDXPF(
122                         SkRegion::kIntersect_Op, false);
123                 return &gIntersectCDXPF;
124             }
125         }
126         case SkRegion::kUnion_Op: {
127             if (invertCoverage) {
128                 static constexpr const GrCoverageSetOpXPFactory gUnionCDXPFI(SkRegion::kUnion_Op,
129                                                                              true);
130                 return &gUnionCDXPFI;
131             } else {
132                 static constexpr const GrCoverageSetOpXPFactory gUnionCDXPF(SkRegion::kUnion_Op,
133                                                                             false);
134                 return &gUnionCDXPF;
135             }
136         }
137         case SkRegion::kXOR_Op: {
138             if (invertCoverage) {
139                 static constexpr const GrCoverageSetOpXPFactory gXORCDXPFI(SkRegion::kXOR_Op, true);
140                 return &gXORCDXPFI;
141             } else {
142                 static constexpr const GrCoverageSetOpXPFactory gXORCDXPF(SkRegion::kXOR_Op, false);
143                 return &gXORCDXPF;
144             }
145         }
146         case SkRegion::kDifference_Op: {
147             if (invertCoverage) {
148                 static constexpr const GrCoverageSetOpXPFactory gDifferenceCDXPFI(
149                         SkRegion::kDifference_Op, true);
150                 return &gDifferenceCDXPFI;
151             } else {
152                 static constexpr const GrCoverageSetOpXPFactory gDifferenceCDXPF(
153                         SkRegion::kDifference_Op, false);
154                 return &gDifferenceCDXPF;
155             }
156         }
157         case SkRegion::kReverseDifference_Op: {
158             if (invertCoverage) {
159                 static constexpr const GrCoverageSetOpXPFactory gRevDiffCDXPFI(
160                         SkRegion::kReverseDifference_Op, true);
161                 return &gRevDiffCDXPFI;
162             } else {
163                 static constexpr const GrCoverageSetOpXPFactory gRevDiffCDXPF(
164                         SkRegion::kReverseDifference_Op, false);
165                 return &gRevDiffCDXPF;
166             }
167         }
168     }
169     SK_ABORT("Unknown region op.");
170 }
171 
makeXferProcessor(const GrProcessorAnalysisColor &,GrProcessorAnalysisCoverage,const GrCaps & caps,GrClampType) const172 sk_sp<const GrXferProcessor> GrCoverageSetOpXPFactory::makeXferProcessor(
173         const GrProcessorAnalysisColor&,
174         GrProcessorAnalysisCoverage,
175         const GrCaps& caps,
176         GrClampType) const {
177     return sk_sp<GrXferProcessor>(new CoverageSetOpXP(fRegionOp, fInvertCoverage));
178 }
179 
180 GR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory);
181 
182 #if GR_TEST_UTILS
TestGet(GrProcessorTestData * d)183 const GrXPFactory* GrCoverageSetOpXPFactory::TestGet(GrProcessorTestData* d) {
184     SkRegion::Op regionOp = SkRegion::Op(d->fRandom->nextULessThan(SkRegion::kLastOp + 1));
185     bool invertCoverage = d->fRandom->nextBool();
186     return GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage);
187 }
188 #endif
189