Replace GraphView::useCache with dirty flag (#1437)

This commit is contained in:
Florian Märkl 2019-04-08 08:59:16 +02:00 committed by GitHub
parent 1cb5c1a8a9
commit 65850d6aee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 26 deletions

View File

@ -318,7 +318,7 @@ void MainWindow::toggleOverview(bool visibility, GraphWidget *targetGraph)
overviewDock->setUserClosed(true); 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() void MainWindow::disconnectOverview()
@ -332,7 +332,7 @@ void MainWindow::disconnectOverview()
disconnect(overviewDock->getGraphView(), SIGNAL(mouseMoved()), this, SLOT(adjustGraph())); disconnect(overviewDock->getGraphView(), SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
disconnect(overviewDock->getGraphView(), SIGNAL(refreshBlock()), this, SLOT(updateOverviewAddr())); disconnect(overviewDock->getGraphView(), SIGNAL(refreshBlock()), this, SLOT(updateOverviewAddr()));
disconnect(overviewDock, &QDockWidget::dockLocationChanged, this, &MainWindow::forceUpdateOverview); 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()) { if (!isOverviewActive()) {
return; return;
} }
overviewDock->getGraphView()->useCache = false;
setOverviewData(); setOverviewData();
drawOverview(); drawOverview();
} }
@ -377,10 +376,7 @@ void MainWindow::updateOverview()
return; return;
} }
if (overviewDock->getGraphView()->currentFcnAddr != targetGraphDock->getGraphView()->currentFcnAddr) { if (overviewDock->getGraphView()->currentFcnAddr != targetGraphDock->getGraphView()->currentFcnAddr) {
overviewDock->getGraphView()->useCache = false;
setOverviewData(); setOverviewData();
} else {
overviewDock->getGraphView()->useCache = true;
} }
drawOverview(); drawOverview();
} }

View File

@ -999,3 +999,10 @@ void DisassemblerGraphView::wheelEvent(QWheelEvent *event)
} }
emit graphMoved(); emit graphMoved();
} }
void DisassemblerGraphView::paintEvent(QPaintEvent *event)
{
// DisassemblerGraphView is always dirty
setCacheDirty();
GraphView::paintEvent(event);
}

View File

@ -130,6 +130,8 @@ protected:
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override; void wheelEvent(QWheelEvent *event) override;
void paintEvent(QPaintEvent *event) override;
private slots: private slots:
void on_actionExportGraph_triggered(); void on_actionExportGraph_triggered();

View File

@ -142,6 +142,42 @@ void GraphView::beginMouseDrag(QMouseEvent *event)
viewport()->grabMouse(); 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 *) void GraphView::paintEvent(QPaintEvent *)
{ {
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
@ -150,8 +186,15 @@ void GraphView::paintEvent(QPaintEvent *)
} }
#endif #endif
if(!useCache || !qFuzzyCompare(devicePixelRatioF(), pixmap.devicePixelRatioF())) { if (!qFuzzyCompare(getCacheDevicePixelRatioF(), getRequiredCacheDevicePixelRatioF())
|| getCacheSize() != getRequiredCacheSize()) {
setCacheDirty();
}
bool cacheWasDirty = cacheDirty;
if(cacheDirty) {
paintGraphCache(); paintGraphCache();
cacheDirty = false;
} }
if (useGL) { if (useGL) {
@ -159,20 +202,19 @@ void GraphView::paintEvent(QPaintEvent *)
auto gl = glWidget->context()->extraFunctions(); auto gl = glWidget->context()->extraFunctions();
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, cacheFBO); gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, cacheFBO);
gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glWidget->defaultFramebufferObject()); 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(), 0, 0, viewport()->width(), viewport()->height(),
GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_COLOR_BUFFER_BIT, GL_NEAREST);
glWidget->doneCurrent(); glWidget->doneCurrent();
#endif #endif
} else { } else {
QRectF target(0.0, 0.0, viewport()->width(), viewport()->height()); QRectF target(0.0, 0.0, viewport()->width(), viewport()->height());
QRectF source(0.0, 0.0, viewport()->width() * pixmap.devicePixelRatioF(), QRectF source(0.0, 0.0, pixmap.width(), pixmap.height());
viewport()->height() * pixmap.devicePixelRatioF());
QPainter p(viewport()); QPainter p(viewport());
p.drawPixmap(target, pixmap, source); p.drawPixmap(target, pixmap, source);
} }
if(!useCache) { // TODO: does this condition make sense? if(cacheWasDirty) { // TODO: does this condition make sense?
emit refreshBlock(); emit refreshBlock();
} }
} }
@ -219,7 +261,7 @@ void GraphView::paintGraphCache()
#endif #endif
} else { } else {
auto dpr = devicePixelRatioF(); auto dpr = devicePixelRatioF();
pixmap = QPixmap(int(viewport()->width() * dpr), int(viewport()->height() * dpr)); pixmap = QPixmap(getRequiredCacheSize());
pixmap.setDevicePixelRatio(dpr); pixmap.setDevicePixelRatio(dpr);
p.begin(&pixmap); p.begin(&pixmap);
p.setRenderHint(QPainter::Antialiasing); p.setRenderHint(QPainter::Antialiasing);

View File

@ -41,8 +41,6 @@ public:
explicit GraphView(QWidget *parent); explicit GraphView(QWidget *parent);
~GraphView() override; ~GraphView() override;
void paintEvent(QPaintEvent *event) override;
void showBlock(GraphBlock &block); void showBlock(GraphBlock &block);
void showBlock(GraphBlock *block); void showBlock(GraphBlock *block);
@ -51,11 +49,6 @@ public:
QPoint offset = QPoint(0, 0); 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 * @brief keep the current addr of the fcn of Graph
* Everytime overview updates its contents, it compares this value with the one in Graph * Everytime overview updates its contents, it compares this value with the one in Graph
@ -70,6 +63,7 @@ protected:
// Padding inside the block // Padding inside the block
int block_padding = 16; int block_padding = 16;
void setCacheDirty() { cacheDirty = true; }
void addBlock(GraphView::GraphBlock block); void addBlock(GraphView::GraphBlock block);
void setEntry(ut64 e); void setEntry(ut64 e);
@ -93,6 +87,8 @@ protected:
void mouseReleaseEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void center(); void center();
void centerX(); void centerX();
void centerY(); void centerY();
@ -132,6 +128,15 @@ private:
QOpenGLWidget *glWidget; QOpenGLWidget *glWidget;
#endif #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); QPolygonF recalculatePolygon(QPolygonF polygon);
void beginMouseDrag(QMouseEvent *event); void beginMouseDrag(QMouseEvent *event);
}; };

View File

@ -23,6 +23,7 @@ void OverviewView::setData(int baseWidth, int baseHeight,
blocks = baseBlocks; blocks = baseBlocks;
edgeConfigurations = baseEdgeConfigurations; edgeConfigurations = baseEdgeConfigurations;
scaleAndCenter(); scaleAndCenter();
setCacheDirty();
} }
OverviewView::~OverviewView() OverviewView::~OverviewView()
@ -102,7 +103,6 @@ void OverviewView::mousePressEvent(QMouseEvent *event)
qreal x = event->localPos().x() - w / 2; qreal x = event->localPos().x() - w / 2;
qreal y = event->localPos().y() - h / 2; qreal y = event->localPos().y() - h / 2;
rangeRect = QRectF(x, y, w, h); rangeRect = QRectF(x, y, w, h);
useCache = true;
viewport()->update(); viewport()->update();
emit mouseMoved(); emit mouseMoved();
mouseContainsRect(event); mouseContainsRect(event);
@ -122,7 +122,6 @@ void OverviewView::mouseMoveEvent(QMouseEvent *event)
qreal x = event->localPos().x() - initialDiff.x(); qreal x = event->localPos().x() - initialDiff.x();
qreal y = event->localPos().y() - initialDiff.y(); qreal y = event->localPos().y() - initialDiff.y();
rangeRect = QRectF(x, y, rangeRect.width(), rangeRect.height()); rangeRect = QRectF(x, y, rangeRect.width(), rangeRect.height());
useCache = true;
viewport()->update(); viewport()->update();
emit mouseMoved(); emit mouseMoved();
} }

View File

@ -68,6 +68,11 @@ protected:
*/ */
void wheelEvent(QWheelEvent *event) override; void wheelEvent(QWheelEvent *event) override;
/**
* @brief override the paintEvent to draw the rect on Overview
*/
void paintEvent(QPaintEvent *event) override;
private: private:
/** /**
* @brief this will be handled in mouse events to move the rect properly * @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, virtual GraphView::EdgeConfiguration edgeConfiguration(GraphView::GraphBlock &from,
GraphView::GraphBlock *to) override; 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. * @brief if the mouse is in the rect in Overview.
*/ */