diff options
author | Mike Reed <reed@google.com> | 2009-09-23 14:44:41 -0400 |
---|---|---|
committer | Mike Reed <reed@google.com> | 2009-09-23 14:44:41 -0400 |
commit | d0195f840fa964da51f7a1192b432954794e660c (patch) | |
tree | 0522c7ea3107169aaffe93a8a616b4981615fe15 | |
parent | 924f59d3627a697f2b0df3299915e814e160f981 (diff) | |
download | skia-d0195f840fa964da51f7a1192b432954794e660c.tar.gz |
refresh from skia, with blitrow_d32 bottlenecks for neon optimizations
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | include/views/SkOSWindow_Mac.h | 4 | ||||
-rw-r--r-- | src/core/SkBlitRow.h | 40 | ||||
-rw-r--r-- | src/core/SkBlitRow_D16.cpp | 2 | ||||
-rw-r--r-- | src/core/SkBlitRow_D32.cpp | 112 | ||||
-rw-r--r-- | src/core/SkBlitter_ARGB32.cpp | 108 | ||||
-rw-r--r-- | src/core/SkComposeShader.cpp | 2 | ||||
-rw-r--r-- | src/core/SkCoreBlitters.h | 6 | ||||
-rw-r--r-- | src/core/SkSpriteBlitter_ARGB32.cpp | 116 | ||||
-rw-r--r-- | src/effects/SkColorFilters.cpp | 8 | ||||
-rw-r--r-- | src/opts/SkBlitRow_opts_arm.cpp | 7 | ||||
-rw-r--r-- | src/opts/SkBlitRow_opts_none.cpp | 7 |
12 files changed, 266 insertions, 147 deletions
diff --git a/Android.mk b/Android.mk index de09fd4901..5d27c91fa1 100644 --- a/Android.mk +++ b/Android.mk @@ -90,6 +90,7 @@ LOCAL_SRC_FILES:= \ src/core/SkBitmapProcState_matrixProcs.cpp \ src/core/SkBitmapSampler.cpp \ src/core/SkBlitRow_D16.cpp \ + src/core/SkBlitRow_D32.cpp \ src/core/SkBlitRow_D4444.cpp \ src/core/SkBlitter.cpp \ src/core/SkBlitter_4444.cpp \ diff --git a/include/views/SkOSWindow_Mac.h b/include/views/SkOSWindow_Mac.h index 47411516bf..98e76b032c 100644 --- a/include/views/SkOSWindow_Mac.h +++ b/include/views/SkOSWindow_Mac.h @@ -30,8 +30,8 @@ public: static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay); - static OSStatus SkOSWindow::EventHandler(EventHandlerCallRef inHandler, - EventRef inEvent, void* userData); + static OSStatus EventHandler(EventHandlerCallRef inHandler, + EventRef inEvent, void* userData); void doPaint(void* ctx); diff --git a/src/core/SkBlitRow.h b/src/core/SkBlitRow.h index ec31ff5309..dbbd84d182 100644 --- a/src/core/SkBlitRow.h +++ b/src/core/SkBlitRow.h @@ -6,7 +6,7 @@ class SkBlitRow { public: - enum { + enum Flags16 { //! If set, the alpha parameter will be != 255 kGlobalAlpha_Flag = 0x01, //! If set, the src colors may have alpha != 255 @@ -32,13 +32,51 @@ public: //! Public entry-point to return a blit function ptr static Proc Factory(unsigned flags, SkBitmap::Config); + ///////////// D32 version + + enum Flags32 { + kGlobalAlpha_Flag32 = 1 << 0, + kSrcPixelAlpha_Flag32 = 1 << 1, + }; + + /** Function pointer that blends 32bit colors onto a 32bit destination. + @param dst array of dst 32bit colors + @param src array of src 32bit colors (w/ or w/o alpha) + @param count number of colors to blend + @param alpha global alpha to be applied to all src colors + */ + typedef void (*Proc32)(uint32_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha); + + static Proc32 Factory32(unsigned flags32); + + /** Blend a single color onto a row of S32 pixels, writing the result + into a row of D32 pixels. src and dst may be the same memory, but + if they are not, they may not overlap. + */ + static void Color32(SkPMColor dst[], const SkPMColor src[], int count, + SkPMColor color); + + /** Blend a single color onto a row of 32bit pixels, writing the result + into the same row. + */ + static void Color32(SkPMColor row[], int count, SkPMColor color) { + Color32(row, row, count, color); + } + private: + enum { + kFlags16_Mask = 7, + kFlags32_Mask = 3 + }; /** These global arrays are indexed using the flags parameter to Factory, and contain either NULL, or a platform-specific function-ptr to be used in place of the system default. */ static const Proc gPlatform_565_Procs[]; static const Proc gPlatform_4444_Procs[]; + static const Proc32 gPlatform_Procs32[]; }; #endif diff --git a/src/core/SkBlitRow_D16.cpp b/src/core/SkBlitRow_D16.cpp index 1860d3bf9a..66ac90e29a 100644 --- a/src/core/SkBlitRow_D16.cpp +++ b/src/core/SkBlitRow_D16.cpp @@ -235,6 +235,8 @@ extern SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags); SkBlitRow::Proc SkBlitRow::Factory(unsigned flags, SkBitmap::Config config) { SkASSERT(flags < SK_ARRAY_COUNT(gDefault_565_Procs)); + // just so we don't crash + flags &= kFlags16_Mask; SkBlitRow::Proc proc = NULL; diff --git a/src/core/SkBlitRow_D32.cpp b/src/core/SkBlitRow_D32.cpp new file mode 100644 index 0000000000..f67bb9abae --- /dev/null +++ b/src/core/SkBlitRow_D32.cpp @@ -0,0 +1,112 @@ +#include "SkBlitRow.h" +#include "SkColorPriv.h" +#include "SkUtils.h" + +static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha) { + SkASSERT(255 == alpha); + memcpy(dst, src, count * sizeof(SkPMColor)); +} + +static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha) { + SkASSERT(alpha <= 255); + if (count > 0) { + unsigned src_scale = SkAlpha255To256(alpha); + unsigned dst_scale = 256 - src_scale; + do { + *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale); + src += 1; + dst += 1; + } while (--count > 0); + } +} + +//#define TEST_SRC_ALPHA + +static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha) { + SkASSERT(255 == alpha); + if (count > 0) { + do { +#ifdef TEST_SRC_ALPHA + SkPMColor sc = *src; + if (sc) { + unsigned srcA = SkGetPackedA32(sc); + SkPMColor result = sc; + if (srcA != 255) { + result = SkPMSrcOver(sc, *dst); + } + *dst = result; + } +#else + *dst = SkPMSrcOver(*src, *dst); +#endif + src += 1; + dst += 1; + } while (--count > 0); + } +} + +static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha) { + SkASSERT(alpha <= 255); + if (count > 0) { + do { + *dst = SkBlendARGB32(*src, *dst, alpha); + src += 1; + dst += 1; + } while (--count > 0); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +static const SkBlitRow::Proc32 gDefault_Procs32[] = { + S32_Opaque_BlitRow32, + S32_Blend_BlitRow32, + S32A_Opaque_BlitRow32, + S32A_Blend_BlitRow32 +}; + +SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) { + SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32)); + // just so we don't crash + flags &= kFlags32_Mask; + + SkBlitRow::Proc32 proc = gPlatform_Procs32[flags]; + if (NULL == proc) { + proc = gDefault_Procs32[flags]; + } + SkASSERT(proc); + return proc; +} + +void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[], int count, + SkPMColor color) { + if (count > 0) { + if (0 == color) { + if (src != dst) { + memcpy(dst, src, count * sizeof(SkPMColor)); + } + } + unsigned colorA = SkGetPackedA32(color); + if (255 == colorA) { + sk_memset32(dst, color, count); + } else { + unsigned scale = 256 - SkAlpha255To256(colorA); + do { + *dst = color + SkAlphaMulQ(*src, scale); + src += 1; + dst += 1; + } while (--count); + } + } +} + + + diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp index d3e5714e8f..37bd0da684 100644 --- a/src/core/SkBlitter_ARGB32.cpp +++ b/src/core/SkBlitter_ARGB32.cpp @@ -69,29 +69,7 @@ const SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) { void SkARGB32_Blitter::blitH(int x, int y, int width) { SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); - if (fSrcA == 0) { - return; - } - - uint32_t* device = fDevice.getAddr32(x, y); - - if (fSrcA == 255) { - sk_memset32(device, fPMColor, width); - } else { - uint32_t color = fPMColor; - unsigned dst_scale = SkAlpha255To256(255 - fSrcA); - uint32_t prevDst = ~device[0]; // so we always fail the test the first time - uint32_t result SK_INIT_TO_AVOID_WARNING; - - for (int i = 0; i < width; i++) { - uint32_t currDst = device[i]; - if (currDst != prevDst) { - result = color + SkAlphaMulQ(currDst, dst_scale); - prevDst = currDst; - } - device[i] = result; - } - } + SkBlitRow::Color32(fDevice.getAddr32(x, y), width, fPMColor); } void SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], @@ -115,13 +93,8 @@ void SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], if ((opaqueMask & aa) == 255) { sk_memset32(device, color, count); } else { - uint32_t sc = SkAlphaMulQ(color, aa); - unsigned dst_scale = 255 - SkGetPackedA32(sc); - int n = count; - do { - --n; - device[n] = sc + SkAlphaMulQ(device[n], dst_scale); - } while (n > 0); + uint32_t sc = SkAlphaMulQ(color, SkAlpha255To256(aa)); + SkBlitRow::Color32(device, count, sc); } } runs += count; @@ -310,29 +283,11 @@ void SkARGB32_Blitter::blitRect(int x, int y, int width, int height) { uint32_t* device = fDevice.getAddr32(x, y); uint32_t color = fPMColor; + size_t rowBytes = fDevice.rowBytes(); - if (fSrcA == 255) { - while (--height >= 0) { - sk_memset32(device, color, width); - device = (uint32_t*)((char*)device + fDevice.rowBytes()); - } - } else { - unsigned dst_scale = SkAlpha255To256(255 - fSrcA); - - while (--height >= 0) { - uint32_t prevDst = ~device[0]; - uint32_t result SK_INIT_TO_AVOID_WARNING; - - for (int i = 0; i < width; i++) { - uint32_t dst = device[i]; - if (dst != prevDst) { - result = color + SkAlphaMulQ(dst, dst_scale); - prevDst = dst; - } - device[i] = result; - } - device = (uint32_t*)((char*)device + fDevice.rowBytes()); - } + while (--height >= 0) { + SkBlitRow::Color32(device, width, color); + device = (uint32_t*)((char*)device + rowBytes); } } @@ -440,11 +395,20 @@ void SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], ////////////////////////////////////////////////////////////////////////////////////////// SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkBitmap& device, - const SkPaint& paint) - : INHERITED(device, paint) { + const SkPaint& paint) : INHERITED(device, paint) { fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor))); - (fXfermode = paint.getXfermode())->safeRef(); + fXfermode = paint.getXfermode(); + SkSafeRef(fXfermode); + + int flags = 0; + if (!(fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) { + flags |= SkBlitRow::kSrcPixelAlpha_Flag32; + } + // we call this on the output from the shader + fProc32 = SkBlitRow::Factory32(flags); + // we call this on the output from the shader + alpha from the aa buffer + fProc32Blend = SkBlitRow::Factory32(flags | SkBlitRow::kGlobalAlpha_Flag32); } SkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() { @@ -465,16 +429,7 @@ void SkARGB32_Shader_Blitter::blitH(int x, int y, int width) { if (fXfermode) { fXfermode->xfer32(device, span, width, NULL); } else { - for (int i = 0; i < width; i++) { - uint32_t src = span[i]; - if (src) { - unsigned srcA = SkGetPackedA32(src); - if (srcA != 0xFF) { - src += SkAlphaMulQ(device[i], SkAlpha255To256(255 - srcA)); - } - device[i] = src; - } - } + fProc32(device, span, width, 255); } } } @@ -519,15 +474,12 @@ void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], } int aa = *antialias; if (aa) { - if (aa == 255) { // cool, have the shader draw right into the device + if (aa == 255) { + // cool, have the shader draw right into the device shader->shadeSpan(x, y, device, count); } else { shader->shadeSpan(x, y, span, count); - for (int i = count - 1; i >= 0; --i) { - if (span[i]) { - device[i] = SkBlendARGB32(span[i], device[i], aa); - } - } + fProc32Blend(device, span, count, aa); } } device += count; @@ -535,7 +487,7 @@ void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], antialias += count; x += count; } - } else { // no xfermode but we are not opaque + } else { // no xfermode but the shader not opaque for (;;) { int count = *runs; if (count <= 0) { @@ -545,17 +497,9 @@ void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], if (aa) { fShader->shadeSpan(x, y, span, count); if (aa == 255) { - for (int i = count - 1; i >= 0; --i) { - if (span[i]) { - device[i] = SkPMSrcOver(span[i], device[i]); - } - } + fProc32(device, span, count, 255); } else { - for (int i = count - 1; i >= 0; --i) { - if (span[i]) { - device[i] = SkBlendARGB32(span[i], device[i], aa); - } - } + fProc32Blend(device, span, count, aa); } } device += count; diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp index 1e5e202b8e..7e566a3d2e 100644 --- a/src/core/SkComposeShader.cpp +++ b/src/core/SkComposeShader.cpp @@ -124,6 +124,8 @@ void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) if (NULL == mode) // implied SRC_OVER { + // TODO: when we have a good test-case, should use SkBlitRow::Proc32 + // for these loops do { int n = count; if (n > TMP_COLOR_COUNT) diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h index 5e34685a08..84f8fa6524 100644 --- a/src/core/SkCoreBlitters.h +++ b/src/core/SkCoreBlitters.h @@ -141,8 +141,10 @@ public: virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]); private: - SkXfermode* fXfermode; - SkPMColor* fBuffer; + SkXfermode* fXfermode; + SkPMColor* fBuffer; + SkBlitRow::Proc32 fProc32; + SkBlitRow::Proc32 fProc32Blend; // illegal SkARGB32_Shader_Blitter& operator=(const SkARGB32_Shader_Blitter&); diff --git a/src/core/SkSpriteBlitter_ARGB32.cpp b/src/core/SkSpriteBlitter_ARGB32.cpp index 6addde7b0f..01ee9f1f69 100644 --- a/src/core/SkSpriteBlitter_ARGB32.cpp +++ b/src/core/SkSpriteBlitter_ARGB32.cpp @@ -16,64 +16,58 @@ */ #include "SkSpriteBlitter.h" +#include "SkBlitRow.h" +#include "SkColorFilter.h" +#include "SkColorPriv.h" #include "SkTemplates.h" #include "SkUtils.h" -#include "SkColorPriv.h" - -#define D32_S32A_Opaque_Pixel(dst, sc) \ -do { \ - if (sc) { \ - unsigned srcA = SkGetPackedA32(sc); \ - uint32_t result = sc; \ - if (srcA != 0xFF) { \ - result += SkAlphaMulQ(*dst, SkAlpha255To256(255 - srcA)); \ - } \ - *dst = result; \ - } \ -} while (0) - -#define SkSPRITE_CLASSNAME Sprite_D32_S32A_Opaque -#define SkSPRITE_ARGS -#define SkSPRITE_FIELDS -#define SkSPRITE_INIT -#define SkSPRITE_DST_TYPE uint32_t -#define SkSPRITE_SRC_TYPE uint32_t -#define SkSPRITE_DST_GETADDR getAddr32 -#define SkSPRITE_SRC_GETADDR getAddr32 -#define SkSPRITE_PREAMBLE(srcBM, x, y) -#define SkSPRITE_BLIT_PIXEL(dst, src) D32_S32A_Opaque_Pixel(dst, src) -#define SkSPRITE_NEXT_ROW -#define SkSPRITE_POSTAMBLE(srcBM) -#include "SkSpriteBlitterTemplate.h" +#include "SkXfermode.h" /////////////////////////////////////////////////////////////////////////////// -class Sprite_D32_S32_Opaque : public SkSpriteBlitter { +class Sprite_D32_S32 : public SkSpriteBlitter { public: - Sprite_D32_S32_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {} + Sprite_D32_S32(const SkBitmap& src, U8CPU alpha) : INHERITED(src) { + SkASSERT(src.config() == SkBitmap::kARGB_8888_Config); + + unsigned flags32 = 0; + if (255 != alpha) { + flags32 |= SkBlitRow::kGlobalAlpha_Flag32; + } + if (!src.isOpaque()) { + flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; + } + fProc32 = SkBlitRow::Factory32(flags32); + fAlpha = alpha; + } + virtual void blitRect(int x, int y, int width, int height) { SkASSERT(width > 0 && height > 0); SK_RESTRICT uint32_t* dst = fDevice->getAddr32(x, y); const SK_RESTRICT uint32_t* src = fSource->getAddr32(x - fLeft, y - fTop); - unsigned dstRB = fDevice->rowBytes(); - unsigned srcRB = fSource->rowBytes(); - size_t size = width * sizeof(uint32_t); + size_t dstRB = fDevice->rowBytes(); + size_t srcRB = fSource->rowBytes(); + SkBlitRow::Proc32 proc = fProc32; + U8CPU alpha = fAlpha; do { - memcpy(dst, src, size); + proc(dst, src, width, alpha); dst = (SK_RESTRICT uint32_t*)((char*)dst + dstRB); src = (const SK_RESTRICT uint32_t*)((const char*)src + srcRB); } while (--height != 0); } + +private: + SkBlitRow::Proc32 fProc32; + U8CPU fAlpha; + + typedef SkSpriteBlitter INHERITED; }; /////////////////////////////////////////////////////////////////////////////// -#include "SkColorFilter.h" -#include "SkXfermode.h" - class Sprite_D32_XferFilter : public SkSpriteBlitter { public: Sprite_D32_XferFilter(const SkBitmap& source, const SkPaint& paint) @@ -86,6 +80,17 @@ public: fBufferSize = 0; fBuffer = NULL; + + unsigned flags32 = 0; + if (255 != paint.getAlpha()) { + flags32 |= SkBlitRow::kGlobalAlpha_Flag32; + } + if (!source.isOpaque()) { + flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; + } + + fProc32 = SkBlitRow::Factory32(flags32); + fAlpha = paint.getAlpha(); } virtual ~Sprite_D32_XferFilter() { @@ -107,11 +112,13 @@ public: } protected: - SkColorFilter* fColorFilter; - SkXfermode* fXfermode; - int fBufferSize; - SkPMColor* fBuffer; - + SkColorFilter* fColorFilter; + SkXfermode* fXfermode; + int fBufferSize; + SkPMColor* fBuffer; + SkBlitRow::Proc32 fProc32; + U8CPU fAlpha; + private: typedef SkSpriteBlitter INHERITED; }; @@ -144,9 +151,7 @@ public: if (NULL != xfermode) { xfermode->xfer32(dst, tmp, width, NULL); } else { - for (int i = 0; i < width; i++) { - dst[i] = SkPMSrcOver(tmp[i], dst[i]); - } + fProc32(dst, tmp, width, fAlpha); } dst = (SK_RESTRICT uint32_t*)((char*)dst + dstRB); @@ -192,9 +197,7 @@ public: if (NULL != xfermode) { xfermode->xfer32(dst, buffer, width, NULL); } else { - for (int i = 0; i < width; i++) { - dst[i] = SkPMSrcOver(buffer[i], dst[i]); - } + fProc32(dst, buffer, width, fAlpha); } dst = (SK_RESTRICT SkPMColor*)((char*)dst + dstRB); @@ -273,16 +276,20 @@ public: SkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, const SkPaint& paint, void* storage, size_t storageSize) { - if (paint.getMaskFilter() != NULL || paint.getAlpha() != 0xFF) { + if (paint.getMaskFilter() != NULL) { return NULL; } + U8CPU alpha = paint.getAlpha(); SkXfermode* xfermode = paint.getXfermode(); SkColorFilter* filter = paint.getColorFilter(); SkSpriteBlitter* blitter = NULL; switch (source.getConfig()) { case SkBitmap::kARGB_4444_Config: + if (alpha != 0xFF) { + return NULL; // we only have opaque sprites + } if (xfermode || filter) { SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_XferFilter, storage, storageSize, (source, paint)); @@ -296,14 +303,15 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, break; case SkBitmap::kARGB_8888_Config: if (xfermode || filter) { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_XferFilter, + if (255 == alpha) { + // this can handle xfermode or filter, but not alpha + SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_XferFilter, storage, storageSize, (source, paint)); - } else if (source.isOpaque()) { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32_Opaque, - storage, storageSize, (source)); + } } else { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_Opaque, - storage, storageSize, (source)); + // this can handle alpha, but not xfermode or filter + SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32, + storage, storageSize, (source, alpha)); } break; default: diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp index 0bb3ae595a..733e1aea8e 100644 --- a/src/effects/SkColorFilters.cpp +++ b/src/effects/SkColorFilters.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "SkBlitRow.h" #include "SkColorFilter.h" #include "SkColorPriv.h" #include "SkUtils.h" @@ -86,12 +87,7 @@ public: virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) { - SkPMColor src = fPMColor; - unsigned scale = SkAlpha255To256(255 - SkGetPackedA32(src)); - - for (int i = 0; i < count; i++) { - result[i] = src + SkAlphaMulQ(shader[i], scale); - } + SkBlitRow::Color32(result, shader, count, fPMColor); } virtual void filterSpan16(const uint16_t shader[], int count, diff --git a/src/opts/SkBlitRow_opts_arm.cpp b/src/opts/SkBlitRow_opts_arm.cpp index 9ed6ef5885..0c38113adf 100644 --- a/src/opts/SkBlitRow_opts_arm.cpp +++ b/src/opts/SkBlitRow_opts_arm.cpp @@ -443,3 +443,10 @@ const SkBlitRow::Proc SkBlitRow::gPlatform_4444_Procs[] = { NULL, // S32A_D4444_Blend_Dither }; +const SkBlitRow::Proc32 SkBlitRow::gPlatform_Procs32[] = { + NULL, // S32_Opaque, + NULL, // S32_Blend, + NULL, // S32A_Opaque, + NULL, // S32A_Blend, +}; + diff --git a/src/opts/SkBlitRow_opts_none.cpp b/src/opts/SkBlitRow_opts_none.cpp index 88ab7c4203..7a777597c8 100644 --- a/src/opts/SkBlitRow_opts_none.cpp +++ b/src/opts/SkBlitRow_opts_none.cpp @@ -30,3 +30,10 @@ const SkBlitRow::Proc SkBlitRow::gPlatform_4444_Procs[] = { NULL, // S32A_D4444_Blend_Dither }; +const SkBlitRow::Proc32 SkBlitRow::gPlatform_Procs32[] = { + NULL, // S32_Opaque, + NULL, // S32_Blend, + NULL, // S32A_Opaque, + NULL, // S32A_Blend, +}; + |