[kgraphviewer-devel] [kgraphviewer/libkgraphviz] src/kgraphviz: Introduce major performance speed up

Kevin Funk krf at electrostorm.net
Thu Jan 27 15:10:44 CET 2011


Git commit 46b58295974176c344ccfb1dfab8e5b84bf30e2b by Kevin Funk.
Pushed by kfunk into branch 'libkgraphviz'.

Introduce major performance speed up

PannerView's content was rendered completely for each scrolling/zooming
of the main content. As the pannerview's content is mostly static,
pre-render this and save it into a pixmap.

M  +8    -7    src/kgraphviz/dotgraphview.cpp     
M  +36   -12   src/kgraphviz/pannerview.cpp     
M  +4    -1    src/kgraphviz/pannerview.h     

http://commits.kde.org/9c7b74a4/46b58295974176c344ccfb1dfab8e5b84bf30e2b

diff --git a/src/kgraphviz/dotgraphview.cpp b/src/kgraphviz/dotgraphview.cpp
index b864f52..eca9184 100644
--- a/src/kgraphviz/dotgraphview.cpp
+++ b/src/kgraphviz/dotgraphview.cpp
@@ -141,7 +141,7 @@ void DotGraphViewPrivate::updateSizes(const QSizeF& size)
   }
 
   kDebug() << "Show the panner view";
-  m_birdEyeView->hide();
+  m_birdEyeView->show();
 
   // first, assume use of 1/3 of width/height (possible larger)
   double zoom = .33 * adjustedSize.width() / cWidth;
@@ -174,12 +174,15 @@ void DotGraphViewPrivate::updateSizes(const QSizeF& size)
   }
   updateBirdEyeView();
   m_birdEyeView->setZoomRect(q->mapToScene(q->viewport()->rect()).boundingRect());
-  m_birdEyeView->show();
 }
 
 void DotGraphViewPrivate::updateBirdEyeView()
 {
+  kDebug();
   Q_Q(DotGraphView);
+
+  m_birdEyeView->updateBackground();
+
   qreal cvW = m_birdEyeView->width();
   qreal cvH = m_birdEyeView->height();
   qreal x = q->width()- cvW - q->verticalScrollBar()->width()    -2;
@@ -594,7 +597,6 @@ void DotGraphViewPrivate::setupCanvas()
   Q_Q(DotGraphView);
   kDebug();
   m_birdEyeView->hide();
-  m_birdEyeView->setScene(0);
   
   q->setScene(0);
 
@@ -611,8 +613,6 @@ void DotGraphViewPrivate::setupCanvas()
 
   // add text item
   m_textItem = newCanvas->addSimpleText(i18n("No graph loaded."));
-
-  m_birdEyeView->setScene(newCanvas);
   
   q->setScene(newCanvas);
   q->connect(newCanvas, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
@@ -1002,6 +1002,7 @@ void DotGraphView::applyZoom(double factor)
 void DotGraphView::scrollContentsBy(int dx, int dy)
 {
   Q_D(DotGraphView);
+//   kDebug() << dx << dy << viewport()->rect() << sceneRect() << d->m_birdEyeView->sceneRect();
   QGraphicsView::scrollContentsBy(dx, dy);
   if (d->m_birdEyeView && scene()) { // we might be shutting down
     d->m_birdEyeView->moveZoomRectTo(mapToScene(viewport()->rect()).boundingRect().center(), false);
@@ -1019,14 +1020,14 @@ void DotGraphView::resizeEvent(QResizeEvent* e)
 
 void DotGraphView::zoomRectMovedTo(QPointF newZoomPos)
 {
-//   kDebug() << "DotGraphView::zoomRectMovedTo " << newZoomPos;
+  kDebug() << "DotGraphView::zoomRectMovedTo " << newZoomPos;
   centerOn(newZoomPos);
 }
                     
 void DotGraphView::zoomRectMoveFinished()
 {
   Q_D(DotGraphView);
-//    kDebug() << "zoomRectMoveFinished";
+    kDebug() << "zoomRectMoveFinished";
   d->updateBirdEyeView();
 //   std::cerr << "zoomRectMoveFinished end" << std::endl;
 }
diff --git a/src/kgraphviz/pannerview.cpp b/src/kgraphviz/pannerview.cpp
index 4420c13..d586c62 100644
--- a/src/kgraphviz/pannerview.cpp
+++ b/src/kgraphviz/pannerview.cpp
@@ -57,6 +57,7 @@ public:
   Q_DECLARE_PUBLIC(DotGraphView)
   DotGraphView* const q_ptr;
 
+  QPixmap m_backgroundPixmap;
   QRectF m_zoomRect;
   bool m_movingZoomRect;
   QPointF m_lastPos;
@@ -66,7 +67,6 @@ PannerViewPrivate::PannerViewPrivate(DotGraphView* parent)
   : q_ptr(parent)
   , m_movingZoomRect(false)
 {
-
 }
 
 PannerViewPrivate::~PannerViewPrivate()
@@ -74,17 +74,18 @@ PannerViewPrivate::~PannerViewPrivate()
   kDebug();
 }
 
-PannerView::PannerView(DotGraphView * parent, const char * name)
+PannerView::PannerView(DotGraphView * parent)
   : QGraphicsView(parent)
   , d_ptr(new PannerViewPrivate(parent))
 {
-  // why doesn't this avoid flicker ?
-  // viewport()->setBackgroundMode(Qt::NoBackground);
-  setBackgroundMode(Qt::NoBackground);
+  setScene(new QGraphicsScene);
+  setCacheMode(QGraphicsView::CacheBackground);
+  setRenderHints(QPainter::Antialiasing);
 
   // if there are ever graphic glitches to be found, remove this again
-  setOptimizationFlags(QGraphicsView::DontAdjustForAntialiasing | QGraphicsView::DontClipPainter |
-                        QGraphicsView::DontSavePainterState);
+  setOptimizationFlags(QGraphicsView::DontAdjustForAntialiasing |
+                       QGraphicsView::DontClipPainter |
+                       QGraphicsView::DontSavePainterState);
 
   setToolTip(i18n("View of the complete graph. Click and drag to move the visible part."));
   setWhatsThis(i18n("<h1>View of the Complete Graph</h1>"
@@ -107,7 +108,6 @@ void PannerView::setZoomRect(const QRectF& rectangle)
   if (rectangle == d->m_zoomRect) {
     return;
   }
-  scene()->invalidate(d->m_zoomRect, QGraphicsScene::ForegroundLayer);
   // get new zoom rect
   d->m_zoomRect = rectangle;
   const qreal q1 = mapToScene(15,0).x();
@@ -139,18 +139,18 @@ void PannerView::setZoomRect(const QRectF& rectangle)
     newRect.setHeight(newHeight);
     d->m_zoomRect = newRect;
   }
-  scene()->invalidate(d->m_zoomRect, QGraphicsScene::ForegroundLayer);
 }
 
 void PannerView::moveZoomRectTo(const QPointF& newPos, bool notify)
 {
   Q_D(PannerView);
+//   kDebug() << newPos << d->m_zoomRect;
   if (!d->m_zoomRect.isValid()) {
     return;
   }
 
   if (d->m_zoomRect.center() == newPos) {
-    kDebug() << "same pos, don't do anything";
+    kDebug() << "Same position, don't do anything";
     return;
   }
 
@@ -159,13 +159,14 @@ void PannerView::moveZoomRectTo(const QPointF& newPos, bool notify)
   scene()->invalidate(d->m_zoomRect, QGraphicsScene::ForegroundLayer);
 
   if (d->m_zoomRect.isValid() && notify) {
-    emit zoomRectMovedTo(newPos);
     d->m_lastPos = newPos;
+	emit zoomRectMovedTo(newPos);
   }
 }
 
 void PannerView::drawForeground(QPainter * p, const QRectF & rect )
 {
+  kDebug();
   Q_D(const PannerView);
   if (d->m_zoomRect.isValid() && rect.intersects(d->m_zoomRect))
   {
@@ -186,6 +187,29 @@ void PannerView::drawForeground(QPainter * p, const QRectF & rect )
   }
 }
 
+
+void PannerView::drawBackground(QPainter* painter, const QRectF& rect)
+{
+  Q_D(const PannerView);
+//   kDebug() << rect << viewport()->rect() << sceneRect() << d->m_backgroundPixmap.rect();
+  
+  painter->eraseRect(viewport()->rect());
+  painter->drawPixmap(rect, d->m_backgroundPixmap, d->m_backgroundPixmap.rect());
+}
+
+void PannerView::updateBackground()
+{
+  Q_D(PannerView);
+  const DotGraphView* view = d->parent();
+  QPixmap pixmap(viewport()->rect().size());
+  QPainter p(&pixmap);
+  view->scene()->render(&p, pixmap.rect(), view->sceneRect(), Qt::IgnoreAspectRatio);
+  setSceneRect(view->sceneRect());
+
+  d->m_backgroundPixmap = pixmap;
+  invalidateScene(QRectF(), QGraphicsScene::BackgroundLayer);
+}
+
 void PannerView::mousePressEvent(QMouseEvent* e)
 {
   Q_D(PannerView);
@@ -223,7 +247,7 @@ void PannerView::mouseReleaseEvent(QMouseEvent* e)
 
 void PannerView::contextMenuEvent(QContextMenuEvent* event)
 {
-  Q_D(const PannerView);
+  Q_D(PannerView);
   d->parent()->contextMenuEvent(event);
 }
 
diff --git a/src/kgraphviz/pannerview.h b/src/kgraphviz/pannerview.h
index fcd2610..842c5f6 100644
--- a/src/kgraphviz/pannerview.h
+++ b/src/kgraphviz/pannerview.h
@@ -43,9 +43,11 @@ class PannerView: public QGraphicsView
   Q_OBJECT
 
 public:
-  explicit PannerView(DotGraphView * parent, const char * name = 0);
+  explicit PannerView(DotGraphView * parent);
   virtual ~PannerView();
 
+  void updateBackground();
+
 public Q_SLOTS:
   void setZoomRect(const QRectF& rectangle);
   void moveZoomRectTo(const QPointF& newPos, const bool notify = true);
@@ -59,6 +61,7 @@ protected:
   virtual void mouseMoveEvent(QMouseEvent*);
   virtual void mouseReleaseEvent(QMouseEvent*);
   virtual void drawForeground(QPainter * p, const QRectF & rect );
+  virtual void drawBackground(QPainter* painter, const QRectF& rect);
   virtual void contextMenuEvent(QContextMenuEvent* event);
 
   PannerViewPrivate* const d_ptr;


More information about the kgraphviewer-devel mailing list