• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SkBlitRow.h"
2 #include "SkColorPriv.h"
3 #include "SkDither.h"
4 
5 ///////////////////////////////////////////////////////////////////////////////
6 
S32_D565_Opaque(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int,int)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 
S32_D565_Blend(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int,int)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 
S32A_D565_Opaque(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int,int)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 
S32A_D565_Blend(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int,int)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), src_scale);
78                     dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale);
79                     db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_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 
S32_D565_Opaque_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)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 
S32_D565_Blend_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)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 
S32A_D565_Opaque_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)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 
S32A_D565_Blend_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)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 static const SkBlitRow::Proc gDefault_565_Procs[] = {
219     // no dither
220     S32_D565_Opaque,
221     S32_D565_Blend,
222 
223     S32A_D565_Opaque,
224     S32A_D565_Blend,
225 
226     // dither
227     S32_D565_Opaque_Dither,
228     S32_D565_Blend_Dither,
229 
230     S32A_D565_Opaque_Dither,
231     S32A_D565_Blend_Dither
232 };
233 
234 extern SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags);
235 
Factory(unsigned flags,SkBitmap::Config config)236 SkBlitRow::Proc SkBlitRow::Factory(unsigned flags, SkBitmap::Config config) {
237     SkASSERT(flags < SK_ARRAY_COUNT(gDefault_565_Procs));
238     // just so we don't crash
239     flags &= kFlags16_Mask;
240 
241     SkBlitRow::Proc proc = NULL;
242 
243     switch (config) {
244         case SkBitmap::kRGB_565_Config:
245             proc = gPlatform_565_Procs[flags];
246             if (NULL == proc) {
247                 proc = gDefault_565_Procs[flags];
248             }
249             break;
250         case SkBitmap::kARGB_4444_Config:
251             proc = gPlatform_4444_Procs[flags];
252             if (NULL == proc) {
253                 proc = SkBlitRow_Factory_4444(flags);
254             }
255             break;
256         default:
257             break;
258     }
259     return proc;
260 }
261 
262