[PATCH 4/5] gdi32: Split out the various offset cases for copy_rect_1() into separate functions.
Huw Davies
huw at codeweavers.com
Thu Aug 25 03:43:10 CDT 2016
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/gdi32/dibdrv/primitives.c | 649 +++++++++++++++++++++++------------------
1 file changed, 371 insertions(+), 278 deletions(-)
diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c
index abfb1b5..090eebe 100644
--- a/dlls/gdi32/dibdrv/primitives.c
+++ b/dlls/gdi32/dibdrv/primitives.c
@@ -237,278 +237,6 @@ static inline void do_rop_codes_line_rev_4(BYTE *dst, int dst_x, const BYTE *src
}
}
-/**************************************************
- * get_src_byte_1
- *
- * Return a byte representing 8 pixels of src data
- * that is aligned with the dst.
- *
- * off is the number of bits that src is ahead of dst
- * measured from the start. If off is +ve then we need to
- * grab data from src[0] and src[1]. If off is -ve we use
- * last (which is equivalent to src[-1]) and src[0]. For
- * the first call in a line the last component will not be
- * needed so it's safe for the caller to zero-init it.
- *
- * S |.....xxx|xxxxxxxx
- * D |..xxxxxx|xxxxxxxx off = +3
- *
- * S |..xxxxxx|xxxxxxxx
- * D |.....xxx|xxxxxxxx off = -3
- */
-static inline BYTE get_src_byte_1(const BYTE *src, int off, BYTE *last)
-{
- BYTE src_val;
-
- if (off == 0)
- src_val = src[0];
- else if (off > 0)
- src_val = (src[0] << off) | (src[1] >> (8 - off));
- else
- {
- src_val = (*last << (8 + off)) | (src[0] >> -off);
- *last = src[0];
- }
-
- return src_val;
-}
-
-static inline void do_rop_codes_line_1(BYTE *dst, int dst_x, const BYTE *src, int src_x,
- struct rop_codes *codes, int len, int rop2)
-{
- BYTE src_val, last_src = 0;
- int off = (src_x & 7) - (dst_x & 7), i, full_bytes;
- int dst_end = dst_x + len;
- BYTE mask;
-
- src += src_x / 8;
- dst += dst_x / 8;
-
- /* Handle special case of all of dst in one byte. */
- if ((dst_x & ~7) == ((dst_end - 1) & ~7))
- {
- if (off == 0)
- src_val = src[0];
- else if (off > 0)
- {
- src_val = src[0] << off;
- if ((dst_end & 7) + off > 8)
- src_val |= (src[1] >> (8 - off));
- }
- else
- src_val = src[0] >> -off;
-
- mask = edge_masks_1[dst_x & 7];
- if (dst_end & 7)
- mask &= ~edge_masks_1[dst_end & 7];
- do_rop_codes_mask_8( dst, src_val, codes, mask );
- return;
- }
-
- if (dst_x & 7)
- {
- src_val = get_src_byte_1( src, off, &last_src );
- mask = edge_masks_1[dst_x & 7];
- do_rop_codes_mask_8( dst, src_val, codes, mask );
- src++;
- dst++;
- }
-
- full_bytes = (dst_end - ((dst_x + 7) & ~7)) / 8;
-
- if (off == 0)
- {
- if (rop2 == R2_COPYPEN)
- {
- memmove( dst, src, full_bytes );
- src += full_bytes;
- dst += full_bytes;
- }
- else
- {
- for (i = 0; i < full_bytes; i++, src++, dst++)
- do_rop_codes_8( dst, src[0], codes );
- }
- }
- else if (off > 0)
- {
- if (rop2 == R2_COPYPEN)
- {
- for (i = 0; i < full_bytes; i++, src++, dst++)
- dst[0] = (src[0] << off) | (src[1] >> (8 - off));
- }
- else
- {
- for (i = 0; i < full_bytes; i++, src++, dst++)
- do_rop_codes_8( dst, (src[0] << off) | (src[1] >> (8 - off)), codes );
- }
- }
- else
- {
- if (rop2 == R2_COPYPEN)
- {
- for (i = 0; i < full_bytes; i++, src++, dst++)
- {
- src_val = (last_src << (8 + off)) | (src[0] >> -off);
- last_src = src[0];
- dst[0] = src_val;
- }
- }
- else
- {
- for (i = 0; i < full_bytes; i++, src++, dst++)
- {
- src_val = (last_src << (8 + off)) | (src[0] >> -off);
- last_src = src[0];
- do_rop_codes_8( dst, src_val, codes );
- }
- }
- }
-
- if (dst_end & 7)
- {
- if (off > 0 && (dst_end & 7) + off <= 8)
- /* Don't read src[1] if everything's in src[0]. */
- src_val = src[0] << off;
- else if (off < 0 && (dst_end & 7) + off <= 0)
- /* Don't read src[0] if everything's in last_src. */
- src_val = last_src << (8 + off);
- else
- src_val = get_src_byte_1( src, off, &last_src );
- mask = ~edge_masks_1[dst_end & 7];
- do_rop_codes_mask_8( dst, src_val, codes, mask );
- }
-}
-
-/**************************************************
- * get_src_byte_rev_1
- *
- * Return a byte representing 8 pixels of src data
- * that is aligned with the dst.
- *
- * off is the number of bits that src is ahead of dst
- * measured from the end. If off is +ve then we need to
- * grab data from src[0] and last (which is equivalent to src[1]).
- * If off is -ve we use src[-1]) and src[0]. For the first call
- * in a line the last component wil not be needed so it is safe
- * for the caller to zero-init it.
- *
- * S xxxxxxxx|xxxxxx..|
- * D xxxxxxxx|xxx.....| off = +3
- *
- * S xxxxxxxx|xxx.....|
- * D xxxxxxxx|xxxxxx..| off = -3
- */
-static inline BYTE get_src_byte_rev_1(const BYTE *src, int off, BYTE *last)
-{
- BYTE src_val;
-
- if (off == 0)
- src_val = src[0];
- else if (off > 0)
- {
- src_val = (src[0] << off) | (*last >> (8 - off));
- *last = *src;
- }
- else
- src_val = (src[-1] << (8 + off)) | (src[0] >> -off);
-
- return src_val;
-}
-
-static inline void do_rop_codes_line_rev_1(BYTE *dst, int dst_x, const BYTE *src, int src_x,
- struct rop_codes *codes, int len, int rop2)
-{
- BYTE src_val, last_src = 0;
- int src_end = src_x + len, dst_end = dst_x + len;
- int off = ((src_end - 1) & 7) - ((dst_end - 1) & 7), i, full_bytes;
- BYTE mask;
-
- /* Handle special case of all of dst in one byte. */
- if ((dst_x & ~7) == ((dst_end - 1) & ~7))
- {
- do_rop_codes_line_1(dst, dst_x, src, src_x, codes, len, rop2);
- return;
- }
-
- src += (src_end - 1) / 8;
- dst += (dst_end - 1) / 8;
-
- if (dst_end & 7)
- {
- src_val = get_src_byte_rev_1( src, off, &last_src );
- mask = ~edge_masks_1[dst_end & 7];
- do_rop_codes_mask_8( dst, src_val, codes, mask );
- src--;
- dst--;
- }
-
- full_bytes = (dst_end - ((dst_x + 7) & ~7)) / 8;
-
- if (off == 0)
- {
- if (rop2 == R2_COPYPEN)
- {
- memmove( dst, src, full_bytes );
- src -= full_bytes;
- dst -= full_bytes;
- }
- else
- {
- for (i = 0; i < full_bytes; i++, src--, dst--)
- do_rop_codes_8( dst, src[0], codes );
- }
- }
- else if (off > 0)
- {
- if (rop2 == R2_COPYPEN)
- {
- for (i = 0; i < full_bytes; i++, src--, dst--)
- {
- src_val = (src[0] << off) | (last_src >> (8 - off));
- last_src = src[0];
- dst[0] = src_val;
- }
- }
- else
- {
- for (i = 0; i < full_bytes; i++, src--, dst--)
- {
- src_val = (src[0] << off) | (last_src >> (8 - off));
- last_src = src[0];
- do_rop_codes_8( dst, src_val, codes );
- }
- }
- }
- else
- {
- if (rop2 == R2_COPYPEN)
- {
- for (i = 0; i < full_bytes; i++, src--, dst--)
- dst[0] = (src[-1] << (8 + off)) | (src[0] >> -off);
- }
- else
- {
- for (i = 0; i < full_bytes; i++, src--, dst--)
- do_rop_codes_8( dst, (src[-1] << (8 + off)) | (src[0] >> -off), codes );
- }
- }
-
- if (dst_x & 7)
- {
- if (off < 0 && (dst_x & 7) + off >= 0)
- /* Don't read src[-1] if everything's in src[0]. */
- src_val = src[0] >> -off;
- else if (off > 0 && (dst_x & 7) + off >= 8)
- /* Don't read src[0] if everything's in last_src. */
- src_val = last_src >> (8 - off);
- else
- src_val = get_src_byte_rev_1( src, off, &last_src );
- mask = edge_masks_1[dst_x & 7];
- do_rop_codes_mask_8( dst, src_val, codes, mask );
- }
-}
-
static inline void memset_32( DWORD *start, DWORD val, DWORD size )
{
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
@@ -1841,15 +1569,360 @@ static void copy_rect_4(const dib_info *dst, const RECT *rc,
}
}
+static inline void copy_rect_bits_partial_1( BYTE *dst_start, int dst_x, const BYTE *src_start, int src_x,
+ const SIZE *size, int dst_stride, int src_stride, int rop2 )
+{
+ const BYTE *src;
+ BYTE *dst, src_val, mask;
+ int dst_end = dst_x + size->cx, y;
+ int off = (src_x & 7) - (dst_x & 7);
+ struct rop_codes codes;
+
+ get_rop_codes( rop2, &codes );
+
+ src_start += src_x / 8;
+ dst_start += dst_x / 8;
+
+ for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride)
+ {
+ dst = dst_start;
+ src = src_start;
+ if (off == 0)
+ src_val = src[0];
+ else if (off > 0)
+ {
+ src_val = src[0] << off;
+ if ((dst_end & 7) + off > 8)
+ src_val |= (src[1] >> (8 - off));
+ }
+ else
+ src_val = src[0] >> -off;
+
+ mask = edge_masks_1[dst_x & 7];
+ if (dst_end & 7)
+ mask &= ~edge_masks_1[dst_end & 7];
+ do_rop_codes_mask_8( dst, src_val, &codes, mask );
+ }
+}
+
+static inline void copy_rect_bits_align_1( BYTE *dst_start, int dst_x, const BYTE *src_start, int src_x,
+ const SIZE *size, int dst_stride, int src_stride, int rop2 )
+{
+ const BYTE *src;
+ BYTE *dst, mask;
+ int y, i, full_bytes, dst_end = dst_x + size->cx;
+ struct rop_codes codes;
+
+ get_rop_codes( rop2, &codes );
+
+ src_start += src_x / 8;
+ dst_start += dst_x / 8;
+ full_bytes = (dst_end - ((dst_x + 7) & ~7)) / 8;
+
+ for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride)
+ {
+ dst = dst_start;
+ src = src_start;
+ if (dst_x & 7)
+ {
+ mask = edge_masks_1[dst_x & 7];
+ do_rop_codes_mask_8( dst, src[0], &codes, mask );
+ src++;
+ dst++;
+ }
+
+ if (rop2 == R2_COPYPEN)
+ {
+ memmove( dst, src, full_bytes );
+ src += full_bytes;
+ dst += full_bytes;
+ }
+ else
+ {
+ for (i = 0; i < full_bytes; i++, src++, dst++)
+ do_rop_codes_8( dst, src[0], &codes );
+ }
+
+ if (dst_end & 7)
+ {
+ mask = ~edge_masks_1[dst_end & 7];
+ do_rop_codes_mask_8( dst, src[0], &codes, mask );
+ }
+ }
+}
+
+static inline void copy_rect_bits_shl_1( BYTE *dst_start, int dst_x, const BYTE *src_start, int src_x,
+ const SIZE *size, int dst_stride, int src_stride, int rop2 )
+{
+ const BYTE *src;
+ BYTE *dst, mask, src_val;
+ int y, i, full_bytes, dst_end = dst_x + size->cx;
+ int off = (src_x & 7) - (dst_x & 7);
+ struct rop_codes codes;
+
+ get_rop_codes( rop2, &codes );
+
+ src_start += src_x / 8;
+ dst_start += dst_x / 8;
+ full_bytes = (dst_end - ((dst_x + 7) & ~7)) / 8;
+
+ for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride)
+ {
+ dst = dst_start;
+ src = src_start;
+ if (dst_x & 7)
+ {
+ src_val = (src[0] << off) | (src[1] >> (8 - off));
+ mask = edge_masks_1[dst_x & 7];
+ do_rop_codes_mask_8( dst, src_val, &codes, mask );
+ src++;
+ dst++;
+ }
+
+ if (rop2 == R2_COPYPEN)
+ {
+ for (i = 0; i < full_bytes; i++, src++, dst++)
+ dst[0] = (src[0] << off) | (src[1] >> (8 - off));
+ }
+ else
+ {
+ for (i = 0; i < full_bytes; i++, src++, dst++)
+ do_rop_codes_8( dst, (src[0] << off) | (src[1] >> (8 - off)), &codes );
+ }
+
+ if (dst_end & 7)
+ {
+ src_val = src[0] << off;
+ if ((dst_end & 7) + off > 8)
+ src_val |= (src[1] >> (8 - off));
+ mask = ~edge_masks_1[dst_end & 7];
+ do_rop_codes_mask_8( dst, src_val, &codes, mask );
+ }
+ }
+}
+
+static inline void copy_rect_bits_shr_1( BYTE *dst_start, int dst_x, const BYTE *src_start, int src_x,
+ const SIZE *size, int dst_stride, int src_stride, int rop2 )
+{
+ const BYTE *src;
+ BYTE *dst, mask, src_val, last_src;
+ int y, i, full_bytes, dst_end = dst_x + size->cx;
+ int off = (src_x & 7) - (dst_x & 7);
+ struct rop_codes codes;
+
+ get_rop_codes( rop2, &codes );
+
+ src_start += src_x / 8;
+ dst_start += dst_x / 8;
+ full_bytes = (dst_end - ((dst_x + 7) & ~7)) / 8;
+
+ for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride)
+ {
+ dst = dst_start;
+ src = src_start;
+ last_src = 0;
+ if (dst_x & 7)
+ {
+ last_src = src[0];
+ mask = edge_masks_1[dst_x & 7];
+ do_rop_codes_mask_8( dst, src[0] >> -off, &codes, mask );
+ src++;
+ dst++;
+ }
+
+ if (rop2 == R2_COPYPEN)
+ {
+ for (i = 0; i < full_bytes; i++, src++, dst++)
+ {
+ src_val = (last_src << (8 + off)) | (src[0] >> -off);
+ last_src = src[0];
+ dst[0] = src_val;
+ }
+ }
+ else
+ {
+ for (i = 0; i < full_bytes; i++, src++, dst++)
+ {
+ src_val = (last_src << (8 + off)) | (src[0] >> -off);
+ last_src = src[0];
+ do_rop_codes_8( dst, src_val, &codes );
+ }
+ }
+
+ if (dst_end & 7)
+ {
+ src_val = last_src << (8 + off);
+ if ((dst_end & 7) + off > 0)
+ src_val |= (src[0] >> -off);
+ mask = ~edge_masks_1[dst_end & 7];
+ do_rop_codes_mask_8( dst, src_val, &codes, mask );
+ }
+ }
+}
+
+static inline void copy_rect_bits_rev_align_1( BYTE *dst_start, int dst_x, const BYTE *src_start, int src_x,
+ const SIZE *size, int dst_stride, int src_stride, int rop2 )
+{
+ const BYTE *src;
+ BYTE *dst, mask;
+ int y, i, full_bytes, dst_end = dst_x + size->cx, src_end = src_x + size->cx;
+ struct rop_codes codes;
+
+ get_rop_codes( rop2, &codes );
+
+ src_start += (src_end - 1) / 8;
+ dst_start += (dst_end - 1) / 8;
+ full_bytes = (dst_end - ((dst_x + 7) & ~7)) / 8;
+
+ for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride)
+ {
+ dst = dst_start;
+ src = src_start;
+ if (dst_end & 7)
+ {
+ mask = ~edge_masks_1[dst_end & 7];
+ do_rop_codes_mask_8( dst, src[0], &codes, mask );
+ src--;
+ dst--;
+ }
+
+ if (rop2 == R2_COPYPEN)
+ {
+ memmove( dst, src, full_bytes );
+ src -= full_bytes;
+ dst -= full_bytes;
+ }
+ else
+ {
+ for (i = 0; i < full_bytes; i++, src--, dst--)
+ do_rop_codes_8( dst, src[0], &codes );
+ }
+
+ if (dst_x & 7)
+ {
+ mask = edge_masks_1[dst_x & 7];
+ do_rop_codes_mask_8( dst, src[0], &codes, mask );
+ }
+ }
+}
+
+static inline void copy_rect_bits_rev_shl_1( BYTE *dst_start, int dst_x, const BYTE *src_start, int src_x,
+ const SIZE *size, int dst_stride, int src_stride, int rop2 )
+{
+ const BYTE *src;
+ BYTE *dst, mask, src_val, last_src;
+ int y, i, full_bytes, dst_end = dst_x + size->cx, src_end = src_x + size->cx;
+ int off = ((src_end - 1) & 7) - ((dst_end - 1) & 7);
+ struct rop_codes codes;
+
+ get_rop_codes( rop2, &codes );
+
+ src_start += (src_end - 1) / 8;
+ dst_start += (dst_end - 1) / 8;
+ full_bytes = (dst_end - ((dst_x + 7) & ~7)) / 8;
+
+ for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride)
+ {
+ dst = dst_start;
+ src = src_start;
+ last_src = 0;
+ if (dst_end & 7)
+ {
+ last_src = src[0];
+ mask = ~edge_masks_1[dst_end & 7];
+ do_rop_codes_mask_8( dst, src[0] << off, &codes, mask );
+ src--;
+ dst--;
+ }
+
+ if (rop2 == R2_COPYPEN)
+ {
+ for (i = 0; i < full_bytes; i++, src--, dst--)
+ {
+ src_val = (src[0] << off) | (last_src >> (8 - off));
+ last_src = src[0];
+ dst[0] = src_val;
+ }
+ }
+ else
+ {
+ for (i = 0; i < full_bytes; i++, src--, dst--)
+ {
+ src_val = (src[0] << off) | (last_src >> (8 - off));
+ last_src = src[0];
+ do_rop_codes_8( dst, src_val, &codes );
+ }
+ }
+
+ if (dst_x & 7)
+ {
+ src_val = last_src >> (8 - off);
+ if ((dst_x & 7) + off < 8)
+ src_val |= (src[0] << off);
+ mask = edge_masks_1[dst_x & 7];
+ do_rop_codes_mask_8( dst, src_val, &codes, mask );
+ }
+ }
+}
+
+static inline void copy_rect_bits_rev_shr_1( BYTE *dst_start, int dst_x, const BYTE *src_start, int src_x,
+ const SIZE *size, int dst_stride, int src_stride, int rop2 )
+{
+ const BYTE *src;
+ BYTE *dst, mask, src_val;
+ int y, i, full_bytes, dst_end = dst_x + size->cx, src_end = src_x + size->cx;
+ int off = ((src_end - 1) & 7) - ((dst_end - 1) & 7);
+ struct rop_codes codes;
+
+ get_rop_codes( rop2, &codes );
+
+ src_start += (src_end - 1) / 8;
+ dst_start += (dst_end - 1) / 8;
+ full_bytes = (dst_end - ((dst_x + 7) & ~7)) / 8;
+
+ for (y = 0; y < size->cy; y++, dst_start += dst_stride, src_start += src_stride)
+ {
+ dst = dst_start;
+ src = src_start;
+ if (dst_end & 7)
+ {
+ mask = edge_masks_1[dst_x & 7];
+ do_rop_codes_mask_8( dst, (src[-1] << (8 + off)) | (src[0] >> -off), &codes, mask );
+ src--;
+ dst--;
+ }
+
+ if (rop2 == R2_COPYPEN)
+ {
+ for (i = 0; i < full_bytes; i++, src--, dst--)
+ dst[0] = (src[-1] << (8 + off)) | (src[0] >> -off);
+ }
+ else
+ {
+ for (i = 0; i < full_bytes; i++, src--, dst--)
+ do_rop_codes_8( dst, (src[-1] << (8 + off)) | (src[0] >> -off), &codes );
+ }
+
+ if (dst_x & 7)
+ {
+ src_val = src[0] >> -off;
+ if ((dst_x & 7) + off < 0)
+ src_val |= (src[-1] << (8 + off));
+ mask = edge_masks_1[dst_x & 7];
+ do_rop_codes_mask_8( dst, src_val, &codes, mask );
+ }
+ }
+}
+
static void copy_rect_1(const dib_info *dst, const RECT *rc,
const dib_info *src, const POINT *origin, int rop2, int overlap)
{
BYTE *dst_start, *src_start;
int y, dst_stride, src_stride;
- struct rop_codes codes;
int left = dst->rect.left + rc->left;
int right = dst->rect.left + rc->right;
int org_x = src->rect.left + origin->x;
+ SIZE size;
if (overlap & OVERLAP_BELOW)
{
@@ -1873,13 +1946,33 @@ static void copy_rect_1(const dib_info *dst, const RECT *rc,
return;
}
- get_rop_codes( rop2, &codes );
- for (y = rc->top; y < rc->bottom; y++, dst_start += dst_stride, src_start += src_stride)
+ size.cx = right - left;
+ size.cy = rc->bottom - rc->top;
+
+ /* Special case starting and finishing in same byte, neither on byte boundary */
+ if ((left & 7) && (right & 7) && (left & ~7) == (right & ~7))
+ copy_rect_bits_partial_1( dst_start, left & 7, src_start, org_x & 7, &size, dst_stride, src_stride, rop2 );
+ else if (overlap & OVERLAP_RIGHT)
{
- if (overlap & OVERLAP_RIGHT)
- do_rop_codes_line_rev_1( dst_start, left & 7, src_start, org_x & 7, &codes, right - left, rop2 );
+ int off = ((org_x + right - left - 1) & 7) - ((right - 1) & 7);
+
+ if (off == 0)
+ copy_rect_bits_rev_align_1( dst_start, left & 7, src_start, org_x & 7, &size, dst_stride, src_stride, rop2 );
+ else if (off > 0)
+ copy_rect_bits_rev_shl_1( dst_start, left & 7, src_start, org_x & 7, &size, dst_stride, src_stride, rop2 );
+ else
+ copy_rect_bits_rev_shr_1( dst_start, left & 7, src_start, org_x & 7, &size, dst_stride, src_stride, rop2 );
+ }
+ else
+ {
+ int off = (org_x & 7) - (left & 7);
+
+ if (off == 0)
+ copy_rect_bits_align_1( dst_start, left & 7, src_start, org_x & 7, &size, dst_stride, src_stride, rop2 );
+ else if (off > 0)
+ copy_rect_bits_shl_1( dst_start, left & 7, src_start, org_x & 7, &size, dst_stride, src_stride, rop2 );
else
- do_rop_codes_line_1( dst_start, left & 7, src_start, org_x & 7, &codes, right - left, rop2 );
+ copy_rect_bits_shr_1( dst_start, left & 7, src_start, org_x & 7, &size, dst_stride, src_stride, rop2 );
}
}
--
2.7.4
More information about the wine-patches
mailing list