diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-15 13:07:48 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-15 13:07:48 +0000 |
commit | 9f63667ff221b72e96fa6a044ccb0dde12af6ebe (patch) | |
tree | 171323d9b062b6c9cfd3fb26aacef4a8f22b11f1 /src/core | |
parent | b4f06d7605081e1e0ce794621063f37aee41b1d4 (diff) |
special-case filling narrow rects, where we can be faster than the SSE2 asm
git-svn-id: http://skia.googlecode.com/svn/trunk@3932 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBlitRow_D32.cpp | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/src/core/SkBlitRow_D32.cpp b/src/core/SkBlitRow_D32.cpp index f1bf0ca1e1..7ed07f3051 100644 --- a/src/core/SkBlitRow_D32.cpp +++ b/src/core/SkBlitRow_D32.cpp @@ -180,12 +180,76 @@ void SkBlitRow::Color32(SkPMColor* SK_RESTRICT dst, } } +template <size_t N> void assignLoop(SkPMColor* dst, SkPMColor color) { + for (size_t i = 0; i < N; ++i) { + *dst++ = color; + } +} + +static inline void assignLoop(SkPMColor dst[], SkPMColor color, int count) { + while (count >= 4) { + *dst++ = color; + *dst++ = color; + *dst++ = color; + *dst++ = color; + count -= 4; + } + if (count >= 2) { + *dst++ = color; + *dst++ = color; + count -= 2; + } + if (count > 0) { + *dst++ = color; + } +} + void SkBlitRow::ColorRect32(SkPMColor* dst, int width, int height, size_t rowBytes, SkPMColor color) { - SkBlitRow::ColorProc proc = SkBlitRow::ColorProcFactory(); - while (--height >= 0) { - (*proc)(dst, dst, width, color); - dst = (SkPMColor*) ((char*)dst + rowBytes); + if (width <= 0 || height <= 0 || 0 == color) { + return; + } + + // Just made up this value, since I saw it once in a SSE2 file. + // We should consider writing some tests to find the optimimal break-point + // (or query the Platform proc?) + static const int MIN_WIDTH_FOR_SCANLINE_PROC = 32; + + bool isOpaque = (0xFF == SkGetPackedA32(color)); + + if (!isOpaque || width >= MIN_WIDTH_FOR_SCANLINE_PROC) { + SkBlitRow::ColorProc proc = SkBlitRow::ColorProcFactory(); + while (--height >= 0) { + (*proc)(dst, dst, width, color); + dst = (SkPMColor*) ((char*)dst + rowBytes); + } + } else { + switch (width) { + case 1: + while (--height >= 0) { + assignLoop<1>(dst, color); + dst = (SkPMColor*) ((char*)dst + rowBytes); + } + break; + case 2: + while (--height >= 0) { + assignLoop<2>(dst, color); + dst = (SkPMColor*) ((char*)dst + rowBytes); + } + break; + case 3: + while (--height >= 0) { + assignLoop<3>(dst, color); + dst = (SkPMColor*) ((char*)dst + rowBytes); + } + break; + default: + while (--height >= 0) { + assignLoop(dst, color, width); + dst = (SkPMColor*) ((char*)dst + rowBytes); + } + break; + } } } |