diff --git a/src/core/MainWindow.cpp b/src/core/MainWindow.cpp index 92f4ede8..02ef1fd2 100644 --- a/src/core/MainWindow.cpp +++ b/src/core/MainWindow.cpp @@ -318,7 +318,7 @@ void MainWindow::toggleOverview(bool visibility, GraphWidget *targetGraph) overviewDock->setUserClosed(true); } }); - connect(overviewDock, SIGNAL(resized()), this, SLOT(forceUpdateOverview())); + connect(overviewDock, SIGNAL(resized()), this, SLOT(forceUpdateOverview())); // TODO: remove this, overviewDock handles resize itself! } void MainWindow::disconnectOverview() @@ -332,7 +332,7 @@ void MainWindow::disconnectOverview() disconnect(overviewDock->getGraphView(), SIGNAL(mouseMoved()), this, SLOT(adjustGraph())); disconnect(overviewDock->getGraphView(), SIGNAL(refreshBlock()), this, SLOT(updateOverviewAddr())); disconnect(overviewDock, &QDockWidget::dockLocationChanged, this, &MainWindow::forceUpdateOverview); - disconnect(overviewDock, SIGNAL(resized()), this, SLOT(forceUpdateOverview())); + disconnect(overviewDock, SIGNAL(resized()), this, SLOT(forceUpdateOverview())); // TODO: remove this, overviewDock handles resize itself! } } @@ -366,7 +366,6 @@ void MainWindow::forceUpdateOverview() if (!isOverviewActive()) { return; } - overviewDock->getGraphView()->useCache = false; setOverviewData(); drawOverview(); } @@ -377,10 +376,7 @@ void MainWindow::updateOverview() return; } if (overviewDock->getGraphView()->currentFcnAddr != targetGraphDock->getGraphView()->currentFcnAddr) { - overviewDock->getGraphView()->useCache = false; setOverviewData(); - } else { - overviewDock->getGraphView()->useCache = true; } drawOverview(); } diff --git a/src/widgets/DisassemblerGraphView.cpp b/src/widgets/DisassemblerGraphView.cpp index 451b4a61..d11d267b 100644 --- a/src/widgets/DisassemblerGraphView.cpp +++ b/src/widgets/DisassemblerGraphView.cpp @@ -999,3 +999,10 @@ void DisassemblerGraphView::wheelEvent(QWheelEvent *event) } emit graphMoved(); } + +void DisassemblerGraphView::paintEvent(QPaintEvent *event) +{ + // DisassemblerGraphView is always dirty + setCacheDirty(); + GraphView::paintEvent(event); +} diff --git a/src/widgets/DisassemblerGraphView.h b/src/widgets/DisassemblerGraphView.h index cf2a2adb..b5ee6a93 100644 --- a/src/widgets/DisassemblerGraphView.h +++ b/src/widgets/DisassemblerGraphView.h @@ -130,6 +130,8 @@ protected: void mouseMoveEvent(QMouseEvent *event) override; void wheelEvent(QWheelEvent *event) override; + void paintEvent(QPaintEvent *event) override; + private slots: void on_actionExportGraph_triggered(); diff --git a/src/widgets/GraphView.cpp b/src/widgets/GraphView.cpp index 0ee403eb..71f1a3c1 100644 --- a/src/widgets/GraphView.cpp +++ b/src/widgets/GraphView.cpp @@ -142,6 +142,42 @@ void GraphView::beginMouseDrag(QMouseEvent *event) viewport()->grabMouse(); } +QSize GraphView::getCacheSize() +{ + return +#ifndef QT_NO_OPENGL + useGL ? cacheSize : +#endif + pixmap.size(); +} + +qreal GraphView::getCacheDevicePixelRatioF() +{ + return +#ifndef QT_NO_OPENGL + useGL ? 1.0 : +#endif + pixmap.devicePixelRatioF(); +} + +QSize GraphView::getRequiredCacheSize() +{ + return +#ifndef QT_NO_OPENGL + useGL ? viewport()->size() : +#endif + viewport()->size() * devicePixelRatioF(); +} + +qreal GraphView::getRequiredCacheDevicePixelRatioF() +{ + return +#ifndef QT_NO_OPENGL + useGL ? 1.0f : +#endif + devicePixelRatioF(); +} + void GraphView::paintEvent(QPaintEvent *) { #ifndef QT_NO_OPENGL @@ -150,8 +186,15 @@ void GraphView::paintEvent(QPaintEvent *) } #endif - if(!useCache || !qFuzzyCompare(devicePixelRatioF(), pixmap.devicePixelRatioF())) { + if (!qFuzzyCompare(getCacheDevicePixelRatioF(), getRequiredCacheDevicePixelRatioF()) + || getCacheSize() != getRequiredCacheSize()) { + setCacheDirty(); + } + + bool cacheWasDirty = cacheDirty; + if(cacheDirty) { paintGraphCache(); + cacheDirty = false; } if (useGL) { @@ -159,20 +202,19 @@ void GraphView::paintEvent(QPaintEvent *) auto gl = glWidget->context()->extraFunctions(); gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, cacheFBO); gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glWidget->defaultFramebufferObject()); - gl->glBlitFramebuffer(0, 0, viewport()->width(), viewport()->height(), + gl->glBlitFramebuffer(0, 0, cacheSize.width(), cacheSize.height(), 0, 0, viewport()->width(), viewport()->height(), GL_COLOR_BUFFER_BIT, GL_NEAREST); glWidget->doneCurrent(); #endif } else { QRectF target(0.0, 0.0, viewport()->width(), viewport()->height()); - QRectF source(0.0, 0.0, viewport()->width() * pixmap.devicePixelRatioF(), - viewport()->height() * pixmap.devicePixelRatioF()); + QRectF source(0.0, 0.0, pixmap.width(), pixmap.height()); QPainter p(viewport()); p.drawPixmap(target, pixmap, source); } - if(!useCache) { // TODO: does this condition make sense? + if(cacheWasDirty) { // TODO: does this condition make sense? emit refreshBlock(); } } @@ -219,7 +261,7 @@ void GraphView::paintGraphCache() #endif } else { auto dpr = devicePixelRatioF(); - pixmap = QPixmap(int(viewport()->width() * dpr), int(viewport()->height() * dpr)); + pixmap = QPixmap(getRequiredCacheSize()); pixmap.setDevicePixelRatio(dpr); p.begin(&pixmap); p.setRenderHint(QPainter::Antialiasing); diff --git a/src/widgets/GraphView.h b/src/widgets/GraphView.h index c49d5d41..5943e141 100644 --- a/src/widgets/GraphView.h +++ b/src/widgets/GraphView.h @@ -41,8 +41,6 @@ public: explicit GraphView(QWidget *parent); ~GraphView() override; - void paintEvent(QPaintEvent *event) override; - void showBlock(GraphBlock &block); void showBlock(GraphBlock *block); @@ -51,11 +49,6 @@ public: QPoint offset = QPoint(0, 0); - /** - * @brief flag to control if the cached pixmap should be used - */ - bool useCache = false; - /** * @brief keep the current addr of the fcn of Graph * Everytime overview updates its contents, it compares this value with the one in Graph @@ -70,6 +63,7 @@ protected: // Padding inside the block int block_padding = 16; + void setCacheDirty() { cacheDirty = true; } void addBlock(GraphView::GraphBlock block); void setEntry(ut64 e); @@ -93,6 +87,8 @@ protected: void mouseReleaseEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent *event) override; + void paintEvent(QPaintEvent *event) override; + void center(); void centerX(); void centerY(); @@ -132,6 +128,15 @@ private: QOpenGLWidget *glWidget; #endif + /** + * @brief flag to control if the cache is invalid and should be re-created in the next draw + */ + bool cacheDirty = true; + QSize getCacheSize(); + qreal getCacheDevicePixelRatioF(); + QSize getRequiredCacheSize(); + qreal getRequiredCacheDevicePixelRatioF(); + QPolygonF recalculatePolygon(QPolygonF polygon); void beginMouseDrag(QMouseEvent *event); }; diff --git a/src/widgets/OverviewView.cpp b/src/widgets/OverviewView.cpp index 52c73b1a..a86bf313 100644 --- a/src/widgets/OverviewView.cpp +++ b/src/widgets/OverviewView.cpp @@ -23,6 +23,7 @@ void OverviewView::setData(int baseWidth, int baseHeight, blocks = baseBlocks; edgeConfigurations = baseEdgeConfigurations; scaleAndCenter(); + setCacheDirty(); } OverviewView::~OverviewView() @@ -102,7 +103,6 @@ void OverviewView::mousePressEvent(QMouseEvent *event) qreal x = event->localPos().x() - w / 2; qreal y = event->localPos().y() - h / 2; rangeRect = QRectF(x, y, w, h); - useCache = true; viewport()->update(); emit mouseMoved(); mouseContainsRect(event); @@ -122,7 +122,6 @@ void OverviewView::mouseMoveEvent(QMouseEvent *event) qreal x = event->localPos().x() - initialDiff.x(); qreal y = event->localPos().y() - initialDiff.y(); rangeRect = QRectF(x, y, rangeRect.width(), rangeRect.height()); - useCache = true; viewport()->update(); emit mouseMoved(); } diff --git a/src/widgets/OverviewView.h b/src/widgets/OverviewView.h index d2c52389..1e5f21f9 100644 --- a/src/widgets/OverviewView.h +++ b/src/widgets/OverviewView.h @@ -68,6 +68,11 @@ protected: */ void wheelEvent(QWheelEvent *event) override; + /** + * @brief override the paintEvent to draw the rect on Overview + */ + void paintEvent(QPaintEvent *event) override; + private: /** * @brief this will be handled in mouse events to move the rect properly @@ -100,11 +105,6 @@ private: virtual GraphView::EdgeConfiguration edgeConfiguration(GraphView::GraphBlock &from, GraphView::GraphBlock *to) override; - /** - * @brief override the paintEvent to draw the rect on Overview - */ - void paintEvent(QPaintEvent *event) override; - /** * @brief if the mouse is in the rect in Overview. */