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

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

Powered by Google App Engine
This is Rietveld 408576698