OLD | NEW |
---|---|
(Empty) | |
1 | |
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" | |
12 #include "GrInvariantOutput.h" | |
13 #include "GrProcessor.h" | |
14 #include "GrProcOptInfo.h" | |
15 #include "gl/GrGLXferProcessor.h" | |
16 #include "gl/builders/GrGLFragmentShaderBuilder.h" | |
17 #include "gl/builders/GrGLProgramBuilder.h" | |
18 | |
19 class GrGLCoverageSetOpXP : public GrGLXferProcessor { | |
20 public: | |
21 GrGLCoverageSetOpXP(const GrProcessor&) {} | |
22 | |
23 virtual ~GrGLCoverageSetOpXP() {} | |
24 | |
25 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { | |
26 const GrCoverageSetOpXP& xp = args.fXP.cast<GrCoverageSetOpXP>(); | |
27 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | |
28 | |
29 if (xp.invertCoverage()) { | |
30 fsBuilder->codeAppendf("%s = 1.0 - %s;", args.fOutputPrimary, args.f InputCoverage); | |
31 } else { | |
32 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputC overage); | |
33 } | |
34 } | |
35 | |
36 virtual void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}; | |
37 | |
bsalomon
2014/12/16 17:35:56
don't need virtuals on these overrides. Also can d
egdaniel
2014/12/17 21:12:37
Done.
| |
38 static void GenKey(const GrProcessor& processor, const GrGLCaps& caps, | |
39 GrProcessorKeyBuilder* b) { | |
40 const GrCoverageSetOpXP& xp = processor.cast<GrCoverageSetOpXP>(); | |
41 uint32_t key = xp.invertCoverage() ? 0x0 : 0x1; | |
42 b->add32(key); | |
43 }; | |
44 | |
45 private: | |
46 typedef GrGLXferProcessor INHERITED; | |
47 }; | |
48 | |
49 /////////////////////////////////////////////////////////////////////////////// | |
50 | |
51 GrCoverageSetOpXP::GrCoverageSetOpXP(SkRegion::Op regionOp, bool invertCoverage) | |
52 : fRegionOp(regionOp) | |
53 , fInvertCoverage(invertCoverage) { | |
54 this->initClassID<GrCoverageSetOpXP>(); | |
55 } | |
56 | |
57 GrCoverageSetOpXP::~GrCoverageSetOpXP() { | |
58 } | |
59 | |
60 void GrCoverageSetOpXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBu ilder* b) const { | |
61 GrGLCoverageSetOpXP::GenKey(*this, caps, b); | |
62 } | |
63 | |
64 GrGLXferProcessor* GrCoverageSetOpXP::createGLInstance() const { | |
65 return SkNEW_ARGS(GrGLCoverageSetOpXP, (*this)); | |
66 } | |
67 | |
68 GrXferProcessor::OptFlags | |
69 GrCoverageSetOpXP::getOptimizations(const GrProcOptInfo& colorPOI, | |
70 const GrProcOptInfo& coveragePOI, | |
71 bool colorWriteDisabled, | |
72 bool doesStencilWrite, | |
73 GrColor* color, | |
74 const GrDrawTargetCaps& caps) { | |
75 // We never look at the color input | |
76 return GrXferProcessor::kIgnoreColor_OptFlag; | |
77 } | |
78 | |
79 void GrCoverageSetOpXP::getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) cons t { | |
80 switch (fRegionOp) { | |
81 case SkRegion::kReplace_Op: | |
82 blendInfo->fSrcBlend = kOne_GrBlendCoeff; | |
83 blendInfo->fDstBlend = kZero_GrBlendCoeff; | |
84 break; | |
85 case SkRegion::kIntersect_Op: | |
86 blendInfo->fSrcBlend = kDC_GrBlendCoeff; | |
87 blendInfo->fDstBlend = kZero_GrBlendCoeff; | |
88 break; | |
89 case SkRegion::kUnion_Op: | |
90 blendInfo->fSrcBlend = kOne_GrBlendCoeff; | |
91 blendInfo->fDstBlend = kISC_GrBlendCoeff; | |
92 break; | |
93 case SkRegion::kXOR_Op: | |
94 blendInfo->fSrcBlend = kIDC_GrBlendCoeff; | |
95 blendInfo->fDstBlend = kISC_GrBlendCoeff; | |
96 break; | |
97 case SkRegion::kDifference_Op: | |
98 blendInfo->fSrcBlend = kZero_GrBlendCoeff; | |
99 blendInfo->fDstBlend = kISC_GrBlendCoeff; | |
100 break; | |
101 case SkRegion::kReverseDifference_Op: | |
102 blendInfo->fSrcBlend = kIDC_GrBlendCoeff; | |
103 blendInfo->fDstBlend = kZero_GrBlendCoeff; | |
104 break; | |
105 default: | |
bsalomon
2014/12/16 17:35:56
If you've exhausted all the possible values for k*
egdaniel
2014/12/17 21:12:37
Done.
| |
106 SkASSERT(false); | |
107 break; | |
108 } | |
109 blendInfo->fBlendConstant = 0; | |
110 } | |
111 | |
112 /////////////////////////////////////////////////////////////////////////////// | |
113 | |
114 GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool i nvertCoverage) | |
115 : fRegionOp(regionOp) | |
116 , fInvertCoverage(invertCoverage) { | |
117 this->initClassID<GrCoverageSetOpXPFactory>(); | |
118 } | |
119 | |
120 GrXPFactory* GrCoverageSetOpXPFactory::Create(SkRegion::Op regionOp, bool invert Coverage) { | |
121 switch (regionOp) { | |
122 case SkRegion::kReplace_Op: { | |
123 if (invertCoverage) { | |
124 static GrCoverageSetOpXPFactory gReplaceCDXPFI(regionOp, invertC overage); | |
125 return SkRef(&gReplaceCDXPFI); | |
126 } else { | |
127 static GrCoverageSetOpXPFactory gReplaceCDXPF(regionOp, invertCo verage); | |
128 return SkRef(&gReplaceCDXPF); | |
129 } | |
130 break; | |
131 } | |
132 case SkRegion::kIntersect_Op: { | |
133 if (invertCoverage) { | |
134 static GrCoverageSetOpXPFactory gIntersectCDXPFI(regionOp, inver tCoverage); | |
135 return SkRef(&gIntersectCDXPFI); | |
136 } else { | |
137 static GrCoverageSetOpXPFactory gIntersectCDXPF(regionOp, invert Coverage); | |
138 return SkRef(&gIntersectCDXPF); | |
139 } | |
140 break; | |
141 } | |
142 case SkRegion::kUnion_Op: { | |
143 if (invertCoverage) { | |
144 static GrCoverageSetOpXPFactory gUnionCDXPFI(regionOp, invertCov erage); | |
145 return SkRef(&gUnionCDXPFI); | |
146 } else { | |
147 static GrCoverageSetOpXPFactory gUnionCDXPF(regionOp, invertCove rage); | |
148 return SkRef(&gUnionCDXPF); | |
149 } | |
150 break; | |
151 } | |
152 case SkRegion::kXOR_Op: { | |
153 if (invertCoverage) { | |
154 static GrCoverageSetOpXPFactory gXORCDXPFI(regionOp, invertCover age); | |
155 return SkRef(&gXORCDXPFI); | |
156 } else { | |
157 static GrCoverageSetOpXPFactory gXORCDXPF(regionOp, invertCovera ge); | |
158 return SkRef(&gXORCDXPF); | |
159 } | |
160 break; | |
161 } | |
162 case SkRegion::kDifference_Op: { | |
163 if (invertCoverage) { | |
164 static GrCoverageSetOpXPFactory gDifferenceCDXPFI(regionOp, inve rtCoverage); | |
165 return SkRef(&gDifferenceCDXPFI); | |
166 } else { | |
167 static GrCoverageSetOpXPFactory gDifferenceCDXPF(regionOp, inver tCoverage); | |
168 return SkRef(&gDifferenceCDXPF); | |
169 } | |
170 break; | |
171 } | |
172 case SkRegion::kReverseDifference_Op: { | |
173 if (invertCoverage) { | |
174 static GrCoverageSetOpXPFactory gRevDiffCDXPFI(regionOp, invertC overage); | |
175 return SkRef(&gRevDiffCDXPFI); | |
176 } else { | |
177 static GrCoverageSetOpXPFactory gRevDiffCDXPF(regionOp, invertCo verage); | |
178 return SkRef(&gRevDiffCDXPF); | |
179 } | |
180 break; | |
181 } | |
182 default: | |
183 return NULL; | |
184 } | |
185 } | |
186 | |
187 GrXferProcessor* GrCoverageSetOpXPFactory::createXferProcessor(const GrProcOptIn fo& /* colorPOI*/, | |
188 const GrProcOptIn fo& covPOI) const { | |
189 if (!covPOI.isFourChannelOutput()) { | |
190 return GrCoverageSetOpXP::Create(fRegionOp, fInvertCoverage); | |
191 } else { | |
192 return NULL; | |
193 } | |
194 } | |
195 | |
196 bool GrCoverageSetOpXPFactory::willBlendWithDst(const GrProcOptInfo& colorPOI, | |
197 const GrProcOptInfo& coveragePOI , | |
198 bool colorWriteDisabled) const { | |
199 // TODO: once all SkXferEffects are XP's then we will never reads dst here s ince only XP's | |
200 // will readDst and this XP doesn't read dst. | |
201 if (coveragePOI.readsDst()) { | |
202 return true; | |
203 } | |
204 | |
205 // Besides Replace all other SkRegion ops will either have a src coeff that references dst or a | |
206 // non zero dst coeff | |
207 return SkRegion::kReplace_Op != fRegionOp; | |
208 } | |
209 | |
210 bool GrCoverageSetOpXPFactory::getOpaqueAndKnownColor(const GrProcOptInfo& color POI, | |
bsalomon
2014/12/16 17:35:56
This is kind of confusing now that we have a cover
egdaniel
2014/12/17 21:12:37
As per our conversation, I will clean up these fun
| |
211 const GrProcOptInfo& cover agePOI, | |
212 GrColor* solidColor, | |
213 uint32_t* solidColorKnownC omponents) const { | |
214 if (!coveragePOI.isSolidWhite()) { | |
215 return false; | |
216 } | |
217 | |
218 SkASSERT((NULL == solidColor) == (NULL == solidColorKnownComponents)); | |
219 | |
220 bool opaque = SkRegion::kReplace_Op == fRegionOp; | |
221 if (solidColor) { | |
222 if (opaque) { | |
223 *solidColor = GrColor_WHITE; | |
224 *solidColorKnownComponents = kRGBA_GrColorComponentFlags; | |
225 } else { | |
226 solidColorKnownComponents = 0; | |
227 } | |
228 } | |
229 return opaque; | |
230 } | |
231 | |
232 GR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory); | |
233 | |
234 GrXPFactory* GrCoverageSetOpXPFactory::TestCreate(SkRandom* random, | |
235 GrContext*, | |
236 const GrDrawTargetCaps&, | |
237 GrTexture*[]) { | |
238 SkRegion::Op regionOp = SkRegion::Op(random->nextULessThan(SkRegion::kLastOp + 1)); | |
239 bool invertCoverage = random->nextBool(); | |
240 return GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage); | |
241 } | |
242 | |
OLD | NEW |