Improve performance of partial repaints
authorchristian <pulvermacher@gmx.de>
Sun, 29 Jan 2012 14:57:50 +0000 (15:57 +0100)
committerchristian <pulvermacher@gmx.de>
Sun, 29 Jan 2012 14:57:50 +0000 (15:57 +0100)
Scrolling is now more fluent when zoomed out, though still a bit sluggish
when the kinetic scrolling overshoots to the left side...

debian/changelog
src/scrollarea.h
src/vncview.cpp

index a4352d2..00b73bd 100644 (file)
@@ -2,6 +2,7 @@ presencevnc (0.8) unstable; urgency=low
 
   * Add --viewonly, --listen and --help command line options
   * Use less CPU when display is off
+  * Improve performance of partial repaints, scrolling more fluent
 
  -- Christian Pulvermacher <pulvermacher@gmx.de>  Thu, 28 Oct 2010 19:48:01 +0200
 
index 956555b..1505b3b 100644 (file)
@@ -27,7 +27,7 @@
 class ScrollArea : public QScrollArea
 {
 public:
-    ScrollArea(QWidget *parent):
+    explicit ScrollArea(QWidget *parent):
         QScrollArea(parent) {
         message.setParent(this);
         message.setVisible(false);
@@ -41,16 +41,16 @@ public:
         message.setPalette(pal);
         message.setAutoFillBackground(true);
 
-        timer.setSingleShot(true);
-        timer.setInterval(2500);
-        connect(&timer, SIGNAL(timeout()),
+        message_timer.setSingleShot(true);
+        message_timer.setInterval(2500);
+        connect(&message_timer, SIGNAL(timeout()),
                 &message, SLOT(hide()));
     }
 
     void showMessage(const QString &s) {
         message.setText(s);
         message.show();
-        timer.start();
+        message_timer.start();
     }
 protected:
     virtual void resizeEvent(QResizeEvent* ev) {
@@ -59,11 +59,16 @@ protected:
     }
     virtual void scrollContentsBy(int dx, int dy) {
         QScrollArea::scrollContentsBy(dx, dy);
-        if(widget())
-            widget()->update(); //update whole widget
+        if(widget()) {
+            const QRegion visible_region_new = widget()->visibleRegion();
+            const QRegion visible_region_old = visible_region_new.translated(-dx, -dy);
+
+            //now update only the region that became visible
+            widget()->update(visible_region_new - visible_region_old);
+        }
     }
 private:
     QLabel message;
-    QTimer timer;
+    QTimer message_timer;
 };
 #endif
index 481bc02..f704a4d 100644 (file)
@@ -387,23 +387,19 @@ void VncView::paintEvent(QPaintEvent *event)
 
     event->accept();
 
-    const QRect update_rect = event->rect();
+    //split update region into smaller non-intersecting rectangles and only paint those
     QPainter painter(this);
-    if (update_rect != rect()) {
-        // kDebug(5011) << "Partial repaint";
+    foreach(const QRect& update_rect, event->region().rects()) {
         const int sx = qRound(update_rect.x()/m_horizontalFactor);
         const int sy = qRound(update_rect.y()/m_verticalFactor);
         const int sw = qRound(update_rect.width()/m_horizontalFactor);
         const int sh = qRound(update_rect.height()/m_verticalFactor);
 
+        //kDebug(5011) << "Partial repaint, widget x,y,w,h:" << update_rect.x() << update_rect.y() << update_rect.width() << update_rect.height() << "orig: " << sx << sy << sw << sh;
+
         painter.drawImage(update_rect,
                           m_frame.copy(sx, sy, sw, sh)
                           .scaled(update_rect.size(), Qt::IgnoreAspectRatio, transformation_mode));
-    } else {
-        //kDebug(5011) << "Full repaint" << width() << height() << m_frame.width() << m_frame.height();
-
-        painter.drawImage(rect(),
-                          m_frame.scaled(size(), Qt::IgnoreAspectRatio, transformation_mode));
     }
 
     //draw local cursor ourselves, normal mouse pointer doesn't deal with scrolling