From cc277b729b16c0d8d042f9ae1db6563fb4538d88 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Thu, 17 Apr 2014 15:19:32 +0000 Subject: [PATCH] Orphan ProcXfermode, with an eye towards removing it BUG=skia: R=scroggo@google.com, mtklein@google.com Author: reed@google.com Review URL: https://codereview.chromium.org/240533003 git-svn-id: http://skia.googlecode.com/svn/trunk@14238 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkXfermode.h | 4 ++ src/core/SkXfermode.cpp | 92 +++++++++++++++++++++++++++- src/core/SkXfermode_proccoeff.h | 26 +++++--- src/utils/debugger/SkDebugCanvas.cpp | 52 +++++++++------- tests/PaintTest.cpp | 2 +- tests/XfermodeTest.cpp | 12 ---- 6 files changed, 142 insertions(+), 46 deletions(-) diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h index 4af6cb43d1..9bad1e8d37 100644 --- a/include/core/SkXfermode.h +++ b/include/core/SkXfermode.h @@ -17,6 +17,8 @@ class GrEffectRef; class GrTexture; class SkString; +//#define SK_SUPPORT_LEGACY_PROCXFERMODE + /** \class SkXfermode * * SkXfermode is the base class for objects that are called to implement custom @@ -246,6 +248,7 @@ private: /////////////////////////////////////////////////////////////////////////////// +#ifdef SK_SUPPORT_LEGACY_PROCXFERMODE /** \class SkProcXfermode SkProcXfermode is a xfermode that applies the specified proc to its colors. @@ -291,5 +294,6 @@ private: typedef SkXfermode INHERITED; }; +#endif #endif diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 32a544c2af..fb1726808f 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -775,6 +775,7 @@ void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, } /////////////////////////////////////////////////////////////////////////////// +#ifdef SK_SUPPORT_LEGACY_PROCXFERMODE void SkProcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, const SkPMColor* SK_RESTRICT src, int count, @@ -884,6 +885,7 @@ void SkProcXfermode::toString(SkString* str) const { } #endif +#endif ////////////////////////////////////////////////////////////////////////////// #if SK_SUPPORT_GPU @@ -1358,11 +1360,10 @@ SkProcCoeffXfermode::SkProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffe fMode = (SkXfermode::Mode)mode32; const ProcCoeff& rec = gProcCoeffs[fMode]; + fProc = rec.fProc; // these may be valid, or may be CANNOT_USE_COEFF fSrcCoeff = rec.fSC; fDstCoeff = rec.fDC; - // now update our function-ptr in the super class - this->INHERITED::setProc(rec.fProc); } bool SkProcCoeffXfermode::asMode(Mode* mode) const { @@ -1386,6 +1387,93 @@ bool SkProcCoeffXfermode::asCoeff(Coeff* sc, Coeff* dc) const { return true; } +void SkProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, + const SkAlpha* SK_RESTRICT aa) const { + SkASSERT(dst && src && count >= 0); + + SkXfermodeProc proc = fProc; + + if (NULL != proc) { + if (NULL == aa) { + for (int i = count - 1; i >= 0; --i) { + dst[i] = proc(src[i], dst[i]); + } + } else { + for (int i = count - 1; i >= 0; --i) { + unsigned a = aa[i]; + if (0 != a) { + SkPMColor dstC = dst[i]; + SkPMColor C = proc(src[i], dstC); + if (a != 0xFF) { + C = SkFourByteInterp(C, dstC, a); + } + dst[i] = C; + } + } + } + } +} + +void SkProcCoeffXfermode::xfer16(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, + const SkAlpha* SK_RESTRICT aa) const { + SkASSERT(dst && src && count >= 0); + + SkXfermodeProc proc = fProc; + + if (NULL != proc) { + if (NULL == aa) { + for (int i = count - 1; i >= 0; --i) { + SkPMColor dstC = SkPixel16ToPixel32(dst[i]); + dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); + } + } else { + for (int i = count - 1; i >= 0; --i) { + unsigned a = aa[i]; + if (0 != a) { + SkPMColor dstC = SkPixel16ToPixel32(dst[i]); + SkPMColor C = proc(src[i], dstC); + if (0xFF != a) { + C = SkFourByteInterp(C, dstC, a); + } + dst[i] = SkPixel32ToPixel16_ToU16(C); + } + } + } + } +} + +void SkProcCoeffXfermode::xferA8(SkAlpha* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, + const SkAlpha* SK_RESTRICT aa) const { + SkASSERT(dst && src && count >= 0); + + SkXfermodeProc proc = fProc; + + if (NULL != proc) { + if (NULL == aa) { + for (int i = count - 1; i >= 0; --i) { + SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); + dst[i] = SkToU8(SkGetPackedA32(res)); + } + } else { + for (int i = count - 1; i >= 0; --i) { + unsigned a = aa[i]; + if (0 != a) { + SkAlpha dstA = dst[i]; + SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); + unsigned A = SkGetPackedA32(res); + if (0xFF != a) { + A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); + } + dst[i] = SkToU8(A); + } + } + } + } +} + #if SK_SUPPORT_GPU bool SkProcCoeffXfermode::asNewEffect(GrEffectRef** effect, GrTexture* background) const { diff --git a/src/core/SkXfermode_proccoeff.h b/src/core/SkXfermode_proccoeff.h index 977c3dace7..7edf6654a4 100644 --- a/src/core/SkXfermode_proccoeff.h +++ b/src/core/SkXfermode_proccoeff.h @@ -13,12 +13,19 @@ struct ProcCoeff { #define CANNOT_USE_COEFF SkXfermode::Coeff(-1) -class SK_API SkProcCoeffXfermode : public SkProcXfermode { +class SK_API SkProcCoeffXfermode : public SkXfermode { public: static SkProcCoeffXfermode* Create(const ProcCoeff& rec, Mode mode) { return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); } + virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, + const SkAlpha aa[]) const SK_OVERRIDE; + virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count, + const SkAlpha aa[]) const SK_OVERRIDE; + virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count, + const SkAlpha aa[]) const SK_OVERRIDE; + virtual bool asMode(Mode* mode) const SK_OVERRIDE; virtual bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE; @@ -32,9 +39,9 @@ public: SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) protected: - SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) - : INHERITED(rec.fProc) { + SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) { fMode = mode; + fProc = rec.fProc; // these may be valid, or may be CANNOT_USE_COEFF fSrcCoeff = rec.fSC; fDstCoeff = rec.fDC; @@ -44,15 +51,16 @@ protected: virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE; - Mode getMode() const { - return fMode; - } + Mode getMode() const { return fMode; } + + SkXfermodeProc getProc() const { return fProc; } private: - Mode fMode; - Coeff fSrcCoeff, fDstCoeff; + SkXfermodeProc fProc; + Mode fMode; + Coeff fSrcCoeff, fDstCoeff; - typedef SkProcXfermode INHERITED; + typedef SkXfermode INHERITED; }; #endif // #ifndef SkXfermode_proccoeff_DEFINED diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp index 0f2b9e0f05..22eef6f9a5 100644 --- a/src/utils/debugger/SkDebugCanvas.cpp +++ b/src/utils/debugger/SkDebugCanvas.cpp @@ -92,37 +92,45 @@ int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) { return layer; } -static SkPMColor OverdrawXferModeProc(SkPMColor src, SkPMColor dst) { - // This table encodes the color progression of the overdraw visualization - static const SkPMColor gTable[] = { - SkPackARGB32(0x00, 0x00, 0x00, 0x00), - SkPackARGB32(0xFF, 128, 158, 255), - SkPackARGB32(0xFF, 170, 185, 212), - SkPackARGB32(0xFF, 213, 195, 170), - SkPackARGB32(0xFF, 255, 192, 127), - SkPackARGB32(0xFF, 255, 185, 85), - SkPackARGB32(0xFF, 255, 165, 42), - SkPackARGB32(0xFF, 255, 135, 0), - SkPackARGB32(0xFF, 255, 95, 0), - SkPackARGB32(0xFF, 255, 50, 0), - SkPackARGB32(0xFF, 255, 0, 0) - }; - - for (size_t i = 0; i < SK_ARRAY_COUNT(gTable)-1; ++i) { - if (gTable[i] == dst) { - return gTable[i+1]; +class OverdrawXfermode : public SkXfermode { +public: + virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const SK_OVERRIDE { + // This table encodes the color progression of the overdraw visualization + static const SkPMColor gTable[] = { + SkPackARGB32(0x00, 0x00, 0x00, 0x00), + SkPackARGB32(0xFF, 128, 158, 255), + SkPackARGB32(0xFF, 170, 185, 212), + SkPackARGB32(0xFF, 213, 195, 170), + SkPackARGB32(0xFF, 255, 192, 127), + SkPackARGB32(0xFF, 255, 185, 85), + SkPackARGB32(0xFF, 255, 165, 42), + SkPackARGB32(0xFF, 255, 135, 0), + SkPackARGB32(0xFF, 255, 95, 0), + SkPackARGB32(0xFF, 255, 50, 0), + SkPackARGB32(0xFF, 255, 0, 0) + }; + + for (size_t i = 0; i < SK_ARRAY_COUNT(gTable)-1; ++i) { + if (gTable[i] == dst) { + return gTable[i+1]; + } } + + return gTable[SK_ARRAY_COUNT(gTable)-1]; } - return gTable[SK_ARRAY_COUNT(gTable)-1]; -} + virtual Factory getFactory() const SK_OVERRIDE { return NULL; } +#ifndef SK_IGNORE_TO_STRING + virtual void toString(SkString* str) const { str->set("OverdrawXfermode"); } +#endif +}; // The OverdrawFilter modifies every paint to use an SkProcXfermode which // in turn invokes OverdrawXferModeProc class SkOverdrawFilter : public SkDrawFilter { public: SkOverdrawFilter() { - fXferMode = SkProcXfermode::Create(OverdrawXferModeProc); + fXferMode = SkNEW(OverdrawXfermode); } virtual ~SkOverdrawFilter() { diff --git a/tests/PaintTest.cpp b/tests/PaintTest.cpp index ab2f22f441..350860cc88 100644 --- a/tests/PaintTest.cpp +++ b/tests/PaintTest.cpp @@ -325,7 +325,7 @@ DEF_TEST(Paint_FlatteningTraits, r) { SkWriteBuffer writer; SkPaint::FlatteningTraits::Flatten(writer, paint); - const size_t expectedBytesWritten = sizeof(void*) == 8 ? 44 : 36; + const size_t expectedBytesWritten = sizeof(void*) == 8 ? 36 : 28; ASSERT(expectedBytesWritten == writer.bytesWritten()); const uint32_t* written = writer.getWriter32()->contiguousArray(); diff --git a/tests/XfermodeTest.cpp b/tests/XfermodeTest.cpp index 4afa522de7..34f5233fcf 100644 --- a/tests/XfermodeTest.cpp +++ b/tests/XfermodeTest.cpp @@ -9,10 +9,6 @@ #include "SkXfermode.h" #include "Test.h" -static SkPMColor bogusXfermodeProc(SkPMColor src, SkPMColor dst) { - return 42; -} - #define ILLEGAL_MODE ((SkXfermode::Mode)-1) static void test_asMode(skiatest::Reporter* reporter) { @@ -36,14 +32,6 @@ static void test_asMode(skiatest::Reporter* reporter) { REPORTER_ASSERT(reporter, SkXfermode::kSrcOver_Mode == mode); } } - - SkXfermode* bogusXfer = SkProcXfermode::Create(bogusXfermodeProc); - SkXfermode::Mode reportedMode = ILLEGAL_MODE; - REPORTER_ASSERT(reporter, !bogusXfer->asMode(&reportedMode)); - REPORTER_ASSERT(reporter, reportedMode == ILLEGAL_MODE); - REPORTER_ASSERT(reporter, !SkXfermode::AsMode(bogusXfer, &reportedMode)); - REPORTER_ASSERT(reporter, reportedMode == ILLEGAL_MODE); - bogusXfer->unref(); } static void test_IsMode(skiatest::Reporter* reporter) {