Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Apr 2019 16:03:35 +0000 (UTC)
From:      Bruce Evans <bde@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r346641 - head/lib/libvgl
Message-ID:  <201904241603.x3OG3ZeG029761@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bde
Date: Wed Apr 24 16:03:35 2019
New Revision: 346641
URL: https://svnweb.freebsd.org/changeset/base/346641

Log:
  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).

Modified:
  head/lib/libvgl/bitmap.c
  head/lib/libvgl/mouse.c
  head/lib/libvgl/vgl.h

Modified: head/lib/libvgl/bitmap.c
==============================================================================
--- head/lib/libvgl/bitmap.c	Wed Apr 24 15:54:18 2019	(r346640)
+++ head/lib/libvgl/bitmap.c	Wed Apr 24 16:03:35 2019	(r346641)
@@ -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;
 }
 

Modified: head/lib/libvgl/mouse.c
==============================================================================
--- head/lib/libvgl/mouse.c	Wed Apr 24 15:54:18 2019	(r346640)
+++ head/lib/libvgl/mouse.c	Wed Apr 24 16:03:35 2019	(r346641)
@@ -356,6 +356,25 @@ VGLMouseOverlap(int x, int y, int width, int hight)
 }
 
 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()
 {
   INTON();

Modified: head/lib/libvgl/vgl.h
==============================================================================
--- head/lib/libvgl/vgl.h	Wed Apr 24 15:54:18 2019	(r346640)
+++ head/lib/libvgl/vgl.h	Wed Apr 24 16:03:35 2019	(r346641)
@@ -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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904241603.x3OG3ZeG029761>