OLD | NEW |
| (Empty) |
1 #include "SkBlitRow.h" | |
2 #include "SkColorPriv.h" | |
3 #include "SkDither.h" | |
4 | |
5 /////////////////////////////////////////////////////////////////////////////// | |
6 | |
7 static void S32_D565_Opaque(uint16_t* SK_RESTRICT dst, | |
8 const SkPMColor* SK_RESTRICT src, int count, | |
9 U8CPU alpha, int /*x*/, int /*y*/) { | |
10 SkASSERT(255 == alpha); | |
11 | |
12 if (count > 0) { | |
13 do { | |
14 SkPMColor c = *src++; | |
15 SkPMColorAssert(c); | |
16 SkASSERT(SkGetPackedA32(c) == 255); | |
17 *dst++ = SkPixel32ToPixel16_ToU16(c); | |
18 } while (--count != 0); | |
19 } | |
20 } | |
21 | |
22 static void S32_D565_Blend(uint16_t* SK_RESTRICT dst, | |
23 const SkPMColor* SK_RESTRICT src, int count, | |
24 U8CPU alpha, int /*x*/, int /*y*/) { | |
25 SkASSERT(255 > alpha); | |
26 | |
27 if (count > 0) { | |
28 int scale = SkAlpha255To256(alpha); | |
29 do { | |
30 SkPMColor c = *src++; | |
31 SkPMColorAssert(c); | |
32 SkASSERT(SkGetPackedA32(c) == 255); | |
33 uint16_t d = *dst; | |
34 *dst++ = SkPackRGB16( | |
35 SkAlphaBlend(SkPacked32ToR16(c), SkGetPackedR16(d), scale), | |
36 SkAlphaBlend(SkPacked32ToG16(c), SkGetPackedG16(d), scale), | |
37 SkAlphaBlend(SkPacked32ToB16(c), SkGetPackedB16(d), scale)); | |
38 } while (--count != 0); | |
39 } | |
40 } | |
41 | |
42 static void S32A_D565_Opaque(uint16_t* SK_RESTRICT dst, | |
43 const SkPMColor* SK_RESTRICT src, int count, | |
44 U8CPU alpha, int /*x*/, int /*y*/) { | |
45 SkASSERT(255 == alpha); | |
46 | |
47 if (count > 0) { | |
48 do { | |
49 SkPMColor c = *src++; | |
50 SkPMColorAssert(c); | |
51 // if (__builtin_expect(c!=0, 1)) | |
52 if (c) { | |
53 *dst = SkSrcOver32To16(c, *dst); | |
54 } | |
55 dst += 1; | |
56 } while (--count != 0); | |
57 } | |
58 } | |
59 | |
60 static void S32A_D565_Blend(uint16_t* SK_RESTRICT dst, | |
61 const SkPMColor* SK_RESTRICT src, int count, | |
62 U8CPU alpha, int /*x*/, int /*y*/) { | |
63 SkASSERT(255 > alpha); | |
64 | |
65 if (count > 0) { | |
66 int src_scale = SkAlpha255To256(alpha); | |
67 do { | |
68 SkPMColor sc = *src++; | |
69 SkPMColorAssert(sc); | |
70 if (sc) | |
71 { | |
72 uint16_t dc = *dst; | |
73 unsigned sa = SkGetPackedA32(sc); | |
74 unsigned dr, dg, db; | |
75 | |
76 if (sa == 255) { | |
77 dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), s
rc_scale); | |
78 dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), s
rc_scale); | |
79 db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), s
rc_scale); | |
80 } else { | |
81 unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale); | |
82 dr = (SkPacked32ToR16(sc) * src_scale + SkGetPackedR16(dc) *
dst_scale) >> 8; | |
83 dg = (SkPacked32ToG16(sc) * src_scale + SkGetPackedG16(dc) *
dst_scale) >> 8; | |
84 db = (SkPacked32ToB16(sc) * src_scale + SkGetPackedB16(dc) *
dst_scale) >> 8; | |
85 } | |
86 *dst = SkPackRGB16(dr, dg, db); | |
87 } | |
88 dst += 1; | |
89 } while (--count != 0); | |
90 } | |
91 } | |
92 | |
93 ///////////////////////////////////////////////////////////////////////////// | |
94 | |
95 static void S32_D565_Opaque_Dither(uint16_t* SK_RESTRICT dst, | |
96 const SkPMColor* SK_RESTRICT src, | |
97 int count, U8CPU alpha, int x, int y) { | |
98 SkASSERT(255 == alpha); | |
99 | |
100 if (count > 0) { | |
101 DITHER_565_SCAN(y); | |
102 do { | |
103 SkPMColor c = *src++; | |
104 SkPMColorAssert(c); | |
105 SkASSERT(SkGetPackedA32(c) == 255); | |
106 | |
107 unsigned dither = DITHER_VALUE(x); | |
108 *dst++ = SkDitherRGB32To565(c, dither); | |
109 DITHER_INC_X(x); | |
110 } while (--count != 0); | |
111 } | |
112 } | |
113 | |
114 static void S32_D565_Blend_Dither(uint16_t* SK_RESTRICT dst, | |
115 const SkPMColor* SK_RESTRICT src, | |
116 int count, U8CPU alpha, int x, int y) { | |
117 SkASSERT(255 > alpha); | |
118 | |
119 if (count > 0) { | |
120 int scale = SkAlpha255To256(alpha); | |
121 DITHER_565_SCAN(y); | |
122 do { | |
123 SkPMColor c = *src++; | |
124 SkPMColorAssert(c); | |
125 SkASSERT(SkGetPackedA32(c) == 255); | |
126 | |
127 int dither = DITHER_VALUE(x); | |
128 int sr = SkGetPackedR32(c); | |
129 int sg = SkGetPackedG32(c); | |
130 int sb = SkGetPackedB32(c); | |
131 sr = SkDITHER_R32To565(sr, dither); | |
132 sg = SkDITHER_G32To565(sg, dither); | |
133 sb = SkDITHER_B32To565(sb, dither); | |
134 | |
135 uint16_t d = *dst; | |
136 *dst++ = SkPackRGB16(SkAlphaBlend(sr, SkGetPackedR16(d), scale), | |
137 SkAlphaBlend(sg, SkGetPackedG16(d), scale), | |
138 SkAlphaBlend(sb, SkGetPackedB16(d), scale)); | |
139 DITHER_INC_X(x); | |
140 } while (--count != 0); | |
141 } | |
142 } | |
143 | |
144 static void S32A_D565_Opaque_Dither(uint16_t* SK_RESTRICT dst, | |
145 const SkPMColor* SK_RESTRICT src, | |
146 int count, U8CPU alpha, int x, int y) { | |
147 SkASSERT(255 == alpha); | |
148 | |
149 if (count > 0) { | |
150 DITHER_565_SCAN(y); | |
151 do { | |
152 SkPMColor c = *src++; | |
153 SkPMColorAssert(c); | |
154 if (c) { | |
155 unsigned a = SkGetPackedA32(c); | |
156 | |
157 int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a)); | |
158 | |
159 unsigned sr = SkGetPackedR32(c); | |
160 unsigned sg = SkGetPackedG32(c); | |
161 unsigned sb = SkGetPackedB32(c); | |
162 sr = SkDITHER_R32_FOR_565(sr, d); | |
163 sg = SkDITHER_G32_FOR_565(sg, d); | |
164 sb = SkDITHER_B32_FOR_565(sb, d); | |
165 | |
166 uint32_t src_expanded = (sg << 24) | (sr << 13) | (sb << 2); | |
167 uint32_t dst_expanded = SkExpand_rgb_16(*dst); | |
168 dst_expanded = dst_expanded * (SkAlpha255To256(255 - a) >> 3); | |
169 // now src and dst expanded are in g:11 r:10 x:1 b:10 | |
170 *dst = SkCompact_rgb_16((src_expanded + dst_expanded) >> 5); | |
171 } | |
172 dst += 1; | |
173 DITHER_INC_X(x); | |
174 } while (--count != 0); | |
175 } | |
176 } | |
177 | |
178 static void S32A_D565_Blend_Dither(uint16_t* SK_RESTRICT dst, | |
179 const SkPMColor* SK_RESTRICT src, | |
180 int count, U8CPU alpha, int x, int y) { | |
181 SkASSERT(255 > alpha); | |
182 | |
183 if (count > 0) { | |
184 int src_scale = SkAlpha255To256(alpha); | |
185 DITHER_565_SCAN(y); | |
186 do { | |
187 SkPMColor c = *src++; | |
188 SkPMColorAssert(c); | |
189 if (c) | |
190 { | |
191 unsigned d = *dst; | |
192 int sa = SkGetPackedA32(c); | |
193 int dst_scale = SkAlpha255To256(255 - SkAlphaMul(sa, src_scale))
; | |
194 int dither = DITHER_VALUE(x); | |
195 | |
196 int sr = SkGetPackedR32(c); | |
197 int sg = SkGetPackedG32(c); | |
198 int sb = SkGetPackedB32(c); | |
199 sr = SkDITHER_R32To565(sr, dither); | |
200 sg = SkDITHER_G32To565(sg, dither); | |
201 sb = SkDITHER_B32To565(sb, dither); | |
202 | |
203 int dr = (sr * src_scale + SkGetPackedR16(d) * dst_scale) >> 8; | |
204 int dg = (sg * src_scale + SkGetPackedG16(d) * dst_scale) >> 8; | |
205 int db = (sb * src_scale + SkGetPackedB16(d) * dst_scale) >> 8; | |
206 | |
207 *dst = SkPackRGB16(dr, dg, db); | |
208 } | |
209 dst += 1; | |
210 DITHER_INC_X(x); | |
211 } while (--count != 0); | |
212 } | |
213 } | |
214 | |
215 /////////////////////////////////////////////////////////////////////////////// | |
216 /////////////////////////////////////////////////////////////////////////////// | |
217 | |
218 #ifdef USE_T32CB16BLEND_ASM | |
219 extern "C" void scanline_t32cb16blend_arm(uint16_t*, uint32_t*, size_t); | |
220 #endif | |
221 | |
222 static const SkBlitRow::Proc gProcs16[] = { | |
223 // no dither | |
224 S32_D565_Opaque, | |
225 S32_D565_Blend, | |
226 | |
227 #ifdef USE_T32CB16BLEND_ASM | |
228 (SkBlitRow::Proc)scanline_t32cb16blend_arm, | |
229 #else | |
230 S32A_D565_Opaque, | |
231 #endif | |
232 | |
233 S32A_D565_Blend, | |
234 | |
235 // dither | |
236 S32_D565_Opaque_Dither, | |
237 S32_D565_Blend_Dither, | |
238 | |
239 S32A_D565_Opaque_Dither, | |
240 S32A_D565_Blend_Dither | |
241 }; | |
242 | |
243 extern SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags); | |
244 | |
245 SkBlitRow::Proc SkBlitRow::Factory(unsigned flags, SkBitmap::Config config) { | |
246 SkASSERT(flags < SK_ARRAY_COUNT(gProcs16)); | |
247 | |
248 switch (config) { | |
249 case SkBitmap::kRGB_565_Config: | |
250 return gProcs16[flags]; | |
251 case SkBitmap::kARGB_4444_Config: | |
252 return SkBlitRow_Factory_4444(flags); | |
253 default: | |
254 break; | |
255 } | |
256 return NULL; | |
257 } | |
258 | |
OLD | NEW |