From 60895e1a140e9db30cfd9c2d8ce3f8e2cb86f271 Mon Sep 17 00:00:00 2001 From: Jean-Philippe ANDRE Date: Sun, 22 Jun 2014 18:35:33 +0900 Subject: [PATCH] Evas ETC2: Remove some C99/GCC extensions code There is still some C99 code in the file in the form of for (int k = 0; ...) If there's a strong requirement not to use this form, I'll change it, otherwise I find this specific code style more readable (k is local to this iteration). This patch and the previous one even give a ~10% speedup on the encoding time. Sweet :) --- src/static_libs/rg_etc/etc2_encoder.c | 123 +++++++++++++++----------- 1 file changed, 73 insertions(+), 50 deletions(-) diff --git a/src/static_libs/rg_etc/etc2_encoder.c b/src/static_libs/rg_etc/etc2_encoder.c index d4bc11c3d5..54481e83af 100644 --- a/src/static_libs/rg_etc/etc2_encoder.c +++ b/src/static_libs/rg_etc/etc2_encoder.c @@ -88,19 +88,38 @@ static const int kBlockWalk[16] = { (((byteval) >> (bit)) & 0x1) // Real clamp -#define CLAMP(a) ({ int _b = (a); (((_b) >= 0) ? (((_b) < 256) ? (_b) : 255) : 0); }) - -// Simple min -#define MIN(a,b) ({ int _z = (a), _y = (b); ((_z <= _y) ? _z : _y); }) - -// Simple max -#define MAX(a,b) ({ int __z = (a), __y = (b); ((__z > __y) ? __z : __y); }) +static inline int +clampi(int a) +{ + if (EINA_LIKELY(!(a & ~0xFF))) + return a; + else if (a < 0) + return 0; + else + return 0xFF; +} // Simple clamp between two values -#define MINMAX(a,b,c) (MIN(c,MAX(a,b))) +static inline int +minmaxi(int val, int m, int M) +{ + if (EINA_LIKELY((val >= m) && (val <= M))) + return val; + else if (val < m) + return m; + else + return M; +} // Simple abs -#define ABS(a) ({ int _a = (a); ((_a >= 0) ? _a : (-_a)); }) +static inline int +absi(int a) +{ + if (EINA_LIKELY(a >= 0)) + return a; + else + return (-a); +} // Write a BGRA value for output to Evas #define BGRA(r,g,b,a) ((a << 24) | (r << 16) | (g << 8) | b) @@ -149,8 +168,8 @@ _etc2_alpha_block_pack(uint8_t *etc2_alpha, // Brute force -- find modifier index for (int k = 0; (k < 8) && minErr; k++) { - int tryA = CLAMP(base_codeword + alphaModifiers[k] * multiplier); - int err = ABS(realA - tryA); + int tryA = clampi(base_codeword + alphaModifiers[k] * multiplier); + int err = absi(realA - tryA); if (err < minErr) { minErr = err; @@ -203,8 +222,9 @@ _etc2_alpha_encode(uint8_t *etc2_alpha, const uint32_t *bgra, for (int i = 0; i < 16; i++) { - int thisDiff = ABS(alphas[i] - avg); - maxDiff = MAX(thisDiff, maxDiff); + int thisDiff = absi(alphas[i] - avg); + if (thisDiff > maxDiff) + maxDiff = thisDiff; diff += thisDiff; } @@ -239,13 +259,13 @@ _etc2_alpha_encode(uint8_t *etc2_alpha, const uint32_t *bgra, // for loop avg, avg-1, avg+1, avg-2, avg+2, ... for (int step = 0; step < base_range; step += base_step) - for (base_codeword = CLAMP(avg - step); - base_codeword <= CLAMP(avg + step);) + for (base_codeword = clampi(avg - step); + base_codeword <= clampi(avg + step);) { for (modifierIdx = 0; modifierIdx < 16; modifierIdx++) for (multiplier = 0; multiplier < 16; multiplier++) { - if ((ABS(multiplier * kAlphaModifiers[modifierIdx][3]) + ABS(base_codeword - avg)) < maxDiff) + if ((absi(multiplier * kAlphaModifiers[modifierIdx][3]) + absi(base_codeword - avg)) < maxDiff) continue; err = _etc2_alpha_block_pack(etc2_alpha, base_codeword, @@ -263,7 +283,7 @@ _etc2_alpha_encode(uint8_t *etc2_alpha, const uint32_t *bgra, } if (step <= 0) break; if (base_codeword < 255) - base_codeword = CLAMP(base_codeword + 2 * step); + base_codeword = clampi(base_codeword + 2 * step); else break; } @@ -350,13 +370,13 @@ _etc2_h_mode_header_pack(uint8_t *etc2, Eina_Bool *swap_colors, // Note: if c1 == c2, no big deal because H is not the best choice of mode if (distanceSpecialBit) { - c1 = MAX(color1, color2); - c2 = MIN(color1, color2); + c1 = (color1 > color2) ? color1 : color2; + c2 = (color1 <= color2) ? color1 : color2; } else { - c1 = MIN(color1, color2); - c2 = MAX(color1, color2); + c1 = (color1 <= color2) ? color1 : color2; + c2 = (color1 > color2) ? color1 : color2; } // Return flag so we use the proper colors when packing the block @@ -433,34 +453,37 @@ _rgb_distance_euclid(uint32_t color1, uint32_t color2) static unsigned int _etc2_th_mode_block_pack(uint8_t *etc2, Eina_Bool h_mode, - uint32_t color1, uint32_t color2, int distance, + uint32_t c1, uint32_t c2, int distance, const uint32_t *bgra, Eina_Bool write, Eina_Bool *swap_colors) { union { uint8_t c[4]; uint32_t v; - } paint_colors[4]; + } paint_colors[4], color1, color2; int errAcc = 0; + color1.v = c1; + color2.v = c2; + if (write) { memset(etc2 + 4, 0, 4); if (!h_mode) { - if (!_etc2_t_mode_header_pack(etc2, color1, color2, distance)) + if (!_etc2_t_mode_header_pack(etc2, color1.v, color2.v, distance)) return INT_MAX; // assert } else { if (!_etc2_h_mode_header_pack(etc2, swap_colors, - color1, color2, distance)) + color1.v, color2.v, distance)) return INT_MAX; // assert if (*swap_colors) { - uint32_t tmp = color1; - color1 = color2; - color2 = tmp; + uint32_t tmp = color1.v; + color1.v = color2.v; + color2.v = tmp; } } } @@ -469,17 +492,17 @@ _etc2_th_mode_block_pack(uint8_t *etc2, Eina_Bool h_mode, { if (!h_mode) { - paint_colors[0].c[k] = ((uint8_t *) &color1)[k]; - paint_colors[1].c[k] = CLAMP(((uint8_t *) &color2)[k] + distance); - paint_colors[2].c[k] = ((uint8_t *) &color2)[k]; - paint_colors[3].c[k] = CLAMP(((uint8_t *) &color2)[k] - distance); + paint_colors[0].c[k] = color1.c[k]; + paint_colors[1].c[k] = clampi(color2.c[k] + distance); + paint_colors[2].c[k] = color2.c[k]; + paint_colors[3].c[k] = clampi(color2.c[k] - distance); } else { - paint_colors[0].c[k] = CLAMP(((uint8_t *) &color1)[k] + distance); - paint_colors[1].c[k] = CLAMP(((uint8_t *) &color1)[k] - distance); - paint_colors[2].c[k] = CLAMP(((uint8_t *) &color2)[k] + distance); - paint_colors[3].c[k] = CLAMP(((uint8_t *) &color2)[k] - distance); + paint_colors[0].c[k] = clampi(color1.c[k] + distance); + paint_colors[1].c[k] = clampi(color1.c[k] - distance); + paint_colors[2].c[k] = clampi(color2.c[k] + distance); + paint_colors[3].c[k] = clampi(color2.c[k] - distance); } } @@ -527,9 +550,9 @@ _color_reduce_444(uint32_t color) B1 = (B & 0xF0) | (B >> 4); B2 = ((B & 0xF0) + 0x10) | ((B >> 4) + 1); - R = (ABS(R - R1) <= ABS(R - R2)) ? R1 : R2; - G = (ABS(G - G1) <= ABS(G - G2)) ? G1 : G2; - B = (ABS(B - B1) <= ABS(B - B2)) ? B1 : B2; + R = (absi(R - R1) <= absi(R - R2)) ? R1 : R2; + G = (absi(G - G1) <= absi(G - G2)) ? G1 : G2; + B = (absi(B - B1) <= absi(B - B2)) ? B1 : B2; return BGRA(R, G, B, 255); } @@ -868,9 +891,9 @@ _etc2_planar_mode_block_pack(uint8_t *etc2, for (int y = 0; y < 4; y++) for (int x = 0; x < 4; x++) { - const int R = CLAMP(((x * (RH - RO)) + y * (RV - RO) + 4 * RO + 2) >> 2); - const int G = CLAMP(((x * (GH - GO)) + y * (GV - GO) + 4 * GO + 2) >> 2); - const int B = CLAMP(((x * (BH - BO)) + y * (BV - BO) + 4 * BO + 2) >> 2); + const int R = clampi(((x * (RH - RO)) + y * (RV - RO) + 4 * RO + 2) >> 2); + const int G = clampi(((x * (GH - GO)) + y * (GV - GO) + 4 * GO + 2) >> 2); + const int B = clampi(((x * (BH - BO)) + y * (BV - BO) + 4 * BO + 2) >> 2); uint32_t color = BGRA(R, G, B, 255); err += _rgb_distance_euclid(color, bgra[x + y * 4]); @@ -901,14 +924,14 @@ _etc2_planar_mode_block_encode(uint8_t *etc2, const uint32_t *bgra, BO = B_VAL((bgra[0])); Ocol = _color_reduce_676(bgra[0]); - Rx = CLAMP(RO + (4 * (R_VAL((bgra[3])) - RO)) / 3); - Gx = CLAMP(GO + (4 * (G_VAL((bgra[3])) - GO)) / 3); - Bx = CLAMP(BO + (4 * (B_VAL((bgra[3])) - BO)) / 3); + Rx = clampi(RO + (4 * (R_VAL((bgra[3])) - RO)) / 3); + Gx = clampi(GO + (4 * (G_VAL((bgra[3])) - GO)) / 3); + Bx = clampi(BO + (4 * (B_VAL((bgra[3])) - BO)) / 3); Hcol = _color_reduce_676(BGRA(Rx, Gx, Bx, 0xFF)); - Rx = CLAMP(RO + (4 * (R_VAL((bgra[12])) - RO)) / 3); - Gx = CLAMP(GO + (4 * (G_VAL((bgra[12])) - GO)) / 3); - Bx = CLAMP(BO + (4 * (B_VAL((bgra[12])) - BO)) / 3); + Rx = clampi(RO + (4 * (R_VAL((bgra[12])) - RO)) / 3); + Gx = clampi(GO + (4 * (G_VAL((bgra[12])) - GO)) / 3); + Bx = clampi(BO + (4 * (B_VAL((bgra[12])) - BO)) / 3); Vcol = _color_reduce_676(BGRA(Rx, Gx, Bx, 0xFF)); err = _etc2_planar_mode_block_pack(etc2, Ocol, Hcol, Vcol, bgra, EINA_TRUE); @@ -949,7 +972,7 @@ etc2_rgba8_block_pack(unsigned char *etc2, const unsigned int *bgra, #endif safe_params.m_dithering = !!params->m_dithering; - safe_params.m_quality = MINMAX(params->m_quality, 0, 2); + safe_params.m_quality = minmaxi(params->m_quality, 0, 2); errors[0] = rg_etc1_pack_block(etc2_try[0], bgra, &safe_params); errors[1] = _etc2_th_mode_block_encode(etc2_try[1], bgra, &safe_params); @@ -1005,7 +1028,7 @@ etc2_rgb8_block_pack(unsigned char *etc2, const unsigned int *bgra, int bestSolution = 0; safe_params.m_dithering = !!params->m_dithering; - safe_params.m_quality = MINMAX(params->m_quality, 0, 2); + safe_params.m_quality = minmaxi(params->m_quality, 0, 2); errors[0] = rg_etc1_pack_block(etc2_try[0], bgra, &safe_params); errors[1] = _etc2_th_mode_block_encode(etc2_try[1], bgra, &safe_params);