pokey@well.UUCP (Jef Poskanzer) (12/31/88)
[Those who read comp.sys.sun have already seen a version of this message.
I am re-posting it here to get better coverage, and because I have made
some changes to the code since I submitted it to sun-spots a few weeks
ago.]
I was playing around with screenload recently, and added a -t for
tiling flag. But I was not happy with the speed. Just from watching a
small bitmap get tiled over the full screen, it looks like pr_replrop
is doing a simple linear replication. Now, any graphics hacker knows
that since edge handling is expensive in bit blitting, a large blit
goes faster than N smaller blits with the same area. So I whipped up a
quick binary replication wrapper routine, and did some timings. For
tiling a small bitmap over the full screen, on a 3/50, my replrop goes
four times faster than Sun's.
The routine is appended. This should be 100% compatible with pr_replrop.
If anyone finds any cases where this isn't so, please let me know. Also,
I would be interested in hearing whether similar speedups are seen on
other configurations, such as color frame buffers.
---
Jef
Jef Poskanzer jef@rtsg.ee.lbl.gov ...well!pokey
jef_pr_replrop(dpr, dx, dy, dw, dh, op, spr, sx, sy)
Pixrect *dpr, *spr;
int dx, dy, dw, dh, op, sx, sy;
{
register int w, h, status;
if ( spr == (Pixrect *) 0 ) {
/* Special case the NULL pixrect. */
w = dw;
h = dh;
} else {
w = spr->pr_size.x;
/* Avoid tiny horizontal blits. */
while ( w < 256 ) w *= 2;
if ( w > dw ) w = dw;
h = spr->pr_size.y;
/* But no edge effects vertically, so no problem. */
if ( h > dh ) h = dh;
}
if (status = pr_replrop(dpr, dx, dy, w, h, op, spr, sx, sy))
return status;
while ( w < dw || h < dh ) {
if ( w < dw )
if (status = pr_rop(dpr, dx + w, dy, w, h, PIX_SRC, dpr,
dx, dy))
return status;
if ( h < dh )
if (status = pr_rop(dpr, dx, dy + h, w, h, PIX_SRC, dpr,
dx, dy))
return status;
if ( w < dw && h < dh )
if (status = pr_rop(dpr, dx + w, dy + h, w, h, PIX_SRC,
dpr, dx, dy))
return status;
w *= 2;
h *= 2;
}
return 0;
}