]> source.dussan.org Git - tigervnc.git/commitdiff
Try to render entire update in one go to avoid tearing.
authorPierre Ossman <ossman@cendio.se>
Wed, 25 Mar 2009 12:13:28 +0000 (12:13 +0000)
committerPierre Ossman <ossman@cendio.se>
Wed, 25 Mar 2009 12:13:28 +0000 (12:13 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3718 3789f03b-4d11-0410-bbf8-ca57d06f2519

win/vncviewer/CConn.cxx
win/vncviewer/DesktopWindow.cxx
win/vncviewer/DesktopWindow.h

index aa4ba75d5024f27fc777116f8b85f9b795cd2c3b..d5eadc4cff765e1ac0731f1c6e83d7a11bc2c4c8 100644 (file)
@@ -511,6 +511,7 @@ CConn::framebufferUpdateEnd() {
     }
     debugRects.clear();
   }
+  window->framebufferUpdateEnd();
 
   if (firstUpdate) {
     int width, height;
index c85730a490a2cb36a499cf33b6f8802b061c9ac4..744149da0b3f4747e5f66acaacc3ea37372febd4 100644 (file)
@@ -42,6 +42,7 @@ static LogWriter vlog("DesktopWindow");
 const int TIMER_BUMPSCROLL = 1;
 const int TIMER_POINTER_INTERVAL = 2;
 const int TIMER_POINTER_3BUTTON = 3;
+const int TIMER_UPDATE = 4;
 
 
 //
@@ -222,6 +223,10 @@ DesktopWindow::DesktopWindow(Callback* cb)
   bumpScrollTimer.setHWND(handle);
   bumpScrollTimer.setId(TIMER_BUMPSCROLL);
 
+  // Initialise the update timer
+  updateTimer.setHWND(handle);
+  updateTimer.setId(TIMER_UPDATE);
+
   // Hook the clipboard
   clipboard.setNotifier(this);
 
@@ -543,6 +548,9 @@ DesktopWindow::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
     case TIMER_POINTER_3BUTTON:
       ptr.handleTimer(callback, wParam);
       break;
+    case TIMER_UPDATE:
+      updateWindow();
+      break;
     }
     break;
 
@@ -871,6 +879,19 @@ DesktopWindow::processMouseMessage(UINT msg, WPARAM wParam, LPARAM lParam)
 #endif
 }
 
+void DesktopWindow::updateWindow()
+{
+  Rect rect;
+
+  updateTimer.stop();
+
+  rect = damage.get_bounding_rect();
+  damage.clear();
+
+  RECT invalid = {rect.tl.x, rect.tl.y, rect.br.x, rect.br.y};
+  InvalidateRect(frameHandle, &invalid, FALSE);
+}
+
 void
 DesktopWindow::hideLocalCursor() {
   // - Blit the cursor backing store over the cursor
@@ -901,6 +922,9 @@ DesktopWindow::showLocalCursor() {
     renderLocalCursor();
 
     invalidateDesktopRect(cursorBackingRect, false);
+    // Since we render the cursor onto the framebuffer, we need to update
+    // right away to get a responsive cursor.
+    updateWindow();
   }
 }
 
@@ -945,8 +969,9 @@ DesktopWindow::invalidateDesktopRect(const Rect& crect, bool scaling) {
     rect = desktopToClient(buffer->calculateScaleBoundary(crect));
   } else rect = desktopToClient(crect);
   if (rect.intersect(client_size).is_empty()) return false;
-  RECT invalid = {rect.tl.x, rect.tl.y, rect.br.x, rect.br.y};
-  InvalidateRect(frameHandle, &invalid, FALSE);
+  damage.assign_union(rfb::Region(rect));
+  if (!updateTimer.isActive())
+    updateTimer.start(100);
   return true;
 }
 
@@ -1262,6 +1287,12 @@ void DesktopWindow::resizeDesktopWindowToBuffer() {
 }
 
 
+void DesktopWindow::framebufferUpdateEnd()
+{
+  updateWindow();
+}
+
+
 void
 DesktopWindow::setName(const char* name) {
   if (name != desktopName) {
index 259b6b0e31bd545ae39d3dd14f12d4ffdaa8f695..4bc7b7a790ae3463d8f238de9a9411c4da524eff 100644 (file)
@@ -119,6 +119,9 @@ namespace rfb {
       // - Set the local clipboard
       void serverCutText(const char* str, rdr::U32 len);
 
+      // - Completion of one FramebufferUpdate
+      void framebufferUpdateEnd();
+
       // - Draw into the desktop buffer & update the window
       void fillRect(const Rect& r, Pixel pix);
       void imageRect(const Rect& r, void* pixels);
@@ -197,6 +200,9 @@ namespace rfb {
       Point bumpScrollDelta;
       IntervalTimer bumpScrollTimer;
 
+      // Track modified areas of the framebuffer
+      void updateWindow();
+
       // Locally-rendered VNC cursor
       void hideLocalCursor();
       void showLocalCursor();
@@ -235,6 +241,10 @@ namespace rfb {
       bool fullscreenActive;
       bool fullscreenRestore;
 
+      // Damage tracking
+      rfb::Region damage;
+      IntervalTimer updateTimer;
+
       // Cursor handling
       Cursor cursor;
       bool systemCursorVisible;  // Should system-cursor be drawn?