diff options
author | scroggo <scroggo@google.com> | 2015-01-20 06:33:13 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-20 06:33:14 -0800 |
commit | b2b416d3847c138a0a13876fdc1cdeae607b7e31 (patch) | |
tree | e9119cd0f165c7b72640a85bf0109811d687af55 | |
parent | 07f26976f74f800368258eb915dfe00d316febe2 (diff) |
Revert of remove unused SkAvoidXfermode (patchset #2 id:20001 of https://codereview.chromium.org/860583002/)
Reason for revert:
Breaking Android framework build, which still uses AvoidXfermode. (failure shown here: https://android-build.storage.googleapis.com/builds/git_master-skia-linux-razor-userdebug/1689202/565b76b4bd8cc2ffd5aeb37e524f6a35e9b8791995d6e8c719a3a6d83aece936/logs/build_error.log?Signature=lHYyiconR%2BoTzY9ILAKlaUm6nFnpJQPTI4XUei1ZccBRyz6PxspCNvYCDO5za92yZSoy9refHT7uh2Hxlxew1ZBePxKCp2nnwJB7a%2B403kiHMHHawjecsbPnTE9QNNO8XMoqAjujcAplorhwsIBZYOCxb%2Bo5010BCfzTd%2F8GFa8%3D&Expires=1421764644&GoogleAccessId=701025073339-mqn0q2nvir9iurm6q5d00tdv7blbgvjr%40developer.gserviceaccount.com)
Here is the Java class that uses it: https://cs.corp.google.com/#android/frameworks/base/graphics/java/android/graphics/AvoidXfermode.java&sq=package:android
It has been deprecated. The glue code (which actually references the Skia file) is here: https://cs.corp.google.com/#android/frameworks/base/core/jni/android/graphics/Xfermode.cpp&q=Xfermode.cpp&sq=package:android
Mike suggested we move the implementation into Android, which is fine with me.
Original issue's description:
> remove unused SkAvoidXfermode
>
> BUG=skia:
> TBR=
> NOTRY=True
>
> Committed: https://skia.googlesource.com/skia/+/2d02df7a9a50217dac8c1d11681832a927ed79ce
TBR=bsalomon@google.com,reed@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Review URL: https://codereview.chromium.org/822953003
-rw-r--r-- | gyp/SampleApp.gyp | 1 | ||||
-rw-r--r-- | gyp/effects.gypi | 1 | ||||
-rw-r--r-- | include/effects/SkAvoidXfermode.h | 68 | ||||
-rw-r--r-- | samplecode/ClockFaceView.cpp | 1 | ||||
-rw-r--r-- | samplecode/SampleAll.cpp | 13 | ||||
-rw-r--r-- | samplecode/SampleAvoid.cpp | 105 | ||||
-rw-r--r-- | src/effects/SkAvoidXfermode.cpp | 178 | ||||
-rw-r--r-- | src/ports/SkGlobalInitialization_chromium.cpp | 2 | ||||
-rw-r--r-- | src/ports/SkGlobalInitialization_default.cpp | 2 |
9 files changed, 371 insertions, 0 deletions
diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp index ce75158f87..7767835437 100644 --- a/gyp/SampleApp.gyp +++ b/gyp/SampleApp.gyp @@ -38,6 +38,7 @@ '../samplecode/SampleAnimBlur.cpp', '../samplecode/SampleApp.cpp', '../samplecode/SampleArc.cpp', + '../samplecode/SampleAvoid.cpp', '../samplecode/SampleBigBlur.cpp', '../samplecode/SampleBigGradient.cpp', '../samplecode/SampleBitmapRect.cpp', diff --git a/gyp/effects.gypi b/gyp/effects.gypi index 19ae8a66b1..494850ee35 100644 --- a/gyp/effects.gypi +++ b/gyp/effects.gypi @@ -14,6 +14,7 @@ '<(skia_src_path)/effects/SkArithmeticMode.cpp', '<(skia_src_path)/effects/SkArithmeticMode_gpu.cpp', '<(skia_src_path)/effects/SkArithmeticMode_gpu.h', + '<(skia_src_path)/effects/SkAvoidXfermode.cpp', '<(skia_src_path)/effects/SkBitmapSource.cpp', '<(skia_src_path)/effects/SkBlurDrawLooper.cpp', '<(skia_src_path)/effects/SkBlurMask.cpp', diff --git a/include/effects/SkAvoidXfermode.h b/include/effects/SkAvoidXfermode.h new file mode 100644 index 0000000000..fa34154295 --- /dev/null +++ b/include/effects/SkAvoidXfermode.h @@ -0,0 +1,68 @@ +/* + * Copyright 2006 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkAvoidXfermode_DEFINED +#define SkAvoidXfermode_DEFINED + +#include "SkXfermode.h" + +/** \class SkAvoidXfermode + + This xfermode will draw the src everywhere except on top of the specified + color. +*/ +class SK_API SkAvoidXfermode : public SkXfermode { +public: + enum Mode { + kAvoidColor_Mode, //!< draw everywhere except on the opColor + kTargetColor_Mode //!< draw only on top of the opColor + }; + + /** This xfermode draws, or doesn't draw, based on the destination's + distance from an op-color. + + There are two modes, and each mode interprets a tolerance value. + + Avoid: In this mode, drawing is allowed only on destination pixels that + are different from the op-color. + Tolerance near 0: avoid any colors even remotely similar to the op-color + Tolerance near 255: avoid only colors nearly identical to the op-color + + Target: In this mode, drawing only occurs on destination pixels that + are similar to the op-color + Tolerance near 0: draw only on colors that are nearly identical to the op-color + Tolerance near 255: draw on any colors even remotely similar to the op-color + */ + static SkAvoidXfermode* Create(SkColor opColor, U8CPU tolerance, Mode mode) { + return SkNEW_ARGS(SkAvoidXfermode, (opColor, tolerance, mode)); + } + + // overrides from SkXfermode + 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; + + SK_TO_STRING_OVERRIDE() + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAvoidXfermode) + +protected: + SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode); + void flatten(SkWriteBuffer&) const SK_OVERRIDE; + +private: + SkColor fOpColor; + uint32_t fDistMul; // x.14 cached from fTolerance + uint8_t fTolerance; + Mode fMode; + + typedef SkXfermode INHERITED; +}; + +#endif diff --git a/samplecode/ClockFaceView.cpp b/samplecode/ClockFaceView.cpp index 2db9753077..1e21bad753 100644 --- a/samplecode/ClockFaceView.cpp +++ b/samplecode/ClockFaceView.cpp @@ -18,6 +18,7 @@ #include "SkColorPriv.h" #include "SkColorFilter.h" #include "SkTypeface.h" +#include "SkAvoidXfermode.h" static inline SkPMColor rgb2gray(SkPMColor c) { unsigned r = SkGetPackedR32(c); diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp index 16c79c9dbf..537659e0e6 100644 --- a/samplecode/SampleAll.cpp +++ b/samplecode/SampleAll.cpp @@ -11,6 +11,7 @@ #include "SkView.h" #include "Sk1DPathEffect.h" #include "Sk2DPathEffect.h" +#include "SkAvoidXfermode.h" #include "SkBlurMaskFilter.h" #include "SkColorFilter.h" #include "SkColorPriv.h" @@ -572,6 +573,18 @@ protected: } canvas->restore(); + + if (1) { + SkAutoTUnref<SkAvoidXfermode> mode(SkAvoidXfermode::Create(SK_ColorWHITE, 0xFF, + SkAvoidXfermode::kTargetColor_Mode)); + SkPaint paint; + x += SkIntToScalar(20); + SkRect r = { x, 0, x + SkIntToScalar(360), SkIntToScalar(700) }; + paint.setXfermode(mode); + paint.setColor(SK_ColorGREEN); + paint.setAntiAlias(true); + canvas->drawOval(r, paint); + } } private: diff --git a/samplecode/SampleAvoid.cpp b/samplecode/SampleAvoid.cpp new file mode 100644 index 0000000000..aa7ca0e8ef --- /dev/null +++ b/samplecode/SampleAvoid.cpp @@ -0,0 +1,105 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SampleCode.h" +#include "SkView.h" +#include "SkCanvas.h" +#include "SkGradientShader.h" +#include "SkAvoidXfermode.h" + +/////////////////////////////////////////////////////////////////////////////// + +class AvoidView : public SampleView { + SkShader* fShader; + + enum { + W = 480, + H = 320 + }; +public: + AvoidView() { + SkColor colors[] = { SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN, SK_ColorCYAN, SK_ColorBLUE }; + +#if 0 + SkPoint pts[] = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) }; + fShader = SkGradientShader::CreateLinear(pts, colors, NULL, + SK_ARRAY_COUNT(colors), + SkShader::kMirror_TileMode); +#else + SkPoint pts[] = { { SkIntToScalar(W)/2, SkIntToScalar(H)/2 } }; + fShader = SkGradientShader::CreateRadial(pts[0], SkIntToScalar(H)/5, + colors, NULL, + SK_ARRAY_COUNT(colors), + SkShader::kMirror_TileMode); +#endif + } + + virtual ~AvoidView() { + fShader->unref(); + } + +protected: + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "AvoidXfermode"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + SkPaint paint; + SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) }; + + canvas->translate(r.width() / 6, r.height() / 6); + + paint.setShader(fShader); + canvas->drawRect(r, paint); + + static const struct { + int fTolerance; + SkAvoidXfermode::Mode fMode; + float fDX, fDY; + } gData[] = { + { 16, SkAvoidXfermode::kAvoidColor_Mode, 0, 0 }, + { 255-16, SkAvoidXfermode::kAvoidColor_Mode, 1, 0 }, + { 16, SkAvoidXfermode::kTargetColor_Mode, 0, 1 }, + { 255-16, SkAvoidXfermode::kTargetColor_Mode, 1, 1 }, + }; + + paint.setShader(NULL); + paint.setColor(SK_ColorMAGENTA); + + SkPaint frameP; + frameP.setStyle(SkPaint::kStroke_Style); + + for (size_t i = 0; i < SK_ARRAY_COUNT(gData); i++) { + SkAutoTUnref<SkAvoidXfermode> mode(SkAvoidXfermode::Create( + SK_ColorGREEN, gData[i].fTolerance, gData[i].fMode)); + paint.setXfermode(mode); + int div = 3; + SkRect rr = { 0, 0, r.width()/div, r.height()/div }; + rr.offset(r.width()/4 - rr.width()/2, r.height()/4 - rr.height()/2); + rr.offset(r.width() * gData[i].fDX/2, r.height() * gData[i].fDY/2); + canvas->drawRect(rr, paint); + paint.setXfermode(NULL); + + canvas->drawRect(rr, frameP); + } + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { + return new AvoidView; +} + +static SkViewRegister reg(MyFactory); diff --git a/src/effects/SkAvoidXfermode.cpp b/src/effects/SkAvoidXfermode.cpp new file mode 100644 index 0000000000..41c4e9646d --- /dev/null +++ b/src/effects/SkAvoidXfermode.cpp @@ -0,0 +1,178 @@ +/* + * Copyright 2006 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkAvoidXfermode.h" +#include "SkColorPriv.h" +#include "SkReadBuffer.h" +#include "SkWriteBuffer.h" +#include "SkString.h" + +SkAvoidXfermode::SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode) { + if (tolerance > 255) { + tolerance = 255; + } + fTolerance = SkToU8(tolerance); + fOpColor = opColor; + fDistMul = (256 << 14) / (tolerance + 1); + fMode = mode; +} + +SkFlattenable* SkAvoidXfermode::CreateProc(SkReadBuffer& buffer) { + const SkColor color = buffer.readColor(); + const unsigned tolerance = buffer.readUInt(); + const unsigned mode = buffer.readUInt(); + return Create(color, tolerance, (Mode)mode); +} + +void SkAvoidXfermode::flatten(SkWriteBuffer& buffer) const { + buffer.writeColor(fOpColor); + buffer.writeUInt(fTolerance); + buffer.writeUInt(fMode); +} + +// returns 0..31 +static unsigned color_dist16(uint16_t c, unsigned r, unsigned g, unsigned b) { + SkASSERT(r <= SK_R16_MASK); + SkASSERT(g <= SK_G16_MASK); + SkASSERT(b <= SK_B16_MASK); + + unsigned dr = SkAbs32(SkGetPackedR16(c) - r); + unsigned dg = SkAbs32(SkGetPackedG16(c) - g) >> (SK_G16_BITS - SK_R16_BITS); + unsigned db = SkAbs32(SkGetPackedB16(c) - b); + + return SkMax32(dr, SkMax32(dg, db)); +} + +// returns 0..255 +static unsigned color_dist32(SkPMColor c, U8CPU r, U8CPU g, U8CPU b) { + SkASSERT(r <= 0xFF); + SkASSERT(g <= 0xFF); + SkASSERT(b <= 0xFF); + + unsigned dr = SkAbs32(SkGetPackedR32(c) - r); + unsigned dg = SkAbs32(SkGetPackedG32(c) - g); + unsigned db = SkAbs32(SkGetPackedB32(c) - b); + + return SkMax32(dr, SkMax32(dg, db)); +} + +static int scale_dist_14(int dist, uint32_t mul, uint32_t sub) { + int tmp = dist * mul - sub; + int result = (tmp + (1 << 13)) >> 14; + + return result; +} + +static inline unsigned Accurate255To256(unsigned x) { + return x + (x >> 7); +} + +void SkAvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count, + const SkAlpha aa[]) const { + unsigned opR = SkColorGetR(fOpColor); + unsigned opG = SkColorGetG(fOpColor); + unsigned opB = SkColorGetB(fOpColor); + uint32_t mul = fDistMul; + uint32_t sub = (fDistMul - (1 << 14)) << 8; + + int MAX, mask; + + if (kTargetColor_Mode == fMode) { + mask = -1; + MAX = 255; + } else { + mask = 0; + MAX = 0; + } + + for (int i = 0; i < count; i++) { + int d = color_dist32(dst[i], opR, opG, opB); + // now reverse d if we need to + d = MAX + (d ^ mask) - mask; + SkASSERT((unsigned)d <= 255); + d = Accurate255To256(d); + + d = scale_dist_14(d, mul, sub); + SkASSERT(d <= 256); + + if (d > 0) { + if (aa) { + d = SkAlphaMul(d, Accurate255To256(*aa++)); + if (0 == d) { + continue; + } + } + dst[i] = SkFourByteInterp256(src[i], dst[i], d); + } + } +} + +static inline U16CPU SkBlend3216(SkPMColor src, U16CPU dst, unsigned scale) { + SkASSERT(scale <= 32); + scale <<= 3; + + return SkPackRGB16( SkAlphaBlend(SkPacked32ToR16(src), SkGetPackedR16(dst), scale), + SkAlphaBlend(SkPacked32ToG16(src), SkGetPackedG16(dst), scale), + SkAlphaBlend(SkPacked32ToB16(src), SkGetPackedB16(dst), scale)); +} + +void SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count, + const SkAlpha aa[]) const { + unsigned opR = SkColorGetR(fOpColor) >> (8 - SK_R16_BITS); + unsigned opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS); + unsigned opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS); + uint32_t mul = fDistMul; + uint32_t sub = (fDistMul - (1 << 14)) << SK_R16_BITS; + + int MAX, mask; + + if (kTargetColor_Mode == fMode) { + mask = -1; + MAX = 31; + } else { + mask = 0; + MAX = 0; + } + + for (int i = 0; i < count; i++) { + int d = color_dist16(dst[i], opR, opG, opB); + // now reverse d if we need to + d = MAX + (d ^ mask) - mask; + SkASSERT((unsigned)d <= 31); + // convert from 0..31 to 0..32 + d += d >> 4; + d = scale_dist_14(d, mul, sub); + SkASSERT(d <= 32); + + if (d > 0) { + if (aa) { + d = SkAlphaMul(d, Accurate255To256(*aa++)); + if (0 == d) { + continue; + } + } + dst[i] = SkBlend3216(src[i], dst[i], d); + } + } +} + +void SkAvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, + const SkAlpha aa[]) const { + // override in subclass +} + +#ifndef SK_IGNORE_TO_STRING +void SkAvoidXfermode::toString(SkString* str) const { + str->append("SkAvoidXfermode: opColor: "); + str->appendHex(fOpColor); + str->appendf("distMul: %d ", fDistMul); + + static const char* gModeStrings[] = { "Avoid", "Target" }; + + str->appendf("mode: %s", gModeStrings[fMode]); +} +#endif diff --git a/src/ports/SkGlobalInitialization_chromium.cpp b/src/ports/SkGlobalInitialization_chromium.cpp index f3e16db12c..cc087c1063 100644 --- a/src/ports/SkGlobalInitialization_chromium.cpp +++ b/src/ports/SkGlobalInitialization_chromium.cpp @@ -17,6 +17,7 @@ #include "Sk2DPathEffect.h" #include "SkArithmeticMode.h" #include "SkArcToPathEffect.h" +#include "SkAvoidXfermode.h" #include "SkBitmapSource.h" #include "SkBlurDrawLooper.h" #include "SkBlurImageFilter.h" @@ -64,6 +65,7 @@ class SkPrivateEffectInitializer { public: static void Init() { SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArcToPathEffect) + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper) diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp index f3e16db12c..cc087c1063 100644 --- a/src/ports/SkGlobalInitialization_default.cpp +++ b/src/ports/SkGlobalInitialization_default.cpp @@ -17,6 +17,7 @@ #include "Sk2DPathEffect.h" #include "SkArithmeticMode.h" #include "SkArcToPathEffect.h" +#include "SkAvoidXfermode.h" #include "SkBitmapSource.h" #include "SkBlurDrawLooper.h" #include "SkBlurImageFilter.h" @@ -64,6 +65,7 @@ class SkPrivateEffectInitializer { public: static void Init() { SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArcToPathEffect) + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurDrawLooper) |