1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkBlitRow.h"
9 #include "SkBlitMask.h"
10 #include "SkColorPriv.h"
11 #include "SkUtils.h"
12
13 #define UNROLL
14
S32_Opaque_BlitRow32(SkPMColor * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha)15 static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
16 const SkPMColor* SK_RESTRICT src,
17 int count, U8CPU alpha) {
18 SkASSERT(255 == alpha);
19 memcpy(dst, src, count * sizeof(SkPMColor));
20 }
21
S32_Blend_BlitRow32(SkPMColor * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha)22 static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
23 const SkPMColor* SK_RESTRICT src,
24 int count, U8CPU alpha) {
25 SkASSERT(alpha <= 255);
26 if (count > 0) {
27 unsigned src_scale = SkAlpha255To256(alpha);
28 unsigned dst_scale = 256 - src_scale;
29
30 #ifdef UNROLL
31 if (count & 1) {
32 *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
33 dst += 1;
34 count -= 1;
35 }
36
37 const SkPMColor* SK_RESTRICT srcEnd = src + count;
38 while (src != srcEnd) {
39 *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
40 dst += 1;
41 *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
42 dst += 1;
43 }
44 #else
45 do {
46 *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale);
47 src += 1;
48 dst += 1;
49 } while (--count > 0);
50 #endif
51 }
52 }
53
54 //#define TEST_SRC_ALPHA
55
S32A_Opaque_BlitRow32(SkPMColor * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha)56 static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
57 const SkPMColor* SK_RESTRICT src,
58 int count, U8CPU alpha) {
59 SkASSERT(255 == alpha);
60 if (count > 0) {
61 #ifdef UNROLL
62 if (count & 1) {
63 *dst = SkPMSrcOver(*(src++), *dst);
64 dst += 1;
65 count -= 1;
66 }
67
68 const SkPMColor* SK_RESTRICT srcEnd = src + count;
69 while (src != srcEnd) {
70 *dst = SkPMSrcOver(*(src++), *dst);
71 dst += 1;
72 *dst = SkPMSrcOver(*(src++), *dst);
73 dst += 1;
74 }
75 #else
76 do {
77 #ifdef TEST_SRC_ALPHA
78 SkPMColor sc = *src;
79 if (sc) {
80 unsigned srcA = SkGetPackedA32(sc);
81 SkPMColor result = sc;
82 if (srcA != 255) {
83 result = SkPMSrcOver(sc, *dst);
84 }
85 *dst = result;
86 }
87 #else
88 *dst = SkPMSrcOver(*src, *dst);
89 #endif
90 src += 1;
91 dst += 1;
92 } while (--count > 0);
93 #endif
94 }
95 }
96
S32A_Blend_BlitRow32(SkPMColor * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha)97 static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
98 const SkPMColor* SK_RESTRICT src,
99 int count, U8CPU alpha) {
100 SkASSERT(alpha <= 255);
101 if (count > 0) {
102 #ifdef UNROLL
103 if (count & 1) {
104 *dst = SkBlendARGB32(*(src++), *dst, alpha);
105 dst += 1;
106 count -= 1;
107 }
108
109 const SkPMColor* SK_RESTRICT srcEnd = src + count;
110 while (src != srcEnd) {
111 *dst = SkBlendARGB32(*(src++), *dst, alpha);
112 dst += 1;
113 *dst = SkBlendARGB32(*(src++), *dst, alpha);
114 dst += 1;
115 }
116 #else
117 do {
118 *dst = SkBlendARGB32(*src, *dst, alpha);
119 src += 1;
120 dst += 1;
121 } while (--count > 0);
122 #endif
123 }
124 }
125
126 ///////////////////////////////////////////////////////////////////////////////
127
128 static const SkBlitRow::Proc32 gDefault_Procs32[] = {
129 S32_Opaque_BlitRow32,
130 S32_Blend_BlitRow32,
131 S32A_Opaque_BlitRow32,
132 S32A_Blend_BlitRow32
133 };
134
Factory32(unsigned flags)135 SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) {
136 SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32));
137 // just so we don't crash
138 flags &= kFlags32_Mask;
139
140 SkBlitRow::Proc32 proc = PlatformProcs32(flags);
141 if (NULL == proc) {
142 proc = gDefault_Procs32[flags];
143 }
144 SkASSERT(proc);
145 return proc;
146 }
147
ColorProcFactory()148 SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() {
149 SkBlitRow::ColorProc proc = PlatformColorProc();
150 if (NULL == proc) {
151 proc = Color32;
152 }
153 SkASSERT(proc);
154 return proc;
155 }
156
Color32(SkPMColor * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,SkPMColor color)157 void SkBlitRow::Color32(SkPMColor* SK_RESTRICT dst,
158 const SkPMColor* SK_RESTRICT src,
159 int count, SkPMColor color) {
160 if (count > 0) {
161 if (0 == color) {
162 if (src != dst) {
163 memcpy(dst, src, count * sizeof(SkPMColor));
164 }
165 return;
166 }
167 unsigned colorA = SkGetPackedA32(color);
168 if (255 == colorA) {
169 sk_memset32(dst, color, count);
170 } else {
171 unsigned scale = 256 - SkAlpha255To256(colorA);
172 do {
173 *dst = color + SkAlphaMulQ(*src, scale);
174 src += 1;
175 dst += 1;
176 } while (--count);
177 }
178 }
179 }
180
181