OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
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 | 9 |
10 #include "SkBlitRow.h" | 10 #include "SkBlitRow.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 | 78 |
79 #ifdef SK_DEVELOPER | 79 #ifdef SK_DEVELOPER |
80 virtual void toString(SkString* str) const SK_OVERRIDE { | 80 virtual void toString(SkString* str) const SK_OVERRIDE { |
81 str->append("SkModeColorFilter: color: 0x"); | 81 str->append("SkModeColorFilter: color: 0x"); |
82 str->appendHex(fColor); | 82 str->appendHex(fColor); |
83 str->append(" mode: "); | 83 str->append(" mode: "); |
84 str->append(SkXfermode::ModeName(fMode)); | 84 str->append(SkXfermode::ModeName(fMode)); |
85 } | 85 } |
86 #endif | 86 #endif |
87 | 87 |
88 #if SK_SUPPORT_GPU | |
89 virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE; | |
90 #endif | |
88 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter) | 91 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter) |
89 | 92 |
90 protected: | 93 protected: |
91 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { | 94 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { |
92 this->INHERITED::flatten(buffer); | 95 this->INHERITED::flatten(buffer); |
93 buffer.writeColor(fColor); | 96 buffer.writeColor(fColor); |
94 buffer.writeUInt(fMode); | 97 buffer.writeUInt(fMode); |
95 } | 98 } |
96 | 99 |
97 SkModeColorFilter(SkFlattenableReadBuffer& buffer) { | 100 SkModeColorFilter(SkFlattenableReadBuffer& buffer) { |
(...skipping 12 matching lines...) Expand all Loading... | |
110 | 113 |
111 void updateCache() { | 114 void updateCache() { |
112 fPMColor = SkPreMultiplyColor(fColor); | 115 fPMColor = SkPreMultiplyColor(fColor); |
113 fProc = SkXfermode::GetProc(fMode); | 116 fProc = SkXfermode::GetProc(fMode); |
114 fProc16 = SkXfermode::GetProc16(fMode, fColor); | 117 fProc16 = SkXfermode::GetProc16(fMode, fColor); |
115 } | 118 } |
116 | 119 |
117 typedef SkColorFilter INHERITED; | 120 typedef SkColorFilter INHERITED; |
118 }; | 121 }; |
119 | 122 |
123 /////////////////////////////////////////////////////////////////////////////// | |
124 #if SK_SUPPORT_GPU | |
125 #include "GrBlend.h" | |
126 #include "GrEffect.h" | |
127 #include "GrEffectUnitTest.h" | |
128 #include "GrTBackendEffectFactory.h" | |
129 #include "gl/GrGLEffect.h" | |
130 #include "gl/GrGLEffectMatrix.h" | |
131 #include "SkGr.h" | |
132 | |
133 namespace { | |
134 /** | |
135 * A definition of blend equation for one coefficient. Generates a | |
136 * blend_coeff * value "expression". | |
137 */ | |
138 template<typename ColorExpr> | |
139 static inline ColorExpr blend_term(SkXfermode::Coeff coeff, | |
140 const ColorExpr& src, | |
141 const ColorExpr& dst, | |
142 const ColorExpr& value) { | |
143 switch (coeff) { | |
144 default: | |
145 GrCrash("Unexpected xfer coeff."); | |
146 case SkXfermode::kZero_Coeff: /** 0 */ | |
147 return ColorExpr(0); | |
148 case SkXfermode::kOne_Coeff: /** 1 */ | |
149 return value; | |
150 case SkXfermode::kSC_Coeff: | |
151 return src * value; | |
152 case SkXfermode::kISC_Coeff: | |
153 return (1 - src) * dst; | |
154 case SkXfermode::kDC_Coeff: | |
155 return dst * value; | |
156 case SkXfermode::kIDC_Coeff: | |
157 return (1 - dst) * value; | |
158 case SkXfermode::kSA_Coeff: /** src alpha */ | |
159 return value * src.a(); | |
160 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ | |
161 return value * (1 - src.a()); | |
162 case SkXfermode::kDA_Coeff: /** dst alpha */ | |
163 return value * dst.a(); | |
164 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ | |
165 return value * (1 - dst.a()); | |
166 } | |
167 } | |
168 /** | |
169 * Creates a color filter expression which modifies the color by | |
170 * the specified color filter. | |
171 */ | |
172 template <typename ColorExpr> | |
173 static inline ColorExpr color_filter_expression(SkXfermode::Mode mode, | |
174 const ColorExpr& filterColor, | |
175 const ColorExpr& inColor) { | |
176 SkXfermode::Coeff colorCoeff; | |
177 SkXfermode::Coeff filterColorCoeff; | |
178 SkAssertResult(SkXfermode::ModeAsCoeff(mode, &filterColorCoeff, &colorCoeff) ); | |
179 return blend_term(colorCoeff, filterColor, inColor, inColor) + | |
180 blend_term(filterColorCoeff, filterColor, inColor, filterColor); | |
181 } | |
182 } | |
183 | |
184 class ModeColorFilterEffect : public GrEffect { | |
185 public: | |
186 static GrEffectRef* Create(const GrColor& c, SkXfermode::Mode mode) { | |
187 AutoEffectUnref effect(SkNEW_ARGS(ModeColorFilterEffect, (c, mode))); | |
188 return CreateEffectRef(effect); | |
189 } | |
190 | |
191 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE; | |
192 | |
193 virtual bool willUseInputColor() const { | |
194 SkXfermode::Coeff dstCoeff; | |
195 SkXfermode::Coeff srcCoeff; | |
196 SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff)); | |
197 // These could be calculated from the blend equation with template trick ery.. | |
198 if (SkXfermode::kZero_Coeff == dstCoeff) { | |
199 return GrBlendCoeffRefsDst(sk_blend_to_grblend(srcCoeff)); | |
200 } | |
201 return true; | |
202 } | |
203 | |
204 bool willUseFilterColor() const { | |
205 SkXfermode::Coeff dstCoeff; | |
206 SkXfermode::Coeff srcCoeff; | |
207 SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff)); | |
208 if (SkXfermode::kZero_Coeff == srcCoeff) { | |
209 return GrBlendCoeffRefsSrc(sk_blend_to_grblend(dstCoeff)); | |
210 } | |
211 return true; | |
212 } | |
213 | |
214 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | |
215 return GrTBackendEffectFactory<ModeColorFilterEffect>::getInstance(); | |
216 } | |
217 | |
218 static const char* Name() { return "ModeColorFilterEffect"; } | |
219 | |
220 SkXfermode::Mode mode() const { return fMode; } | |
221 GrColor color() const { return fColor; } | |
222 | |
223 class GLEffect : public GrGLEffect { | |
224 public: | |
225 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | |
226 : INHERITED(factory) { | |
227 } | |
228 | |
229 virtual void emitCode(GrGLShaderBuilder* builder, | |
230 const GrDrawEffect& drawEffect, | |
231 EffectKey key, | |
232 const char* outputColor, | |
233 const char* inputColor, | |
234 const TextureSamplerArray& samplers) SK_OVERRIDE { | |
235 SkXfermode::Mode mode = drawEffect.castEffect<ModeColorFilterEffect> ().mode(); | |
236 | |
237 SkASSERT(SkXfermode::kDst_Mode != mode); | |
238 const char* colorFilterColorUniName = NULL; | |
239 if (drawEffect.castEffect<ModeColorFilterEffect>().willUseFilterColo r()) { | |
240 fFilterColorUni = builder->addUniform(GrGLShaderBuilder::kFragme nt_Visibility, | |
241 kVec4f_GrSLType, "FilterCo lor", | |
242 &colorFilterColorUniName); | |
243 } | |
244 | |
245 GrGLSLExpr<4> filter = color_filter_expression(mode, | |
246 GrGLSLExpr<4>(colorFi lterColorUniName), | |
247 GrGLSLExpr<4>(inputCo lor)); | |
248 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, filter.c_str()); | |
249 } | |
250 | |
251 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { | |
252 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect <ModeColorFilterEffect>(); | |
253 // The SL code does not depend on filter color at the moment, so no need to represent it | |
254 // in the key. | |
255 EffectKey modeKey = colorModeFilter.mode(); | |
256 return modeKey; | |
257 } | |
258 | |
259 virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) SK_OVERRIDE { | |
260 if (fFilterColorUni.isValid()) { | |
261 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEf fect<ModeColorFilterEffect>(); | |
262 GrGLfloat c[4]; | |
263 GrColorToRGBAFloat(colorModeFilter.color(), c); | |
264 uman.set4fv(fFilterColorUni, 0, 1, c); | |
265 } | |
266 } | |
267 | |
268 private: | |
269 | |
270 static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsT ype; | |
271 GrGLUniformManager::UniformHandle fFilterColorUni; | |
272 typedef GrGLEffect INHERITED; | |
273 }; | |
274 | |
275 GR_DECLARE_EFFECT_TEST; | |
276 | |
277 private: | |
278 ModeColorFilterEffect(GrColor color, SkXfermode::Mode mode) | |
279 : fMode(mode), | |
280 fColor(color) { | |
281 } | |
282 | |
283 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | |
284 const ModeColorFilterEffect& s = CastEffect<ModeColorFilterEffect>(other ); | |
285 return fMode == s.fMode && fColor == s.fColor; | |
286 } | |
287 | |
288 SkXfermode::Mode fMode; | |
289 GrColor fColor; | |
290 | |
291 typedef GrEffect INHERITED; | |
292 }; | |
293 | |
294 namespace { | |
295 /** MaskedColorExpr is used to evaluate the color and valid color component | |
296 * flags through the blending equation. | |
297 */ | |
298 class MaskedColorExpr { | |
299 public: | |
300 MaskedColorExpr(const GrGLfloat color[], uint32_t flags) | |
301 : fFlags(flags) { | |
302 fColor[0] = color[0]; | |
303 fColor[1] = color[1]; | |
304 fColor[2] = color[2]; | |
305 fColor[3] = color[3]; | |
306 } | |
307 MaskedColorExpr(float v) | |
308 : fFlags(kRGBA_GrColorComponentFlags) { | |
309 fColor[0] = v; | |
310 fColor[1] = v; | |
311 fColor[2] = v; | |
312 fColor[3] = v; | |
313 } | |
314 | |
315 MaskedColorExpr operator*(const MaskedColorExpr& other) const { | |
316 GrGLfloat tmp[4]; | |
317 tmp[0] = GrMax(0.f, GrMin(1.f, fColor[0] * other.fColor[0])); | |
318 tmp[1] = GrMax(0.f, GrMin(1.f, fColor[1] * other.fColor[1])); | |
319 tmp[2] = GrMax(0.f, GrMin(1.f, fColor[2] * other.fColor[2])); | |
320 tmp[3] = GrMax(0.f, GrMin(1.f, fColor[3] * other.fColor[3])); | |
321 | |
322 return MaskedColorExpr(tmp, fFlags & other.fFlags); | |
323 } | |
324 | |
325 MaskedColorExpr operator+(const MaskedColorExpr& other) const { | |
326 GrGLfloat tmp[4]; | |
327 tmp[0] = GrMax(0.f, GrMin(1.f, fColor[0] + other.fColor[0])); | |
328 tmp[1] = GrMax(0.f, GrMin(1.f, fColor[1] + other.fColor[1])); | |
329 tmp[2] = GrMax(0.f, GrMin(1.f, fColor[2] + other.fColor[2])); | |
330 tmp[3] = GrMax(0.f, GrMin(1.f, fColor[3] + other.fColor[3])); | |
331 | |
332 return MaskedColorExpr(tmp, fFlags & other.fFlags); | |
333 } | |
334 | |
335 MaskedColorExpr operator-(const MaskedColorExpr& other) const { | |
336 GrGLfloat tmp[4]; | |
337 tmp[0] = GrMax(0.f, GrMin(1.f, fColor[0] - other.fColor[0])); | |
338 tmp[1] = GrMax(0.f, GrMin(1.f, fColor[1] - other.fColor[1])); | |
339 tmp[2] = GrMax(0.f, GrMin(1.f, fColor[2] - other.fColor[2])); | |
340 tmp[3] = GrMax(0.f, GrMin(1.f, fColor[3] - other.fColor[3])); | |
341 | |
342 return MaskedColorExpr(tmp, fFlags & other.fFlags); | |
343 } | |
344 | |
345 MaskedColorExpr a() const { | |
346 return MaskedColorExpr(fColor[3]); | |
347 } | |
348 | |
349 GrColor getColor() const { | |
350 return GrColorPackRGBA(fColor[0] * 255.f, fColor[1] * 255.f, | |
351 fColor[2] * 255.f, fColor[3] * 255.f); | |
352 } | |
353 | |
354 uint32_t getValidComponents() const { return fFlags; } | |
355 | |
356 private: | |
357 GrGLfloat fColor[4]; | |
358 uint32_t fFlags; | |
359 }; | |
360 | |
361 MaskedColorExpr operator-(int v, const MaskedColorExpr& other) { | |
362 return MaskedColorExpr(v) - other; | |
363 } | |
364 } | |
365 | |
366 void ModeColorFilterEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { | |
Kimmo Kinnunen
2013/10/01 12:55:46
Btw: It'd be great to be able to unit test these s
| |
367 GrGLfloat inputColor[4]; | |
368 GrColorToRGBAFloat(*color, inputColor); | |
369 GrGLfloat filterColor[4]; | |
370 GrColorToRGBAFloat(fColor, filterColor); | |
371 MaskedColorExpr result = | |
372 color_filter_expression(fMode, | |
373 MaskedColorExpr(filterColor, kRGBA_GrColorCompon entFlags), | |
374 MaskedColorExpr(inputColor, *validFlags)); | |
375 | |
376 *color = result.getColor(); | |
377 *validFlags = result.getValidComponents(); | |
378 } | |
379 | |
380 GR_DEFINE_EFFECT_TEST(ModeColorFilterEffect); | |
381 GrEffectRef* ModeColorFilterEffect::TestCreate(SkRandom* rand, | |
382 GrContext*, | |
383 const GrDrawTargetCaps&, | |
384 GrTexture*[]) { | |
385 int mode = rand->nextRangeU(0, SkXfermode::kLastCoeffMode); | |
386 GrColor color = rand->nextU(); | |
387 static AutoEffectUnref gEffect(SkNEW_ARGS(ModeColorFilterEffect, (color, sta tic_cast<SkXfermode::Mode>(mode)))); | |
388 return CreateEffectRef(gEffect); | |
389 } | |
390 | |
391 GrEffectRef* SkModeColorFilter::asNewEffect(GrContext*) const { | |
392 if (SkXfermode::kDst_Mode != fMode) { | |
393 return ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode); | |
394 } | |
395 return NULL; | |
396 } | |
397 | |
398 #endif | |
399 | |
400 /////////////////////////////////////////////////////////////////////////////// | |
401 | |
120 class Src_SkModeColorFilter : public SkModeColorFilter { | 402 class Src_SkModeColorFilter : public SkModeColorFilter { |
121 public: | 403 public: |
122 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod e) {} | 404 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod e) {} |
123 | 405 |
124 virtual uint32_t getFlags() const SK_OVERRIDE { | 406 virtual uint32_t getFlags() const SK_OVERRIDE { |
125 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { | 407 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { |
126 return kAlphaUnchanged_Flag | kHasFilter16_Flag; | 408 return kAlphaUnchanged_Flag | kHasFilter16_Flag; |
127 } else { | 409 } else { |
128 return 0; | 410 return 0; |
129 } | 411 } |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
538 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) | 820 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) |
539 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) | 821 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) |
540 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) | 822 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) |
541 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) | 823 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) |
542 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) | 824 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) |
543 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) | 825 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) |
544 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) | 826 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) |
545 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) | 827 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) |
546 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) | 828 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) |
547 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 829 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |