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

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 "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
296 /** Function color_component_to_int tries to reproduce the GLSL rounding. The sp ec doesn't specify
297 * to which direction the 0.5 goes.
298 */
299 static inline int color_component_to_int(float value) {
300 return sk_float_round2int(GrMax(0.f, GrMin(1.f, value)) * 255.f);
301 }
302
303 /** MaskedColorExpr is used to evaluate the color and valid color component
304 * flags through the blending equation.
bsalomon 2013/10/02 16:37:59 "It has members similar to GrGLSLExpr so that it c
Kimmo Kinnunen 2013/10/04 06:21:18 Done.
305 */
306 class MaskedColorExpr {
307 public:
308 MaskedColorExpr(const GrGLfloat color[], uint32_t flags)
bsalomon 2013/10/02 16:37:59 maybe just float or SkScalar? We usually only use
Kimmo Kinnunen 2013/10/04 06:21:18 Done.
309 : fFlags(flags) {
310 fColor[0] = color[0];
311 fColor[1] = color[1];
312 fColor[2] = color[2];
313 fColor[3] = color[3];
314 }
315
316 MaskedColorExpr(float v, uint32_t flags = kRGBA_GrColorComponentFlags)
317 : fFlags(flags) {
318 fColor[0] = v;
319 fColor[1] = v;
320 fColor[2] = v;
321 fColor[3] = v;
322 }
323
324 MaskedColorExpr operator*(const MaskedColorExpr& other) const {
325 GrGLfloat tmp[4];
326 tmp[0] = fColor[0] * other.fColor[0];
327 tmp[1] = fColor[1] * other.fColor[1];
328 tmp[2] = fColor[2] * other.fColor[2];
329 tmp[3] = fColor[3] * other.fColor[3];
330
331 return MaskedColorExpr(tmp, fFlags & other.fFlags);
332 }
333
334 MaskedColorExpr operator+(const MaskedColorExpr& other) const {
335 GrGLfloat tmp[4];
336 tmp[0] = fColor[0] + other.fColor[0];
337 tmp[1] = fColor[1] + other.fColor[1];
338 tmp[2] = fColor[2] + other.fColor[2];
339 tmp[3] = fColor[3] + other.fColor[3];
340
341 return MaskedColorExpr(tmp, fFlags & other.fFlags);
342 }
343
344 MaskedColorExpr operator-(const MaskedColorExpr& other) const {
345 GrGLfloat tmp[4];
346 tmp[0] = fColor[0] - other.fColor[0];
347 tmp[1] = fColor[1] - other.fColor[1];
348 tmp[2] = fColor[2] - other.fColor[2];
349 tmp[3] = fColor[3] - other.fColor[3];
350
351 return MaskedColorExpr(tmp, fFlags & other.fFlags);
352 }
353
354 MaskedColorExpr a() const {
355 uint32_t flags = (fFlags & kA_GrColorComponentFlag) ? kRGBA_GrColorCompo nentFlags : 0;
356 return MaskedColorExpr(fColor[3], flags);
357 }
358
359 GrColor getColor() const {
360 return GrColorPackRGBA(color_component_to_int(fColor[0]),
361 color_component_to_int(fColor[1]),
362 color_component_to_int(fColor[2]),
363 color_component_to_int(fColor[3]));
364 }
365
366 uint32_t getValidComponents() const { return fFlags; }
367
368 private:
369 GrGLfloat fColor[4];
370 uint32_t fFlags;
371 };
372
373 MaskedColorExpr operator-(int v, const MaskedColorExpr& other) {
374 return MaskedColorExpr(v) - other;
375 }
376 }
377
378 void ModeColorFilterEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
379 GrGLfloat inputColor[4];
380 GrColorToRGBAFloat(*color, inputColor);
381 GrGLfloat filterColor[4];
382 GrColorToRGBAFloat(fColor, filterColor);
383 MaskedColorExpr result =
384 color_filter_expression(fMode,
385 MaskedColorExpr(filterColor, kRGBA_GrColorCompon entFlags),
386 MaskedColorExpr(inputColor, *validFlags));
387
388 *color = result.getColor();
389 *validFlags = result.getValidComponents();
390 }
391
392 GR_DEFINE_EFFECT_TEST(ModeColorFilterEffect);
393 GrEffectRef* ModeColorFilterEffect::TestCreate(SkRandom* rand,
394 GrContext*,
395 const GrDrawTargetCaps&,
396 GrTexture*[]) {
397 int mode = rand->nextRangeU(0, SkXfermode::kLastCoeffMode);
398 GrColor color = rand->nextU();
399 static AutoEffectUnref gEffect(SkNEW_ARGS(ModeColorFilterEffect, (color, sta tic_cast<SkXfermode::Mode>(mode))));
400 return CreateEffectRef(gEffect);
401 }
402
403 GrEffectRef* SkModeColorFilter::asNewEffect(GrContext*) const {
404 if (SkXfermode::kDst_Mode != fMode) {
405 return ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode);
406 }
407 return NULL;
408 }
409
410 #endif
411
412 ///////////////////////////////////////////////////////////////////////////////
413
120 class Src_SkModeColorFilter : public SkModeColorFilter { 414 class Src_SkModeColorFilter : public SkModeColorFilter {
121 public: 415 public:
122 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod e) {} 416 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod e) {}
123 417
124 virtual uint32_t getFlags() const SK_OVERRIDE { 418 virtual uint32_t getFlags() const SK_OVERRIDE {
125 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { 419 if (SkGetPackedA32(this->getPMColor()) == 0xFF) {
126 return kAlphaUnchanged_Flag | kHasFilter16_Flag; 420 return kAlphaUnchanged_Flag | kHasFilter16_Flag;
127 } else { 421 } else {
128 return 0; 422 return 0;
129 } 423 }
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) 832 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
539 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) 833 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter)
540 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) 834 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter)
541 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) 835 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter)
542 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) 836 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd)
543 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) 837 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul)
544 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) 838 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul)
545 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) 839 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin)
546 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) 840 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter)
547 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 841 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « include/gpu/GrPaint.h ('k') | src/gpu/GrDrawState.h » ('j') | src/gpu/GrDrawState.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698