aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Reed <reed@google.com>2009-09-23 14:44:41 -0400
committerMike Reed <reed@google.com>2009-09-23 14:44:41 -0400
commitd0195f840fa964da51f7a1192b432954794e660c (patch)
tree0522c7ea3107169aaffe93a8a616b4981615fe15
parent924f59d3627a697f2b0df3299915e814e160f981 (diff)
downloadskia-d0195f840fa964da51f7a1192b432954794e660c.tar.gz
refresh from skia, with blitrow_d32 bottlenecks for neon optimizations
-rw-r--r--Android.mk1
-rw-r--r--include/views/SkOSWindow_Mac.h4
-rw-r--r--src/core/SkBlitRow.h40
-rw-r--r--src/core/SkBlitRow_D16.cpp2
-rw-r--r--src/core/SkBlitRow_D32.cpp112
-rw-r--r--src/core/SkBlitter_ARGB32.cpp108
-rw-r--r--src/core/SkComposeShader.cpp2
-rw-r--r--src/core/SkCoreBlitters.h6
-rw-r--r--src/core/SkSpriteBlitter_ARGB32.cpp116
-rw-r--r--src/effects/SkColorFilters.cpp8
-rw-r--r--src/opts/SkBlitRow_opts_arm.cpp7
-rw-r--r--src/opts/SkBlitRow_opts_none.cpp7
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,
+};
+