diff options
author | Robin Watts <robin.watts@artifex.com> | 2018-01-11 12:03:30 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2018-01-11 12:52:17 +0000 |
commit | 9b3b93ca92f8b9370d4cb5a4e6176df1a06afeda (patch) | |
tree | 202c59954df3e43845ec460a523d2cc1a9f98062 /base/gsroprun.c | |
parent | c56dff6dea636c89b7c24bbec7b28f15171d7810 (diff) | |
download | ghostpdl-9b3b93ca92f8b9370d4cb5a4e6176df1a06afeda.tar.gz |
ROP optimisation: Map more rops onto one another.
Establish an ordering on rops ("unused" < "constant" <
"bitmap" < "1 bit bitmap") and swap orders such that S
is always >= T.
This cuts the number of cases down a bit more.
Diffstat (limited to 'base/gsroprun.c')
-rw-r--r-- | base/gsroprun.c | 562 |
1 files changed, 185 insertions, 377 deletions
diff --git a/base/gsroprun.c b/base/gsroprun.c index 1d302e7ba..0022fb5a2 100644 --- a/base/gsroprun.c +++ b/base/gsroprun.c @@ -87,11 +87,6 @@ static void record(int rop) usage[3*rop]++; } - -static void unrecord(int rop) -{ - usage[3*rop]--; -} #endif #define get24(ptr)\ @@ -192,22 +187,22 @@ static void invert_rop_run24(rop_run_op *op, byte *d, int len) } #endif -/* Rop 0x0f = ~t */ +/* Rop 0x33 = ~s */ -/* 0x0F = ~t dep=1 s_constant */ +/* 0x33 = ~s dep=1 t_constant */ #ifdef USE_TEMPLATES -#define TEMPLATE_NAME notT_rop_run1_const_s -#define SPECIFIC_ROP 0x0F -#define SPECIFIC_CODE(O,D,S,T) do { O = ~T; } while (0) -#define S_CONST +#define TEMPLATE_NAME notS_rop_run1_const_t +#define SPECIFIC_ROP 0x33 +#define SPECIFIC_CODE(O,D,S,T) do { O = ~S; } while (0) +#define T_CONST #include "gsroprun1.h" #else -static void notT_rop_run1_const_s(rop_run_op *op, byte *d, int len) +static void notS_rop_run1_const_s(rop_run_op *op, byte *d, int len) { byte lmask, rmask; - const byte *t = op->t.b.ptr; - byte T; - int t_skew; + const byte *s = op->s.b.ptr; + byte S; + int s_skew; len = len * op->depth + op->dpos; /* lmask = the set of bits to alter in the output bitmap on the left @@ -222,48 +217,48 @@ static void notT_rop_run1_const_s(rop_run_op *op, byte *d, int len) * of them due to the allocator. If we ever get valgrind properly marking * allocated blocks as readable etc, then this may throw some spurious * errors. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; + s_skew = op->t.b.pos - op->dpos; + if (s_skew < 0) { + s_skew += 8; + s--; } len -= 8; if (len < 0) { /* Short case - starts and ends in the same byte */ lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - *d = (*d & ~lmask) | (~T & lmask); + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + *d = (*d & ~lmask) | (~S & lmask); return; } if (lmask != 0xFF) { /* Unaligned left hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; - *d = (*d & ~lmask) | (~T & lmask); + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + s++; + *d = (*d & ~lmask) | (~S & lmask); d++; len -= 8; } if (len >= 0) { /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { + if (s_skew == 0) { do { - *d++ = ~*t++; + *d++ = ~*s++; len -= 8; } while (len >= 0); } else { do { - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; - *d++ = ~T; + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + s++; + *d++ = ~S; len -= 8; } while (len >= 0); } } if (rmask != 0xFF) { /* Unaligned right hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - *d = (~T & ~rmask) | (*d & rmask); + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + *d = (~S & ~rmask) | (*d & rmask); } } #endif @@ -348,102 +343,22 @@ static void dors_rop_run1_const_t(rop_run_op *op, byte *d, int len) } #endif -/* Rop 0xfa = d|t */ - -/* 0xFA = d|t dep=1 s_constant */ -#ifdef USE_TEMPLATES -#define TEMPLATE_NAME dort_rop_run1_const_s -#define SPECIFIC_ROP 0xFA -#define SPECIFIC_CODE(O,D,S,T) do { O = D|T; } while (0) -#define S_CONST -#include "gsroprun1.h" -#else -static void dort_rop_run1_const_s(rop_run_op *op, byte *d, int len) -{ - byte lmask, rmask; - const byte *t = op->t.b.ptr; - byte T, D; - int t_skew; - - len = len * op->depth + op->dpos; - /* lmask = the set of bits to alter in the output bitmap on the left - * hand edge of the run. rmask = the set of bits NOT to alter in the - * output bitmap on the right hand edge of the run. */ - lmask = 255>>(7 & op->dpos); - rmask = 255>>(7 & len); - - /* Note #1: This mirrors what the original code did, but I think it has - * the risk of moving s and t back beyond officially allocated space. We - * may be saved by the fact that all blocks have a word or two in front - * of them due to the allocator. If we ever get valgrind properly marking - * allocated blocks as readable etc, then this may throw some spurious - * errors. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; - } - - len -= 8; - if (len < 0) { - /* Short case - starts and ends in the same byte */ - lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - D = *d | T; - *d = (*d & ~lmask) | (D & lmask); - return; - } - if (lmask != 0xFF) { - /* Unaligned left hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; - D = *d | T; - *d = (*d & ~lmask) | (D & lmask); - d++; - len -= 8; - } - if (len >= 0) { - /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { - do { - *d++ |= *t++; - len -= 8; - } while (len >= 0); - } else { - do { - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; - *d |= T; - d++; - len -= 8; - } while (len >= 0); - } - } - if (rmask != 0xFF) { - /* Unaligned right hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - D = *d | T; - *d = (D & ~rmask) | (*d & rmask); - } -} -#endif - /* Rop 0x66 = d^s (and 0x5A = d^t) */ -/* 0x5A = d^t dep=1 s_constant */ +/* 0x66 = d^s dep=1 t_constant */ #ifdef USE_TEMPLATES -#define TEMPLATE_NAME xor_rop_run1_const_s -#define SPECIFIC_ROP 0x5A -#define SPECIFIC_CODE(O,D,S,T) do { O = D^T; } while (0) -#define S_CONST +#define TEMPLATE_NAME xor_rop_run1_const_t +#define SPECIFIC_ROP 0x66 +#define SPECIFIC_CODE(O,D,S,T) do { O = D^S; } while (0) +#define T_CONST #include "gsroprun1.h" #else -static void xor_rop_run1_const_s(rop_run_op *op, byte *d, int len) +static void xor_rop_run1_const_t(rop_run_op *op, byte *d, int len) { byte lmask, rmask; - const byte *t = op->t.b.ptr; - byte T, D; - int t_skew; + const byte *s = op->s.b.ptr; + byte S, D; + int s_skew; len = len * op->depth + op->dpos; /* lmask = the set of bits to alter in the output bitmap on the left @@ -458,42 +373,42 @@ static void xor_rop_run1_const_s(rop_run_op *op, byte *d, int len) * of them due to the allocator. If we ever get valgrind properly marking * allocated blocks as readable etc, then this may throw some spurious * errors. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; + s_skew = op->s.b.pos - op->dpos; + if (s_skew < 0) { + s_skew += 8; + s--; } len -= 8; if (len < 0) { /* Short case - starts and ends in the same byte */ lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - D = *d ^ T; + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + D = *d ^ S; *d = (*d & ~lmask) | (D & lmask); return; } if (lmask != 0xFF) { /* Unaligned left hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; - D = *d ^ T; + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + s++; + D = *d ^ S; *d = (*d & ~lmask) | (D & lmask); d++; len -= 8; } if (len >= 0) { /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { + if (s_skew == 0) { do { - *d++ ^= *t++; + *d++ ^= *s++; len -= 8; } while (len >= 0); } else { do { - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; - *d = *d ^ T; + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + s++; + *d = *d ^ S; d++; len -= 8; } while (len >= 0); @@ -501,8 +416,8 @@ static void xor_rop_run1_const_s(rop_run_op *op, byte *d, int len) } if (rmask != 0xFF) { /* Unaligned right hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - D = *d ^ T; + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + D = *d ^ S; *d = (D & ~rmask) | (*d & rmask); } } @@ -554,108 +469,11 @@ static void xor_rop_run24_const_st(rop_run_op *op, byte *d, int len) } #endif -/* rop = 0xFC = s | t dep=24 s_constant t_constant */ -#ifdef USE_TEMPLATES -/* FIXME: Not optimal; introduce 'PRE' code to combine S and T. */ -#define TEMPLATE_NAME sort_rop_run24_const_st -#define SPECIFIC_ROP 0xFC -#define SPECIFIC_CODE(O,D,S,T) do { O = S|T; } while (0) -#define S_CONST -#define T_CONST -#include "gsroprun24.h" -#else -static void sort_rop_run24_const_st(rop_run_op *op, byte *d, int len) -{ - rop_operand SorT = op->s.c | op->t.c; - do - { - put24(d, SorT); - d += 3; - } - while (--len); -} -#endif - /* rop = 0xAA = d dep=? s_constant t_constant */ static void nop_rop_const_st(rop_run_op *op, byte *d, int len) { } -/* rop = 0xF0 = t dep=1 s_constant */ -#ifdef USE_TEMPLATES -#define TEMPLATE_NAME sett_rop_run1_const_s -#define SPECIFIC_ROP 0xF0 -#define SPECIFIC_CODE(O,D,S,T) do { O = T; } while (0) -#define S_CONST -#include "gsroprun1.h" -#else -static void sett_rop_run1_const_s(rop_run_op *op, byte *d, int len) -{ - rop_proc proc = rop_proc_table[op->rop]; - byte lmask, rmask; - byte T, D; - const byte *t = op->t.b.ptr; - int t_skew; - - len = len*op->depth + op->dpos; - /* lmask = the set of bits to alter in the output bitmap on the left - * hand edge of the run. rmask = the set of bits NOT to alter in the - * output bitmap on the right hand edge of the run. */ - lmask = 255>>(7 & op->dpos); - rmask = 255>>(7 & len); - - /* See note #1 above. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; - } - - len -= 8; - if (len < 0) { - /* Short case - starts and ends in the same byte */ - lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - D = proc(*d, 0, T); - *d = (*d & ~lmask) | (D & lmask); - return; - } - if (lmask != 0xFF) { - /* Unaligned left hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; - D = proc(*d, 0, T); - *d = (*d & ~lmask) | (D & lmask); - d++; - len -= 8; - } - if (len >= 0) { - /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { - do { - *d = proc(*d, 0, *t++); - d++; - len -= 8; - } while (len >= 0); - } else { - do { - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; - *d = proc(*d, 0, T); - d++; - len -= 8; - } while (len >= 0); - } - } - if (rmask != 0xFF) { - /* Unaligned right hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - D = proc(*d, 0, T); - *d = (D & ~rmask) | (*d & rmask); - } -} -#endif - /* rop = 0xCC = s dep=1 t_constant */ #ifdef USE_TEMPLATES #define TEMPLATE_NAME sets_rop_run1 @@ -691,7 +509,7 @@ static void sets_rop_run1(rop_run_op *op, byte *d, int len) /* Short case - starts and ends in the same byte */ lmask &= ~rmask; /* Combined mask = bits to alter */ S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); - D = proc(*d, 0, S); + D = proc(*d, S, 0); *d = (*d & ~lmask) | (D & lmask); return; } @@ -699,7 +517,7 @@ static void sets_rop_run1(rop_run_op *op, byte *d, int len) /* Unaligned left hand case */ S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); s++; - D = proc(*d, 0, S); + D = proc(*d, S, 0); *d = (*d & ~lmask) | (D & lmask); d++; len -= 8; @@ -708,7 +526,7 @@ static void sets_rop_run1(rop_run_op *op, byte *d, int len) /* Simple middle case (complete destination bytes). */ if (s_skew == 0) { do { - *d = proc(*d, 0, *s++); + *d = proc(*d, *s++, 0); d++; len -= 8; } while (len >= 0); @@ -716,7 +534,7 @@ static void sets_rop_run1(rop_run_op *op, byte *d, int len) do { S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); s++; - *d = proc(*d, 0, S); + *d = proc(*d, S, 0); d++; len -= 8; } while (len >= 0); @@ -725,7 +543,7 @@ static void sets_rop_run1(rop_run_op *op, byte *d, int len) if (rmask != 0xFF) { /* Unaligned right hand case */ S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); - D = proc(*d, 0, S); + D = proc(*d, S, 0); *d = (D & ~rmask) | (*d & rmask); } } @@ -1131,27 +949,27 @@ static void generic_rop_run24_1bit(rop_run_op *op, byte *d, int len) #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run1_const_s -#define S_CONST +#define TEMPLATE_NAME generic_rop_run1_const_t +#define T_CONST #include "gsroprun1.h" #else -static void generic_rop_run1_const_s(rop_run_op *op, byte *d, int len) +static void generic_rop_run1_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[op->rop]; byte lmask, rmask; - byte S = (byte)op->s.c; - byte T, D; - const byte *t = op->t.b.ptr; - int t_skew; + byte T = (byte)op->t.c; + byte S, D; + const byte *s = op->s.b.ptr; + int s_skew; - /* S should be supplied as 'depth' bits. Duplicate that up to be byte + /* T should be supplied as 'depth' bits. Duplicate that up to be byte * size (if it's supplied byte sized, that's fine too). */ if (op->depth & 1) - S |= S<<1; + T |= T<<1; if (op->depth & 3) - S |= S<<2; + T |= T<<2; if (op->depth & 7) - S |= S<<4; + T |= T<<4; len = len*op->depth + op->dpos; /* lmask = the set of bits to alter in the output bitmap on the left @@ -1161,25 +979,25 @@ static void generic_rop_run1_const_s(rop_run_op *op, byte *d, int len) rmask = 255>>(7 & len); /* See note #1 above. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; + s_skew = op->s.b.pos - op->dpos; + if (s_skew < 0) { + s_skew += 8; + s--; } len -= 8; if (len < 0) { /* Short case - starts and ends in the same byte */ lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); D = proc(*d, S, T); *d = (*d & ~lmask) | (D & lmask); return; } if (lmask != 0xFF) { /* Unaligned left hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + s++; D = proc(*d, S, T); *d = (*d & ~lmask) | (D & lmask); d++; @@ -1187,16 +1005,16 @@ static void generic_rop_run1_const_s(rop_run_op *op, byte *d, int len) } if (len >= 0) { /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { + if (s_skew == 0) { do { - *d = proc(*d, S, *t++); + *d = proc(*d, *s++, T); d++; len -= 8; } while (len >= 0); } else { do { - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); - t++; + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); + s++; *d = proc(*d, S, T); d++; len -= 8; @@ -1205,7 +1023,7 @@ static void generic_rop_run1_const_s(rop_run_op *op, byte *d, int len) } if (rmask != 0xFF) { /* Unaligned right hand case */ - T = (t[0]<<t_skew) | (t[1]>>(8-t_skew)); + S = (s[0]<<s_skew) | (s[1]>>(8-s_skew)); D = proc(*d, S, T); *d = (D & ~rmask) | (*d & rmask); } @@ -1213,15 +1031,15 @@ static void generic_rop_run1_const_s(rop_run_op *op, byte *d, int len) #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run8_const_s -#define S_CONST +#define TEMPLATE_NAME generic_rop_run8_const_t +#define T_CONST #include "gsroprun8.h" #else -static void generic_rop_run8_const_s(rop_run_op *op, byte *d, int len) +static void generic_rop_run8_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[op->rop]; - byte s = op->s.c; - const byte *t = op->t.b.ptr; + const byte *s = op->s.b.ptr; + byte t = op->t.c; do { *d = proc(*d, s, *t++); @@ -1232,26 +1050,26 @@ static void generic_rop_run8_const_s(rop_run_op *op, byte *d, int len) #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run8_const_s_trans -#define S_CONST +#define TEMPLATE_NAME generic_rop_run8_const_t_trans #define S_TRANS MAYBE +#define T_CONST #define T_TRANS MAYBE #include "gsroprun8.h" #else -static void generic_rop_run8_const_s_trans(rop_run_op *op, byte *d, int len) +static void generic_rop_run8_const_t_trans(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[lop_rop(op->rop)]; - byte S = op->s.c; - const byte *t = op->t.b.ptr; + const byte *s = op->s.b.ptr; + byte T = op->t.c; rop_operand strans = (op->rop & lop_S_transparent ? 255 : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 255 : -1); - if (S == strans) + if (T == ttrans) return; do { - rop_operand T = *t++; - if (T != ttrans) + rop_operand S = *s++; + if (S != strans) *d = proc(*d, S, T); d++; } @@ -1260,35 +1078,34 @@ static void generic_rop_run8_const_s_trans(rop_run_op *op, byte *d, int len) #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run8_const_s_1bit -#define S_CONST +#define TEMPLATE_NAME generic_rop_run8_1bit_const_t #define S_TRANS MAYBE -#define T_TRANS MAYBE -#define T_1BIT YES +#define S_1BIT YES +#define T_CONST #include "gsroprun8.h" #else -static void generic_rop_run8_const_s_1bit(rop_run_op *op, byte *d, int len) +static void generic_rop_run8_1bit_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[lop_rop(op->rop)]; - byte S = op->s.c; - const byte *t = op->t.b.ptr; + byte T = op->t.c; + const byte *s = op->s.b.ptr; rop_operand strans = (op->rop & lop_S_transparent ? 255 : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 255 : -1); - int troll; - const byte *tcolors = op->tcolors; - if (S == strans) + int sroll; + const byte *scolors = op->scolors; + if (T == ttrans) return; - t = op->t.b.ptr + (op->t.b.pos>>3); - troll = 8-(op->t.b.pos & 7); + s = op->s.b.ptr + (op->s.b.pos>>3); + sroll = 8-(op->s.b.pos & 7); do { - rop_operand T; - --troll; - T = tcolors[(*t >> troll) & 1]; - if (troll == 0) { - troll = 8; - t++; + rop_operand S; + --sroll; + S = scolors[(*s >> sroll) & 1]; + if (sroll == 0) { + sroll = 8; + s++; } - if ((T != ttrans)) + if ((S != strans)) *d = proc(*d, S, T); d++; } @@ -1297,20 +1114,20 @@ static void generic_rop_run8_const_s_1bit(rop_run_op *op, byte *d, int len) #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run24_const_s -#define S_CONST +#define TEMPLATE_NAME generic_rop_run24_const_t +#define T_CONST #include "gsroprun24.h" #else -static void generic_rop_run24_const_s(rop_run_op *op, byte *d, int len) +static void generic_rop_run24_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[op->rop]; - rop_operand s = op->s.c; - const byte *t = op->t.b.ptr; + const byte *s = op->s.b.ptr; + rop_operand T = op->t.c; do { - rop_operand D = proc(get24(d), s, get24(t)); + rop_operand D = proc(get24(d), get24(s), T); put24(d, D); - t += 3; + s += 3; d += 3; } while (--len); @@ -1318,30 +1135,30 @@ static void generic_rop_run24_const_s(rop_run_op *op, byte *d, int len) #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run24_const_s_trans -#define S_CONST +#define TEMPLATE_NAME generic_rop_run24_const_t_trans #define S_TRANS MAYBE +#define T_CONST #define T_TRANS MAYBE #include "gsroprun24.h" #else -static void generic_rop_run24_const_s_trans(rop_run_op *op, byte *d, int len) +static void generic_rop_run24_const_t_trans(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[lop_rop(op->rop)]; - rop_operand s = op->s.c; - const byte *t = op->t.b.ptr; + const byte *s = op->s.b.ptr; + rop_operand T = op->t.c; rop_operand strans = (op->rop & lop_S_transparent ? 0xFFFFFF : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 0xFFFFFF : -1); - if (s == strans) + if (T == ttrans) return; do { - rop_operand T = get24(t); + rop_operand S = get24(s); rop_operand D; - if (T != ttrans) { - D = proc(get24(d), s, get24(t)); + if (S != strans) { + D = proc(get24(d), get24(s), T); put24(d, D); } - t += 3; + s += 3; d += 3; } while (--len); @@ -1349,38 +1166,38 @@ static void generic_rop_run24_const_s_trans(rop_run_op *op, byte *d, int len) #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run24_const_s_1bit -#define S_CONST +#define TEMPLATE_NAME generic_rop_run24_1bit_const_t +#define S_1BIT YES #define S_TRANS MAYBE +#define T_CONST #define T_TRANS MAYBE -#define T_1BIT YES #include "gsroprun24.h" #else -static void generic_rop_run24_const_s_1bit(rop_run_op *op, byte *d, int len) +static void generic_rop_run24_1bit_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[lop_rop(op->rop)]; - rop_operand S = op->s.c; - const byte *t = op->t.b.ptr; + rop_operand T = op->t.c; + const byte *s = op->s.b.ptr; rop_operand strans = (op->rop & lop_S_transparent ? 0xFFFFFF : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 0xFFFFFF : -1); - int troll; - const byte *tcolors = op->tcolors; - rop_operand tc[2]; - if (S == strans) + int sroll; + const byte *scolors = op->scolors; + rop_operand sc[2]; + if (T == ttrans) return; - t = op->t.b.ptr + (op->t.b.pos>>3); - troll = 8-(op->t.b.pos & 7); - tc[0] = ((const gx_color_index *)op->tcolors)[0]; - tc[1] = ((const gx_color_index *)op->tcolors)[3]; + s = op->s.b.ptr + (op->s.b.pos>>3); + sroll = 8-(op->s.b.pos & 7); + sc[0] = ((const gx_color_index *)op->scolors)[0]; + sc[1] = ((const gx_color_index *)op->scolors)[3]; do { - rop_operand T; - --troll; - T = tc[(*t >> troll) & 1]; - if (troll == 0) { - troll = 8; - t++; + rop_operand S; + --sroll; + S = sc[(*s >> sroll) & 1]; + if (sroll == 0) { + sroll = 8; + s++; } - if ((T != ttrans)) { + if ((S != strans)) { rop_operand D = proc(get24(d), S, T); put24(d, D); } @@ -1601,7 +1418,6 @@ int rop_get_run_op(rop_run_op *op, int rop, int depth, int flags) { int key; int swap = 0; - int could_swap = 0; #ifdef DISABLE_ROPS rop = 0xAA; @@ -1660,16 +1476,21 @@ int rop_get_run_op(rop_run_op *op, int rop, int depth, int flags) } } - /* Cut down the number of cases by mapping 'S bitmap,T constant' onto - * 'S constant,Tbitmap'. */ - could_swap = ((flags & (rop_s_constant | rop_t_constant)) == rop_t_constant); - if (0 == 1) { -force_swap: -#ifdef RECORD_ROP_USAGE - unrecord((int)op->opaque); -#endif - could_swap = 0; + /* Cut down the number of cases. */ + /* S or T can either be constant, bitmaps, or '1-bitmaps' + * (arrays of single bits to choose between 2 preset colors). + * If S or T is unused, then it will appear as constant. + */ + switch (flags) + { + case rop_s_constant: /* Map 'S constant,T bitmap' -> 'S bitmap,T constant' */ + case rop_s_constant | rop_t_1bit: /* Map 'S constant,T 1-bitmap' -> 'S 1-bitmap,T constant' */ + case rop_t_1bit: /* Map 'S bitmap,T 1-bitmap' -> 'S 1-bitmap,T bitmap' */ swap = 1; + break; + case rop_s_constant | rop_t_constant: /* Map 'S unused, T used' -> 'S used, T unused' */ + swap = ((rop_usage_table[rop & 0xff] & (rop_usage_S | rop_usage_T)) == rop_usage_T); + break; } if (swap) { flags = ((flags & rop_t_constant ? rop_s_constant : 0) | @@ -1678,6 +1499,10 @@ force_swap: (flags & rop_s_1bit ? rop_t_1bit : 0)); rop = lop_swap_S_T(rop); } + /* At this point, we know that in the ordering: + * 'unused' < 'constant' < 'bitmap' < '1-bitmap', + * that S >= T. + */ op->flags = (flags & (rop_s_constant | rop_t_constant | rop_s_1bit | rop_t_1bit)); op->depth = (byte)depth; @@ -1728,7 +1553,8 @@ force_swap: break; /* Skip 1111 as doesn't use S or T */ default: - abort(); /* Never happens */ + /* Never happens */ + break; } rop = (rop & ~0xff) | rop3_S; } @@ -1748,9 +1574,9 @@ retry: switch (key) { /* First, the rop specific ones */ - /* 0x0F = T */ - case ROP_SPECIFIC_KEY(0x0F, 1, rop_s_constant): - op->run = notT_rop_run1_const_s; + /* 0x33 = ~S */ + case ROP_SPECIFIC_KEY(0x33, 1, rop_t_constant): + op->run = notS_rop_run1_const_t; break; /* 0x55 = Invert */ case ROP_SPECIFIC_KEY(0x55, 1, rop_s_constant | rop_t_constant): @@ -1766,16 +1592,12 @@ retry: op->run = invert_rop_run24; break; /* 0x66 = D xor S */ - case ROP_SPECIFIC_KEY(0x5a, 1, rop_s_constant): - op->run = xor_rop_run1_const_s; + case ROP_SPECIFIC_KEY(0x66, 1, rop_t_constant): + op->run = xor_rop_run1_const_t; break; - case ROP_SPECIFIC_KEY(0x5a, 8, rop_s_constant | rop_t_constant): /* S_UNUSED */ - goto force_swap; case ROP_SPECIFIC_KEY(0x66, 8, rop_s_constant | rop_t_constant): /* T_UNUSED */ op->run = xor_rop_run8_const_st; break; - case ROP_SPECIFIC_KEY(0x5a, 24, rop_s_constant | rop_t_constant): /* S_UNUSED */ - goto force_swap; case ROP_SPECIFIC_KEY(0x66, 24, rop_s_constant | rop_t_constant): /* T_UNUSED */ op->run = xor_rop_run24_const_st; break; @@ -1798,14 +1620,6 @@ retry: case ROP_SPECIFIC_KEY(0xEE, 1, rop_t_constant): op->run = dors_rop_run1_const_t; break; - /* 0xF0 = T */ - case ROP_SPECIFIC_KEY(0xF0, 1, rop_s_constant): /* S_UNUSED */ - op->run = sett_rop_run1_const_s; - break; - /* 0xFA = D or T */ - case ROP_SPECIFIC_KEY(0xFA, 1, rop_s_constant): - op->run = dort_rop_run1_const_s; - break; /* Then the generic ones */ case KEY(1, 0): op->run = generic_rop_run1; @@ -1826,7 +1640,6 @@ retry: op->run = generic_rop_run8; break; case KEY(8, rop_s_1bit): - case KEY(8, rop_t_1bit): case KEY(8, rop_s_1bit | rop_t_1bit ): op->run = generic_rop_run8_1bit; break; @@ -1837,33 +1650,32 @@ retry: op->run = generic_rop_run24; break; case KEY(24, rop_s_1bit): - case KEY(24, rop_t_1bit): case KEY(24, rop_s_1bit | rop_t_1bit ): op->run = generic_rop_run24_1bit; break; - case KEY(1, rop_s_constant): - op->run = generic_rop_run1_const_s; + case KEY(1, rop_t_constant): + op->run = generic_rop_run1_const_t; op->s.b.pos = 0; op->t.b.pos = 0; op->dpos = 0; break; - case KEY(8, rop_s_constant): + case KEY(8, rop_t_constant): if (rop & (lop_S_transparent | lop_T_transparent)) - op->run = generic_rop_run8_const_s_trans; + op->run = generic_rop_run8_const_t_trans; else - op->run = generic_rop_run8_const_s; + op->run = generic_rop_run8_const_t; break; - case KEY(8, rop_s_constant | rop_t_1bit): - op->run = generic_rop_run8_const_s_1bit; + case KEY(8, rop_s_1bit | rop_t_constant): + op->run = generic_rop_run8_1bit_const_t; break; - case KEY(24, rop_s_constant): + case KEY(24, rop_t_constant): if (rop & (lop_S_transparent | lop_T_transparent)) - op->run = generic_rop_run24_const_s_trans; + op->run = generic_rop_run24_const_t_trans; else - op->run = generic_rop_run24_const_s; + op->run = generic_rop_run24_const_t; break; - case KEY(24, rop_s_constant | rop_t_1bit): - op->run = generic_rop_run24_const_s_1bit; + case KEY(24, rop_s_1bit | rop_t_constant): + op->run = generic_rop_run24_1bit_const_t; break; case KEY(1, rop_s_constant | rop_t_constant): op->run = generic_rop_run1_const_st; @@ -1884,10 +1696,6 @@ retry: op->run = generic_rop_run24_const_st; break; default: - /* If we failed to find a specific one, and swapping is an option, - * then try swapping. */ - if (could_swap) - goto force_swap; /* If we failed to find a specific one for this rop value, try again * for a generic one. */ if (KEY_IS_ROP_SPECIFIC(key)) |