Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/core/SkConfig8888.cpp

Issue 203993002: hide Config8888 entirely (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/core/SkConfig8888.h ('k') | src/core/SkDevice.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #include "SkConfig8888.h" 1 #include "SkConfig8888.h"
2 #include "SkColorPriv.h"
2 #include "SkMathPriv.h" 3 #include "SkMathPriv.h"
3 #include "SkUnPreMultiply.h" 4 #include "SkUnPreMultiply.h"
4 5
5 namespace { 6 enum AlphaVerb {
7 kNothing_AlphaVerb,
8 kPremul_AlphaVerb,
9 kUnpremul_AlphaVerb,
10 };
6 11
7 template <int A_IDX, int R_IDX, int G_IDX, int B_IDX> 12 template <bool doSwapRB, AlphaVerb doAlpha> uint32_t convert32(uint32_t c) {
8 inline uint32_t pack_config8888(uint32_t a, uint32_t r, 13 if (doSwapRB) {
9 uint32_t g, uint32_t b) { 14 c = SkSwizzle_RB(c);
10 #ifdef SK_CPU_LENDIAN 15 }
11 return (a << (A_IDX * 8)) | (r << (R_IDX * 8)) | 16
12 (g << (G_IDX * 8)) | (b << (B_IDX * 8)); 17 // Lucky for us, in both RGBA and BGRA, the alpha component is always in the same place, so
13 #else 18 // we can perform premul or unpremul the same way without knowing the swizzl es for RGB.
14 return (a << ((3-A_IDX) * 8)) | (r << ((3-R_IDX) * 8)) | 19 switch (doAlpha) {
15 (g << ((3-G_IDX) * 8)) | (b << ((3-B_IDX) * 8)); 20 case kNothing_AlphaVerb:
16 #endif 21 // no change
22 break;
23 case kPremul_AlphaVerb:
24 c = SkPreMultiplyARGB(SkGetPackedA32(c), SkGetPackedR32(c),
25 SkGetPackedG32(c), SkGetPackedB32(c));
26 break;
27 case kUnpremul_AlphaVerb:
28 c = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(c);
29 break;
30 }
31 return c;
17 } 32 }
18 33
19 template <int A_IDX, int R_IDX, int G_IDX, int B_IDX> 34 template <bool doSwapRB, AlphaVerb doAlpha>
20 inline void unpack_config8888(uint32_t color, 35 void convert32_row(uint32_t* dst, const uint32_t* src, int count) {
21 uint32_t* a, uint32_t* r, 36 // This has to be correct if src == dst (but not partial overlap)
22 uint32_t* g, uint32_t* b) { 37 for (int i = 0; i < count; ++i) {
23 #ifdef SK_CPU_LENDIAN 38 dst[i] = convert32<doSwapRB, doAlpha>(src[i]);
24 *a = (color >> (A_IDX * 8)) & 0xff;
25 *r = (color >> (R_IDX * 8)) & 0xff;
26 *g = (color >> (G_IDX * 8)) & 0xff;
27 *b = (color >> (B_IDX * 8)) & 0xff;
28 #else
29 *a = (color >> ((3 - A_IDX) * 8)) & 0xff;
30 *r = (color >> ((3 - R_IDX) * 8)) & 0xff;
31 *g = (color >> ((3 - G_IDX) * 8)) & 0xff;
32 *b = (color >> ((3 - B_IDX) * 8)) & 0xff;
33 #endif
34 }
35
36 #ifdef SK_CPU_LENDIAN
37 static const int SK_NATIVE_A_IDX = SK_A32_SHIFT / 8;
38 static const int SK_NATIVE_R_IDX = SK_R32_SHIFT / 8;
39 static const int SK_NATIVE_G_IDX = SK_G32_SHIFT / 8;
40 static const int SK_NATIVE_B_IDX = SK_B32_SHIFT / 8;
41 #else
42 static const int SK_NATIVE_A_IDX = 3 - (SK_A32_SHIFT / 8);
43 static const int SK_NATIVE_R_IDX = 3 - (SK_R32_SHIFT / 8);
44 static const int SK_NATIVE_G_IDX = 3 - (SK_G32_SHIFT / 8);
45 static const int SK_NATIVE_B_IDX = 3 - (SK_B32_SHIFT / 8);
46 #endif
47
48 /**
49 * convert_pixel<OUT_CFG, IN_CFG converts a pixel value from one Config8888 to
50 * another. It is implemented by first expanding OUT_CFG to r, g, b, a indices
51 * and an is_premul bool as params to another template function. Then IN_CFG is
52 * expanded via another function call.
53 */
54
55 template <bool OUT_PM, int OUT_A_IDX, int OUT_R_IDX, int OUT_G_IDX, int OUT_B_ID X,
56 bool IN_PM, int IN_A_IDX, int IN_R_IDX, int IN_G_IDX, int IN_B_IDX >
57 inline uint32_t convert_pixel(uint32_t pixel) {
58 uint32_t a, r, g, b;
59 unpack_config8888<IN_A_IDX, IN_R_IDX, IN_G_IDX, IN_B_IDX>(pixel, &a, &r, &g, &b);
60 if (IN_PM && !OUT_PM) {
61 // Using SkUnPreMultiply::ApplyScale is faster than (value * 0xff) / a.
62 if (a) {
63 SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(a);
64 r = SkUnPreMultiply::ApplyScale(scale, r);
65 g = SkUnPreMultiply::ApplyScale(scale, g);
66 b = SkUnPreMultiply::ApplyScale(scale, b);
67 } else {
68 return 0;
69 }
70 } else if (!IN_PM && OUT_PM) {
71 // This matches SkUnPreMultiply conversion which we are replacing.
72 r = SkMulDiv255Round(r, a);
73 g = SkMulDiv255Round(g, a);
74 b = SkMulDiv255Round(b, a);
75 }
76 return pack_config8888<OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX>(a, r, g, b);
77 }
78
79 template <bool OUT_PM, int OUT_A_IDX, int OUT_R_IDX, int OUT_G_IDX, int OUT_B_ID X, SkCanvas::Config8888 IN_CFG>
80 inline uint32_t convert_pixel(uint32_t pixel) {
81 switch(IN_CFG) {
82 case SkCanvas::kNative_Premul_Config8888:
83 return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G _IDX, OUT_B_IDX,
84 true, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_NA TIVE_G_IDX, SK_NATIVE_B_IDX>(pixel);
85 break;
86 case SkCanvas::kNative_Unpremul_Config8888:
87 return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G _IDX, OUT_B_IDX,
88 false, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_NA TIVE_G_IDX, SK_NATIVE_B_IDX>(pixel);
89 break;
90 case SkCanvas::kBGRA_Premul_Config8888:
91 return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_ IDX,
92 true, 3, 2, 1, 0>(pixe l);
93 break;
94 case SkCanvas::kBGRA_Unpremul_Config8888:
95 return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_ IDX,
96 false, 3, 2, 1, 0>(pix el);
97 break;
98 case SkCanvas::kRGBA_Premul_Config8888:
99 return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_ IDX,
100 true, 3, 0, 1, 2>(pixe l);
101 break;
102 case SkCanvas::kRGBA_Unpremul_Config8888:
103 return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_ IDX,
104 false, 3, 0, 1, 2>(pix el);
105 break;
106 default:
107 SkDEBUGFAIL("Unexpected config8888");
108 return 0;
109 break;
110 } 39 }
111 } 40 }
112 41
113 template <SkCanvas::Config8888 OUT_CFG, SkCanvas::Config8888 IN_CFG> 42 static bool is_32bit_colortype(SkColorType ct) {
114 inline uint32_t convert_pixel(uint32_t pixel) { 43 return kRGBA_8888_SkColorType == ct || kBGRA_8888_SkColorType == ct;
115 switch(OUT_CFG) { 44 }
116 case SkCanvas::kNative_Premul_Config8888: 45
117 return convert_pixel<true, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_NA TIVE_G_IDX, SK_NATIVE_B_IDX, IN_CFG>(pixel); 46 static AlphaVerb compute_AlphaVerb(SkAlphaType src, SkAlphaType dst) {
118 break; 47 SkASSERT(kIgnore_SkAlphaType != src);
119 case SkCanvas::kNative_Unpremul_Config8888: 48 SkASSERT(kIgnore_SkAlphaType != dst);
120 return convert_pixel<false, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_N ATIVE_G_IDX, SK_NATIVE_B_IDX, IN_CFG>(pixel); 49
121 break; 50 if (kOpaque_SkAlphaType == src || kOpaque_SkAlphaType == dst || src == dst) {
122 case SkCanvas::kBGRA_Premul_Config8888: 51 return kNothing_AlphaVerb;
123 return convert_pixel<true, 3, 2, 1, 0, IN_CFG>(pixel); 52 }
124 break; 53 if (kPremul_SkAlphaType == dst) {
125 case SkCanvas::kBGRA_Unpremul_Config8888: 54 SkASSERT(kUnpremul_SkAlphaType == src);
126 return convert_pixel<false, 3, 2, 1, 0, IN_CFG>(pixel); 55 return kPremul_AlphaVerb;
127 break; 56 } else {
128 case SkCanvas::kRGBA_Premul_Config8888: 57 SkASSERT(kPremul_SkAlphaType == src);
129 return convert_pixel<true, 3, 0, 1, 2, IN_CFG>(pixel); 58 SkASSERT(kUnpremul_SkAlphaType == dst);
130 break; 59 return kUnpremul_AlphaVerb;
131 case SkCanvas::kRGBA_Unpremul_Config8888:
132 return convert_pixel<false, 3, 0, 1, 2, IN_CFG>(pixel);
133 break;
134 default:
135 SkDEBUGFAIL("Unexpected config8888");
136 return 0;
137 break;
138 } 60 }
139 } 61 }
140 62
141 /** 63 static void memcpy32_row(uint32_t* dst, const uint32_t* src, int count) {
142 * SkConvertConfig8888Pixels has 6 * 6 possible combinations of src and dst 64 memcpy(dst, src, count * 4);
143 * configs. Each is implemented as an instantiation templated function. Two
144 * levels of switch statements are used to select the correct instantiation, one
145 * for the src config and one for the dst config.
146 */
147
148 template <SkCanvas::Config8888 DST_CFG, SkCanvas::Config8888 SRC_CFG>
149 inline void convert_config8888(uint32_t* dstPixels,
150 size_t dstRowBytes,
151 const uint32_t* srcPixels,
152 size_t srcRowBytes,
153 int width,
154 int height) {
155 intptr_t dstPix = reinterpret_cast<intptr_t>(dstPixels);
156 intptr_t srcPix = reinterpret_cast<intptr_t>(srcPixels);
157
158 for (int y = 0; y < height; ++y) {
159 srcPixels = reinterpret_cast<const uint32_t*>(srcPix);
160 dstPixels = reinterpret_cast<uint32_t*>(dstPix);
161 for (int x = 0; x < width; ++x) {
162 dstPixels[x] = convert_pixel<DST_CFG, SRC_CFG>(srcPixels[x]);
163 }
164 dstPix += dstRowBytes;
165 srcPix += srcRowBytes;
166 }
167 } 65 }
168 66
169 template <SkCanvas::Config8888 SRC_CFG> 67 bool SkSrcPixelInfo::convertPixelsTo(SkDstPixelInfo* dst, int width, int height) const {
170 inline void convert_config8888(uint32_t* dstPixels, 68 if (width <= 0 || height <= 0) {
171 size_t dstRowBytes, 69 return false;
172 SkCanvas::Config8888 dstConfig, 70 }
173 const uint32_t* srcPixels, 71
174 size_t srcRowBytes, 72 if (!is_32bit_colortype(fColorType) || !is_32bit_colortype(dst->fColorType)) {
175 int width, 73 return false;
176 int height) { 74 }
177 switch(dstConfig) { 75
178 case SkCanvas::kNative_Premul_Config8888: 76 void (*proc)(uint32_t* dst, const uint32_t* src, int count);
179 convert_config8888<SkCanvas::kNative_Premul_Config8888, SRC_CFG>(dst Pixels, dstRowBytes, srcPixels, srcRowBytes, width, height); 77 AlphaVerb doAlpha = compute_AlphaVerb(fAlphaType, dst->fAlphaType);
78 bool doSwapRB = fColorType != dst->fColorType;
79
80 switch (doAlpha) {
81 case kNothing_AlphaVerb:
82 if (doSwapRB) {
83 proc = convert32_row<true, kNothing_AlphaVerb>;
84 } else {
85 if (fPixels == dst->fPixels) {
86 return true;
87 }
88 proc = memcpy32_row;
89 }
180 break; 90 break;
181 case SkCanvas::kNative_Unpremul_Config8888: 91 case kPremul_AlphaVerb:
182 convert_config8888<SkCanvas::kNative_Unpremul_Config8888, SRC_CFG>(d stPixels, dstRowBytes, srcPixels, srcRowBytes, width, height); 92 if (doSwapRB) {
93 proc = convert32_row<true, kPremul_AlphaVerb>;
94 } else {
95 proc = convert32_row<false, kPremul_AlphaVerb>;
96 }
183 break; 97 break;
184 case SkCanvas::kBGRA_Premul_Config8888: 98 case kUnpremul_AlphaVerb:
185 convert_config8888<SkCanvas::kBGRA_Premul_Config8888, SRC_CFG>(dstPi xels, dstRowBytes, srcPixels, srcRowBytes, width, height); 99 if (doSwapRB) {
186 break; 100 proc = convert32_row<true, kUnpremul_AlphaVerb>;
187 case SkCanvas::kBGRA_Unpremul_Config8888: 101 } else {
188 convert_config8888<SkCanvas::kBGRA_Unpremul_Config8888, SRC_CFG>(dst Pixels, dstRowBytes, srcPixels, srcRowBytes, width, height); 102 proc = convert32_row<false, kUnpremul_AlphaVerb>;
189 break; 103 }
190 case SkCanvas::kRGBA_Premul_Config8888:
191 convert_config8888<SkCanvas::kRGBA_Premul_Config8888, SRC_CFG>(dstPi xels, dstRowBytes, srcPixels, srcRowBytes, width, height);
192 break;
193 case SkCanvas::kRGBA_Unpremul_Config8888:
194 convert_config8888<SkCanvas::kRGBA_Unpremul_Config8888, SRC_CFG>(dst Pixels, dstRowBytes, srcPixels, srcRowBytes, width, height);
195 break;
196 default:
197 SkDEBUGFAIL("Unexpected config8888");
198 break; 104 break;
199 } 105 }
106
107 uint32_t* dstP = static_cast<uint32_t*>(dst->fPixels);
108 const uint32_t* srcP = static_cast<const uint32_t*>(fPixels);
109 size_t srcInc = fRowBytes >> 2;
110 size_t dstInc = dst->fRowBytes >> 2;
111 for (int y = 0; y < height; ++y) {
112 proc(dstP, srcP, width);
113 dstP += dstInc;
114 srcP += srcInc;
115 }
116 return true;
200 } 117 }
201 118
202 }
203
204 void SkConvertConfig8888Pixels(uint32_t* dstPixels,
205 size_t dstRowBytes,
206 SkCanvas::Config8888 dstConfig,
207 const uint32_t* srcPixels,
208 size_t srcRowBytes,
209 SkCanvas::Config8888 srcConfig,
210 int width,
211 int height) {
212 if (srcConfig == dstConfig) {
213 if (srcPixels == dstPixels) {
214 return;
215 }
216 if (dstRowBytes == srcRowBytes &&
217 4U * width == srcRowBytes) {
218 memcpy(dstPixels, srcPixels, srcRowBytes * height);
219 return;
220 } else {
221 intptr_t srcPix = reinterpret_cast<intptr_t>(srcPixels);
222 intptr_t dstPix = reinterpret_cast<intptr_t>(dstPixels);
223 for (int y = 0; y < height; ++y) {
224 srcPixels = reinterpret_cast<const uint32_t*>(srcPix);
225 dstPixels = reinterpret_cast<uint32_t*>(dstPix);
226 memcpy(dstPixels, srcPixels, 4 * width);
227 srcPix += srcRowBytes;
228 dstPix += dstRowBytes;
229 }
230 return;
231 }
232 }
233 switch(srcConfig) {
234 case SkCanvas::kNative_Premul_Config8888:
235 convert_config8888<SkCanvas::kNative_Premul_Config8888>(dstPixels, d stRowBytes, dstConfig, srcPixels, srcRowBytes, width, height);
236 break;
237 case SkCanvas::kNative_Unpremul_Config8888:
238 convert_config8888<SkCanvas::kNative_Unpremul_Config8888>(dstPixels, dstRowBytes, dstConfig, srcPixels, srcRowBytes, width, height);
239 break;
240 case SkCanvas::kBGRA_Premul_Config8888:
241 convert_config8888<SkCanvas::kBGRA_Premul_Config8888>(dstPixels, dst RowBytes, dstConfig, srcPixels, srcRowBytes, width, height);
242 break;
243 case SkCanvas::kBGRA_Unpremul_Config8888:
244 convert_config8888<SkCanvas::kBGRA_Unpremul_Config8888>(dstPixels, d stRowBytes, dstConfig, srcPixels, srcRowBytes, width, height);
245 break;
246 case SkCanvas::kRGBA_Premul_Config8888:
247 convert_config8888<SkCanvas::kRGBA_Premul_Config8888>(dstPixels, dst RowBytes, dstConfig, srcPixels, srcRowBytes, width, height);
248 break;
249 case SkCanvas::kRGBA_Unpremul_Config8888:
250 convert_config8888<SkCanvas::kRGBA_Unpremul_Config8888>(dstPixels, d stRowBytes, dstConfig, srcPixels, srcRowBytes, width, height);
251 break;
252 default:
253 SkDEBUGFAIL("Unexpected config8888");
254 break;
255 }
256 }
257
258 uint32_t SkPackConfig8888(SkCanvas::Config8888 config,
259 uint32_t a,
260 uint32_t r,
261 uint32_t g,
262 uint32_t b) {
263 switch (config) {
264 case SkCanvas::kNative_Premul_Config8888:
265 case SkCanvas::kNative_Unpremul_Config8888:
266 return pack_config8888<SK_NATIVE_A_IDX,
267 SK_NATIVE_R_IDX,
268 SK_NATIVE_G_IDX,
269 SK_NATIVE_B_IDX>(a, r, g, b);
270 case SkCanvas::kBGRA_Premul_Config8888:
271 case SkCanvas::kBGRA_Unpremul_Config8888:
272 return pack_config8888<3, 2, 1, 0>(a, r, g, b);
273 case SkCanvas::kRGBA_Premul_Config8888:
274 case SkCanvas::kRGBA_Unpremul_Config8888:
275 return pack_config8888<3, 0, 1, 2>(a, r, g, b);
276 default:
277 SkDEBUGFAIL("Unexpected config8888");
278 return 0;
279 }
280 }
OLDNEW
« no previous file with comments | « src/core/SkConfig8888.h ('k') | src/core/SkDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698