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

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: rebase 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
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 "SkGr.h"
131
132 namespace {
133 /**
134 * A definition of blend equation for one coefficient. Generates a
135 * blend_coeff * value "expression".
136 */
137 template<typename ColorExpr, typename AlphaExtractor>
138 static inline ColorExpr blend_term(SkXfermode::Coeff coeff,
139 const ColorExpr& src,
140 const ColorExpr& dst,
141 const ColorExpr& value,
142 const AlphaExtractor& a) {
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 * a(src);
160 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */
161 return value * (1 - a(src));
162 case SkXfermode::kDA_Coeff: /** dst alpha */
163 return value * a(dst);
164 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */
165 return value * (1 - a(dst));
166 }
167 }
168 /**
169 * Creates a color filter expression which modifies the color by
170 * the specified color filter.
171 */
172 template <typename ColorExpr, typename AlphaExtractor>
173 static inline ColorExpr color_filter_expression(const SkXfermode::Mode& mode,
174 const ColorExpr& filterColor,
175 const ColorExpr& inColor,
176 const AlphaExtractor& a) {
177 SkXfermode::Coeff colorCoeff;
178 SkXfermode::Coeff filterColorCoeff;
179 SkAssertResult(SkXfermode::ModeAsCoeff(mode, &filterColorCoeff, &colorCoeff) );
180 return blend_term(colorCoeff, filterColor, inColor, inColor, a) +
181 blend_term(filterColorCoeff, filterColor, inColor, filterColor, a);
182 }
183
184 class GrGLSLExprAlphaExtractor {
185 public:
186 GrGLSLExpr<1> operator()(const GrGLSLExpr<4>& expr) const {
187 return GrGLSLExprExtractAlpha(expr);
188 }
189 };
190
191 }
192
193 class ModeColorFilterEffect : public GrEffect {
194 public:
195 static GrEffectRef* Create(const GrColor& c, SkXfermode::Mode mode) {
196 AutoEffectUnref effect(SkNEW_ARGS(ModeColorFilterEffect, (c, mode)));
197 return CreateEffectRef(effect);
198 }
199
200 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE;
201
202 virtual bool willUseInputColor() const {
203 SkXfermode::Coeff dstCoeff;
204 SkXfermode::Coeff srcCoeff;
205 SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff));
206 // These could be calculated from the blend equation with template trick ery..
207 if (SkXfermode::kZero_Coeff == dstCoeff) {
208 return GrBlendCoeffRefsDst(sk_blend_to_grblend(srcCoeff));
209 }
210 return true;
211 }
212
213 bool willUseFilterColor() const {
214 SkXfermode::Coeff dstCoeff;
215 SkXfermode::Coeff srcCoeff;
216 SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff));
217 if (SkXfermode::kZero_Coeff == srcCoeff) {
218 return GrBlendCoeffRefsSrc(sk_blend_to_grblend(dstCoeff));
219 }
220 return true;
221 }
222
223 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
224 return GrTBackendEffectFactory<ModeColorFilterEffect>::getInstance();
225 }
226
227 static const char* Name() { return "ModeColorFilterEffect"; }
228
229 SkXfermode::Mode mode() const { return fMode; }
230 GrColor color() const { return fColor; }
231
232 class GLEffect : public GrGLEffect {
233 public:
234 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
235 : INHERITED(factory) {
236 }
237
238 virtual void emitCode(GrGLShaderBuilder* builder,
239 const GrDrawEffect& drawEffect,
240 EffectKey key,
241 const char* outputColor,
242 const char* inputColor,
243 const TransformedCoordsArray& coords,
244 const TextureSamplerArray& samplers) SK_OVERRIDE {
245 SkXfermode::Mode mode = drawEffect.castEffect<ModeColorFilterEffect> ().mode();
246
247 SkASSERT(SkXfermode::kDst_Mode != mode);
248 const char* colorFilterColorUniName = NULL;
249 if (drawEffect.castEffect<ModeColorFilterEffect>().willUseFilterColo r()) {
250 fFilterColorUni = builder->addUniform(GrGLShaderBuilder::kFragme nt_Visibility,
251 kVec4f_GrSLType, "FilterCo lor",
252 &colorFilterColorUniName);
253 }
254
255 GrGLSLExprAlphaExtractor a;
256 GrGLSLExpr<4> filter =
257 color_filter_expression<GrGLSLExpr<4>, GrGLSLExprAlphaExtractor> (mode, GrGLSLExpr<4>(colorFilterColorUniName), GrGLSLExpr<4>(inputColor), a);
258
259 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, filter.c_str());
260 }
261
262 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) {
263 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect <ModeColorFilterEffect>();
264 // The SL code does not depend on filter color at the moment, so no need to represent it
265 // in the key.
266 EffectKey modeKey = colorModeFilter.mode();
267 return modeKey;
268 }
269
270 virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) SK_OVERRIDE {
271 if (fFilterColorUni.isValid()) {
272 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEf fect<ModeColorFilterEffect>();
273 GrGLfloat c[4];
274 GrColorToRGBAFloat(colorModeFilter.color(), c);
275 uman.set4fv(fFilterColorUni, 0, 1, c);
276 }
277 }
278
279 private:
280
281 GrGLUniformManager::UniformHandle fFilterColorUni;
282 typedef GrGLEffect INHERITED;
283 };
284
285 GR_DECLARE_EFFECT_TEST;
286
287 private:
288 ModeColorFilterEffect(GrColor color, SkXfermode::Mode mode)
289 : fMode(mode),
290 fColor(color) {
291 }
292
293 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
294 const ModeColorFilterEffect& s = CastEffect<ModeColorFilterEffect>(other );
295 return fMode == s.fMode && fColor == s.fColor;
296 }
297
298 SkXfermode::Mode fMode;
299 GrColor fColor;
300
301 typedef GrEffect INHERITED;
302 };
303
304 namespace {
305
306 /** Function color_component_to_int tries to reproduce the GLSL rounding. The sp ec doesn't specify
307 * to which direction the 0.5 goes.
308 */
309 static inline int color_component_to_int(float value) {
310 return sk_float_round2int(GrMax(0.f, GrMin(1.f, value)) * 255.f);
311 }
312
313 /** MaskedColorExpr is used to evaluate the color and valid color component flag s through the
314 * blending equation. It has members similar to GrGLSLExpr so that it can be use d with the
315 * templated helpers above.
316 */
317 class MaskedColorExpr {
318 public:
319 MaskedColorExpr(const float color[], uint32_t flags)
320 : fFlags(flags) {
321 fColor[0] = color[0];
322 fColor[1] = color[1];
323 fColor[2] = color[2];
324 fColor[3] = color[3];
325 }
326
327 MaskedColorExpr(float v, uint32_t flags = kRGBA_GrColorComponentFlags)
328 : fFlags(flags) {
329 fColor[0] = v;
330 fColor[1] = v;
331 fColor[2] = v;
332 fColor[3] = v;
333 }
334
335 MaskedColorExpr operator*(const MaskedColorExpr& other) const {
336 float tmp[4];
337 tmp[0] = fColor[0] * other.fColor[0];
338 tmp[1] = fColor[1] * other.fColor[1];
339 tmp[2] = fColor[2] * other.fColor[2];
340 tmp[3] = fColor[3] * other.fColor[3];
341
342 return MaskedColorExpr(tmp, fFlags & other.fFlags);
343 }
344
345 MaskedColorExpr operator+(const MaskedColorExpr& other) const {
346 float tmp[4];
347 tmp[0] = fColor[0] + other.fColor[0];
348 tmp[1] = fColor[1] + other.fColor[1];
349 tmp[2] = fColor[2] + other.fColor[2];
350 tmp[3] = fColor[3] + other.fColor[3];
351
352 return MaskedColorExpr(tmp, fFlags & other.fFlags);
353 }
354
355 MaskedColorExpr operator-(const MaskedColorExpr& other) const {
356 float tmp[4];
357 tmp[0] = fColor[0] - other.fColor[0];
358 tmp[1] = fColor[1] - other.fColor[1];
359 tmp[2] = fColor[2] - other.fColor[2];
360 tmp[3] = fColor[3] - other.fColor[3];
361
362 return MaskedColorExpr(tmp, fFlags & other.fFlags);
363 }
364
365 MaskedColorExpr a() const {
366 uint32_t flags = (fFlags & kA_GrColorComponentFlag) ? kRGBA_GrColorCompo nentFlags : 0;
367 return MaskedColorExpr(fColor[3], flags);
368 }
369
370 GrColor getColor() const {
371 return GrColorPackRGBA(color_component_to_int(fColor[0]),
372 color_component_to_int(fColor[1]),
373 color_component_to_int(fColor[2]),
374 color_component_to_int(fColor[3]));
375 }
376
377 uint32_t getValidComponents() const { return fFlags; }
378
379 private:
380 float fColor[4];
381 uint32_t fFlags;
382 };
383
384 MaskedColorExpr operator-(int v, const MaskedColorExpr& other) {
385 return MaskedColorExpr(v) - other;
386 }
387
388 class MaskedColorExprAlphaExtractor {
389 public:
390 MaskedColorExpr operator()(const MaskedColorExpr& expr) const { return expr. a(); }
391 };
392
393 }
394
395
396 void ModeColorFilterEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
397 float inputColor[4];
398 GrColorToRGBAFloat(*color, inputColor);
399 float filterColor[4];
400 GrColorToRGBAFloat(fColor, filterColor);
401 MaskedColorExprAlphaExtractor a;
402
403 MaskedColorExpr result =
404 color_filter_expression(fMode,
405 MaskedColorExpr(filterColor, kRGBA_GrColorCompon entFlags),
406 MaskedColorExpr(inputColor, *validFlags),
407 a);
408
409 *color = result.getColor();
410 *validFlags = result.getValidComponents();
411 }
412
413 GR_DEFINE_EFFECT_TEST(ModeColorFilterEffect);
414 GrEffectRef* ModeColorFilterEffect::TestCreate(SkRandom* rand,
415 GrContext*,
416 const GrDrawTargetCaps&,
417 GrTexture*[]) {
418 int mode = rand->nextRangeU(0, SkXfermode::kLastCoeffMode);
419 GrColor color = rand->nextU();
420 static AutoEffectUnref gEffect(SkNEW_ARGS(ModeColorFilterEffect, (color, sta tic_cast<SkXfermode::Mode>(mode))));
421 return CreateEffectRef(gEffect);
422 }
423
424 GrEffectRef* SkModeColorFilter::asNewEffect(GrContext*) const {
425 if (SkXfermode::kDst_Mode != fMode) {
426 return ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode);
427 }
428 return NULL;
429 }
430
431 #endif
432
433 ///////////////////////////////////////////////////////////////////////////////
434
120 class Src_SkModeColorFilter : public SkModeColorFilter { 435 class Src_SkModeColorFilter : public SkModeColorFilter {
121 public: 436 public:
122 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod e) {} 437 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod e) {}
123 438
124 virtual uint32_t getFlags() const SK_OVERRIDE { 439 virtual uint32_t getFlags() const SK_OVERRIDE {
125 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { 440 if (SkGetPackedA32(this->getPMColor()) == 0xFF) {
126 return kAlphaUnchanged_Flag | kHasFilter16_Flag; 441 return kAlphaUnchanged_Flag | kHasFilter16_Flag;
127 } else { 442 } else {
128 return 0; 443 return 0;
129 } 444 }
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) 853 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
539 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) 854 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter)
540 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) 855 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter)
541 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) 856 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter)
542 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) 857 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd)
543 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) 858 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul)
544 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) 859 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul)
545 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) 860 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin)
546 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) 861 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter)
547 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 862 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « include/gpu/GrPaint.h ('k') | src/gpu/GrContext.cpp » ('j') | src/gpu/GrDrawState.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698