blob: 7025d20395f2af1b71327506e6b64bbc50756178 [file] [log] [blame]
egdaniel87509242014-12-17 13:37:13 -08001
2/*
3 * Copyright 2014 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "effects/GrCoverageSetOpXP.h"
10#include "GrColor.h"
11#include "GrDrawTargetCaps.h"
egdaniel87509242014-12-17 13:37:13 -080012#include "GrProcessor.h"
13#include "GrProcOptInfo.h"
14#include "gl/GrGLXferProcessor.h"
15#include "gl/builders/GrGLFragmentShaderBuilder.h"
16#include "gl/builders/GrGLProgramBuilder.h"
17
18class GrGLCoverageSetOpXP : public GrGLXferProcessor {
19public:
20 GrGLCoverageSetOpXP(const GrProcessor&) {}
21
22 ~GrGLCoverageSetOpXP() SK_OVERRIDE {}
23
bsalomon50785a32015-02-06 07:02:37 -080024 static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
25 GrProcessorKeyBuilder* b) {
26 const GrCoverageSetOpXP& xp = processor.cast<GrCoverageSetOpXP>();
27 uint32_t key = xp.invertCoverage() ? 0x0 : 0x1;
28 b->add32(key);
29 };
30
31private:
32 void onEmitCode(const EmitArgs& args) SK_OVERRIDE {
egdaniel87509242014-12-17 13:37:13 -080033 const GrCoverageSetOpXP& xp = args.fXP.cast<GrCoverageSetOpXP>();
34 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
35
36 if (xp.invertCoverage()) {
37 fsBuilder->codeAppendf("%s = 1.0 - %s;", args.fOutputPrimary, args.fInputCoverage);
38 } else {
39 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage);
40 }
41 }
42
bsalomon50785a32015-02-06 07:02:37 -080043 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
egdaniel87509242014-12-17 13:37:13 -080044
egdaniel87509242014-12-17 13:37:13 -080045 typedef GrGLXferProcessor INHERITED;
46};
47
48///////////////////////////////////////////////////////////////////////////////
49
50GrCoverageSetOpXP::GrCoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage)
51 : fRegionOp(regionOp)
52 , fInvertCoverage(invertCoverage) {
53 this->initClassID<GrCoverageSetOpXP>();
54}
55
56GrCoverageSetOpXP::~GrCoverageSetOpXP() {
57}
58
bsalomon50785a32015-02-06 07:02:37 -080059void GrCoverageSetOpXP::onGetGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
egdaniel87509242014-12-17 13:37:13 -080060 GrGLCoverageSetOpXP::GenKey(*this, caps, b);
61}
62
63GrGLXferProcessor* GrCoverageSetOpXP::createGLInstance() const {
64 return SkNEW_ARGS(GrGLCoverageSetOpXP, (*this));
65}
66
67GrXferProcessor::OptFlags
68GrCoverageSetOpXP::getOptimizations(const GrProcOptInfo& colorPOI,
69 const GrProcOptInfo& coveragePOI,
egdaniel87509242014-12-17 13:37:13 -080070 bool doesStencilWrite,
71 GrColor* color,
72 const GrDrawTargetCaps& caps) {
73 // We never look at the color input
74 return GrXferProcessor::kIgnoreColor_OptFlag;
75}
76
77void GrCoverageSetOpXP::getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const {
78 switch (fRegionOp) {
79 case SkRegion::kReplace_Op:
80 blendInfo->fSrcBlend = kOne_GrBlendCoeff;
81 blendInfo->fDstBlend = kZero_GrBlendCoeff;
82 break;
83 case SkRegion::kIntersect_Op:
84 blendInfo->fSrcBlend = kDC_GrBlendCoeff;
85 blendInfo->fDstBlend = kZero_GrBlendCoeff;
86 break;
87 case SkRegion::kUnion_Op:
88 blendInfo->fSrcBlend = kOne_GrBlendCoeff;
89 blendInfo->fDstBlend = kISC_GrBlendCoeff;
90 break;
91 case SkRegion::kXOR_Op:
92 blendInfo->fSrcBlend = kIDC_GrBlendCoeff;
93 blendInfo->fDstBlend = kISC_GrBlendCoeff;
94 break;
95 case SkRegion::kDifference_Op:
96 blendInfo->fSrcBlend = kZero_GrBlendCoeff;
97 blendInfo->fDstBlend = kISC_GrBlendCoeff;
98 break;
99 case SkRegion::kReverseDifference_Op:
100 blendInfo->fSrcBlend = kIDC_GrBlendCoeff;
101 blendInfo->fDstBlend = kZero_GrBlendCoeff;
102 break;
103 }
104 blendInfo->fBlendConstant = 0;
105}
106
107///////////////////////////////////////////////////////////////////////////////
108
109GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage)
110 : fRegionOp(regionOp)
111 , fInvertCoverage(invertCoverage) {
112 this->initClassID<GrCoverageSetOpXPFactory>();
113}
114
115GrXPFactory* GrCoverageSetOpXPFactory::Create(SkRegion::Op regionOp, bool invertCoverage) {
116 switch (regionOp) {
117 case SkRegion::kReplace_Op: {
118 if (invertCoverage) {
119 static GrCoverageSetOpXPFactory gReplaceCDXPFI(regionOp, invertCoverage);
120 return SkRef(&gReplaceCDXPFI);
121 } else {
122 static GrCoverageSetOpXPFactory gReplaceCDXPF(regionOp, invertCoverage);
123 return SkRef(&gReplaceCDXPF);
124 }
125 break;
126 }
127 case SkRegion::kIntersect_Op: {
128 if (invertCoverage) {
129 static GrCoverageSetOpXPFactory gIntersectCDXPFI(regionOp, invertCoverage);
130 return SkRef(&gIntersectCDXPFI);
131 } else {
132 static GrCoverageSetOpXPFactory gIntersectCDXPF(regionOp, invertCoverage);
133 return SkRef(&gIntersectCDXPF);
134 }
135 break;
136 }
137 case SkRegion::kUnion_Op: {
138 if (invertCoverage) {
139 static GrCoverageSetOpXPFactory gUnionCDXPFI(regionOp, invertCoverage);
140 return SkRef(&gUnionCDXPFI);
141 } else {
142 static GrCoverageSetOpXPFactory gUnionCDXPF(regionOp, invertCoverage);
143 return SkRef(&gUnionCDXPF);
144 }
145 break;
146 }
147 case SkRegion::kXOR_Op: {
148 if (invertCoverage) {
149 static GrCoverageSetOpXPFactory gXORCDXPFI(regionOp, invertCoverage);
150 return SkRef(&gXORCDXPFI);
151 } else {
152 static GrCoverageSetOpXPFactory gXORCDXPF(regionOp, invertCoverage);
153 return SkRef(&gXORCDXPF);
154 }
155 break;
156 }
157 case SkRegion::kDifference_Op: {
158 if (invertCoverage) {
159 static GrCoverageSetOpXPFactory gDifferenceCDXPFI(regionOp, invertCoverage);
160 return SkRef(&gDifferenceCDXPFI);
161 } else {
162 static GrCoverageSetOpXPFactory gDifferenceCDXPF(regionOp, invertCoverage);
163 return SkRef(&gDifferenceCDXPF);
164 }
165 break;
166 }
167 case SkRegion::kReverseDifference_Op: {
168 if (invertCoverage) {
169 static GrCoverageSetOpXPFactory gRevDiffCDXPFI(regionOp, invertCoverage);
170 return SkRef(&gRevDiffCDXPFI);
171 } else {
172 static GrCoverageSetOpXPFactory gRevDiffCDXPF(regionOp, invertCoverage);
173 return SkRef(&gRevDiffCDXPF);
174 }
175 break;
176 }
177 default:
178 return NULL;
179 }
180}
181
bsalomon50785a32015-02-06 07:02:37 -0800182GrXferProcessor*
183GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI,
184 const GrProcOptInfo& covPOI,
185 const GrDeviceCoordTexture* dstCopy) const {
egdaniel87509242014-12-17 13:37:13 -0800186 return GrCoverageSetOpXP::Create(fRegionOp, fInvertCoverage);
187}
188
egdaniel9e4ecdc2014-12-18 12:44:55 -0800189void GrCoverageSetOpXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI,
190 const GrProcOptInfo& coveragePOI,
egdaniel9e4ecdc2014-12-18 12:44:55 -0800191 GrXPFactory::InvariantOutput* output) const {
192 if (SkRegion::kReplace_Op == fRegionOp) {
193 if (coveragePOI.isSolidWhite()) {
194 output->fBlendedColor = GrColor_WHITE;
195 output->fBlendedColorFlags = kRGBA_GrColorComponentFlags;
egdaniel87509242014-12-17 13:37:13 -0800196 } else {
egdaniel9e4ecdc2014-12-18 12:44:55 -0800197 output->fBlendedColorFlags = 0;
egdaniel87509242014-12-17 13:37:13 -0800198 }
egdaniel9e4ecdc2014-12-18 12:44:55 -0800199
egdaniel71e236c2015-01-20 06:34:51 -0800200 output->fWillBlendWithDst = false;
egdaniel9e4ecdc2014-12-18 12:44:55 -0800201 } else {
202 output->fBlendedColorFlags = 0;
203 output->fWillBlendWithDst = true;
egdaniel87509242014-12-17 13:37:13 -0800204 }
egdaniel87509242014-12-17 13:37:13 -0800205}
206
egdaniel87509242014-12-17 13:37:13 -0800207GR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory);
208
209GrXPFactory* GrCoverageSetOpXPFactory::TestCreate(SkRandom* random,
210 GrContext*,
211 const GrDrawTargetCaps&,
212 GrTexture*[]) {
213 SkRegion::Op regionOp = SkRegion::Op(random->nextULessThan(SkRegion::kLastOp + 1));
214 bool invertCoverage = random->nextBool();
215 return GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage);
216}
217