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

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

Issue 15402003: Improve the performance of SkConvertConfig8888Pixels using Array lookup (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: change to use SkMulDiv255Round to benifit ARM architecture Created 7 years, 6 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 | « no previous file | no next file » | 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 "SkMathPriv.h" 2 #include "SkMathPriv.h"
3 #include "SkUnPreMultiply.h"
3 4
4 namespace { 5 namespace {
5 6
6 template <int A_IDX, int R_IDX, int G_IDX, int B_IDX> 7 template <int A_IDX, int R_IDX, int G_IDX, int B_IDX>
7 inline uint32_t pack_config8888(uint32_t a, uint32_t r, 8 inline uint32_t pack_config8888(uint32_t a, uint32_t r,
8 uint32_t g, uint32_t b) { 9 uint32_t g, uint32_t b) {
9 #ifdef SK_CPU_LENDIAN 10 #ifdef SK_CPU_LENDIAN
10 return (a << (A_IDX * 8)) | (r << (R_IDX * 8)) | 11 return (a << (A_IDX * 8)) | (r << (R_IDX * 8)) |
11 (g << (G_IDX * 8)) | (b << (B_IDX * 8)); 12 (g << (G_IDX * 8)) | (b << (B_IDX * 8));
12 #else 13 #else
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 * and an is_premul bool as params to another template function. Then IN_CFG is 51 * and an is_premul bool as params to another template function. Then IN_CFG is
51 * expanded via another function call. 52 * expanded via another function call.
52 */ 53 */
53 54
54 template <bool OUT_PM, int OUT_A_IDX, int OUT_R_IDX, int OUT_G_IDX, int OUT_B_ID X, 55 template <bool OUT_PM, int OUT_A_IDX, int OUT_R_IDX, int OUT_G_IDX, int OUT_B_ID X,
55 bool IN_PM, int IN_A_IDX, int IN_R_IDX, int IN_G_IDX, int IN_B_IDX > 56 bool IN_PM, int IN_A_IDX, int IN_R_IDX, int IN_G_IDX, int IN_B_IDX >
56 inline uint32_t convert_pixel(uint32_t pixel) { 57 inline uint32_t convert_pixel(uint32_t pixel) {
57 uint32_t a, r, g, b; 58 uint32_t a, r, g, b;
58 unpack_config8888<IN_A_IDX, IN_R_IDX, IN_G_IDX, IN_B_IDX>(pixel, &a, &r, &g, &b); 59 unpack_config8888<IN_A_IDX, IN_R_IDX, IN_G_IDX, IN_B_IDX>(pixel, &a, &r, &g, &b);
59 if (IN_PM && !OUT_PM) { 60 if (IN_PM && !OUT_PM) {
60 // We're doing the explicit divide to match WebKit layout 61 // Using SkUnPreMultiply::ApplyScale is faster than (value * 0xff) / a.
61 // test expectations. We can modify and rebaseline if there
62 // it can be shown that there is a more performant way to
63 // unpremul.
64 if (a) { 62 if (a) {
65 r = r * 0xff / a; 63 SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(a);
66 g = g * 0xff / a; 64 r = SkUnPreMultiply::ApplyScale(scale, r);
67 b = b * 0xff / a; 65 g = SkUnPreMultiply::ApplyScale(scale, g);
66 b = SkUnPreMultiply::ApplyScale(scale, b);
68 } else { 67 } else {
69 return 0; 68 return 0;
70 } 69 }
71 } else if (!IN_PM && OUT_PM) { 70 } else if (!IN_PM && OUT_PM) {
72 // This matches WebKit's conversion which we are replacing. 71 // This matches SkUnPreMultiply conversion which we are replacing.
73 // We can consider alternative rounding rules for performance. 72 r = SkMulDiv255Round(r, a);
74 r = SkMulDiv255Ceiling(r, a); 73 g = SkMulDiv255Round(g, a);
75 g = SkMulDiv255Ceiling(g, a); 74 b = SkMulDiv255Round(b, a);
76 b = SkMulDiv255Ceiling(b, a);
77 } 75 }
78 return pack_config8888<OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX>(a, r, g, b); 76 return pack_config8888<OUT_A_IDX, OUT_R_IDX, OUT_G_IDX, OUT_B_IDX>(a, r, g, b);
79 } 77 }
80 78
81 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> 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>
82 inline uint32_t convert_pixel(uint32_t pixel) { 80 inline uint32_t convert_pixel(uint32_t pixel) {
83 switch(IN_CFG) { 81 switch(IN_CFG) {
84 case SkCanvas::kNative_Premul_Config8888: 82 case SkCanvas::kNative_Premul_Config8888:
85 return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G _IDX, OUT_B_IDX, 83 return convert_pixel<OUT_PM, OUT_A_IDX, OUT_R_IDX, OUT_G _IDX, OUT_B_IDX,
86 true, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_NA TIVE_G_IDX, SK_NATIVE_B_IDX>(pixel); 84 true, SK_NATIVE_A_IDX, SK_NATIVE_R_IDX, SK_NA TIVE_G_IDX, SK_NATIVE_B_IDX>(pixel);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 case SkCanvas::kBGRA_Unpremul_Config8888: 271 case SkCanvas::kBGRA_Unpremul_Config8888:
274 return pack_config8888<3, 2, 1, 0>(a, r, g, b); 272 return pack_config8888<3, 2, 1, 0>(a, r, g, b);
275 case SkCanvas::kRGBA_Premul_Config8888: 273 case SkCanvas::kRGBA_Premul_Config8888:
276 case SkCanvas::kRGBA_Unpremul_Config8888: 274 case SkCanvas::kRGBA_Unpremul_Config8888:
277 return pack_config8888<3, 0, 1, 2>(a, r, g, b); 275 return pack_config8888<3, 0, 1, 2>(a, r, g, b);
278 default: 276 default:
279 SkDEBUGFAIL("Unexpected config8888"); 277 SkDEBUGFAIL("Unexpected config8888");
280 return 0; 278 return 0;
281 } 279 }
282 } 280 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698