SkBlitRow_D32.cpp revision 981d4798007b91e2e19c13b171583927a56df63b
1#include "SkBlitRow.h"
2#include "SkColorPriv.h"
3#include "SkUtils.h"
4
5#define UNROLL
6
7static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
8                                 const SkPMColor* SK_RESTRICT src,
9                                 int count, U8CPU alpha) {
10    SkASSERT(255 == alpha);
11    memcpy(dst, src, count * sizeof(SkPMColor));
12}
13
14static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
15                                const SkPMColor* SK_RESTRICT src,
16                                int count, U8CPU alpha) {
17    SkASSERT(alpha <= 255);
18    if (count > 0) {
19        unsigned src_scale = SkAlpha255To256(alpha);
20        unsigned dst_scale = 256 - src_scale;
21
22#ifdef UNROLL
23        if (count & 1) {
24            *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
25            dst += 1;
26            count -= 1;
27        }
28
29        const SkPMColor* SK_RESTRICT srcEnd = src + count;
30        while (src != srcEnd) {
31            *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
32            dst += 1;
33            *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
34            dst += 1;
35        }
36#else
37        do {
38            *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale);
39            src += 1;
40            dst += 1;
41        } while (--count > 0);
42#endif
43    }
44}
45
46//#define TEST_SRC_ALPHA
47
48static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
49                                  const SkPMColor* SK_RESTRICT src,
50                                  int count, U8CPU alpha) {
51    SkASSERT(255 == alpha);
52    if (count > 0) {
53#ifdef UNROLL
54        if (count & 1) {
55            *dst = SkPMSrcOver(*(src++), *dst);
56            dst += 1;
57            count -= 1;
58        }
59
60        const SkPMColor* SK_RESTRICT srcEnd = src + count;
61        while (src != srcEnd) {
62            *dst = SkPMSrcOver(*(src++), *dst);
63            dst += 1;
64            *dst = SkPMSrcOver(*(src++), *dst);
65            dst += 1;
66        }
67#else
68        do {
69#ifdef TEST_SRC_ALPHA
70            SkPMColor sc = *src;
71            if (sc) {
72                unsigned srcA = SkGetPackedA32(sc);
73                SkPMColor result = sc;
74                if (srcA != 255) {
75                    result = SkPMSrcOver(sc, *dst);
76                }
77                *dst = result;
78            }
79#else
80            *dst = SkPMSrcOver(*src, *dst);
81#endif
82            src += 1;
83            dst += 1;
84        } while (--count > 0);
85#endif
86    }
87}
88
89static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
90                                 const SkPMColor* SK_RESTRICT src,
91                                 int count, U8CPU alpha) {
92    SkASSERT(alpha <= 255);
93    if (count > 0) {
94#ifdef UNROLL
95        if (count & 1) {
96            *dst = SkBlendARGB32(*(src++), *dst, alpha);
97            dst += 1;
98            count -= 1;
99        }
100
101        const SkPMColor* SK_RESTRICT srcEnd = src + count;
102        while (src != srcEnd) {
103            *dst = SkBlendARGB32(*(src++), *dst, alpha);
104            dst += 1;
105            *dst = SkBlendARGB32(*(src++), *dst, alpha);
106            dst += 1;
107        }
108#else
109        do {
110            *dst = SkBlendARGB32(*src, *dst, alpha);
111            src += 1;
112            dst += 1;
113        } while (--count > 0);
114#endif
115    }
116}
117
118///////////////////////////////////////////////////////////////////////////////
119
120static const SkBlitRow::Proc32 gDefault_Procs32[] = {
121    S32_Opaque_BlitRow32,
122    S32_Blend_BlitRow32,
123    S32A_Opaque_BlitRow32,
124    S32A_Blend_BlitRow32
125};
126
127SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) {
128    SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32));
129    // just so we don't crash
130    flags &= kFlags32_Mask;
131
132    SkBlitRow::Proc32 proc = PlatformProcs32(flags);
133    if (NULL == proc) {
134        proc = gDefault_Procs32[flags];
135    }
136    SkASSERT(proc);
137    return proc;
138}
139
140SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() {
141    SkBlitRow::ColorProc proc = PlatformColorProc();
142    if (NULL == proc) {
143        proc = Color32;
144    }
145    SkASSERT(proc);
146    return proc;
147}
148
149void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[],
150                        int count, SkPMColor color) {
151    if (count > 0) {
152        if (0 == color) {
153            if (src != dst) {
154                memcpy(dst, src, count * sizeof(SkPMColor));
155            }
156        }
157        unsigned colorA = SkGetPackedA32(color);
158        if (255 == colorA) {
159            sk_memset32(dst, color, count);
160        } else {
161            unsigned scale = 256 - SkAlpha255To256(colorA);
162            do {
163                *dst = color + SkAlphaMulQ(*src, scale);
164                src += 1;
165                dst += 1;
166            } while (--count);
167        }
168    }
169}
170
171///////////////////////////////////////////////////////////////////////////////
172
173static void SkARGB32_BlitMask_portable(void* dst, size_t dstRB,
174                                       SkBitmap::Config dstConfig,
175                                       const uint8_t* mask,
176                                       size_t maskRB, SkColor color,
177                                       int width, int height) {
178    size_t dstOffset = dstRB - (width << 2);
179    size_t maskOffset = maskRB - width;
180    SkPMColor *device = (SkPMColor *)dst;
181    do {
182        int w = width;
183        do {
184            unsigned aa = *mask++;
185            *device = SkBlendARGB32(color, *device, aa);
186            device += 1;
187        } while (--w != 0);
188        device = (uint32_t*)((char*)device + dstOffset);
189        mask += maskOffset;
190    } while (--height != 0);
191}
192
193SkBlitMask::Proc SkBlitMask::Factory(SkBitmap::Config config, SkColor color) {
194    SkBlitMask::Proc proc = PlatformProcs(config, color);
195    if (NULL == proc) {
196        switch (config) {
197            case SkBitmap::kARGB_8888_Config:
198                if ( SK_ColorBLACK != color && 0xFF != SkColorGetA(color) ) {
199                    //TODO: blitmask for black;
200                    //TODO: blitmask for opaque;
201                    proc = SkARGB32_BlitMask_portable;
202                }
203                break;
204            default:
205                break;
206        }
207    }
208    return proc;
209}
210
211