[PATCH 5/5] win32u: Remove the branches in blend_color_gamma().
Byeongsik Jeon
bsjeon at hanmail.net
Wed Apr 20 11:40:07 CDT 2022
Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
---
Numerically, there is a difference in code behavior because it only
processes the full pixel alpha value 0xFFFFF(~0u).
For example, if the red subpixel alpha value is 0xFF, the dst red subpixel is
calculated by:
gamma->encode[ blend_color( gamma->decode[dst.r], gamma->decode[text.r], alpha.r) ]
alpha.r == 0xFF, so,
gamma->encode[ gamma->decode(text.r) ]
The original code will get text.r, but the changed code will cause little errors.
However, since the affected pixels have already been changed by the LCD Filter,
I wonder if they require strict pixel accuracy.
dlls/win32u/dibdrv/primitives.c | 65 ++++++++++++++-------------------
1 file changed, 27 insertions(+), 38 deletions(-)
diff --git a/dlls/win32u/dibdrv/primitives.c b/dlls/win32u/dibdrv/primitives.c
index 4687ead5585..30f326934f0 100644
--- a/dlls/win32u/dibdrv/primitives.c
+++ b/dlls/win32u/dibdrv/primitives.c
@@ -6339,22 +6339,18 @@ static void draw_glyph_null( const dib_info *dib, const RECT *rect, const dib_in
{
return;
}
-static inline BYTE blend_color_gamma( BYTE dst, BYTE text, BYTE decoded_text, BYTE alpha,
+static inline BYTE blend_color_gamma( BYTE dst, BYTE decoded_text, BYTE alpha,
const struct font_gamma_ramp *gamma_ramp )
{
- if (alpha == 0) return dst;
- if (alpha == 255) return text;
- if (dst == text) return dst;
-
return gamma_ramp->encode[ blend_color( gamma_ramp->decode[dst], decoded_text, alpha ) ];
}
-static inline DWORD blend_subpixel( BYTE r, BYTE g, BYTE b, DWORD text, DWORD decoded_text, DWORD alpha,
+static inline DWORD blend_subpixel( BYTE r, BYTE g, BYTE b, DWORD decoded_text, DWORD alpha,
const struct font_gamma_ramp *gamma_ramp )
{
- return blend_color_gamma( r, text >> 16, decoded_text >> 16, alpha >> 16, gamma_ramp ) << 16 |
- blend_color_gamma( g, text >> 8, decoded_text >> 8, alpha >> 8, gamma_ramp ) << 8 |
- blend_color_gamma( b, text, decoded_text, alpha, gamma_ramp );
+ return blend_color_gamma( r, decoded_text >> 16, alpha >> 16, gamma_ramp ) << 16 |
+ blend_color_gamma( g, decoded_text >> 8, alpha >> 8, gamma_ramp ) << 8 |
+ blend_color_gamma( b, decoded_text, alpha, gamma_ramp );
}
static void draw_subpixel_glyph_8888( const dib_info *dib, const RECT *rect, const dib_info *glyph,
@@ -6375,8 +6371,9 @@ static void draw_subpixel_glyph_8888( const dib_info *dib, const RECT *rect, con
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] == 0) continue;
+ if (glyph_ptr[x] == ~0u) { dst_ptr[x] = text_pixel; continue; }
dst_ptr[x] = blend_subpixel( dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x],
- text_pixel, decoded_text, glyph_ptr[x], gamma_ramp );
+ decoded_text, glyph_ptr[x], gamma_ramp );
}
dst_ptr += dib->stride / 4;
glyph_ptr += glyph->stride / 4;
@@ -6390,25 +6387,22 @@ static void draw_subpixel_glyph_32( const dib_info *dib, const RECT *rect, const
DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top );
const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y );
int x, y;
- DWORD text, decoded_text, val;
-
- text = get_field( text_pixel, dib->red_shift, dib->red_len ) << 16 |
- get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 |
- get_field( text_pixel, dib->blue_shift, dib->blue_len );
+ DWORD decoded_text, val;
- decoded_text = gamma_ramp->decode[ (BYTE)(text >> 16) ] << 16 |
- gamma_ramp->decode[ (BYTE)(text >> 8 ) ] << 8 |
- gamma_ramp->decode[ (BYTE)(text ) ];
+ decoded_text = gamma_ramp->decode[ get_field( text_pixel, dib->red_shift, dib->red_len ) ] << 16 |
+ gamma_ramp->decode[ get_field( text_pixel, dib->green_shift, dib->green_len ) ] << 8 |
+ gamma_ramp->decode[ get_field( text_pixel, dib->blue_shift, dib->blue_len ) ];
for (y = rect->top; y < rect->bottom; y++)
{
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] == 0) continue;
+ if (glyph_ptr[x] == ~0u) { dst_ptr[x] = text_pixel; continue; }
val = blend_subpixel( get_field(dst_ptr[x], dib->red_shift, dib->red_len),
get_field(dst_ptr[x], dib->green_shift, dib->green_len),
get_field(dst_ptr[x], dib->blue_shift, dib->blue_len),
- text, decoded_text, glyph_ptr[x], gamma_ramp );
+ decoded_text, glyph_ptr[x], gamma_ramp );
dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val );
}
dst_ptr += dib->stride / 4;
@@ -6434,8 +6428,9 @@ static void draw_subpixel_glyph_24( const dib_info *dib, const RECT *rect, const
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] == 0) continue;
+ if (glyph_ptr[x] == ~0u) { dst_ptr[x] = text_pixel; continue; }
val = blend_subpixel( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
- text_pixel, decoded_text, glyph_ptr[x], gamma_ramp );
+ decoded_text, glyph_ptr[x], gamma_ramp );
dst_ptr[x * 3] = val;
dst_ptr[x * 3 + 1] = val >> 8;
dst_ptr[x * 3 + 2] = val >> 16;
@@ -6452,25 +6447,22 @@ static void draw_subpixel_glyph_555( const dib_info *dib, const RECT *rect, cons
WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y );
int x, y;
- DWORD text, decoded_text, val;
-
- text = ((text_pixel << 9) & 0xf80000) | ((text_pixel << 4) & 0x070000) |
- ((text_pixel << 6) & 0x00f800) | ((text_pixel << 1) & 0x000700) |
- ((text_pixel << 3) & 0x0000f8) | ((text_pixel >> 2) & 0x000007);
+ DWORD decoded_text, val;
- decoded_text = gamma_ramp->decode[ (BYTE)(text >> 16) ] << 16 |
- gamma_ramp->decode[ (BYTE)(text >> 8 ) ] << 8 |
- gamma_ramp->decode[ (BYTE)(text ) ];
+ decoded_text = gamma_ramp->decode[ ((text_pixel >> 7) & 0xf8) | ((text_pixel >> 12) & 0x07) ] << 16 |
+ gamma_ramp->decode[ ((text_pixel >> 2) & 0xf8) | ((text_pixel >> 7) & 0x07) ] << 8 |
+ gamma_ramp->decode[ ((text_pixel << 3) & 0xf8) | ((text_pixel >> 2) & 0x07) ];
for (y = rect->top; y < rect->bottom; y++)
{
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] == 0) continue;
+ if (glyph_ptr[x] == ~0u) { dst_ptr[x] = text_pixel; continue; }
val = blend_subpixel( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >> 7) & 0x07),
((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >> 2) & 0x07),
- text, decoded_text, glyph_ptr[x], NULL );
+ decoded_text, glyph_ptr[x], NULL );
dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
}
dst_ptr += dib->stride / 2;
@@ -6485,25 +6477,22 @@ static void draw_subpixel_glyph_16( const dib_info *dib, const RECT *rect, const
WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y );
int x, y;
- DWORD text, decoded_text, val;
-
- text = get_field( text_pixel, dib->red_shift, dib->red_len ) << 16 |
- get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 |
- get_field( text_pixel, dib->blue_shift, dib->blue_len );
+ DWORD decoded_text, val;
- decoded_text = gamma_ramp->decode[ (BYTE)(text >> 16) ] << 16 |
- gamma_ramp->decode[ (BYTE)(text >> 8 ) ] << 8 |
- gamma_ramp->decode[ (BYTE)(text ) ];
+ decoded_text = gamma_ramp->decode[ get_field( text_pixel, dib->red_shift, dib->red_len ) ] << 16 |
+ gamma_ramp->decode[ get_field( text_pixel, dib->green_shift, dib->green_len ) ] << 8 |
+ gamma_ramp->decode[ get_field( text_pixel, dib->blue_shift, dib->blue_len ) ];
for (y = rect->top; y < rect->bottom; y++)
{
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] == 0) continue;
+ if (glyph_ptr[x] == ~0u) { dst_ptr[x] = text_pixel; continue; }
val = blend_subpixel( get_field(dst_ptr[x], dib->red_shift, dib->red_len),
get_field(dst_ptr[x], dib->green_shift, dib->green_len),
get_field(dst_ptr[x], dib->blue_shift, dib->blue_len),
- text, decoded_text, glyph_ptr[x], NULL );
+ decoded_text, glyph_ptr[x], NULL );
dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val );
}
dst_ptr += dib->stride / 2;
--
2.36.0
More information about the wine-devel
mailing list