From 2f5cff37506aaa5d4ebf53560981899efadcc5e2 Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Fri, 3 May 2019 13:06:46 +0000 Subject: [PATCH] Fix copying planar bitmaps when the horizontal start and end are both not multiples of 8. Then the misaligned pixels at the end were not copied. Clean up variable misuse related to this bug. The width in bytes was first calculated correctly and used to do complicated reblocking correctly, but it was stored in an unrelated scratch variable and later recalculated with an off-by-1-error, so the last byte (times 4 planes) in the intermediate copy was not copied. This doubly-misaligned case is especially slow. Misalignment complicates the reblocking, and each misaligment requires a read before write, and this read is still not done from the shadow buffer. --- lib/libvgl/bitmap.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/libvgl/bitmap.c b/lib/libvgl/bitmap.c index 0a7f049d9fa0..e37a96318e0f 100644 --- a/lib/libvgl/bitmap.c +++ b/lib/libvgl/bitmap.c @@ -47,7 +47,7 @@ static int color2bit[16] = {0x00000000, 0x00000001, 0x00000100, 0x00000101, static void WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line) { - int i, pos, last, planepos, start_offset, end_offset, offset; + int bwidth, i, pos, last, planepos, start_offset, end_offset, offset; int len; unsigned int word = 0; byte *address; @@ -58,13 +58,13 @@ WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line) case VIDBUF4S: start_offset = (x & 0x07); end_offset = (x + width) & 0x07; - i = (width + start_offset) / 8; + bwidth = (width + start_offset) / 8; if (end_offset) - i++; + bwidth++; VGLPlane[0] = VGLBuf; - VGLPlane[1] = VGLPlane[0] + i; - VGLPlane[2] = VGLPlane[1] + i; - VGLPlane[3] = VGLPlane[2] + i; + VGLPlane[1] = VGLPlane[0] + bwidth; + VGLPlane[2] = VGLPlane[1] + bwidth; + VGLPlane[3] = VGLPlane[2] + bwidth; pos = 0; planepos = 0; last = 8 - start_offset; @@ -87,9 +87,6 @@ WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line) VGLPlane[2][planepos] = word>>16; VGLPlane[3][planepos] = word>>24; } - if (start_offset || end_offset) - width+=8; - width /= 8; outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ for (i=0; i<4; i++) { @@ -103,7 +100,7 @@ WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line) VGLPlane[i][planepos] |= dst->Bitmap[pos+planepos] & mask[end_offset]; if (start_offset) VGLPlane[i][0] |= dst->Bitmap[pos] & ~mask[start_offset]; - bcopy(&VGLPlane[i][0], dst->Bitmap + pos, width); + bcopy(&VGLPlane[i][0], dst->Bitmap + pos, bwidth); } else { /* VIDBUF4S */ if (end_offset) { offset = VGLSetSegment(pos + planepos); @@ -112,9 +109,9 @@ WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line) offset = VGLSetSegment(pos); if (start_offset) VGLPlane[i][0] |= dst->Bitmap[offset] & ~mask[start_offset]; - for (last = width; ; ) { + for (last = bwidth; ; ) { len = min(VGLAdpInfo.va_window_size - offset, last); - bcopy(&VGLPlane[i][width - last], dst->Bitmap + offset, len); + bcopy(&VGLPlane[i][bwidth - last], dst->Bitmap + offset, len); pos += len; last -= len; if (last <= 0)