11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkSpriteBlitter.h"
11d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkBlitRow.h"
12d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkColorFilter.h"
13d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkColorPriv.h"
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplates.h"
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
16d0195f840fa964da51f7a1192b432954794e660cMike Reed#include "SkXfermode.h"
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20d0195f840fa964da51f7a1192b432954794e660cMike Reedclass Sprite_D32_S32 : public SkSpriteBlitter {
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
22d0195f840fa964da51f7a1192b432954794e660cMike Reed    Sprite_D32_S32(const SkBitmap& src, U8CPU alpha)  : INHERITED(src) {
23d0195f840fa964da51f7a1192b432954794e660cMike Reed        SkASSERT(src.config() == SkBitmap::kARGB_8888_Config);
24d0195f840fa964da51f7a1192b432954794e660cMike Reed
25d0195f840fa964da51f7a1192b432954794e660cMike Reed        unsigned flags32 = 0;
26d0195f840fa964da51f7a1192b432954794e660cMike Reed        if (255 != alpha) {
27d0195f840fa964da51f7a1192b432954794e660cMike Reed            flags32 |= SkBlitRow::kGlobalAlpha_Flag32;
28d0195f840fa964da51f7a1192b432954794e660cMike Reed        }
29d0195f840fa964da51f7a1192b432954794e660cMike Reed        if (!src.isOpaque()) {
30d0195f840fa964da51f7a1192b432954794e660cMike Reed            flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32;
31d0195f840fa964da51f7a1192b432954794e660cMike Reed        }
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
33d0195f840fa964da51f7a1192b432954794e660cMike Reed        fProc32 = SkBlitRow::Factory32(flags32);
34d0195f840fa964da51f7a1192b432954794e660cMike Reed        fAlpha = alpha;
35d0195f840fa964da51f7a1192b432954794e660cMike Reed    }
3640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitRect(int x, int y, int width, int height) {
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(width > 0 && height > 0);
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y);
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft,
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                             y - fTop);
42d0195f840fa964da51f7a1192b432954794e660cMike Reed        size_t dstRB = fDevice->rowBytes();
43d0195f840fa964da51f7a1192b432954794e660cMike Reed        size_t srcRB = fSource->rowBytes();
44d0195f840fa964da51f7a1192b432954794e660cMike Reed        SkBlitRow::Proc32 proc = fProc32;
45d0195f840fa964da51f7a1192b432954794e660cMike Reed        U8CPU             alpha = fAlpha;
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
48d0195f840fa964da51f7a1192b432954794e660cMike Reed            proc(dst, src, width, alpha);
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--height != 0);
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
53d0195f840fa964da51f7a1192b432954794e660cMike Reed
54d0195f840fa964da51f7a1192b432954794e660cMike Reedprivate:
55d0195f840fa964da51f7a1192b432954794e660cMike Reed    SkBlitRow::Proc32   fProc32;
56d0195f840fa964da51f7a1192b432954794e660cMike Reed    U8CPU               fAlpha;
5740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
58d0195f840fa964da51f7a1192b432954794e660cMike Reed    typedef SkSpriteBlitter INHERITED;
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_XferFilter : public SkSpriteBlitter {
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sprite_D32_XferFilter(const SkBitmap& source, const SkPaint& paint)
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : SkSpriteBlitter(source) {
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fColorFilter = paint.getColorFilter();
6840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeRef(fColorFilter);
6940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fXfermode = paint.getXfermode();
7140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeRef(fXfermode);
7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBufferSize = 0;
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBuffer = NULL;
75d0195f840fa964da51f7a1192b432954794e660cMike Reed
76d0195f840fa964da51f7a1192b432954794e660cMike Reed        unsigned flags32 = 0;
77d0195f840fa964da51f7a1192b432954794e660cMike Reed        if (255 != paint.getAlpha()) {
78d0195f840fa964da51f7a1192b432954794e660cMike Reed            flags32 |= SkBlitRow::kGlobalAlpha_Flag32;
79d0195f840fa964da51f7a1192b432954794e660cMike Reed        }
80d0195f840fa964da51f7a1192b432954794e660cMike Reed        if (!source.isOpaque()) {
81d0195f840fa964da51f7a1192b432954794e660cMike Reed            flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32;
82d0195f840fa964da51f7a1192b432954794e660cMike Reed        }
8340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
84d0195f840fa964da51f7a1192b432954794e660cMike Reed        fProc32 = SkBlitRow::Factory32(flags32);
85d0195f840fa964da51f7a1192b432954794e660cMike Reed        fAlpha = paint.getAlpha();
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual ~Sprite_D32_XferFilter() {
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        delete[] fBuffer;
9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(fXfermode);
9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(fColorFilter);
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void setup(const SkBitmap& device, int left, int top,
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                       const SkPaint& paint) {
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::setup(device, left, top, paint);
9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int width = device.width();
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (width > fBufferSize) {
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fBufferSize = width;
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            delete[] fBuffer;
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fBuffer = new SkPMColor[width];
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
107d0195f840fa964da51f7a1192b432954794e660cMike Reed    SkColorFilter*      fColorFilter;
108d0195f840fa964da51f7a1192b432954794e660cMike Reed    SkXfermode*         fXfermode;
109d0195f840fa964da51f7a1192b432954794e660cMike Reed    int                 fBufferSize;
110d0195f840fa964da51f7a1192b432954794e660cMike Reed    SkPMColor*          fBuffer;
111d0195f840fa964da51f7a1192b432954794e660cMike Reed    SkBlitRow::Proc32   fProc32;
112d0195f840fa964da51f7a1192b432954794e660cMike Reed    U8CPU               fAlpha;
113d0195f840fa964da51f7a1192b432954794e660cMike Reed
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkSpriteBlitter INHERITED;
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter {
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sprite_D32_S32A_XferFilter(const SkBitmap& source, const SkPaint& paint)
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : Sprite_D32_XferFilter(source, paint) {}
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitRect(int x, int y, int width, int height) {
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(width > 0 && height > 0);
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y);
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft,
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                             y - fTop);
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned dstRB = fDevice->rowBytes();
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned srcRB = fSource->rowBytes();
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkColorFilter* colorFilter = fColorFilter;
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkXfermode* xfermode = fXfermode;
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const SkPMColor* tmp = src;
13740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != colorFilter) {
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                colorFilter->filterSpan(src, width, fBuffer);
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                tmp = fBuffer;
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
14240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != xfermode) {
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                xfermode->xfer32(dst, tmp, width, NULL);
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else {
146d0195f840fa964da51f7a1192b432954794e660cMike Reed                fProc32(dst, tmp, width, fAlpha);
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--height != 0);
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef Sprite_D32_XferFilter INHERITED;
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void fillbuffer(SkPMColor* SK_RESTRICT dst,
1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                       const SkPMColor16* SK_RESTRICT src, int count) {
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count > 0);
16140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *dst++ = SkPixel4444ToPixel32(*src++);
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (--count != 0);
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_S4444_XferFilter : public Sprite_D32_XferFilter {
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sprite_D32_S4444_XferFilter(const SkBitmap& source, const SkPaint& paint)
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        : Sprite_D32_XferFilter(source, paint) {}
17140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitRect(int x, int y, int width, int height) {
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(width > 0 && height > 0);
1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                                y - fTop);
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned dstRB = fDevice->rowBytes();
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned srcRB = fSource->rowBytes();
1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPMColor* SK_RESTRICT buffer = fBuffer;
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkColorFilter* colorFilter = fColorFilter;
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkXfermode* xfermode = fXfermode;
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fillbuffer(buffer, src, width);
18540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != colorFilter) {
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                colorFilter->filterSpan(buffer, width, buffer);
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != xfermode) {
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                xfermode->xfer32(dst, buffer, width, NULL);
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else {
192d0195f840fa964da51f7a1192b432954794e660cMike Reed                fProc32(dst, buffer, width, fAlpha);
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
19440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--height != 0);
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
19940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef Sprite_D32_XferFilter INHERITED;
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void src_row(SkPMColor* SK_RESTRICT dst,
2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    const SkPMColor16* SK_RESTRICT src, int count) {
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *dst = SkPixel4444ToPixel32(*src);
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        src += 1;
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst += 1;
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (--count != 0);
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_S4444_Opaque : public SkSpriteBlitter {
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sprite_D32_S4444_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {}
21840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitRect(int x, int y, int width, int height) {
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(width > 0 && height > 0);
2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                                y - fTop);
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned dstRB = fDevice->rowBytes();
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned srcRB = fSource->rowBytes();
22640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            src_row(dst, src, width);
2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--height != 0);
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void srcover_row(SkPMColor* SK_RESTRICT dst,
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        const SkPMColor16* SK_RESTRICT src, int count) {
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *dst = SkPMSrcOver(SkPixel4444ToPixel32(*src), *dst);
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        src += 1;
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst += 1;
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (--count != 0);
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sprite_D32_S4444 : public SkSpriteBlitter {
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sprite_D32_S4444(const SkBitmap& source) : SkSpriteBlitter(source) {}
24740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    virtual void blitRect(int x, int y, int width, int height) {
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(width > 0 && height > 0);
2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                                y - fTop);
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned dstRB = fDevice->rowBytes();
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned srcRB = fSource->rowBytes();
25540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            srcover_row(dst, src, width);
2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (--height != 0);
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplatesPriv.h"
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source,
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            const SkPaint& paint,
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            void* storage, size_t storageSize) {
271d0195f840fa964da51f7a1192b432954794e660cMike Reed    if (paint.getMaskFilter() != NULL) {
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return NULL;
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
275d0195f840fa964da51f7a1192b432954794e660cMike Reed    U8CPU       alpha = paint.getAlpha();
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkXfermode* xfermode = paint.getXfermode();
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkColorFilter* filter = paint.getColorFilter();
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkSpriteBlitter* blitter = NULL;
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (source.getConfig()) {
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkBitmap::kARGB_4444_Config:
282d0195f840fa964da51f7a1192b432954794e660cMike Reed            if (alpha != 0xFF) {
283d0195f840fa964da51f7a1192b432954794e660cMike Reed                return NULL;    // we only have opaque sprites
284d0195f840fa964da51f7a1192b432954794e660cMike Reed            }
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (xfermode || filter) {
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_XferFilter,
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                      storage, storageSize, (source, paint));
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else if (source.isOpaque()) {
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_Opaque,
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                      storage, storageSize, (source));
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else {
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444,
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                      storage, storageSize, (source));
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkBitmap::kARGB_8888_Config:
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (xfermode || filter) {
298d0195f840fa964da51f7a1192b432954794e660cMike Reed                if (255 == alpha) {
299d0195f840fa964da51f7a1192b432954794e660cMike Reed                    // this can handle xfermode or filter, but not alpha
300d0195f840fa964da51f7a1192b432954794e660cMike Reed                    SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_XferFilter,
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                      storage, storageSize, (source, paint));
302d0195f840fa964da51f7a1192b432954794e660cMike Reed                }
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else {
304d0195f840fa964da51f7a1192b432954794e660cMike Reed                // this can handle alpha, but not xfermode or filter
305d0195f840fa964da51f7a1192b432954794e660cMike Reed                SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32,
306d0195f840fa964da51f7a1192b432954794e660cMike Reed                              storage, storageSize, (source, alpha));
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return blitter;
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
314