1f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
2f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/*
3f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Copyright 2006 The Android Open Source Project
4f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *
5f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
6f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * found in the LICENSE file.
7f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */
8f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
9f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
10f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkSpriteBlitter.h"
11f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkBlitRow.h"
12f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkColorFilter.h"
13f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkColorPriv.h"
14f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkTemplates.h"
15f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkUtils.h"
16f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkXfermode.h"
17f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
18f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
19f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
20f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S32 : public SkSpriteBlitter {
21f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic:
22f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sprite_D32_S32(const SkBitmap& src, U8CPU alpha)  : INHERITED(src) {
23f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(src.config() == SkBitmap::kARGB_8888_Config);
24f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
25f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned flags32 = 0;
26f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (255 != alpha) {
27f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            flags32 |= SkBlitRow::kGlobalAlpha_Flag32;
28f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
29f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (!src.isOpaque()) {
30f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32;
31f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
32f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
33f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fProc32 = SkBlitRow::Factory32(flags32);
34f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fAlpha = alpha;
35f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
36f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
37f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void blitRect(int x, int y, int width, int height) {
38f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(width > 0 && height > 0);
39f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y);
40f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft,
41f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                                             y - fTop);
42f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        size_t dstRB = fDevice->rowBytes();
43f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        size_t srcRB = fSource->rowBytes();
44f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkBlitRow::Proc32 proc = fProc32;
45f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        U8CPU             alpha = fAlpha;
46f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
47f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        do {
48f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            proc(dst, src, width, alpha);
49f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
50f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
51f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } while (--height != 0);
52f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
53f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
54f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate:
55f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkBlitRow::Proc32   fProc32;
56f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    U8CPU               fAlpha;
57f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
58f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    typedef SkSpriteBlitter INHERITED;
59f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
60f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
61f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
62f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
63f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_XferFilter : public SkSpriteBlitter {
64f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic:
65f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sprite_D32_XferFilter(const SkBitmap& source, const SkPaint& paint)
66f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        : SkSpriteBlitter(source) {
67f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fColorFilter = paint.getColorFilter();
68f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkSafeRef(fColorFilter);
69f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
70f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fXfermode = paint.getXfermode();
71f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkSafeRef(fXfermode);
72f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
73f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fBufferSize = 0;
74f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fBuffer = NULL;
75f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
76f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned flags32 = 0;
77f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (255 != paint.getAlpha()) {
78f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            flags32 |= SkBlitRow::kGlobalAlpha_Flag32;
79f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
80f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (!source.isOpaque()) {
81f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32;
82f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
83f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
84f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fProc32 = SkBlitRow::Factory32(flags32);
85f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        fAlpha = paint.getAlpha();
86f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
87f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
88f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual ~Sprite_D32_XferFilter() {
89f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        delete[] fBuffer;
90f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkSafeUnref(fXfermode);
91f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkSafeUnref(fColorFilter);
92f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
93f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
94f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void setup(const SkBitmap& device, int left, int top,
95f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                       const SkPaint& paint) {
96f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        this->INHERITED::setup(device, left, top, paint);
97f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
98f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        int width = device.width();
99f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        if (width > fBufferSize) {
100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fBufferSize = width;
101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            delete[] fBuffer;
102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fBuffer = new SkPMColor[width];
103f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        }
104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprotected:
107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkColorFilter*      fColorFilter;
108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkXfermode*         fXfermode;
109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    int                 fBufferSize;
110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkPMColor*          fBuffer;
111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkBlitRow::Proc32   fProc32;
112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    U8CPU               fAlpha;
113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate:
115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    typedef SkSpriteBlitter INHERITED;
116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter {
121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic:
122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sprite_D32_S32A_XferFilter(const SkBitmap& source, const SkPaint& paint)
123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        : Sprite_D32_XferFilter(source, paint) {}
124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void blitRect(int x, int y, int width, int height) {
126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(width > 0 && height > 0);
127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y);
128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const uint32_t* SK_RESTRICT src = fSource->getAddr32(x - fLeft,
129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                                             y - fTop);
130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned dstRB = fDevice->rowBytes();
131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned srcRB = fSource->rowBytes();
132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkColorFilter* colorFilter = fColorFilter;
133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkXfermode* xfermode = fXfermode;
134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        do {
136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            const SkPMColor* tmp = src;
137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (NULL != colorFilter) {
139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                colorFilter->filterSpan(src, width, fBuffer);
140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                tmp = fBuffer;
141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (NULL != xfermode) {
144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                xfermode->xfer32(dst, tmp, width, NULL);
145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            } else {
146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                fProc32(dst, tmp, width, fAlpha);
147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } while (--height != 0);
152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate:
155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    typedef Sprite_D32_XferFilter INHERITED;
156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void fillbuffer(SkPMColor* SK_RESTRICT dst,
159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                       const SkPMColor16* SK_RESTRICT src, int count) {
160f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkASSERT(count > 0);
161f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
162f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    do {
163f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        *dst++ = SkPixel4444ToPixel32(*src++);
164f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } while (--count != 0);
165f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
166f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
167f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S4444_XferFilter : public Sprite_D32_XferFilter {
168f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic:
169f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sprite_D32_S4444_XferFilter(const SkBitmap& source, const SkPaint& paint)
170f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        : Sprite_D32_XferFilter(source, paint) {}
171f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
172f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void blitRect(int x, int y, int width, int height) {
173f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(width > 0 && height > 0);
174f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
175f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
176f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                                                y - fTop);
177f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned dstRB = fDevice->rowBytes();
178f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned srcRB = fSource->rowBytes();
179f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkPMColor* SK_RESTRICT buffer = fBuffer;
180f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkColorFilter* colorFilter = fColorFilter;
181f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkXfermode* xfermode = fXfermode;
182f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
183f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        do {
184f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            fillbuffer(buffer, src, width);
185f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
186f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (NULL != colorFilter) {
187f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                colorFilter->filterSpan(buffer, width, buffer);
188f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
189f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (NULL != xfermode) {
190f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                xfermode->xfer32(dst, buffer, width, NULL);
191f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            } else {
192f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                fProc32(dst, buffer, width, fAlpha);
193f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
194f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
195f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
196f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
197f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } while (--height != 0);
198f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
199f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
200f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate:
201f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    typedef Sprite_D32_XferFilter INHERITED;
202f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
203f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
204f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
205f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
206f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void src_row(SkPMColor* SK_RESTRICT dst,
207f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                    const SkPMColor16* SK_RESTRICT src, int count) {
208f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    do {
209f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        *dst = SkPixel4444ToPixel32(*src);
210f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        src += 1;
211f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dst += 1;
212f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } while (--count != 0);
213f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
214f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
215f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S4444_Opaque : public SkSpriteBlitter {
216f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic:
217f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sprite_D32_S4444_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {}
218f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
219f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void blitRect(int x, int y, int width, int height) {
220f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(width > 0 && height > 0);
221f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
222f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
223f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                                                y - fTop);
224f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned dstRB = fDevice->rowBytes();
225f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned srcRB = fSource->rowBytes();
226f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
227f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        do {
228f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            src_row(dst, src, width);
229f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
230f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
231f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } while (--height != 0);
232f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
233f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
234f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
235f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic void srcover_row(SkPMColor* SK_RESTRICT dst,
236f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                        const SkPMColor16* SK_RESTRICT src, int count) {
237f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    do {
238f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        *dst = SkPMSrcOver(SkPixel4444ToPixel32(*src), *dst);
239f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        src += 1;
240f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        dst += 1;
241f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    } while (--count != 0);
242f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
243f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
244f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass Sprite_D32_S4444 : public SkSpriteBlitter {
245f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic:
246f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    Sprite_D32_S4444(const SkBitmap& source) : SkSpriteBlitter(source) {}
247f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
248f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    virtual void blitRect(int x, int y, int width, int height) {
249f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkASSERT(width > 0 && height > 0);
250f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
251f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        const SkPMColor16* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
252f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                                                y - fTop);
253f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned dstRB = fDevice->rowBytes();
254f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        unsigned srcRB = fSource->rowBytes();
255f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
256f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        do {
257f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            srcover_row(dst, src, width);
258f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
259f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
260f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        } while (--height != 0);
261f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
262f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger};
263f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
264f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
265f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
266f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkTemplatesPriv.h"
267f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
268f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source,
269f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                            const SkPaint& paint,
270f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                            void* storage, size_t storageSize) {
271f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    if (paint.getMaskFilter() != NULL) {
272f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        return NULL;
273f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
274f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
275f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    U8CPU       alpha = paint.getAlpha();
276f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkXfermode* xfermode = paint.getXfermode();
277f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkColorFilter* filter = paint.getColorFilter();
278f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    SkSpriteBlitter* blitter = NULL;
279f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger
280f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    switch (source.getConfig()) {
281f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kARGB_4444_Config:
282f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (alpha != 0xFF) {
283f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                return NULL;    // we only have opaque sprites
284f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
285f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (xfermode || filter) {
286f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_XferFilter,
287f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                      storage, storageSize, (source, paint));
288f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            } else if (source.isOpaque()) {
289f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_Opaque,
290f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                      storage, storageSize, (source));
291f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            } else {
292f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444,
293f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                      storage, storageSize, (source));
294f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
295f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
296f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        case SkBitmap::kARGB_8888_Config:
297f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            if (xfermode || filter) {
298f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                if (255 == alpha) {
299f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                    // this can handle xfermode or filter, but not alpha
300f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                    SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_XferFilter,
301f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                                      storage, storageSize, (source, paint));
302f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                }
303f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            } else {
304f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                // this can handle alpha, but not xfermode or filter
305f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32,
306f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger                              storage, storageSize, (source, alpha));
307f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            }
308f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
309f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger        default:
310f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger            break;
311f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    }
312f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger    return blitter;
313f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}
314