1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkSpriteBlitter.h"
11c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkBlitRow.h"
12c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkColorFilter.h"
13c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkColorPriv.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
16c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkXfermode.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.comclass Sprite_D32_S32 : public SkSpriteBlitter {
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
22c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    Sprite_D32_S32(const SkBitmap& src, U8CPU alpha)  : INHERITED(src) {
2328fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        SkASSERT(src.colorType() == kN32_SkColorType);
24c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com
25c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        unsigned flags32 = 0;
26c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        if (255 != alpha) {
27c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com            flags32 |= SkBlitRow::kGlobalAlpha_Flag32;
28c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        }
29c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        if (!src.isOpaque()) {
30c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com            flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32;
31c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        }
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
33c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        fProc32 = SkBlitRow::Factory32(flags32);
34c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        fAlpha = alpha;
35c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    }
3682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void blitRect(int x, int y, int width, int height) {
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(width > 0 && height > 0);
39a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y);
40a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft,
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                             y - fTop);
42c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        size_t dstRB = fDevice->rowBytes();
43c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        size_t srcRB = fSource->rowBytes();
44c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        SkBlitRow::Proc32 proc = fProc32;
45c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        U8CPU             alpha = fAlpha;
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        do {
48c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com            proc(dst, src, width, alpha);
49a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
50a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } while (--height != 0);
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
53c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com
54c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.comprivate:
55c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    SkBlitRow::Proc32   fProc32;
56c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    U8CPU               fAlpha;
5782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
58c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    typedef SkSpriteBlitter INHERITED;
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sprite_D32_XferFilter : public SkSpriteBlitter {
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Sprite_D32_XferFilter(const SkBitmap& source, const SkPaint& paint)
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : SkSpriteBlitter(source) {
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fColorFilter = paint.getColorFilter();
6882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        SkSafeRef(fColorFilter);
6982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fXfermode = paint.getXfermode();
7182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        SkSafeRef(fXfermode);
7282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBufferSize = 0;
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBuffer = NULL;
75c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com
76c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        unsigned flags32 = 0;
77c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        if (255 != paint.getAlpha()) {
78c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com            flags32 |= SkBlitRow::kGlobalAlpha_Flag32;
79c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        }
80c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        if (!source.isOpaque()) {
81c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com            flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32;
82c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        }
8382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
84c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        fProc32 = SkBlitRow::Factory32(flags32);
85c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com        fAlpha = paint.getAlpha();
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
8782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual ~Sprite_D32_XferFilter() {
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        delete[] fBuffer;
9082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        SkSafeUnref(fXfermode);
9182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        SkSafeUnref(fColorFilter);
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
9382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void setup(const SkBitmap& device, int left, int top,
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                       const SkPaint& paint) {
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->INHERITED::setup(device, left, top, paint);
9782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int width = device.width();
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (width > fBufferSize) {
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fBufferSize = width;
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            delete[] fBuffer;
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fBuffer = new SkPMColor[width];
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
107c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    SkColorFilter*      fColorFilter;
108c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    SkXfermode*         fXfermode;
109c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    int                 fBufferSize;
110c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    SkPMColor*          fBuffer;
111c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    SkBlitRow::Proc32   fProc32;
112c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    U8CPU               fAlpha;
113c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkSpriteBlitter INHERITED;
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter {
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Sprite_D32_S32A_XferFilter(const SkBitmap& source, const SkPaint& paint)
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : Sprite_D32_XferFilter(source, paint) {}
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void blitRect(int x, int y, int width, int height) {
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(width > 0 && height > 0);
127a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y);
128a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft,
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                             y - fTop);
130e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com        size_t dstRB = fDevice->rowBytes();
131e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com        size_t srcRB = fSource->rowBytes();
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkColorFilter* colorFilter = fColorFilter;
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkXfermode* xfermode = fXfermode;
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        do {
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            const SkPMColor* tmp = src;
13782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (NULL != colorFilter) {
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                colorFilter->filterSpan(src, width, fBuffer);
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                tmp = fBuffer;
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
14282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (NULL != xfermode) {
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                xfermode->xfer32(dst, tmp, width, NULL);
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
146c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                fProc32(dst, tmp, width, fAlpha);
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
149a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
150a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } while (--height != 0);
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
15382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef Sprite_D32_XferFilter INHERITED;
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
158a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comstatic void fillbuffer(SkPMColor* SK_RESTRICT dst,
159a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com                       const SkPMColor16* SK_RESTRICT src, int count) {
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(count > 0);
16182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *dst++ = SkPixel4444ToPixel32(*src++);
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (--count != 0);
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sprite_D32_S4444_XferFilter : public Sprite_D32_XferFilter {
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Sprite_D32_S4444_XferFilter(const SkBitmap& source, const SkPaint& paint)
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : Sprite_D32_XferFilter(source, paint) {}
17182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void blitRect(int x, int y, int width, int height) {
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(width > 0 && height > 0);
174a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
175a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                                y - fTop);
177e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com        size_t dstRB = fDevice->rowBytes();
178e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com        size_t srcRB = fSource->rowBytes();
179a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        SkPMColor* SK_RESTRICT buffer = fBuffer;
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkColorFilter* colorFilter = fColorFilter;
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkXfermode* xfermode = fXfermode;
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        do {
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fillbuffer(buffer, src, width);
18582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (NULL != colorFilter) {
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                colorFilter->filterSpan(buffer, width, buffer);
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (NULL != xfermode) {
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                xfermode->xfer32(dst, buffer, width, NULL);
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
192c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                fProc32(dst, buffer, width, fAlpha);
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
19482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
195a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
196a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } while (--height != 0);
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
19982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef Sprite_D32_XferFilter INHERITED;
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
206a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comstatic void src_row(SkPMColor* SK_RESTRICT dst,
207a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com                    const SkPMColor16* SK_RESTRICT src, int count) {
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *dst = SkPixel4444ToPixel32(*src);
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        src += 1;
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dst += 1;
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (--count != 0);
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sprite_D32_S4444_Opaque : public SkSpriteBlitter {
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Sprite_D32_S4444_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {}
21882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void blitRect(int x, int y, int width, int height) {
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(width > 0 && height > 0);
221a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
222a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                                y - fTop);
224e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com        size_t dstRB = fDevice->rowBytes();
225e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com        size_t srcRB = fSource->rowBytes();
22682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        do {
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            src_row(dst, src, width);
229a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
230a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } while (--height != 0);
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
235a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.comstatic void srcover_row(SkPMColor* SK_RESTRICT dst,
236a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com                        const SkPMColor16* SK_RESTRICT src, int count) {
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *dst = SkPMSrcOver(SkPixel4444ToPixel32(*src), *dst);
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        src += 1;
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dst += 1;
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (--count != 0);
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sprite_D32_S4444 : public SkSpriteBlitter {
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Sprite_D32_S4444(const SkBitmap& source) : SkSpriteBlitter(source) {}
24782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void blitRect(int x, int y, int width, int height) {
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(width > 0 && height > 0);
250a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
251a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com        const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                                y - fTop);
253e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com        size_t dstRB = fDevice->rowBytes();
254e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com        size_t srcRB = fSource->rowBytes();
25582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        do {
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            srcover_row(dst, src, width);
258a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
259a87cd2af4c7f46ba8437c2e500805c9deb9e3a40tomhudson@google.com            src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } while (--height != 0);
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
266a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.orgSkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, const SkPaint& paint,
267a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org        SkTBlitterAllocator* allocator) {
268a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org    SkASSERT(allocator != NULL);
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
270c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    if (paint.getMaskFilter() != NULL) {
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return NULL;
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
274c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com    U8CPU       alpha = paint.getAlpha();
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkXfermode* xfermode = paint.getXfermode();
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkColorFilter* filter = paint.getColorFilter();
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkSpriteBlitter* blitter = NULL;
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
279900ecf2f1579d42c9d2959831787af0346320f86reed@google.com    switch (source.colorType()) {
280900ecf2f1579d42c9d2959831787af0346320f86reed@google.com        case kARGB_4444_SkColorType:
281c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com            if (alpha != 0xFF) {
282c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                return NULL;    // we only have opaque sprites
283c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com            }
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (xfermode || filter) {
285a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org                blitter = allocator->createT<Sprite_D32_S4444_XferFilter>(source, paint);
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else if (source.isOpaque()) {
287a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org                blitter = allocator->createT<Sprite_D32_S4444_Opaque>(source);
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
289a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org                blitter = allocator->createT<Sprite_D32_S4444>(source);
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
29228fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org        case kN32_SkColorType:
2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (xfermode || filter) {
294c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                if (255 == alpha) {
295c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                    // this can handle xfermode or filter, but not alpha
296a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org                    blitter = allocator->createT<Sprite_D32_S32A_XferFilter>(source, paint);
297c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                }
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
299c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com                // this can handle alpha, but not xfermode or filter
300a5572e5bb2a2bbeeb59de0741c2527869d365a0ccommit-bot@chromium.org                blitter = allocator->createT<Sprite_D32_S32>(source, alpha);
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return blitter;
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
308