Chromium Code Reviews| Index: src/effects/SkLumaXfermode.cpp |
| =================================================================== |
| --- src/effects/SkLumaXfermode.cpp (revision 11192) |
| +++ src/effects/SkLumaXfermode.cpp (working copy) |
| @@ -17,7 +17,15 @@ |
| #include "GrTBackendEffectFactory.h" |
| #endif |
| -static inline SkPMColor luma_proc(const SkPMColor a, const SkPMColor b) { |
| +class SkLumaMaskXfermodeSrcOver : public SkLumaMaskXfermode { |
| +public: |
| + SkLumaMaskXfermodeSrcOver(); |
| + |
| +private: |
| + virtual SkPMColor lumaProc(const SkPMColor a, const SkPMColor b) const; |
| +}; |
| + |
| +SkPMColor SkLumaMaskXfermode::lumaProc(const SkPMColor a, const SkPMColor b) const { |
| unsigned luma = SkComputeLuminance(SkGetPackedR32(b), |
| SkGetPackedG32(b), |
| SkGetPackedB32(b)); |
| @@ -40,18 +48,22 @@ |
| if (kSrcIn_Mode == mode || kDstIn_Mode == mode) { |
| return SkNEW_ARGS(SkLumaMaskXfermode, (mode)); |
| } |
| + if (kSrcOver_Mode == mode) { |
| + return SkNEW_ARGS(SkLumaMaskXfermodeSrcOver, ()); |
| + } |
| + |
| return NULL; |
| } |
| SkLumaMaskXfermode::SkLumaMaskXfermode(SkXfermode::Mode mode) |
| : fMode(mode) { |
| - SkASSERT(kSrcIn_Mode == mode || kDstIn_Mode == mode); |
| + SkASSERT(kSrcIn_Mode == mode || kDstIn_Mode == mode || kSrcOver_Mode == mode); |
| } |
| SkLumaMaskXfermode::SkLumaMaskXfermode(SkFlattenableReadBuffer& buffer) |
| : INHERITED(buffer) |
| , fMode((SkXfermode::Mode)buffer.readUInt()) { |
| - SkASSERT(kSrcIn_Mode == fMode || kDstIn_Mode == fMode); |
| + SkASSERT(kSrcIn_Mode == fMode || kDstIn_Mode == fMode || kSrcOver_Mode == fMode); |
| } |
| void SkLumaMaskXfermode::flatten(SkFlattenableWriteBuffer& buffer) const { |
| @@ -62,7 +74,7 @@ |
| SkPMColor SkLumaMaskXfermode::xferColor(SkPMColor src, SkPMColor dst) const { |
| const SkPMColor* a = lumaOpA<SkPMColor>(fMode, &src, &dst); |
| const SkPMColor* b = lumaOpB<SkPMColor>(fMode, &src, &dst); |
| - return luma_proc(*a, *b); |
| + return this->lumaProc(*a, *b); |
| } |
| void SkLumaMaskXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], |
| @@ -74,7 +86,7 @@ |
| for (int i = 0; i < count; ++i) { |
| unsigned cov = aa[i]; |
| if (cov) { |
| - unsigned resC = luma_proc(a[i], b[i]); |
| + unsigned resC = this->lumaProc(a[i], b[i]); |
| if (cov < 255) { |
| resC = SkFastFourByteInterp256(resC, dst[i], |
| SkAlpha255To256(cov)); |
| @@ -84,7 +96,7 @@ |
| } |
| } else { |
| for (int i = 0; i < count; ++i) { |
| - dst[i] = luma_proc(a[i], b[i]); |
| + dst[i] = this->lumaProc(a[i], b[i]); |
| } |
| } |
| } |
| @@ -96,6 +108,27 @@ |
| } |
| #endif |
| +SkLumaMaskXfermodeSrcOver::SkLumaMaskXfermodeSrcOver() : SkLumaMaskXfermode(kSrcOver_Mode) {} |
| + |
| +SkPMColor SkLumaMaskXfermodeSrcOver::lumaProc(const SkPMColor a, const SkPMColor b) const { |
| + unsigned luma = SkComputeLuminance(SkGetPackedR32(b), |
| + SkGetPackedG32(b), |
| + SkGetPackedB32(b)); |
| + |
| + unsigned oldAlpha = SkGetPackedA32(b); |
| + unsigned newR = 0, newG = 0, newB = 0; |
| + |
| + if (oldAlpha > 0) { |
| + newR = SkGetPackedR32(b) * 255 / oldAlpha; |
| + newG = SkGetPackedG32(b) * 255 / oldAlpha; |
| + newB = SkGetPackedB32(b) * 255 / oldAlpha; |
| + } |
| + |
| + SkPMColor colorB = SkPremultiplyARGBInline(luma, newR, newG, newB); |
| + |
| + return SkPMSrcOver(colorB, a); |
| +} |
| + |
| #if SK_SUPPORT_GPU |
| ////////////////////////////////////////////////////////////////////////////// |
| @@ -174,7 +207,12 @@ |
| SK_ITU_BT709_LUM_COEFF_G, |
| SK_ITU_BT709_LUM_COEFF_B, |
| opB); |
| - builder->fsCodeAppendf("\t\t%s = %s * luma;\n", outputColor, opA); |
| + if (SkXfermode::kSrcOver_Mode == lumaEffect.getMode()) { |
| + builder->fsCodeAppendf("\t\tvec4 newB = %s;\t\tif (newB.a > 0.0) { newB *= luma / newB.a; }\n\t\tnewB.a = luma;\n", opB); |
|
bsalomon
2013/09/16 13:41:27
nit probably want a \n after the vec4 newB = ...;
|
| + builder->fsCodeAppendf("\t\t%s = newB + %s * (1.0 - luma); \n", outputColor, opA); |
| + } else { |
| + builder->fsCodeAppendf("\t\t%s = %s * luma;\n", outputColor, opA); |
| + } |
| } |
| GrGLEffect::EffectKey GrGLLumaMaskEffect::GenKey(const GrDrawEffect& drawEffect, |