blob: f50077839e825ac5a3808bbd087eb6fed62de3ea [file] [log] [blame]
reed@android.comc4cae852009-09-23 15:06:10 +00001#include "SkBlitRow.h"
2#include "SkColorPriv.h"
3#include "SkUtils.h"
4
djsollen@google.com57f49692011-02-23 20:46:31 +00005#define UNROLL
6
reed@android.comc4cae852009-09-23 15:06:10 +00007static 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;
djsollen@google.com57f49692011-02-23 20:46:31 +000021
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
reed@android.comc4cae852009-09-23 15:06:10 +000037 do {
38 *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale);
39 src += 1;
40 dst += 1;
41 } while (--count > 0);
djsollen@google.com57f49692011-02-23 20:46:31 +000042#endif
reed@android.comc4cae852009-09-23 15:06:10 +000043 }
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) {
djsollen@google.com57f49692011-02-23 20:46:31 +000053#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
reed@android.comc4cae852009-09-23 15:06:10 +000068 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);
djsollen@google.com57f49692011-02-23 20:46:31 +000085#endif
reed@android.comc4cae852009-09-23 15:06:10 +000086 }
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) {
djsollen@google.com57f49692011-02-23 20:46:31 +000094#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
reed@android.comc4cae852009-09-23 15:06:10 +0000109 do {
110 *dst = SkBlendARGB32(*src, *dst, alpha);
111 src += 1;
112 dst += 1;
113 } while (--count > 0);
djsollen@google.com57f49692011-02-23 20:46:31 +0000114#endif
reed@android.comc4cae852009-09-23 15:06:10 +0000115 }
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
senorblanco@chromium.org92727612009-11-04 20:51:06 +0000132 SkBlitRow::Proc32 proc = PlatformProcs32(flags);
reed@android.comc4cae852009-09-23 15:06:10 +0000133 if (NULL == proc) {
134 proc = gDefault_Procs32[flags];
135 }
136 SkASSERT(proc);
137 return proc;
138}
139
senorblanco@chromium.org29e50542010-12-16 19:07:45 +0000140SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() {
senorblanco@chromium.orgc3856382010-12-13 15:27:20 +0000141 SkBlitRow::ColorProc proc = PlatformColorProc();
142 if (NULL == proc) {
senorblanco@chromium.org29e50542010-12-16 19:07:45 +0000143 proc = Color32;
senorblanco@chromium.orgc3856382010-12-13 15:27:20 +0000144 }
senorblanco@chromium.org29e50542010-12-16 19:07:45 +0000145 SkASSERT(proc);
146 return proc;
senorblanco@chromium.orgc3856382010-12-13 15:27:20 +0000147}
148
senorblanco@chromium.org29e50542010-12-16 19:07:45 +0000149void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[],
150 int count, SkPMColor color) {
reed@android.comc4cae852009-09-23 15:06:10 +0000151 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