epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2006 The Android Open Source Project |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 8 | #include "SkSpriteBlitter.h" |
Herb Derby | 57bfa02 | 2017-02-09 17:25:43 -0500 | [diff] [blame^] | 9 | #include "SkArenaAlloc.h" |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 10 | #include "SkBlitRow.h" |
| 11 | #include "SkColorFilter.h" |
| 12 | #include "SkColorPriv.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 13 | #include "SkTemplates.h" |
| 14 | #include "SkUtils.h" |
Mike Reed | d470673 | 2016-11-15 16:44:34 -0500 | [diff] [blame] | 15 | #include "SkXfermodePriv.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 16 | |
| 17 | /////////////////////////////////////////////////////////////////////////////// |
| 18 | |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 19 | class Sprite_D32_S32 : public SkSpriteBlitter { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 20 | public: |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 21 | Sprite_D32_S32(const SkPixmap& src, U8CPU alpha) : INHERITED(src) { |
commit-bot@chromium.org | 28fcae2 | 2014-04-11 17:15:40 +0000 | [diff] [blame] | 22 | SkASSERT(src.colorType() == kN32_SkColorType); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 23 | |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 24 | unsigned flags32 = 0; |
| 25 | if (255 != alpha) { |
| 26 | flags32 |= SkBlitRow::kGlobalAlpha_Flag32; |
| 27 | } |
| 28 | if (!src.isOpaque()) { |
| 29 | flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; |
| 30 | } |
| 31 | |
| 32 | fProc32 = SkBlitRow::Factory32(flags32); |
| 33 | fAlpha = alpha; |
| 34 | } |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 35 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 36 | void blitRect(int x, int y, int width, int height) override { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 37 | SkASSERT(width > 0 && height > 0); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 38 | uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 39 | const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 40 | size_t dstRB = fDst.rowBytes(); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 41 | size_t srcRB = fSource.rowBytes(); |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 42 | SkBlitRow::Proc32 proc = fProc32; |
| 43 | U8CPU alpha = fAlpha; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 44 | |
| 45 | do { |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 46 | proc(dst, src, width, alpha); |
tomhudson@google.com | a87cd2a | 2011-06-15 16:50:27 +0000 | [diff] [blame] | 47 | dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB); |
| 48 | src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 49 | } while (--height != 0); |
| 50 | } |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 51 | |
| 52 | private: |
| 53 | SkBlitRow::Proc32 fProc32; |
| 54 | U8CPU fAlpha; |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 55 | |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 56 | typedef SkSpriteBlitter INHERITED; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 57 | }; |
| 58 | |
| 59 | /////////////////////////////////////////////////////////////////////////////// |
| 60 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 61 | class Sprite_D32_XferFilter : public SkSpriteBlitter { |
| 62 | public: |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 63 | Sprite_D32_XferFilter(const SkPixmap& source, const SkPaint& paint) : SkSpriteBlitter(source) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 64 | fColorFilter = paint.getColorFilter(); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 65 | SkSafeRef(fColorFilter); |
| 66 | |
reed | 374772b | 2016-10-05 17:33:02 -0700 | [diff] [blame] | 67 | fXfermode = SkXfermode::Peek(paint.getBlendMode()); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 68 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 69 | fBufferSize = 0; |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 70 | fBuffer = nullptr; |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 71 | |
| 72 | unsigned flags32 = 0; |
| 73 | if (255 != paint.getAlpha()) { |
| 74 | flags32 |= SkBlitRow::kGlobalAlpha_Flag32; |
| 75 | } |
| 76 | if (!source.isOpaque()) { |
| 77 | flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32; |
| 78 | } |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 79 | |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 80 | fProc32 = SkBlitRow::Factory32(flags32); |
| 81 | fAlpha = paint.getAlpha(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 82 | } |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 83 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 84 | virtual ~Sprite_D32_XferFilter() { |
| 85 | delete[] fBuffer; |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 86 | SkSafeUnref(fColorFilter); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 87 | } |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 88 | |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 89 | void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override { |
| 90 | this->INHERITED::setup(dst, left, top, paint); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 91 | |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 92 | int width = dst.width(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 93 | if (width > fBufferSize) { |
| 94 | fBufferSize = width; |
| 95 | delete[] fBuffer; |
| 96 | fBuffer = new SkPMColor[width]; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | protected: |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 101 | SkColorFilter* fColorFilter; |
| 102 | SkXfermode* fXfermode; |
| 103 | int fBufferSize; |
| 104 | SkPMColor* fBuffer; |
| 105 | SkBlitRow::Proc32 fProc32; |
| 106 | U8CPU fAlpha; |
| 107 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 108 | private: |
| 109 | typedef SkSpriteBlitter INHERITED; |
| 110 | }; |
| 111 | |
| 112 | /////////////////////////////////////////////////////////////////////////////// |
| 113 | |
| 114 | class Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter { |
| 115 | public: |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 116 | Sprite_D32_S32A_XferFilter(const SkPixmap& source, const SkPaint& paint) |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 117 | : Sprite_D32_XferFilter(source, paint) {} |
| 118 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 119 | void blitRect(int x, int y, int width, int height) override { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 120 | SkASSERT(width > 0 && height > 0); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 121 | uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 122 | const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 123 | size_t dstRB = fDst.rowBytes(); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 124 | size_t srcRB = fSource.rowBytes(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 125 | SkColorFilter* colorFilter = fColorFilter; |
| 126 | SkXfermode* xfermode = fXfermode; |
| 127 | |
| 128 | do { |
| 129 | const SkPMColor* tmp = src; |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 130 | |
bsalomon | 49f085d | 2014-09-05 13:34:00 -0700 | [diff] [blame] | 131 | if (colorFilter) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 132 | colorFilter->filterSpan(src, width, fBuffer); |
| 133 | tmp = fBuffer; |
| 134 | } |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 135 | |
bsalomon | 49f085d | 2014-09-05 13:34:00 -0700 | [diff] [blame] | 136 | if (xfermode) { |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 137 | xfermode->xfer32(dst, tmp, width, nullptr); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 138 | } else { |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 139 | fProc32(dst, tmp, width, fAlpha); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 140 | } |
| 141 | |
tomhudson@google.com | a87cd2a | 2011-06-15 16:50:27 +0000 | [diff] [blame] | 142 | dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB); |
| 143 | src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 144 | } while (--height != 0); |
| 145 | } |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 146 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 147 | private: |
| 148 | typedef Sprite_D32_XferFilter INHERITED; |
| 149 | }; |
| 150 | |
tomhudson@google.com | a87cd2a | 2011-06-15 16:50:27 +0000 | [diff] [blame] | 151 | static void fillbuffer(SkPMColor* SK_RESTRICT dst, |
| 152 | const SkPMColor16* SK_RESTRICT src, int count) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 153 | SkASSERT(count > 0); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 154 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 155 | do { |
| 156 | *dst++ = SkPixel4444ToPixel32(*src++); |
| 157 | } while (--count != 0); |
| 158 | } |
| 159 | |
| 160 | class Sprite_D32_S4444_XferFilter : public Sprite_D32_XferFilter { |
| 161 | public: |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 162 | Sprite_D32_S4444_XferFilter(const SkPixmap& source, const SkPaint& paint) |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 163 | : Sprite_D32_XferFilter(source, paint) {} |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 164 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 165 | void blitRect(int x, int y, int width, int height) override { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 166 | SkASSERT(width > 0 && height > 0); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 167 | SkPMColor* SK_RESTRICT dst = fDst.writable_addr32(x, y); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 168 | const SkPMColor16* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 169 | size_t dstRB = fDst.rowBytes(); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 170 | size_t srcRB = fSource.rowBytes(); |
tomhudson@google.com | a87cd2a | 2011-06-15 16:50:27 +0000 | [diff] [blame] | 171 | SkPMColor* SK_RESTRICT buffer = fBuffer; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 172 | SkColorFilter* colorFilter = fColorFilter; |
| 173 | SkXfermode* xfermode = fXfermode; |
| 174 | |
| 175 | do { |
| 176 | fillbuffer(buffer, src, width); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 177 | |
bsalomon | 49f085d | 2014-09-05 13:34:00 -0700 | [diff] [blame] | 178 | if (colorFilter) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 179 | colorFilter->filterSpan(buffer, width, buffer); |
| 180 | } |
bsalomon | 49f085d | 2014-09-05 13:34:00 -0700 | [diff] [blame] | 181 | if (xfermode) { |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 182 | xfermode->xfer32(dst, buffer, width, nullptr); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 183 | } else { |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 184 | fProc32(dst, buffer, width, fAlpha); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 185 | } |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 186 | |
tomhudson@google.com | a87cd2a | 2011-06-15 16:50:27 +0000 | [diff] [blame] | 187 | dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB); |
| 188 | src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 189 | } while (--height != 0); |
| 190 | } |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 191 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 192 | private: |
| 193 | typedef Sprite_D32_XferFilter INHERITED; |
| 194 | }; |
| 195 | |
| 196 | /////////////////////////////////////////////////////////////////////////////// |
| 197 | |
tomhudson@google.com | a87cd2a | 2011-06-15 16:50:27 +0000 | [diff] [blame] | 198 | static void src_row(SkPMColor* SK_RESTRICT dst, |
| 199 | const SkPMColor16* SK_RESTRICT src, int count) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 200 | do { |
| 201 | *dst = SkPixel4444ToPixel32(*src); |
| 202 | src += 1; |
| 203 | dst += 1; |
| 204 | } while (--count != 0); |
| 205 | } |
| 206 | |
| 207 | class Sprite_D32_S4444_Opaque : public SkSpriteBlitter { |
| 208 | public: |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 209 | Sprite_D32_S4444_Opaque(const SkPixmap& source) : SkSpriteBlitter(source) {} |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 210 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 211 | void blitRect(int x, int y, int width, int height) override { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 212 | SkASSERT(width > 0 && height > 0); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 213 | SkPMColor* SK_RESTRICT dst = fDst.writable_addr32(x, y); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 214 | const SkPMColor16* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 215 | size_t dstRB = fDst.rowBytes(); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 216 | size_t srcRB = fSource.rowBytes(); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 217 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 218 | do { |
| 219 | src_row(dst, src, width); |
tomhudson@google.com | a87cd2a | 2011-06-15 16:50:27 +0000 | [diff] [blame] | 220 | dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB); |
| 221 | src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 222 | } while (--height != 0); |
| 223 | } |
| 224 | }; |
| 225 | |
tomhudson@google.com | a87cd2a | 2011-06-15 16:50:27 +0000 | [diff] [blame] | 226 | static void srcover_row(SkPMColor* SK_RESTRICT dst, |
| 227 | const SkPMColor16* SK_RESTRICT src, int count) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 228 | do { |
| 229 | *dst = SkPMSrcOver(SkPixel4444ToPixel32(*src), *dst); |
| 230 | src += 1; |
| 231 | dst += 1; |
| 232 | } while (--count != 0); |
| 233 | } |
| 234 | |
| 235 | class Sprite_D32_S4444 : public SkSpriteBlitter { |
| 236 | public: |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 237 | Sprite_D32_S4444(const SkPixmap& source) : SkSpriteBlitter(source) {} |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 238 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 239 | void blitRect(int x, int y, int width, int height) override { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 240 | SkASSERT(width > 0 && height > 0); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 241 | SkPMColor* SK_RESTRICT dst = fDst.writable_addr32(x, y); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 242 | const SkPMColor16* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop); |
reed | cb67414 | 2015-06-05 06:58:22 -0700 | [diff] [blame] | 243 | size_t dstRB = fDst.rowBytes(); |
reed | c240e71 | 2015-05-23 12:26:41 -0700 | [diff] [blame] | 244 | size_t srcRB = fSource.rowBytes(); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 245 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 246 | do { |
| 247 | srcover_row(dst, src, width); |
tomhudson@google.com | a87cd2a | 2011-06-15 16:50:27 +0000 | [diff] [blame] | 248 | dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB); |
| 249 | src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 250 | } while (--height != 0); |
| 251 | } |
| 252 | }; |
| 253 | |
| 254 | /////////////////////////////////////////////////////////////////////////////// |
| 255 | |
brianosman | fe4b4f0 | 2016-02-26 09:19:02 -0800 | [diff] [blame] | 256 | SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPaint& paint, |
Herb Derby | 57bfa02 | 2017-02-09 17:25:43 -0500 | [diff] [blame^] | 257 | SkArenaAlloc* allocator) { |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 258 | SkASSERT(allocator != nullptr); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 259 | |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 260 | if (paint.getMaskFilter() != nullptr) { |
| 261 | return nullptr; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 262 | } |
| 263 | |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 264 | U8CPU alpha = paint.getAlpha(); |
reed | 374772b | 2016-10-05 17:33:02 -0700 | [diff] [blame] | 265 | bool isSrcOver = paint.isSrcOver(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 266 | SkColorFilter* filter = paint.getColorFilter(); |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 267 | SkSpriteBlitter* blitter = nullptr; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 268 | |
reed@google.com | 900ecf2 | 2014-02-20 20:55:37 +0000 | [diff] [blame] | 269 | switch (source.colorType()) { |
| 270 | case kARGB_4444_SkColorType: |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 271 | if (alpha != 0xFF) { |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 272 | return nullptr; // we only have opaque sprites |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 273 | } |
reed | 374772b | 2016-10-05 17:33:02 -0700 | [diff] [blame] | 274 | if (!isSrcOver || filter) { |
Herb Derby | 57bfa02 | 2017-02-09 17:25:43 -0500 | [diff] [blame^] | 275 | blitter = allocator->make<Sprite_D32_S4444_XferFilter>(source, paint); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 276 | } else if (source.isOpaque()) { |
Herb Derby | 57bfa02 | 2017-02-09 17:25:43 -0500 | [diff] [blame^] | 277 | blitter = allocator->make<Sprite_D32_S4444_Opaque>(source); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 278 | } else { |
Herb Derby | 57bfa02 | 2017-02-09 17:25:43 -0500 | [diff] [blame^] | 279 | blitter = allocator->make<Sprite_D32_S4444>(source); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 280 | } |
| 281 | break; |
commit-bot@chromium.org | 28fcae2 | 2014-04-11 17:15:40 +0000 | [diff] [blame] | 282 | case kN32_SkColorType: |
reed | 374772b | 2016-10-05 17:33:02 -0700 | [diff] [blame] | 283 | if (!isSrcOver || filter) { |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 284 | if (255 == alpha) { |
| 285 | // this can handle xfermode or filter, but not alpha |
Herb Derby | 57bfa02 | 2017-02-09 17:25:43 -0500 | [diff] [blame^] | 286 | blitter = allocator->make<Sprite_D32_S32A_XferFilter>(source, paint); |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 287 | } |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 288 | } else { |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 289 | // this can handle alpha, but not xfermode or filter |
Herb Derby | 57bfa02 | 2017-02-09 17:25:43 -0500 | [diff] [blame^] | 290 | blitter = allocator->make<Sprite_D32_S32>(source, alpha); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 291 | } |
| 292 | break; |
| 293 | default: |
| 294 | break; |
| 295 | } |
| 296 | return blitter; |
| 297 | } |