OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrFragmentProcessor.h" | 9 #include "GrFragmentProcessor.h" |
10 #include "GrCoordTransform.h" | 10 #include "GrCoordTransform.h" |
11 #include "gl/builders/GrGLProgramBuilder.h" | |
egdaniel
2015/09/25 20:01:55
this should go below the gl/*.cpp
bsalomon
2015/09/25 20:45:07
ok
| |
11 #include "gl/GrGLFragmentProcessor.h" | 12 #include "gl/GrGLFragmentProcessor.h" |
12 #include "effects/GrXfermodeFragmentProcessor.h" | 13 #include "effects/GrXfermodeFragmentProcessor.h" |
13 | 14 |
14 GrFragmentProcessor::~GrFragmentProcessor() { | 15 GrFragmentProcessor::~GrFragmentProcessor() { |
15 // If we got here then our ref count must have reached zero, so we will have converted refs | 16 // If we got here then our ref count must have reached zero, so we will have converted refs |
16 // to pending executions for all children. | 17 // to pending executions for all children. |
17 for (int i = 0; i < fChildProcessors.count(); ++i) { | 18 for (int i = 0; i < fChildProcessors.count(); ++i) { |
18 fChildProcessors[i]->completedExecution(); | 19 fChildProcessors[i]->completedExecution(); |
19 } | 20 } |
20 } | 21 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 } | 116 } |
116 int count = this->numTransforms(); | 117 int count = this->numTransforms(); |
117 for (int i = 0; i < count; ++i) { | 118 for (int i = 0; i < count; ++i) { |
118 if (this->coordTransform(i) != that.coordTransform(i)) { | 119 if (this->coordTransform(i) != that.coordTransform(i)) { |
119 return false; | 120 return false; |
120 } | 121 } |
121 } | 122 } |
122 return true; | 123 return true; |
123 } | 124 } |
124 | 125 |
125 const GrFragmentProcessor* GrFragmentProcessor::MulOuputByInputAlpha( | 126 const GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputAlpha( |
126 const GrFragmentProcessor* fp) { | 127 const GrFragmentProcessor* fp) { |
128 if (!fp) { | |
129 return nullptr; | |
130 } | |
127 return GrXfermodeFragmentProcessor::CreateFromDstProcessor(fp, SkXfermode::k DstIn_Mode); | 131 return GrXfermodeFragmentProcessor::CreateFromDstProcessor(fp, SkXfermode::k DstIn_Mode); |
128 } | 132 } |
129 | 133 |
134 const GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputUnpremulColor( | |
135 const GrFragmentProcessor* fp) { | |
136 | |
137 class PremulFragmentProcessor : public GrFragmentProcessor { | |
138 public: | |
139 PremulFragmentProcessor(const GrFragmentProcessor* processor) { | |
140 this->initClassID<PremulFragmentProcessor>(); | |
141 this->registerChildProcessor(processor); | |
142 } | |
143 | |
144 const char* name() const override { return "Premultiply"; } | |
145 | |
146 private: | |
147 GrGLFragmentProcessor* onCreateGLInstance() const override { | |
148 class GLFP : public GrGLFragmentProcessor { | |
149 public: | |
150 GLFP() {} | |
151 | |
152 void emitCode(EmitArgs& args) override { | |
153 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentS haderBuilder(); | |
154 this->emitChild(0, nullptr, args); | |
155 fsBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColo r, | |
156 args.fInputColor ); | |
157 fsBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, arg s.fInputColor); | |
158 } | |
159 | |
160 private: | |
161 typedef GrGLFragmentProcessor INHERITED; | |
162 }; | |
163 return new GLFP; | |
164 } | |
165 | |
166 void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) cons t override {} | |
167 | |
168 bool onIsEqual(const GrFragmentProcessor&) const override { return true; } | |
169 | |
170 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { | |
171 // TODO: Add a helper to GrInvariantOutput that handles multiplying by color with flags? | |
172 if (!(inout->validFlags() & kA_GrColorComponentFlag)) { | |
173 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); | |
174 return; | |
175 } | |
176 | |
177 GrInvariantOutput childOutput(GrColor_WHITE, kRGBA_GrColorComponentF lags, false); | |
178 this->childProcessor(0).computeInvariantOutput(&childOutput); | |
179 | |
180 if (0 == GrColorUnpackA(inout->color()) || 0 == GrColorUnpackA(child Output.color())) { | |
181 inout->mulByKnownFourComponents(0x0); | |
182 return; | |
183 } | |
184 GrColorComponentFlags commonFlags = childOutput.validFlags() & inout ->validFlags(); | |
185 GrColor c0 = GrPremulColor(inout->color()); | |
186 GrColor c1 = childOutput.color(); | |
187 GrColor color = 0x0; | |
188 if (commonFlags & kR_GrColorComponentFlag) { | |
189 color |= SkMulDiv255Round(GrColorUnpackR(c0), GrColorUnpackR(c1) ) << | |
190 GrColor_SHIFT_R; | |
191 } | |
192 if (commonFlags & kG_GrColorComponentFlag) { | |
193 color |= SkMulDiv255Round(GrColorUnpackG(c0), GrColorUnpackG(c1) ) << | |
194 GrColor_SHIFT_G; | |
195 } | |
196 if (commonFlags & kB_GrColorComponentFlag) { | |
197 color |= SkMulDiv255Round(GrColorUnpackB(c0), GrColorUnpackB(c1) ) << | |
198 GrColor_SHIFT_B; | |
199 } | |
200 inout->setToOther(commonFlags, color, GrInvariantOutput::kWill_ReadI nput); | |
201 } | |
202 | |
203 typedef GrFragmentProcessor INHERITED; | |
204 }; | |
205 if (!fp) { | |
206 return nullptr; | |
207 } | |
208 return new PremulFragmentProcessor(fp); | |
209 } | |
210 | |
211 ////////////////////////////////////////////////////////////////////////////// | |
212 | |
213 const GrFragmentProcessor* GrFragmentProcessor::ReplaceInput(const GrFragmentPro cessor* fp, | |
214 GrColor color) { | |
215 class ReplaceInputFragmentProcessor : public GrFragmentProcessor { | |
216 public: | |
217 ReplaceInputFragmentProcessor(const GrFragmentProcessor* child, GrColor color) | |
218 : fColor(color) { | |
219 this->initClassID<ReplaceInputFragmentProcessor>(); | |
220 this->registerChildProcessor(child); | |
221 } | |
222 | |
223 const char* name() const override { return "Replace Color"; } | |
224 | |
225 GrGLFragmentProcessor* onCreateGLInstance() const override { | |
226 class GLFP : public GrGLFragmentProcessor { | |
227 public: | |
228 GLFP() : fHaveSetColor(false) {} | |
229 void emitCode(EmitArgs& args) override { | |
230 const char* colorName; | |
231 fColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kF ragment_Visibility, | |
232 kVec4f_GrSLType, kDefa ult_GrSLPrecision, | |
233 "Color", &colorName); | |
234 this->emitChild(0, colorName, args); | |
235 } | |
236 | |
237 private: | |
238 void onSetData(const GrGLProgramDataManager& pdman, | |
239 const GrProcessor& fp) override { | |
240 GrColor color = fp.cast<ReplaceInputFragmentProcessor>().fCo lor; | |
241 if (!fHaveSetColor || color != fPreviousColor) { | |
242 static const GrGLfloat scale = 1.f / 255.f; | |
243 GrGLfloat floatColor[4] = { | |
244 GrColorUnpackR(color) * scale, | |
245 GrColorUnpackG(color) * scale, | |
246 GrColorUnpackB(color) * scale, | |
247 GrColorUnpackA(color) * scale, | |
248 }; | |
249 pdman.set4fv(fColorUni, 1, floatColor); | |
250 fPreviousColor = color; | |
251 fHaveSetColor = true; | |
252 } | |
253 } | |
254 | |
255 GrGLProgramDataManager::UniformHandle fColorUni; | |
256 bool fHaveSetColor; | |
257 GrColor fPreviousColor; | |
258 | |
259 typedef GrGLFragmentProcessor INHERITED; | |
260 }; | |
261 | |
262 return new GLFP; | |
263 } | |
264 | |
265 private: | |
266 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {} | |
267 | |
268 bool onIsEqual(const GrFragmentProcessor& that) const override { | |
269 return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor; | |
270 } | |
271 | |
272 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { | |
273 inout->setToOther(kRGBA_GrColorComponentFlags, fColor, | |
274 GrInvariantOutput::kWillNot_ReadInput); | |
275 this->childProcessor(0).computeInvariantOutput(inout); | |
276 } | |
277 | |
278 GrColor fColor; | |
279 | |
280 typedef GrFragmentProcessor INHERITED; | |
281 }; | |
282 | |
283 GrInvariantOutput childOut(0x0, kNone_GrColorComponentFlags, false); | |
284 fp->computeInvariantOutput(&childOut); | |
285 if (childOut.willUseInputColor()) { | |
286 return new ReplaceInputFragmentProcessor(fp, color); | |
287 } else { | |
288 return SkRef(fp); | |
289 } | |
290 } | |
OLD | NEW |