| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 The Android Open Source Project | 2 * Copyright 2013 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkXfermodeImageFilter.h" | 8 #include "SkXfermodeImageFilter.h" |
| 9 #include "SkArithmeticModePriv.h" |
| 9 | 10 |
| 10 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
| 11 #include "SkColorPriv.h" | 12 #include "SkColorPriv.h" |
| 12 #include "SkReadBuffer.h" | 13 #include "SkReadBuffer.h" |
| 13 #include "SkSpecialImage.h" | 14 #include "SkSpecialImage.h" |
| 14 #include "SkSpecialSurface.h" | 15 #include "SkSpecialSurface.h" |
| 15 #include "SkWriteBuffer.h" | 16 #include "SkWriteBuffer.h" |
| 16 #include "SkXfermode.h" | 17 #include "SkXfermode.h" |
| 17 #if SK_SUPPORT_GPU | 18 #if SK_SUPPORT_GPU |
| 18 #include "GrContext.h" | 19 #include "GrContext.h" |
| 19 #include "GrDrawContext.h" | 20 #include "GrDrawContext.h" |
| 20 #include "effects/GrConstColorProcessor.h" | 21 #include "effects/GrConstColorProcessor.h" |
| 21 #include "effects/GrTextureDomain.h" | 22 #include "effects/GrTextureDomain.h" |
| 22 #include "effects/GrSimpleTextureEffect.h" | 23 #include "effects/GrSimpleTextureEffect.h" |
| 23 #include "SkArithmeticMode_gpu.h" | 24 #include "SkArithmeticMode_gpu.h" |
| 24 #include "SkGr.h" | 25 #include "SkGr.h" |
| 25 #include "SkGrPriv.h" | 26 #include "SkGrPriv.h" |
| 26 #endif | 27 #endif |
| 27 | 28 |
| 28 class SkXfermodeImageFilter_Base : public SkImageFilter { | 29 class SkXfermodeImageFilter_Base : public SkImageFilter { |
| 29 public: | 30 public: |
| 30 SkXfermodeImageFilter_Base(sk_sp<SkXfermode> mode, sk_sp<SkImageFilter> inpu
ts[2], | 31 SkXfermodeImageFilter_Base(SkBlendMode mode, sk_sp<SkImageFilter> inputs[2], |
| 31 const CropRect* cropRect); | 32 const CropRect* cropRect); |
| 32 | 33 |
| 33 SK_TO_STRING_OVERRIDE() | 34 SK_TO_STRING_OVERRIDE() |
| 34 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkXfermodeImageFilter_Ba
se) | 35 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkXfermodeImageFilter_Ba
se) |
| 35 | 36 |
| 36 protected: | 37 protected: |
| 37 sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&, | 38 sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&, |
| 38 SkIPoint* offset) const override; | 39 SkIPoint* offset) const override; |
| 39 | 40 |
| 40 #if SK_SUPPORT_GPU | 41 #if SK_SUPPORT_GPU |
| 41 sk_sp<SkSpecialImage> filterImageGPU(SkSpecialImage* source, | 42 sk_sp<SkSpecialImage> filterImageGPU(SkSpecialImage* source, |
| 42 sk_sp<SkSpecialImage> background, | 43 sk_sp<SkSpecialImage> background, |
| 43 const SkIPoint& backgroundOffset, | 44 const SkIPoint& backgroundOffset, |
| 44 sk_sp<SkSpecialImage> foreground, | 45 sk_sp<SkSpecialImage> foreground, |
| 45 const SkIPoint& foregroundOffset, | 46 const SkIPoint& foregroundOffset, |
| 46 const SkIRect& bounds, | 47 const SkIRect& bounds, |
| 47 const OutputProperties& outputPropertie
s) const; | 48 const OutputProperties& outputPropertie
s) const; |
| 48 #endif | 49 #endif |
| 49 | 50 |
| 50 void flatten(SkWriteBuffer&) const override; | 51 void flatten(SkWriteBuffer&) const override; |
| 51 | 52 |
| 52 virtual void drawForeground(SkCanvas* canvas, SkSpecialImage*, const SkIRect
&) const; | 53 virtual void drawForeground(SkCanvas* canvas, SkSpecialImage*, const SkIRect
&) const; |
| 53 #if SK_SUPPORT_GPU | 54 #if SK_SUPPORT_GPU |
| 54 virtual sk_sp<GrFragmentProcessor> makeFGFrag(sk_sp<GrFragmentProcessor> bgF
P) const; | 55 virtual sk_sp<GrFragmentProcessor> makeFGFrag(sk_sp<GrFragmentProcessor> bgF
P) const; |
| 55 #endif | 56 #endif |
| 56 | 57 |
| 57 private: | 58 private: |
| 58 sk_sp<SkXfermode> fMode; | 59 SkBlendMode fMode; |
| 59 | 60 |
| 60 friend class SkXfermodeImageFilter; | 61 friend class SkXfermodeImageFilter; |
| 61 | 62 |
| 62 typedef SkImageFilter INHERITED; | 63 typedef SkImageFilter INHERITED; |
| 63 }; | 64 }; |
| 64 | 65 |
| 65 /////////////////////////////////////////////////////////////////////////////// | 66 /////////////////////////////////////////////////////////////////////////////// |
| 66 | 67 |
| 67 sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode, | 68 sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(SkBlendMode mode, |
| 68 sk_sp<SkImageFilter> background
, | 69 sk_sp<SkImageFilter> background
, |
| 69 sk_sp<SkImageFilter> foreground
, | 70 sk_sp<SkImageFilter> foreground
, |
| 70 const SkImageFilter::CropRect*
cropRect) { | 71 const SkImageFilter::CropRect*
cropRect) { |
| 71 sk_sp<SkImageFilter> inputs[2] = { std::move(background), std::move(foregrou
nd) }; | 72 sk_sp<SkImageFilter> inputs[2] = { std::move(background), std::move(foregrou
nd) }; |
| 72 return sk_sp<SkImageFilter>(new SkXfermodeImageFilter_Base(mode, inputs, cro
pRect)); | 73 return sk_sp<SkImageFilter>(new SkXfermodeImageFilter_Base(mode, inputs, cro
pRect)); |
| 73 } | 74 } |
| 74 | 75 |
| 75 SkXfermodeImageFilter_Base::SkXfermodeImageFilter_Base(sk_sp<SkXfermode> mode, | 76 #ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT |
| 76 sk_sp<SkImageFilter> inputs[2], | 77 sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode, |
| 77 const CropRect* cropRect) | 78 sk_sp<SkImageFilter> background
, |
| 79 sk_sp<SkImageFilter> foreground
, |
| 80 const SkImageFilter::CropRect*
cropRect) { |
| 81 return Make(mode ? mode->blend() : SkBlendMode::kSrcOver, |
| 82 std::move(background), std::move(foreground), cropRect); |
| 83 } |
| 84 #endif |
| 85 |
| 86 SkXfermodeImageFilter_Base::SkXfermodeImageFilter_Base(SkBlendMode mode, |
| 87 sk_sp<SkImageFilter> inpu
ts[2], |
| 88 const CropRect* cropRect) |
| 78 : INHERITED(inputs, 2, cropRect) | 89 : INHERITED(inputs, 2, cropRect) |
| 79 , fMode(std::move(mode)) { | 90 , fMode(mode) |
| 91 {} |
| 92 |
| 93 static int unflatten_blendmode(SkReadBuffer& buffer, SkArithmeticParams* arith)
{ |
| 94 if (buffer.isVersionLT(SkReadBuffer::kXfermodeToBlendMode_Version)) { |
| 95 sk_sp<SkXfermode> xfer = buffer.readXfermode(); |
| 96 if (xfer) { |
| 97 if (xfer->isArithmetic(arith)) { |
| 98 return -1; |
| 99 } |
| 100 return (int)xfer->blend(); |
| 101 } else { |
| 102 return (int)SkBlendMode::kSrcOver; |
| 103 } |
| 104 } else { |
| 105 uint32_t mode = buffer.read32(); |
| 106 (void)buffer.validate(mode <= (unsigned)SkBlendMode::kLastMode); |
| 107 return mode; |
| 108 } |
| 80 } | 109 } |
| 81 | 110 |
| 82 sk_sp<SkFlattenable> SkXfermodeImageFilter_Base::CreateProc(SkReadBuffer& buffer
) { | 111 sk_sp<SkFlattenable> SkXfermodeImageFilter_Base::CreateProc(SkReadBuffer& buffer
) { |
| 83 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); | 112 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); |
| 84 sk_sp<SkXfermode> mode(buffer.readXfermode()); | 113 SkArithmeticParams arith; |
| 85 return SkXfermodeImageFilter::Make(std::move(mode), common.getInput(0), comm
on.getInput(1), | 114 int mode = unflatten_blendmode(buffer, &arith); |
| 86 &common.cropRect()); | 115 if (mode >= 0) { |
| 116 return SkXfermodeImageFilter::Make((SkBlendMode)mode, common.getInput(0)
, |
| 117 common.getInput(1), &common.cropRect(
)); |
| 118 } else { |
| 119 return SkXfermodeImageFilter::MakeArithmetic(arith.fK[0], arith.fK[1], a
rith.fK[2], |
| 120 arith.fK[3], arith.fEnforce
PMColor, |
| 121 common.getInput(0), |
| 122 common.getInput(1), &common
.cropRect()); |
| 123 } |
| 87 } | 124 } |
| 88 | 125 |
| 89 void SkXfermodeImageFilter_Base::flatten(SkWriteBuffer& buffer) const { | 126 void SkXfermodeImageFilter_Base::flatten(SkWriteBuffer& buffer) const { |
| 90 this->INHERITED::flatten(buffer); | 127 this->INHERITED::flatten(buffer); |
| 91 buffer.writeFlattenable(fMode.get()); | 128 buffer.write32((unsigned)fMode); |
| 92 } | 129 } |
| 93 | 130 |
| 94 sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage*
source, | 131 sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage*
source, |
| 95 const Context& ctx, | 132 const Context& ctx, |
| 96 SkIPoint* offset) con
st { | 133 SkIPoint* offset) con
st { |
| 97 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); | 134 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); |
| 98 sk_sp<SkSpecialImage> background(this->filterInput(0, source, ctx, &backgrou
ndOffset)); | 135 sk_sp<SkSpecialImage> background(this->filterInput(0, source, ctx, &backgrou
ndOffset)); |
| 99 | 136 |
| 100 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); | 137 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); |
| 101 sk_sp<SkSpecialImage> foreground(this->filterInput(1, source, ctx, &foregrou
ndOffset)); | 138 sk_sp<SkSpecialImage> foreground(this->filterInput(1, source, ctx, &foregrou
ndOffset)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 } | 177 } |
| 141 | 178 |
| 142 SkCanvas* canvas = surf->getCanvas(); | 179 SkCanvas* canvas = surf->getCanvas(); |
| 143 SkASSERT(canvas); | 180 SkASSERT(canvas); |
| 144 | 181 |
| 145 canvas->clear(0x0); // can't count on background to fully clear the backgrou
nd | 182 canvas->clear(0x0); // can't count on background to fully clear the backgrou
nd |
| 146 canvas->translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()
)); | 183 canvas->translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()
)); |
| 147 | 184 |
| 148 if (background) { | 185 if (background) { |
| 149 SkPaint paint; | 186 SkPaint paint; |
| 150 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 187 paint.setBlendMode(SkBlendMode::kSrc); |
| 151 background->draw(canvas, | 188 background->draw(canvas, |
| 152 SkIntToScalar(backgroundOffset.fX), SkIntToScalar(backg
roundOffset.fY), | 189 SkIntToScalar(backgroundOffset.fX), SkIntToScalar(backg
roundOffset.fY), |
| 153 &paint); | 190 &paint); |
| 154 } | 191 } |
| 155 | 192 |
| 156 this->drawForeground(canvas, foreground.get(), foregroundBounds); | 193 this->drawForeground(canvas, foreground.get(), foregroundBounds); |
| 157 | 194 |
| 158 return surf->makeImageSnapshot(); | 195 return surf->makeImageSnapshot(); |
| 159 } | 196 } |
| 160 | 197 |
| 161 void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage
* img, | 198 void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage
* img, |
| 162 const SkIRect& fgBounds) const { | 199 const SkIRect& fgBounds) const { |
| 163 SkPaint paint; | 200 SkPaint paint; |
| 164 paint.setXfermode(fMode); | 201 paint.setBlendMode(fMode); |
| 165 if (img) { | 202 if (img) { |
| 166 img->draw(canvas, SkIntToScalar(fgBounds.fLeft), SkIntToScalar(fgBounds.
fTop), &paint); | 203 img->draw(canvas, SkIntToScalar(fgBounds.fLeft), SkIntToScalar(fgBounds.
fTop), &paint); |
| 167 } | 204 } |
| 168 | 205 |
| 169 SkAutoCanvasRestore acr(canvas, true); | 206 SkAutoCanvasRestore acr(canvas, true); |
| 170 canvas->clipRect(SkRect::Make(fgBounds), SkCanvas::kDifference_Op); | 207 canvas->clipRect(SkRect::Make(fgBounds), SkCanvas::kDifference_Op); |
| 171 paint.setColor(0); | 208 paint.setColor(0); |
| 172 canvas->drawPaint(paint); | 209 canvas->drawPaint(paint); |
| 173 } | 210 } |
| 174 | 211 |
| 175 #ifndef SK_IGNORE_TO_STRING | 212 #ifndef SK_IGNORE_TO_STRING |
| 176 void SkXfermodeImageFilter_Base::toString(SkString* str) const { | 213 void SkXfermodeImageFilter_Base::toString(SkString* str) const { |
| 177 str->appendf("SkXfermodeImageFilter: ("); | 214 str->appendf("SkXfermodeImageFilter: ("); |
| 178 str->appendf("xfermode: ("); | 215 str->appendf("blendmode: (%d)", (int)fMode); |
| 179 if (fMode) { | |
| 180 fMode->toString(str); | |
| 181 } | |
| 182 str->append(")"); | |
| 183 if (this->getInput(0)) { | 216 if (this->getInput(0)) { |
| 184 str->appendf("foreground: ("); | 217 str->appendf("foreground: ("); |
| 185 this->getInput(0)->toString(str); | 218 this->getInput(0)->toString(str); |
| 186 str->appendf(")"); | 219 str->appendf(")"); |
| 187 } | 220 } |
| 188 if (this->getInput(1)) { | 221 if (this->getInput(1)) { |
| 189 str->appendf("background: ("); | 222 str->appendf("background: ("); |
| 190 this->getInput(1)->toString(str); | 223 this->getInput(1)->toString(str); |
| 191 str->appendf(")"); | 224 str->appendf(")"); |
| 192 } | 225 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 sk_sp<GrFragmentProcessor> xferFP = this->makeFGFrag(bgFP); | 292 sk_sp<GrFragmentProcessor> xferFP = this->makeFGFrag(bgFP); |
| 260 | 293 |
| 261 // A null 'xferFP' here means kSrc_Mode was used in which case we can ju
st proceed | 294 // A null 'xferFP' here means kSrc_Mode was used in which case we can ju
st proceed |
| 262 if (xferFP) { | 295 if (xferFP) { |
| 263 paint.addColorFragmentProcessor(std::move(xferFP)); | 296 paint.addColorFragmentProcessor(std::move(xferFP)); |
| 264 } | 297 } |
| 265 } else { | 298 } else { |
| 266 paint.addColorFragmentProcessor(std::move(bgFP)); | 299 paint.addColorFragmentProcessor(std::move(bgFP)); |
| 267 } | 300 } |
| 268 | 301 |
| 269 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); | 302 paint.setPorterDuffXPFactory(SkBlendMode::kSrc); |
| 270 | 303 |
| 271 sk_sp<GrDrawContext> drawContext( | 304 sk_sp<GrDrawContext> drawContext( |
| 272 context->makeDrawContext(SkBackingFit::kApprox, bounds.width(), bounds.h
eight(), | 305 context->makeDrawContext(SkBackingFit::kApprox, bounds.width(), bounds.h
eight(), |
| 273 GrRenderableConfigForColorSpace(outputPropertie
s.colorSpace()), | 306 GrRenderableConfigForColorSpace(outputPropertie
s.colorSpace()), |
| 274 sk_ref_sp(outputProperties.colorSpace()))); | 307 sk_ref_sp(outputProperties.colorSpace()))); |
| 275 if (!drawContext) { | 308 if (!drawContext) { |
| 276 return nullptr; | 309 return nullptr; |
| 277 } | 310 } |
| 278 paint.setGammaCorrect(drawContext->isGammaCorrect()); | 311 paint.setGammaCorrect(drawContext->isGammaCorrect()); |
| 279 | 312 |
| 280 SkMatrix matrix; | 313 SkMatrix matrix; |
| 281 matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top
())); | 314 matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top
())); |
| 282 drawContext->drawRect(GrNoClip(), paint, matrix, SkRect::Make(bounds)); | 315 drawContext->drawRect(GrNoClip(), paint, matrix, SkRect::Make(bounds)); |
| 283 | 316 |
| 284 return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.he
ight()), | 317 return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.he
ight()), |
| 285 kNeedNewImageUniqueID_SpecialImage, | 318 kNeedNewImageUniqueID_SpecialImage, |
| 286 drawContext->asTexture(), | 319 drawContext->asTexture(), |
| 287 sk_ref_sp(drawContext->getColorSpace())); | 320 sk_ref_sp(drawContext->getColorSpace())); |
| 288 } | 321 } |
| 289 | 322 |
| 290 sk_sp<GrFragmentProcessor> | 323 sk_sp<GrFragmentProcessor> |
| 291 SkXfermodeImageFilter_Base::makeFGFrag(sk_sp<GrFragmentProcessor> bgFP) const { | 324 SkXfermodeImageFilter_Base::makeFGFrag(sk_sp<GrFragmentProcessor> bgFP) const { |
| 292 // A null fMode is interpreted to mean kSrcOver_Mode (to match raster). | 325 // A null fMode is interpreted to mean kSrcOver_Mode (to match raster). |
| 293 SkAutoTUnref<SkXfermode> mode(SkSafeRef(fMode.get())); | 326 SkXfermode* xfer = SkXfermode::Peek(fMode); |
| 294 if (!mode) { | 327 sk_sp<SkXfermode> srcover; |
| 328 if (!xfer) { |
| 295 // It would be awesome to use SkXfermode::Create here but it knows bette
r | 329 // It would be awesome to use SkXfermode::Create here but it knows bette
r |
| 296 // than us and won't return a kSrcOver_Mode SkXfermode. That means we | 330 // than us and won't return a kSrcOver_Mode SkXfermode. That means we |
| 297 // have to get one the hard way. | 331 // have to get one the hard way. |
| 298 struct ProcCoeff rec; | 332 struct ProcCoeff rec; |
| 299 rec.fProc = SkXfermode::GetProc(SkXfermode::kSrcOver_Mode); | 333 rec.fProc = SkXfermode::GetProc(SkXfermode::kSrcOver_Mode); |
| 300 SkXfermode::ModeAsCoeff(SkXfermode::kSrcOver_Mode, &rec.fSC, &rec.fDC); | 334 SkXfermode::ModeAsCoeff(SkXfermode::kSrcOver_Mode, &rec.fSC, &rec.fDC); |
| 301 | 335 |
| 302 mode.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode)); | 336 srcover.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode)); |
| 337 xfer = srcover.get(); |
| 338 |
| 303 } | 339 } |
| 304 return mode->makeFragmentProcessorForImageFilter(std::move(bgFP)); | 340 return xfer->makeFragmentProcessorForImageFilter(std::move(bgFP)); |
| 305 } | 341 } |
| 306 | 342 |
| 307 #endif | 343 #endif |
| 308 | 344 |
| 309 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 345 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 310 | 346 |
| 311 class SkArithmeticImageFilter : public SkXfermodeImageFilter_Base { | 347 class SkArithmeticImageFilter : public SkXfermodeImageFilter_Base { |
| 312 public: | 348 public: |
| 313 SkArithmeticImageFilter(float k1, float k2, float k3, float k4, bool enforce
PMColor, | 349 SkArithmeticImageFilter(float k1, float k2, float k3, float k4, bool enforce
PMColor, |
| 314 sk_sp<SkImageFilter> inputs[2], const CropRect* crop
Rect) | 350 sk_sp<SkImageFilter> inputs[2], const CropRect* crop
Rect) |
| 315 : SkXfermodeImageFilter_Base(nullptr, inputs, cropRect) | 351 // need to pass a blendmode to our inherited constructor, but we ignore
it |
| 352 : SkXfermodeImageFilter_Base(SkBlendMode::kSrcOver, inputs, cropRect) |
| 316 , fK{ k1, k2, k3, k4 } | 353 , fK{ k1, k2, k3, k4 } |
| 317 , fEnforcePMColor(enforcePMColor) | 354 , fEnforcePMColor(enforcePMColor) |
| 318 {} | 355 {} |
| 319 | 356 |
| 320 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticImageFilter) | 357 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticImageFilter) |
| 321 | 358 |
| 322 protected: | 359 protected: |
| 323 void flatten(SkWriteBuffer& buffer) const override { | 360 void flatten(SkWriteBuffer& buffer) const override { |
| 324 this->INHERITED::flatten(buffer); | 361 this->INHERITED::flatten(buffer); |
| 325 for (int i = 0; i < 4; ++i) { | 362 for (int i = 0; i < 4; ++i) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 340 | 377 |
| 341 friend class SkXfermodeImageFilter; | 378 friend class SkXfermodeImageFilter; |
| 342 | 379 |
| 343 typedef SkXfermodeImageFilter_Base INHERITED; | 380 typedef SkXfermodeImageFilter_Base INHERITED; |
| 344 }; | 381 }; |
| 345 | 382 |
| 346 sk_sp<SkFlattenable> SkArithmeticImageFilter::CreateProc(SkReadBuffer& buffer) { | 383 sk_sp<SkFlattenable> SkArithmeticImageFilter::CreateProc(SkReadBuffer& buffer) { |
| 347 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); | 384 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); |
| 348 | 385 |
| 349 // skip the mode (srcover) our parent-class wrote | 386 // skip the mode (srcover) our parent-class wrote |
| 350 sk_sp<SkXfermode> mode(buffer.readXfermode()); | 387 SkDEBUGCODE(int mode =) unflatten_blendmode(buffer, nullptr); |
| 351 SkASSERT(nullptr == mode); | 388 if (!buffer.isValid()) { |
| 389 return nullptr; |
| 390 } |
| 391 SkASSERT(SkBlendMode::kSrcOver == (SkBlendMode)mode); |
| 352 | 392 |
| 353 float k[4]; | 393 float k[4]; |
| 354 for (int i = 0; i < 4; ++i) { | 394 for (int i = 0; i < 4; ++i) { |
| 355 k[i] = buffer.readScalar(); | 395 k[i] = buffer.readScalar(); |
| 356 } | 396 } |
| 357 const bool enforcePMColor = buffer.readBool(); | 397 const bool enforcePMColor = buffer.readBool(); |
| 358 return SkXfermodeImageFilter::MakeArithmetic(k[0], k[1], k[2], k[3], enforce
PMColor, | 398 return SkXfermodeImageFilter::MakeArithmetic(k[0], k[1], k[2], k[3], enforce
PMColor, |
| 359 common.getInput(0), common.getI
nput(1), | 399 common.getInput(0), common.getI
nput(1), |
| 360 &common.cropRect()); | 400 &common.cropRect()); |
| 361 } | 401 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 const SkImageFilter::
CropRect* crop) { | 508 const SkImageFilter::
CropRect* crop) { |
| 469 if (!SkScalarIsFinite(k1) || !SkScalarIsFinite(k2) || | 509 if (!SkScalarIsFinite(k1) || !SkScalarIsFinite(k2) || |
| 470 !SkScalarIsFinite(k3) || !SkScalarIsFinite(k4)) { | 510 !SkScalarIsFinite(k3) || !SkScalarIsFinite(k4)) { |
| 471 return nullptr; | 511 return nullptr; |
| 472 } | 512 } |
| 473 | 513 |
| 474 // are we nearly some other "std" mode? | 514 // are we nearly some other "std" mode? |
| 475 int mode = -1; // illegal mode | 515 int mode = -1; // illegal mode |
| 476 if (SkScalarNearlyZero(k1) && SkScalarNearlyEqual(k2, SK_Scalar1) && | 516 if (SkScalarNearlyZero(k1) && SkScalarNearlyEqual(k2, SK_Scalar1) && |
| 477 SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) { | 517 SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) { |
| 478 mode = SkXfermode::kSrc_Mode; | 518 mode = (int)SkBlendMode::kSrc; |
| 479 } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) && | 519 } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) && |
| 480 SkScalarNearlyEqual(k3, SK_Scalar1) && SkScalarNearlyZero(k4)) { | 520 SkScalarNearlyEqual(k3, SK_Scalar1) && SkScalarNearlyZero(k4)) { |
| 481 mode = SkXfermode::kDst_Mode; | 521 mode = (int)SkBlendMode::kDst; |
| 482 } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) && | 522 } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) && |
| 483 SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) { | 523 SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) { |
| 484 mode = SkXfermode::kClear_Mode; | 524 mode = (int)SkBlendMode::kClear; |
| 485 } | 525 } |
| 486 if (mode >= 0) { | 526 if (mode >= 0) { |
| 487 return SkXfermodeImageFilter::Make(SkXfermode::Make((SkXfermode::Mode)mo
de), | 527 return SkXfermodeImageFilter::Make((SkBlendMode)mode, |
| 488 std::move(background), std::move(fore
ground), crop); | 528 std::move(background), std::move(fore
ground), crop); |
| 489 } | 529 } |
| 490 | 530 |
| 491 sk_sp<SkImageFilter> inputs[2] = { std::move(background), std::move(foregrou
nd) }; | 531 sk_sp<SkImageFilter> inputs[2] = { std::move(background), std::move(foregrou
nd) }; |
| 492 return sk_sp<SkImageFilter>(new SkArithmeticImageFilter(k1, k2, k3, k4, enfo
rcePMColor, | 532 return sk_sp<SkImageFilter>(new SkArithmeticImageFilter(k1, k2, k3, k4, enfo
rcePMColor, |
| 493 inputs, crop)); | 533 inputs, crop)); |
| 494 } | 534 } |
| 495 | 535 |
| 496 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 536 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 497 | 537 |
| 498 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermodeImageFilter) | 538 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermodeImageFilter) |
| 499 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter_Base) | 539 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkXfermodeImageFilter_Base) |
| 500 // manually register the legacy serialized name "SkXfermodeImageFilter" | 540 // manually register the legacy serialized name "SkXfermodeImageFilter" |
| 501 SkFlattenable::Register("SkXfermodeImageFilter", SkXfermodeImageFilter_Base:
:CreateProc, | 541 SkFlattenable::Register("SkXfermodeImageFilter", SkXfermodeImageFilter_Base:
:CreateProc, |
| 502 SkFlattenable::kSkImageFilter_Type); | 542 SkFlattenable::kSkImageFilter_Type); |
| 503 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticImageFilter) | 543 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticImageFilter) |
| 504 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 544 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |