gdi32: Add faster implementation of the pattern_rects primitive when we don't need an AND mask.
This commit is contained in:
parent
2aff4696b6
commit
7339308e16
|
@ -108,6 +108,13 @@ static inline void calc_rop_masks(INT rop, DWORD color, rop_mask *masks)
|
||||||
calc_and_xor_masks( rop, color, &masks->and, &masks->xor );
|
calc_and_xor_masks( rop, color, &masks->and, &masks->xor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline BOOL rop_needs_and_mask( INT rop )
|
||||||
|
{
|
||||||
|
struct rop_codes codes;
|
||||||
|
get_rop_codes( rop, &codes );
|
||||||
|
return codes.a1 || codes.a2;
|
||||||
|
}
|
||||||
|
|
||||||
static inline RGBQUAD rgbquad_from_colorref(COLORREF c)
|
static inline RGBQUAD rgbquad_from_colorref(COLORREF c)
|
||||||
{
|
{
|
||||||
RGBQUAD ret;
|
RGBQUAD ret;
|
||||||
|
@ -1768,8 +1775,8 @@ static BOOL alloc_brush_mask_bits( dib_brush *brush )
|
||||||
assert(brush->masks.xor == NULL);
|
assert(brush->masks.xor == NULL);
|
||||||
assert(brush->dib.stride > 0);
|
assert(brush->dib.stride > 0);
|
||||||
|
|
||||||
if (!(brush->masks.and = HeapAlloc(GetProcessHeap(), 0, 2 * size))) return FALSE;
|
if (!(brush->masks.xor = HeapAlloc(GetProcessHeap(), 0, 2 * size))) return FALSE;
|
||||||
brush->masks.xor = (char *)brush->masks.and + size;
|
brush->masks.and = (char *)brush->masks.xor + size;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1980,7 +1987,7 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
|
||||||
brush->rop = rop;
|
brush->rop = rop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(brush->masks.and == NULL)
|
if(brush->masks.xor == NULL)
|
||||||
{
|
{
|
||||||
switch(brush->style)
|
switch(brush->style)
|
||||||
{
|
{
|
||||||
|
@ -2005,6 +2012,7 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_brush *brush, dib_info *dib,
|
||||||
ERR("Unexpected brush style %d\n", brush->style);
|
ERR("Unexpected brush style %d\n", brush->style);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
if (!rop_needs_and_mask( brush->rop )) brush->masks.and = NULL; /* ignore the and mask */
|
||||||
}
|
}
|
||||||
|
|
||||||
GetBrushOrgEx(pdev->dev.hdc, &origin);
|
GetBrushOrgEx(pdev->dev.hdc, &origin);
|
||||||
|
|
|
@ -836,17 +836,19 @@ static void pattern_rects_32(const dib_info *dib, int num, const RECT *rc, const
|
||||||
const dib_info *brush, const rop_mask_bits *bits)
|
const dib_info *brush, const rop_mask_bits *bits)
|
||||||
{
|
{
|
||||||
DWORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
|
DWORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
|
||||||
int x, y, i;
|
int x, y, i, len, brush_x;
|
||||||
POINT offset;
|
POINT offset;
|
||||||
|
|
||||||
for(i = 0; i < num; i++, rc++)
|
for(i = 0; i < num; i++, rc++)
|
||||||
{
|
{
|
||||||
offset = calc_brush_offset(rc, brush, origin);
|
offset = calc_brush_offset(rc, brush, origin);
|
||||||
|
|
||||||
start = get_pixel_ptr_32(dib, rc->left, rc->top);
|
start = get_pixel_ptr_32(dib, rc->left, rc->top);
|
||||||
start_and = (DWORD*)bits->and + offset.y * brush->stride / 4;
|
|
||||||
start_xor = (DWORD*)bits->xor + offset.y * brush->stride / 4;
|
start_xor = (DWORD*)bits->xor + offset.y * brush->stride / 4;
|
||||||
|
|
||||||
|
if (bits->and)
|
||||||
|
{
|
||||||
|
start_and = (DWORD*)bits->and + offset.y * brush->stride / 4;
|
||||||
|
|
||||||
for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
|
||||||
{
|
{
|
||||||
and_ptr = start_and + offset.x;
|
and_ptr = start_and + offset.x;
|
||||||
|
@ -876,13 +878,34 @@ static void pattern_rects_32(const dib_info *dib, int num, const RECT *rc, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 4)
|
||||||
|
{
|
||||||
|
for (x = rc->left, brush_x = offset.x; x < rc->right; x += len)
|
||||||
|
{
|
||||||
|
len = min( rc->right - x, brush->width - brush_x );
|
||||||
|
memcpy( start + x - rc->left, start_xor + brush_x, len * 4 );
|
||||||
|
brush_x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_xor += brush->stride / 4;
|
||||||
|
offset.y++;
|
||||||
|
if(offset.y == brush->height)
|
||||||
|
{
|
||||||
|
start_xor = bits->xor;
|
||||||
|
offset.y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pattern_rects_24(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
static void pattern_rects_24(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
||||||
const dib_info *brush, const rop_mask_bits *bits)
|
const dib_info *brush, const rop_mask_bits *bits)
|
||||||
{
|
{
|
||||||
BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
|
BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
|
||||||
int x, y, i;
|
int x, y, i, len, brush_x;
|
||||||
POINT offset;
|
POINT offset;
|
||||||
|
|
||||||
for(i = 0; i < num; i++, rc++)
|
for(i = 0; i < num; i++, rc++)
|
||||||
|
@ -890,9 +913,11 @@ static void pattern_rects_24(const dib_info *dib, int num, const RECT *rc, const
|
||||||
offset = calc_brush_offset(rc, brush, origin);
|
offset = calc_brush_offset(rc, brush, origin);
|
||||||
|
|
||||||
start = get_pixel_ptr_24(dib, rc->left, rc->top);
|
start = get_pixel_ptr_24(dib, rc->left, rc->top);
|
||||||
start_and = (BYTE*)bits->and + offset.y * brush->stride;
|
|
||||||
start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
|
start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
|
||||||
|
|
||||||
|
if (bits->and)
|
||||||
|
{
|
||||||
|
start_and = (BYTE*)bits->and + offset.y * brush->stride;
|
||||||
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||||
{
|
{
|
||||||
and_ptr = start_and + offset.x * 3;
|
and_ptr = start_and + offset.x * 3;
|
||||||
|
@ -924,13 +949,34 @@ static void pattern_rects_24(const dib_info *dib, int num, const RECT *rc, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||||
|
{
|
||||||
|
for (x = rc->left, brush_x = offset.x; x < rc->right; x += len)
|
||||||
|
{
|
||||||
|
len = min( rc->right - x, brush->width - brush_x );
|
||||||
|
memcpy( start + (x - rc->left) * 3, start_xor + brush_x * 3, len * 3 );
|
||||||
|
brush_x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_xor += brush->stride;
|
||||||
|
offset.y++;
|
||||||
|
if(offset.y == brush->height)
|
||||||
|
{
|
||||||
|
start_xor = bits->xor;
|
||||||
|
offset.y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pattern_rects_16(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
static void pattern_rects_16(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
||||||
const dib_info *brush, const rop_mask_bits *bits)
|
const dib_info *brush, const rop_mask_bits *bits)
|
||||||
{
|
{
|
||||||
WORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
|
WORD *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
|
||||||
int x, y, i;
|
int x, y, i, len, brush_x;
|
||||||
POINT offset;
|
POINT offset;
|
||||||
|
|
||||||
for(i = 0; i < num; i++, rc++)
|
for(i = 0; i < num; i++, rc++)
|
||||||
|
@ -938,9 +984,11 @@ static void pattern_rects_16(const dib_info *dib, int num, const RECT *rc, const
|
||||||
offset = calc_brush_offset(rc, brush, origin);
|
offset = calc_brush_offset(rc, brush, origin);
|
||||||
|
|
||||||
start = get_pixel_ptr_16(dib, rc->left, rc->top);
|
start = get_pixel_ptr_16(dib, rc->left, rc->top);
|
||||||
start_and = (WORD*)bits->and + offset.y * brush->stride / 2;
|
|
||||||
start_xor = (WORD*)bits->xor + offset.y * brush->stride / 2;
|
start_xor = (WORD*)bits->xor + offset.y * brush->stride / 2;
|
||||||
|
|
||||||
|
if (bits->and)
|
||||||
|
{
|
||||||
|
start_and = (WORD*)bits->and + offset.y * brush->stride / 2;
|
||||||
for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
|
||||||
{
|
{
|
||||||
and_ptr = start_and + offset.x;
|
and_ptr = start_and + offset.x;
|
||||||
|
@ -970,13 +1018,34 @@ static void pattern_rects_16(const dib_info *dib, int num, const RECT *rc, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride / 2)
|
||||||
|
{
|
||||||
|
for (x = rc->left, brush_x = offset.x; x < rc->right; x += len)
|
||||||
|
{
|
||||||
|
len = min( rc->right - x, brush->width - brush_x );
|
||||||
|
memcpy( start + x - rc->left, start_xor + brush_x, len * 2 );
|
||||||
|
brush_x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_xor += brush->stride / 2;
|
||||||
|
offset.y++;
|
||||||
|
if(offset.y == brush->height)
|
||||||
|
{
|
||||||
|
start_xor = bits->xor;
|
||||||
|
offset.y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pattern_rects_8(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
static void pattern_rects_8(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
||||||
const dib_info *brush, const rop_mask_bits *bits)
|
const dib_info *brush, const rop_mask_bits *bits)
|
||||||
{
|
{
|
||||||
BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
|
BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
|
||||||
int x, y, i;
|
int x, y, i, len, brush_x;
|
||||||
POINT offset;
|
POINT offset;
|
||||||
|
|
||||||
for(i = 0; i < num; i++, rc++)
|
for(i = 0; i < num; i++, rc++)
|
||||||
|
@ -984,9 +1053,11 @@ static void pattern_rects_8(const dib_info *dib, int num, const RECT *rc, const
|
||||||
offset = calc_brush_offset(rc, brush, origin);
|
offset = calc_brush_offset(rc, brush, origin);
|
||||||
|
|
||||||
start = get_pixel_ptr_8(dib, rc->left, rc->top);
|
start = get_pixel_ptr_8(dib, rc->left, rc->top);
|
||||||
start_and = (BYTE*)bits->and + offset.y * brush->stride;
|
|
||||||
start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
|
start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
|
||||||
|
|
||||||
|
if (bits->and)
|
||||||
|
{
|
||||||
|
start_and = (BYTE*)bits->and + offset.y * brush->stride;
|
||||||
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||||
{
|
{
|
||||||
and_ptr = start_and + offset.x;
|
and_ptr = start_and + offset.x;
|
||||||
|
@ -1016,6 +1087,27 @@ static void pattern_rects_8(const dib_info *dib, int num, const RECT *rc, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||||
|
{
|
||||||
|
for (x = rc->left, brush_x = offset.x; x < rc->right; x += len)
|
||||||
|
{
|
||||||
|
len = min( rc->right - x, brush->width - brush_x );
|
||||||
|
memcpy( start + x - rc->left, start_xor + brush_x, len );
|
||||||
|
brush_x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_xor += brush->stride;
|
||||||
|
offset.y++;
|
||||||
|
if(offset.y == brush->height)
|
||||||
|
{
|
||||||
|
start_xor = bits->xor;
|
||||||
|
offset.y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pattern_rects_4(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
static void pattern_rects_4(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
||||||
|
@ -1032,9 +1124,11 @@ static void pattern_rects_4(const dib_info *dib, int num, const RECT *rc, const
|
||||||
right = dib->rect.left + rc->right;
|
right = dib->rect.left + rc->right;
|
||||||
|
|
||||||
start = get_pixel_ptr_4(dib, rc->left, rc->top);
|
start = get_pixel_ptr_4(dib, rc->left, rc->top);
|
||||||
start_and = (BYTE*)bits->and + offset.y * brush->stride;
|
|
||||||
start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
|
start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
|
||||||
|
|
||||||
|
if (bits->and)
|
||||||
|
{
|
||||||
|
start_and = (BYTE*)bits->and + offset.y * brush->stride;
|
||||||
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||||
{
|
{
|
||||||
INT brush_x = offset.x;
|
INT brush_x = offset.x;
|
||||||
|
@ -1098,6 +1192,54 @@ static void pattern_rects_4(const dib_info *dib, int num, const RECT *rc, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||||
|
{
|
||||||
|
INT brush_x = offset.x;
|
||||||
|
BYTE byte_xor;
|
||||||
|
|
||||||
|
xor_ptr = start_xor + brush_x / 2;
|
||||||
|
|
||||||
|
for(x = left, ptr = start; x < right; x++)
|
||||||
|
{
|
||||||
|
/* FIXME: Two pixels at a time */
|
||||||
|
if(x & 1) /* lower dst nibble */
|
||||||
|
{
|
||||||
|
if(brush_x & 1) /* lower pat nibble */
|
||||||
|
byte_xor = *xor_ptr++ & 0x0f;
|
||||||
|
else /* upper pat nibble */
|
||||||
|
byte_xor = (*xor_ptr >> 4) & 0x0f;
|
||||||
|
do_rop_8(ptr, 0xf0, byte_xor);
|
||||||
|
}
|
||||||
|
else /* upper dst nibble */
|
||||||
|
{
|
||||||
|
if(brush_x & 1) /* lower pat nibble */
|
||||||
|
byte_xor = (*xor_ptr++ << 4) & 0xf0;
|
||||||
|
else /* upper pat nibble */
|
||||||
|
byte_xor = *xor_ptr & 0xf0;
|
||||||
|
do_rop_8(ptr, 0x0f, byte_xor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x & 1) ptr++;
|
||||||
|
|
||||||
|
if(++brush_x == brush->width)
|
||||||
|
{
|
||||||
|
brush_x = 0;
|
||||||
|
xor_ptr = start_xor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start_xor += brush->stride;
|
||||||
|
offset.y++;
|
||||||
|
if(offset.y == brush->height)
|
||||||
|
{
|
||||||
|
start_xor = bits->xor;
|
||||||
|
offset.y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pattern_rects_1(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
static void pattern_rects_1(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
||||||
|
@ -1114,9 +1256,11 @@ static void pattern_rects_1(const dib_info *dib, int num, const RECT *rc, const
|
||||||
right = dib->rect.left + rc->right;
|
right = dib->rect.left + rc->right;
|
||||||
|
|
||||||
start = get_pixel_ptr_1(dib, rc->left, rc->top);
|
start = get_pixel_ptr_1(dib, rc->left, rc->top);
|
||||||
start_and = (BYTE*)bits->and + offset.y * brush->stride;
|
|
||||||
start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
|
start_xor = (BYTE*)bits->xor + offset.y * brush->stride;
|
||||||
|
|
||||||
|
if (bits->and)
|
||||||
|
{
|
||||||
|
start_and = (BYTE*)bits->and + offset.y * brush->stride;
|
||||||
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||||
{
|
{
|
||||||
INT brush_x = offset.x;
|
INT brush_x = offset.x;
|
||||||
|
@ -1164,6 +1308,41 @@ static void pattern_rects_1(const dib_info *dib, int num, const RECT *rc, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||||
|
{
|
||||||
|
INT brush_x = offset.x;
|
||||||
|
|
||||||
|
xor_ptr = start_xor + brush_x / 8;
|
||||||
|
|
||||||
|
for(x = left, ptr = start; x < right; x++)
|
||||||
|
{
|
||||||
|
BYTE byte_xor = (*xor_ptr & pixel_masks_1[brush_x % 8]) ? 0xff : 0;
|
||||||
|
byte_xor &= pixel_masks_1[x % 8];
|
||||||
|
|
||||||
|
do_rop_8(ptr, ~pixel_masks_1[x % 8], byte_xor);
|
||||||
|
|
||||||
|
if((x & 7) == 7) ptr++;
|
||||||
|
if((brush_x & 7) == 7) xor_ptr++;
|
||||||
|
|
||||||
|
if(++brush_x == brush->width)
|
||||||
|
{
|
||||||
|
brush_x = 0;
|
||||||
|
xor_ptr = start_xor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start_xor += brush->stride;
|
||||||
|
offset.y++;
|
||||||
|
if(offset.y == brush->height)
|
||||||
|
{
|
||||||
|
start_xor = bits->xor;
|
||||||
|
offset.y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pattern_rects_null(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
static void pattern_rects_null(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
||||||
|
|
Loading…
Reference in New Issue