gdi32: Move the loop through each clipped rectangle to the primitive blend funcs.

This is to prepare so we don't recalculate the lookup cache map for color
tables on every clipped rect (which is expensive).

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Gabriel Ivăncescu 2021-04-16 11:11:19 +01:00 committed by Alexandre Julliard
parent e9412a8ae0
commit d4dc8fd2c2
3 changed files with 194 additions and 164 deletions

View File

@ -584,17 +584,15 @@ static void mask_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src,
static DWORD blend_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src, const RECT *src_rect,
HRGN clip, BLENDFUNCTION blend )
{
POINT origin;
POINT offset;
struct clipped_rects clipped_rects;
int i;
if (!get_clipped_rects( dst, dst_rect, clip, &clipped_rects )) return ERROR_SUCCESS;
for (i = 0; i < clipped_rects.count; i++)
{
origin.x = src_rect->left + clipped_rects.rects[i].left - dst_rect->left;
origin.y = src_rect->top + clipped_rects.rects[i].top - dst_rect->top;
dst->funcs->blend_rect( dst, &clipped_rects.rects[i], src, &origin, blend );
}
offset.x = src_rect->left - dst_rect->left;
offset.y = src_rect->top - dst_rect->top;
dst->funcs->blend_rects( dst, clipped_rects.count, clipped_rects.rects, src, &offset, blend );
free_clipped_rects( &clipped_rects );
return ERROR_SUCCESS;
}

View File

@ -189,8 +189,8 @@ typedef struct primitive_funcs
const dib_info *brush, const rop_mask_bits *bits);
void (* copy_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
const POINT *origin, int rop2, int overlap);
void (* blend_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
const POINT *origin, BLENDFUNCTION blend);
void (* blend_rects)(const dib_info *dst, int num, const RECT *rc, const dib_info *src,
const POINT *offset, BLENDFUNCTION blend);
BOOL (* gradient_rect)(const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode);
void (* mask_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
const POINT *origin, int rop2);

View File

@ -4651,12 +4651,15 @@ static inline DWORD blend_rgb( BYTE dst_r, BYTE dst_g, BYTE dst_b, DWORD src, BL
blend_color( dst_r, src >> 16, blend.SourceConstantAlpha ) << 16);
}
static void blend_rect_8888(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
static void blend_rects_8888(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
int i, x, y;
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
int x, y;
if (blend.AlphaFormat & AC_SRC_ALPHA)
{
@ -4678,13 +4681,17 @@ static void blend_rect_8888(const dib_info *dst, const RECT *rc,
for (x = 0; x < rc->right - rc->left; x++)
dst_ptr[x] = blend_argb_no_src_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
}
}
static void blend_rect_32(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
static void blend_rects_32(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
int i, x, y;
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
int x, y;
if (dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
{
@ -4717,13 +4724,17 @@ static void blend_rect_32(const dib_info *dst, const RECT *rc,
}
}
}
}
static void blend_rect_24(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
static void blend_rects_24(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
int i, x, y;
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
BYTE *dst_ptr = get_pixel_ptr_24( dst, rc->left, rc->top );
int x, y;
for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
@ -4737,13 +4748,17 @@ static void blend_rect_24(const dib_info *dst, const RECT *rc,
}
}
}
}
static void blend_rect_555(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
static void blend_rects_555(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
int i, x, y;
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
int x, y;
for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
{
@ -4757,13 +4772,17 @@ static void blend_rect_555(const dib_info *dst, const RECT *rc,
}
}
}
}
static void blend_rect_16(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
static void blend_rects_16(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
int i, x, y;
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
int x, y;
for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
{
@ -4777,14 +4796,18 @@ static void blend_rect_16(const dib_info *dst, const RECT *rc,
}
}
}
}
static void blend_rect_8(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
static void blend_rects_8(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
int i, x, y;
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
BYTE *dst_ptr = get_pixel_ptr_8( dst, rc->left, rc->top );
int x, y;
for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
@ -4796,22 +4819,26 @@ static void blend_rect_8(const dib_info *dst, const RECT *rc,
}
}
}
}
static void blend_rect_4(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
static void blend_rects_4(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
int i, j, x, y;
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
BYTE *dst_ptr = get_pixel_ptr_4( dst, rc->left, rc->top );
int i, x, y;
for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
for (i = 0, x = (dst->rect.left + rc->left) & 1; i < rc->right - rc->left; i++, x++)
for (j = 0, x = (dst->rect.left + rc->left) & 1; j < rc->right - rc->left; j++, x++)
{
DWORD val = ((x & 1) ? dst_ptr[x / 2] : (dst_ptr[x / 2] >> 4)) & 0x0f;
RGBQUAD rgb = color_table[val];
val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[i], blend );
val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[j], blend );
val = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
if (x & 1)
dst_ptr[x / 2] = val | (dst_ptr[x / 2] & 0xf0);
@ -4820,30 +4847,35 @@ static void blend_rect_4(const dib_info *dst, const RECT *rc,
}
}
}
}
static void blend_rect_1(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
static void blend_rects_1(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
int i, j, x, y;
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
BYTE *dst_ptr = get_pixel_ptr_1( dst, rc->left, rc->top );
int i, x, y;
for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
for (i = 0, x = (dst->rect.left + rc->left) & 7; i < rc->right - rc->left; i++, x++)
for (j = 0, x = (dst->rect.left + rc->left) & 7; j < rc->right - rc->left; j++, x++)
{
DWORD val = (dst_ptr[x / 8] & pixel_masks_1[x % 8]) ? 1 : 0;
RGBQUAD rgb = color_table[val];
val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[i], blend );
val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[j], blend );
val = rgb_to_pixel_colortable(dst, val >> 16, val >> 8, val) ? 0xff : 0;
dst_ptr[x / 8] = (dst_ptr[x / 8] & ~pixel_masks_1[x % 8]) | (val & pixel_masks_1[x % 8]);
}
}
}
}
static void blend_rect_null(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
static void blend_rects_null(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
}
@ -7373,7 +7405,7 @@ const primitive_funcs funcs_8888 =
solid_line_32,
pattern_rects_32,
copy_rect_32,
blend_rect_8888,
blend_rects_8888,
gradient_rect_8888,
mask_rect_32,
draw_glyph_8888,
@ -7394,7 +7426,7 @@ const primitive_funcs funcs_32 =
solid_line_32,
pattern_rects_32,
copy_rect_32,
blend_rect_32,
blend_rects_32,
gradient_rect_32,
mask_rect_32,
draw_glyph_32,
@ -7415,7 +7447,7 @@ const primitive_funcs funcs_24 =
solid_line_24,
pattern_rects_24,
copy_rect_24,
blend_rect_24,
blend_rects_24,
gradient_rect_24,
mask_rect_24,
draw_glyph_24,
@ -7436,7 +7468,7 @@ const primitive_funcs funcs_555 =
solid_line_16,
pattern_rects_16,
copy_rect_16,
blend_rect_555,
blend_rects_555,
gradient_rect_555,
mask_rect_16,
draw_glyph_555,
@ -7457,7 +7489,7 @@ const primitive_funcs funcs_16 =
solid_line_16,
pattern_rects_16,
copy_rect_16,
blend_rect_16,
blend_rects_16,
gradient_rect_16,
mask_rect_16,
draw_glyph_16,
@ -7478,7 +7510,7 @@ const primitive_funcs funcs_8 =
solid_line_8,
pattern_rects_8,
copy_rect_8,
blend_rect_8,
blend_rects_8,
gradient_rect_8,
mask_rect_8,
draw_glyph_8,
@ -7499,7 +7531,7 @@ const primitive_funcs funcs_4 =
solid_line_4,
pattern_rects_4,
copy_rect_4,
blend_rect_4,
blend_rects_4,
gradient_rect_4,
mask_rect_4,
draw_glyph_4,
@ -7520,7 +7552,7 @@ const primitive_funcs funcs_1 =
solid_line_1,
pattern_rects_1,
copy_rect_1,
blend_rect_1,
blend_rects_1,
gradient_rect_1,
mask_rect_null,
draw_glyph_1,
@ -7541,7 +7573,7 @@ const primitive_funcs funcs_null =
solid_line_null,
pattern_rects_null,
copy_rect_null,
blend_rect_null,
blend_rects_null,
gradient_rect_null,
mask_rect_null,
draw_glyph_null,