Avoid hiding and unhiding the mouse cursor when copying bitmaps to the

screen.  Instead, copy a merged bitmap 1 line at a time.

This fixes flashing of the cursor and is faster in all modes (especially
in planar modes).
This commit is contained in:
Bruce Evans 2019-04-24 16:03:35 +00:00
parent c7432537b1
commit a07067ea3f
3 changed files with 45 additions and 18 deletions

View File

@ -167,8 +167,17 @@ int
__VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
VGLBitmap *dst, int dstx, int dsty, int width, int hight)
{
int srcline, dstline, yend, yextra, ystep;
byte *buffer, *p;
int mousemerge, srcline, dstline, yend, yextra, ystep;
mousemerge = 0;
if (hight < 0) {
hight = -hight;
mousemerge = (dst == VGLDisplay &&
VGLMouseOverlap(dstx, dsty, width, hight));
if (mousemerge)
buffer = alloca(width*src->PixelBytes);
}
if (srcx>src->VXsize || srcy>src->VYsize
|| dstx>dst->VXsize || dsty>dst->VYsize)
return -1;
@ -204,8 +213,13 @@ __VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
}
for (srcline = srcy + yextra, dstline = dsty + yextra; srcline != yend;
srcline += ystep, dstline += ystep) {
WriteVerticalLine(dst, dstx, dstline, width,
src->Bitmap+(srcline*src->VXsize+srcx)*dst->PixelBytes);
p = src->Bitmap+(srcline*src->VXsize+srcx)*dst->PixelBytes;
if (mousemerge && VGLMouseOverlap(dstx, dstline, width, 1)) {
bcopy(p, buffer, width*src->PixelBytes);
p = buffer;
VGLMouseMerge(dstx, dstline, width, p);
}
WriteVerticalLine(dst, dstx, dstline, width, p);
}
return 0;
}
@ -214,36 +228,29 @@ int
VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
VGLBitmap *dst, int dstx, int dsty, int width, int hight)
{
int error, mouseoverlap;
int error;
if (hight < 0)
return -1;
if (src == VGLDisplay)
src = &VGLVDisplay;
if (src->Type != MEMBUF)
return -1; /* invalid */
if (dst == VGLDisplay) {
VGLMouseFreeze();
mouseoverlap = VGLMouseOverlap(dstx, dsty, width, hight);
if (mouseoverlap)
VGLMousePointerHide();
__VGLBitmapCopy(src, srcx, srcy, &VGLVDisplay, dstx, dsty, width, hight);
error = __VGLBitmapCopy(src, srcx, srcy, &VGLVDisplay, dstx, dsty,
width, hight);
if (error != 0) {
if (mouseoverlap)
VGLMousePointerShow();
VGLMouseUnFreeze();
if (error != 0)
return error;
}
src = &VGLVDisplay;
srcx = dstx;
srcy = dsty;
} else if (dst->Type != MEMBUF)
return -1; /* invalid */
error = __VGLBitmapCopy(src, srcx, srcy, dst, dstx, dsty, width, hight);
if (dst == VGLDisplay) {
if (mouseoverlap)
VGLMousePointerShow();
error = __VGLBitmapCopy(src, srcx, srcy, dst, dstx, dsty, width, -hight);
if (dst == VGLDisplay)
VGLMouseUnFreeze();
}
return error;
}

View File

@ -355,6 +355,25 @@ VGLMouseOverlap(int x, int y, int width, int hight)
return overlap > 0;
}
void
VGLMouseMerge(int x, int y, int width, byte *line)
{
int pos, x1, xend, xstart;
xstart = x;
if (xstart < VGLMouseXpos)
xstart = VGLMouseXpos;
xend = x + width;
if (xend > VGLMouseXpos + MOUSE_IMG_SIZE)
xend = VGLMouseXpos + MOUSE_IMG_SIZE;
for (x1 = xstart; x1 < xend; x1++) {
pos = (y - VGLMouseYpos) * MOUSE_IMG_SIZE + x1 - VGLMouseXpos;
if (VGLMouseAndMask->Bitmap[pos])
bcopy(&VGLMouseOrMask->Bitmap[pos * VGLDisplay->PixelBytes],
&line[(x1 - x) * VGLDisplay->PixelBytes], VGLDisplay->PixelBytes);
}
}
void
VGLMouseUnFreeze()
{

View File

@ -136,6 +136,7 @@ void VGLMouseRestore(void);
int VGLMouseStatus(int *x, int *y, char *buttons);
void VGLMouseFreeze(void);
int VGLMouseFreezeXY(int x, int y);
void VGLMouseMerge(int x, int y, int width, byte *line);
int VGLMouseOverlap(int x, int y, int width, int hight);
void VGLMouseUnFreeze(void);
/* simple.c */