| Index: src/effects/SkXfermodeImageFilter.cpp
|
| diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
|
| index 952ce977aaf20cd6fb6dd6b2a3d11346c872a5f1..b0735168b51a857d2d6672d651e833eecb2dcd18 100644
|
| --- a/src/effects/SkXfermodeImageFilter.cpp
|
| +++ b/src/effects/SkXfermodeImageFilter.cpp
|
| @@ -6,6 +6,7 @@
|
| */
|
|
|
| #include "SkXfermodeImageFilter.h"
|
| +#include "SkArithmeticModePriv.h"
|
|
|
| #include "SkCanvas.h"
|
| #include "SkColorPriv.h"
|
| @@ -27,7 +28,7 @@
|
|
|
| class SkXfermodeImageFilter_Base : public SkImageFilter {
|
| public:
|
| - SkXfermodeImageFilter_Base(sk_sp<SkXfermode> mode, sk_sp<SkImageFilter> inputs[2],
|
| + SkXfermodeImageFilter_Base(SkBlendMode mode, sk_sp<SkImageFilter> inputs[2],
|
| const CropRect* cropRect);
|
|
|
| SK_TO_STRING_OVERRIDE()
|
| @@ -55,7 +56,7 @@ protected:
|
| #endif
|
|
|
| private:
|
| - sk_sp<SkXfermode> fMode;
|
| + SkBlendMode fMode;
|
|
|
| friend class SkXfermodeImageFilter;
|
|
|
| @@ -64,7 +65,7 @@ private:
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode,
|
| +sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(SkBlendMode mode,
|
| sk_sp<SkImageFilter> background,
|
| sk_sp<SkImageFilter> foreground,
|
| const SkImageFilter::CropRect* cropRect) {
|
| @@ -72,23 +73,59 @@ sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode,
|
| return sk_sp<SkImageFilter>(new SkXfermodeImageFilter_Base(mode, inputs, cropRect));
|
| }
|
|
|
| -SkXfermodeImageFilter_Base::SkXfermodeImageFilter_Base(sk_sp<SkXfermode> mode,
|
| - sk_sp<SkImageFilter> inputs[2],
|
| - const CropRect* cropRect)
|
| +#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
|
| +sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode,
|
| + sk_sp<SkImageFilter> background,
|
| + sk_sp<SkImageFilter> foreground,
|
| + const SkImageFilter::CropRect* cropRect) {
|
| + return Make(mode ? mode->blend() : SkBlendMode::kSrcOver,
|
| + std::move(background), std::move(foreground), cropRect);
|
| +}
|
| +#endif
|
| +
|
| +SkXfermodeImageFilter_Base::SkXfermodeImageFilter_Base(SkBlendMode mode,
|
| + sk_sp<SkImageFilter> inputs[2],
|
| + const CropRect* cropRect)
|
| : INHERITED(inputs, 2, cropRect)
|
| - , fMode(std::move(mode)) {
|
| + , fMode(mode)
|
| +{}
|
| +
|
| +static int unflatten_blendmode(SkReadBuffer& buffer, SkArithmeticParams* arith) {
|
| + if (buffer.isVersionLT(SkReadBuffer::kXfermodeToBlendMode_Version)) {
|
| + sk_sp<SkXfermode> xfer = buffer.readXfermode();
|
| + if (xfer) {
|
| + if (xfer->isArithmetic(arith)) {
|
| + return -1;
|
| + }
|
| + return (int)xfer->blend();
|
| + } else {
|
| + return (int)SkBlendMode::kSrcOver;
|
| + }
|
| + } else {
|
| + uint32_t mode = buffer.read32();
|
| + (void)buffer.validate(mode <= (unsigned)SkBlendMode::kLastMode);
|
| + return mode;
|
| + }
|
| }
|
|
|
| sk_sp<SkFlattenable> SkXfermodeImageFilter_Base::CreateProc(SkReadBuffer& buffer) {
|
| SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
|
| - sk_sp<SkXfermode> mode(buffer.readXfermode());
|
| - return SkXfermodeImageFilter::Make(std::move(mode), common.getInput(0), common.getInput(1),
|
| - &common.cropRect());
|
| + SkArithmeticParams arith;
|
| + int mode = unflatten_blendmode(buffer, &arith);
|
| + if (mode >= 0) {
|
| + return SkXfermodeImageFilter::Make((SkBlendMode)mode, common.getInput(0),
|
| + common.getInput(1), &common.cropRect());
|
| + } else {
|
| + return SkXfermodeImageFilter::MakeArithmetic(arith.fK[0], arith.fK[1], arith.fK[2],
|
| + arith.fK[3], arith.fEnforcePMColor,
|
| + common.getInput(0),
|
| + common.getInput(1), &common.cropRect());
|
| + }
|
| }
|
|
|
| void SkXfermodeImageFilter_Base::flatten(SkWriteBuffer& buffer) const {
|
| this->INHERITED::flatten(buffer);
|
| - buffer.writeFlattenable(fMode.get());
|
| + buffer.write32((unsigned)fMode);
|
| }
|
|
|
| sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage* source,
|
| @@ -147,7 +184,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage*
|
|
|
| if (background) {
|
| SkPaint paint;
|
| - paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
| + paint.setBlendMode(SkBlendMode::kSrc);
|
| background->draw(canvas,
|
| SkIntToScalar(backgroundOffset.fX), SkIntToScalar(backgroundOffset.fY),
|
| &paint);
|
| @@ -161,7 +198,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage*
|
| void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage* img,
|
| const SkIRect& fgBounds) const {
|
| SkPaint paint;
|
| - paint.setXfermode(fMode);
|
| + paint.setBlendMode(fMode);
|
| if (img) {
|
| img->draw(canvas, SkIntToScalar(fgBounds.fLeft), SkIntToScalar(fgBounds.fTop), &paint);
|
| }
|
| @@ -175,11 +212,7 @@ void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage
|
| #ifndef SK_IGNORE_TO_STRING
|
| void SkXfermodeImageFilter_Base::toString(SkString* str) const {
|
| str->appendf("SkXfermodeImageFilter: (");
|
| - str->appendf("xfermode: (");
|
| - if (fMode) {
|
| - fMode->toString(str);
|
| - }
|
| - str->append(")");
|
| + str->appendf("blendmode: (%d)", (int)fMode);
|
| if (this->getInput(0)) {
|
| str->appendf("foreground: (");
|
| this->getInput(0)->toString(str);
|
| @@ -266,7 +299,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::filterImageGPU(
|
| paint.addColorFragmentProcessor(std::move(bgFP));
|
| }
|
|
|
| - paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
| + paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
|
|
|
| sk_sp<GrDrawContext> drawContext(
|
| context->makeDrawContext(SkBackingFit::kApprox, bounds.width(), bounds.height(),
|
| @@ -290,8 +323,9 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::filterImageGPU(
|
| sk_sp<GrFragmentProcessor>
|
| SkXfermodeImageFilter_Base::makeFGFrag(sk_sp<GrFragmentProcessor> bgFP) const {
|
| // A null fMode is interpreted to mean kSrcOver_Mode (to match raster).
|
| - SkAutoTUnref<SkXfermode> mode(SkSafeRef(fMode.get()));
|
| - if (!mode) {
|
| + SkXfermode* xfer = SkXfermode::Peek(fMode);
|
| + sk_sp<SkXfermode> srcover;
|
| + if (!xfer) {
|
| // It would be awesome to use SkXfermode::Create here but it knows better
|
| // than us and won't return a kSrcOver_Mode SkXfermode. That means we
|
| // have to get one the hard way.
|
| @@ -299,9 +333,11 @@ SkXfermodeImageFilter_Base::makeFGFrag(sk_sp<GrFragmentProcessor> bgFP) const {
|
| rec.fProc = SkXfermode::GetProc(SkXfermode::kSrcOver_Mode);
|
| SkXfermode::ModeAsCoeff(SkXfermode::kSrcOver_Mode, &rec.fSC, &rec.fDC);
|
|
|
| - mode.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode));
|
| + srcover.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode));
|
| + xfer = srcover.get();
|
| +
|
| }
|
| - return mode->makeFragmentProcessorForImageFilter(std::move(bgFP));
|
| + return xfer->makeFragmentProcessorForImageFilter(std::move(bgFP));
|
| }
|
|
|
| #endif
|
| @@ -312,7 +348,8 @@ class SkArithmeticImageFilter : public SkXfermodeImageFilter_Base {
|
| public:
|
| SkArithmeticImageFilter(float k1, float k2, float k3, float k4, bool enforcePMColor,
|
| sk_sp<SkImageFilter> inputs[2], const CropRect* cropRect)
|
| - : SkXfermodeImageFilter_Base(nullptr, inputs, cropRect)
|
| + // need to pass a blendmode to our inherited constructor, but we ignore it
|
| + : SkXfermodeImageFilter_Base(SkBlendMode::kSrcOver, inputs, cropRect)
|
| , fK{ k1, k2, k3, k4 }
|
| , fEnforcePMColor(enforcePMColor)
|
| {}
|
| @@ -347,8 +384,11 @@ sk_sp<SkFlattenable> SkArithmeticImageFilter::CreateProc(SkReadBuffer& buffer) {
|
| SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
|
|
|
| // skip the mode (srcover) our parent-class wrote
|
| - sk_sp<SkXfermode> mode(buffer.readXfermode());
|
| - SkASSERT(nullptr == mode);
|
| + SkDEBUGCODE(int mode =) unflatten_blendmode(buffer, nullptr);
|
| + if (!buffer.isValid()) {
|
| + return nullptr;
|
| + }
|
| + SkASSERT(SkBlendMode::kSrcOver == (SkBlendMode)mode);
|
|
|
| float k[4];
|
| for (int i = 0; i < 4; ++i) {
|
| @@ -475,16 +515,16 @@ sk_sp<SkImageFilter> SkXfermodeImageFilter::MakeArithmetic(float k1, float k2, f
|
| int mode = -1; // illegal mode
|
| if (SkScalarNearlyZero(k1) && SkScalarNearlyEqual(k2, SK_Scalar1) &&
|
| SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) {
|
| - mode = SkXfermode::kSrc_Mode;
|
| + mode = (int)SkBlendMode::kSrc;
|
| } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) &&
|
| SkScalarNearlyEqual(k3, SK_Scalar1) && SkScalarNearlyZero(k4)) {
|
| - mode = SkXfermode::kDst_Mode;
|
| + mode = (int)SkBlendMode::kDst;
|
| } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) &&
|
| SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) {
|
| - mode = SkXfermode::kClear_Mode;
|
| + mode = (int)SkBlendMode::kClear;
|
| }
|
| if (mode >= 0) {
|
| - return SkXfermodeImageFilter::Make(SkXfermode::Make((SkXfermode::Mode)mode),
|
| + return SkXfermodeImageFilter::Make((SkBlendMode)mode,
|
| std::move(background), std::move(foreground), crop);
|
| }
|
|
|
|
|