Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Side by Side Diff: src/effects/SkColorFilters.cpp

Issue 25023003: Implement color filter as GrGLEffect (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix a small thinko Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/gpu/GrPaint.h ('k') | src/gpu/GrDrawState.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « include/gpu/GrPaint.h ('k') | src/gpu/GrDrawState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698