From 258dd617d0eeb9d23e6be0aca26be2504ccc33f6 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Thu, 6 Apr 2023 14:12:42 -0400 Subject: [PATCH] Remove xfermode support from legacy shader blitter Change-Id: I0f7e96af54d0e1d5b08b0d58b61c85e2db3bac36 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/667578 Reviewed-by: Kevin Lubick Commit-Queue: Brian Osman --- src/core/SkBlitter.cpp | 45 ++------ src/core/SkBlitter_ARGB32.cpp | 211 ++++++++-------------------------- src/core/SkCoreBlitters.h | 1 - 3 files changed, 63 insertions(+), 194 deletions(-) diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 5bc696c9594b..688e7f56e4b2 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -661,29 +661,15 @@ bool SkBlitter::UseLegacyBlitter(const SkPixmap& device, return false; } -#if !defined(SK_USE_LEGACY_XFERMODE_SHADER_BLITTERS) - if (!paint.isSrcOver()) { - return false; - } -#endif - const SkMaskFilterBase* mf = as_MFB(paint.getMaskFilter()); - const auto mode = paint.asBlendMode(); - // The legacy blitters cannot handle any of these complex features (anymore). + // The legacy blitters cannot handle any of these "complex" features (anymore). if (device.alphaType() == kUnpremul_SkAlphaType || - !mode || - mode.value() > SkBlendMode::kLastCoeffMode || + !paint.isSrcOver() || (mf && mf->getFormat() == SkMask::k3D_Format)) { return false; } - // All the real legacy fast paths are for shaders and SrcOver. - // Choosing SkRasterPipelineBlitter will also let us to hit its single-color memset path. - if (!paint.getShader() && mode != SkBlendMode::kSrcOver) { - return false; - } - auto cs = device.colorSpace(); // We check (indirectly via makeContext()) later on if the shader can handle the colorspace // in legacy mode, so here we just focus on if a single color needs raster-pipeline. @@ -791,8 +777,8 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, // Everything but legacy kN32_SkColorType should already be handled. SkASSERT(device.colorType() == kN32_SkColorType); - // And we should either have a shader, be blending with SrcOver, or both. - SkASSERT(paint->getShader() || paint->asBlendMode() == SkBlendMode::kSrcOver); + // And we should be blending with SrcOver + SkASSERT(paint->asBlendMode() == SkBlendMode::kSrcOver); // Legacy blitters keep their shader state on a shader context. SkShaderBase::Context* shaderContext = nullptr; @@ -807,21 +793,14 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, } } - switch (device.colorType()) { - case kN32_SkColorType: - if (shaderContext) { - return alloc->make(device, *paint, shaderContext); - } else if (paint->getColor() == SK_ColorBLACK) { - return alloc->make(device, *paint); - } else if (paint->getAlpha() == 0xFF) { - return alloc->make(device, *paint); - } else { - return alloc->make(device, *paint); - } - - default: - SkASSERT(false); - return alloc->make(); + if (shaderContext) { + return alloc->make(device, *paint, shaderContext); + } else if (paint->getColor() == SK_ColorBLACK) { + return alloc->make(device, *paint); + } else if (paint->getAlpha() == 0xFF) { + return alloc->make(device, *paint); + } else { + return alloc->make(device, *paint); } } diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp index fbb5322080f3..e4086982ca22 100644 --- a/src/core/SkBlitter_ARGB32.cpp +++ b/src/core/SkBlitter_ARGB32.cpp @@ -10,7 +10,6 @@ #include "src/base/SkVx.h" #include "src/core/SkCoreBlitters.h" #include "src/core/SkOpts.h" -#include "src/core/SkXfermodePriv.h" static inline int upscale_31_to_32(int value) { SkASSERT((unsigned)value <= 31); @@ -950,24 +949,13 @@ void SkARGB32_Black_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) { /////////////////////////////////////////////////////////////////////////////// -// Special version of SkBlitRow::Factory32 that knows we're in kSrc_Mode, -// instead of kSrcOver_Mode -static void blend_srcmode(SkPMColor* SK_RESTRICT device, - const SkPMColor* SK_RESTRICT span, - int count, U8CPU aa) { - int aa256 = SkAlpha255To256(aa); - for (int i = 0; i < count; ++i) { - device[i] = SkFourByteInterp256(span[i], device[i], aa256); - } -} - SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, SkShaderBase::Context* shaderContext) : INHERITED(device, paint, shaderContext) { fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor))); - fXfermode = SkXfermode::Peek(paint.getBlendMode_or(SkBlendMode::kSrcOver)); + SkASSERT(paint.isSrcOver()); int flags = 0; if (!(shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)) { @@ -978,18 +966,8 @@ SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device, // we call this on the output from the shader + alpha from the aa buffer fProc32Blend = SkBlitRow::Factory32(flags | SkBlitRow::kGlobalAlpha_Flag32); - fShadeDirectlyIntoDevice = false; - if (fXfermode == nullptr) { - if (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) { - fShadeDirectlyIntoDevice = true; - } - } else { - if (SkBlendMode::kSrc == paint.asBlendMode()) { - fShadeDirectlyIntoDevice = true; - fProc32Blend = blend_srcmode; - } - } - + fShadeDirectlyIntoDevice = + SkToBool(shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag); fConstInY = SkToBool(shaderContext->getFlags() & SkShaderBase::kConstInY32_Flag); } @@ -1007,11 +985,7 @@ void SkARGB32_Shader_Blitter::blitH(int x, int y, int width) { } else { SkPMColor* span = fBuffer; fShaderContext->shadeSpan(x, y, span, width); - if (fXfermode) { - fXfermode->xfer32(device, span, width, nullptr); - } else { - fProc32(device, span, width, 255); - } + fProc32(device, span, width, 255); } } @@ -1035,21 +1009,12 @@ void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { } } else { shaderContext->shadeSpan(x, y, span, width); - SkXfermode* xfer = fXfermode; - if (xfer) { - do { - xfer->xfer32(device, span, width, nullptr); - y += 1; - device = (uint32_t*)((char*)device + deviceRB); - } while (--height > 0); - } else { - SkBlitRow::Proc32 proc = fProc32; - do { - proc(device, span, width, 255); - y += 1; - device = (uint32_t*)((char*)device + deviceRB); - } while (--height > 0); - } + SkBlitRow::Proc32 proc = fProc32; + do { + proc(device, span, width, 255); + y += 1; + device = (uint32_t*)((char*)device + deviceRB); + } while (--height > 0); } return; } @@ -1061,23 +1026,13 @@ void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { device = (uint32_t*)((char*)device + deviceRB); } while (--height > 0); } else { - SkXfermode* xfer = fXfermode; - if (xfer) { - do { - shaderContext->shadeSpan(x, y, span, width); - xfer->xfer32(device, span, width, nullptr); - y += 1; - device = (uint32_t*)((char*)device + deviceRB); - } while (--height > 0); - } else { - SkBlitRow::Proc32 proc = fProc32; - do { - shaderContext->shadeSpan(x, y, span, width); - proc(device, span, width, 255); - y += 1; - device = (uint32_t*)((char*)device + deviceRB); - } while (--height > 0); - } + SkBlitRow::Proc32 proc = fProc32; + do { + shaderContext->shadeSpan(x, y, span, width); + proc(device, span, width, 255); + y += 1; + device = (uint32_t*)((char*)device + deviceRB); + } while (--height > 0); } } @@ -1087,32 +1042,7 @@ void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], uint32_t* device = fDevice.writable_addr32(x, y); auto* shaderContext = fShaderContext; - if (fXfermode && !fShadeDirectlyIntoDevice) { - for (;;) { - SkXfermode* xfer = fXfermode; - - int count = *runs; - if (count <= 0) - break; - int aa = *antialias; - if (aa) { - shaderContext->shadeSpan(x, y, span, count); - if (aa == 255) { - xfer->xfer32(device, span, count, nullptr); - } else { - // count is almost always 1 - for (int i = count - 1; i >= 0; --i) { - xfer->xfer32(&device[i], &span[i], 1, antialias); - } - } - } - device += count; - runs += count; - antialias += count; - x += count; - } - } else if (fShadeDirectlyIntoDevice || - (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)) { + if (fShadeDirectlyIntoDevice || (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)) { for (;;) { int count = *runs; if (count <= 0) { @@ -1280,31 +1210,23 @@ static void blend_row_LCD16_opaque(SkPMColor* dst, const void* vmask, const SkPM } void SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) { - // we only handle kA8 with an xfermode - if (fXfermode && (SkMask::kA8_Format != mask.fFormat)) { - this->INHERITED::blitMask(mask, clip); - return; - } - SkASSERT(mask.fBounds.contains(clip)); void (*blend_row)(SkPMColor*, const void* mask, const SkPMColor*, int) = nullptr; - if (!fXfermode) { - bool opaque = (fShaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag); - - if (mask.fFormat == SkMask::kA8_Format && opaque) { - blend_row = blend_row_A8_opaque; - } else if (mask.fFormat == SkMask::kA8_Format) { - blend_row = blend_row_A8; - } else if (mask.fFormat == SkMask::kLCD16_Format && opaque) { - blend_row = blend_row_LCD16_opaque; - } else if (mask.fFormat == SkMask::kLCD16_Format) { - blend_row = blend_row_lcd16; - } else { - this->INHERITED::blitMask(mask, clip); - return; - } + bool opaque = (fShaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag); + + if (mask.fFormat == SkMask::kA8_Format && opaque) { + blend_row = blend_row_A8_opaque; + } else if (mask.fFormat == SkMask::kA8_Format) { + blend_row = blend_row_A8; + } else if (mask.fFormat == SkMask::kLCD16_Format && opaque) { + blend_row = blend_row_LCD16_opaque; + } else if (mask.fFormat == SkMask::kLCD16_Format) { + blend_row = blend_row_lcd16; + } else { + this->INHERITED::blitMask(mask, clip); + return; } const int x = clip.fLeft; @@ -1318,27 +1240,14 @@ void SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) const size_t maskRB = mask.fRowBytes; SkPMColor* span = fBuffer; - - if (fXfermode) { - SkASSERT(SkMask::kA8_Format == mask.fFormat); - SkXfermode* xfer = fXfermode; - do { - fShaderContext->shadeSpan(x, y, span, width); - xfer->xfer32(reinterpret_cast(dstRow), span, width, maskRow); - dstRow += dstRB; - maskRow += maskRB; - y += 1; - } while (--height > 0); - } else { - SkASSERT(blend_row); - do { - fShaderContext->shadeSpan(x, y, span, width); - blend_row(reinterpret_cast(dstRow), maskRow, span, width); - dstRow += dstRB; - maskRow += maskRB; - y += 1; - } while (--height > 0); - } + SkASSERT(blend_row); + do { + fShaderContext->shadeSpan(x, y, span, width); + blend_row(reinterpret_cast(dstRow), maskRow, span, width); + dstRow += dstRB; + maskRow += maskRB; + y += 1; + } while (--height > 0); } void SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { @@ -1364,19 +1273,11 @@ void SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { } while (--height > 0); } } else { - SkXfermode* xfer = fXfermode; - if (xfer) { - do { - xfer->xfer32(device, &c, 1, &alpha); - device = (uint32_t*)((char*)device + deviceRB); - } while (--height > 0); - } else { - SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend; - do { - proc(device, &c, 1, alpha); - device = (uint32_t*)((char*)device + deviceRB); - } while (--height > 0); - } + SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend; + do { + proc(device, &c, 1, alpha); + device = (uint32_t*)((char*)device + deviceRB); + } while (--height > 0); } return; } @@ -1399,22 +1300,12 @@ void SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { } } else { SkPMColor* span = fBuffer; - SkXfermode* xfer = fXfermode; - if (xfer) { - do { - fShaderContext->shadeSpan(x, y, span, 1); - xfer->xfer32(device, span, 1, &alpha); - y += 1; - device = (uint32_t*)((char*)device + deviceRB); - } while (--height > 0); - } else { - SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend; - do { - fShaderContext->shadeSpan(x, y, span, 1); - proc(device, span, 1, alpha); - y += 1; - device = (uint32_t*)((char*)device + deviceRB); - } while (--height > 0); - } + SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend; + do { + fShaderContext->shadeSpan(x, y, span, 1); + proc(device, span, 1, alpha); + y += 1; + device = (uint32_t*)((char*)device + deviceRB); + } while (--height > 0); } } diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h index aa658a63bf3d..a131c95a8a96 100644 --- a/src/core/SkCoreBlitters.h +++ b/src/core/SkCoreBlitters.h @@ -116,7 +116,6 @@ class SkARGB32_Shader_Blitter : public SkShaderBlitter { void blitMask(const SkMask&, const SkIRect&) override; private: - SkXfermode* fXfermode; SkPMColor* fBuffer; SkBlitRow::Proc32 fProc32; SkBlitRow::Proc32 fProc32Blend;