Skip to content

Commit 27a9266

Browse files
committed
GUI: do not render instructions that are not visible on the screen + remove timer
x64dbg#1819
1 parent 4eb0fb6 commit 27a9266

File tree

2 files changed

+60
-96
lines changed

2 files changed

+60
-96
lines changed

src/gui/Src/Gui/DisassemblerGraphView.cpp

Lines changed: 60 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget* parent)
3333

3434
//Start disassembly view at the entry point of the binary
3535
this->function = 0;
36-
this->update_id = 0;
3736
this->ready = false;
3837
this->desired_pos = nullptr;
3938
this->highlight_token = nullptr;
@@ -46,13 +45,6 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget* parent)
4645
this->blocks.clear();
4746
this->saveGraph = false;
4847

49-
//Create timer to automatically refresh view when it needs to be updated
50-
this->updateTimer = new QTimer();
51-
this->updateTimer->setInterval(100);
52-
this->updateTimer->setSingleShot(false);
53-
connect(this->updateTimer, SIGNAL(timeout()), this, SLOT(updateTimerEvent()));
54-
this->updateTimer->start();
55-
5648
this->initFont();
5749

5850
//Initialize scroll bars
@@ -214,35 +206,38 @@ void DisassemblerGraphView::paintNormal(QPainter & p, QRect & viewportRect, int
214206
int y = block.y + (2 * this->charWidth) + (int(block.block.header_text.lines.size()) * this->charHeight);
215207
for(Instr & instr : block.block.instrs)
216208
{
217-
auto selected = instr.addr == this->cur_instr;
218-
auto traceCount = dbgfunctions->GetTraceRecordHitCount(instr.addr);
219-
220-
if(selected && traceCount)
221-
{
222-
p.fillRect(QRect(block.x + this->charWidth + 3, y, block.width - (10 + 2 * this->charWidth),
223-
int(instr.text.lines.size()) * this->charHeight), disassemblyTracedSelectionColor);
224-
}
225-
else if(selected)
226-
{
227-
p.fillRect(QRect(block.x + this->charWidth + 3, y, block.width - (10 + 2 * this->charWidth),
228-
int(instr.text.lines.size()) * this->charHeight), disassemblySelectionColor);
229-
}
230-
else if(traceCount)
209+
if(y > viewportRect.y() - int(instr.text.lines.size()) * this->charHeight && y < viewportRect.bottom())
231210
{
232-
// Color depending on how often a sequence of code is executed
233-
int exponent = 1;
234-
while(traceCount >>= 1) //log2(traceCount)
235-
exponent++;
236-
int colorDiff = (exponent * exponent) / 2;
237-
238-
// If the user has a light trace background color, substract
239-
if(disassemblyTracedColor.blue() > 160)
240-
colorDiff *= -1;
241-
242-
p.fillRect(QRect(block.x + this->charWidth + 3, y, block.width - (10 + 2 * this->charWidth), int(instr.text.lines.size()) * this->charHeight),
243-
QColor(disassemblyTracedColor.red(),
244-
disassemblyTracedColor.green(),
245-
std::max(0, std::min(256, disassemblyTracedColor.blue() + colorDiff))));
211+
auto selected = instr.addr == this->cur_instr;
212+
auto traceCount = dbgfunctions->GetTraceRecordHitCount(instr.addr);
213+
214+
if(selected && traceCount)
215+
{
216+
p.fillRect(QRect(block.x + this->charWidth + 3, y, block.width - (10 + 2 * this->charWidth),
217+
int(instr.text.lines.size()) * this->charHeight), disassemblyTracedSelectionColor);
218+
}
219+
else if(selected)
220+
{
221+
p.fillRect(QRect(block.x + this->charWidth + 3, y, block.width - (10 + 2 * this->charWidth),
222+
int(instr.text.lines.size()) * this->charHeight), disassemblySelectionColor);
223+
}
224+
else if(traceCount)
225+
{
226+
// Color depending on how often a sequence of code is executed
227+
int exponent = 1;
228+
while(traceCount >>= 1) //log2(traceCount)
229+
exponent++;
230+
int colorDiff = (exponent * exponent) / 2;
231+
232+
// If the user has a light trace background color, substract
233+
if(disassemblyTracedColor.blue() > 160)
234+
colorDiff *= -1;
235+
236+
p.fillRect(QRect(block.x + this->charWidth + 3, y, block.width - (10 + 2 * this->charWidth), int(instr.text.lines.size()) * this->charHeight),
237+
QColor(disassemblyTracedColor.red(),
238+
disassemblyTracedColor.green(),
239+
std::max(0, std::min(256, disassemblyTracedColor.blue() + colorDiff))));
240+
}
246241
}
247242
y += int(instr.text.lines.size()) * this->charHeight;
248243
}
@@ -253,43 +248,49 @@ void DisassemblerGraphView::paintNormal(QPainter & p, QRect & viewportRect, int
253248
auto y = block.y + (2 * this->charWidth);
254249
for(auto & line : block.block.header_text.lines)
255250
{
256-
RichTextPainter::paintRichText(&p, x, y, block.width, this->charHeight, 0, line, mFontMetrics);
251+
if(y > viewportRect.y() - this->charHeight && y < viewportRect.bottom())
252+
{
253+
RichTextPainter::paintRichText(&p, x, y, block.width, this->charHeight, 0, line, mFontMetrics);
254+
}
257255
y += this->charHeight;
258256
}
259257

260258
for(Instr & instr : block.block.instrs)
261259
{
262260
for(auto & line : instr.text.lines)
263261
{
264-
int rectSize = qRound(this->charWidth);
265-
if(rectSize % 2)
266-
rectSize++;
262+
if(y > viewportRect.y() - this->charHeight && y < viewportRect.bottom())
263+
{
264+
int rectSize = qRound(this->charWidth);
265+
if(rectSize % 2)
266+
rectSize++;
267267

268-
// Assume charWidth <= charHeight
269-
QRectF bpRect(x - rectSize / 3.0, y + (this->charHeight - rectSize) / 2.0, rectSize, rectSize);
268+
// Assume charWidth <= charHeight
269+
QRectF bpRect(x - rectSize / 3.0, y + (this->charHeight - rectSize) / 2.0, rectSize, rectSize);
270270

271-
bool isbp = DbgGetBpxTypeAt(instr.addr) != bp_none;
272-
bool isbpdisabled = DbgIsBpDisabled(instr.addr);
273-
bool iscip = instr.addr == mCip;
271+
bool isbp = DbgGetBpxTypeAt(instr.addr) != bp_none;
272+
bool isbpdisabled = DbgIsBpDisabled(instr.addr);
273+
bool iscip = instr.addr == mCip;
274274

275-
if(isbp || isbpdisabled)
276-
{
277-
if(iscip)
275+
if(isbp || isbpdisabled)
278276
{
279-
// Left half is cip
280-
bpRect.setWidth(bpRect.width() / 2);
281-
p.fillRect(bpRect, mCipColor);
277+
if(iscip)
278+
{
279+
// Left half is cip
280+
bpRect.setWidth(bpRect.width() / 2);
281+
p.fillRect(bpRect, mCipColor);
282+
283+
// Right half is breakpoint
284+
bpRect.translate(bpRect.width(), 0);
285+
}
282286

283-
// Right half is breakpoint
284-
bpRect.translate(bpRect.width(), 0);
287+
p.fillRect(bpRect, isbp ? mBreakpointColor : mDisabledBreakpointColor);
285288
}
289+
else if(iscip)
290+
p.fillRect(bpRect, mCipColor);
286291

287-
p.fillRect(bpRect, isbp ? mBreakpointColor : mDisabledBreakpointColor);
292+
RichTextPainter::paintRichText(&p, x + this->charWidth, y, block.width - this->charWidth, this->charHeight, 0, line, mFontMetrics);
288293
}
289-
else if(iscip)
290-
p.fillRect(bpRect, mCipColor);
291-
292-
RichTextPainter::paintRichText(&p, x + this->charWidth, y, block.width - this->charWidth, this->charHeight, 0, line, mFontMetrics);
293294
y += this->charHeight;
294295
}
295296
}
@@ -1386,43 +1387,11 @@ void DisassemblerGraphView::renderFunction(Function & func)
13861387
this->verticalScrollBar()->setValue(0);
13871388
}
13881389

1389-
this->analysis.update_id = this->update_id = func.update_id;
13901390
this->ready = true;
13911391
this->viewport()->update(0, 0, areaSize.width(), areaSize.height());
13921392
//puts("Finished");
13931393
}
13941394

1395-
void DisassemblerGraphView::updateTimerEvent()
1396-
{
1397-
auto status = this->analysis.status;
1398-
if(status != this->status)
1399-
{
1400-
this->status = status;
1401-
this->viewport()->update();
1402-
}
1403-
1404-
if(this->function == 0)
1405-
return;
1406-
1407-
if(this->ready)
1408-
{
1409-
//Check for updated code
1410-
if(this->update_id != this->analysis.update_id)
1411-
this->renderFunction(this->analysis.functions[this->function]);
1412-
return;
1413-
}
1414-
1415-
//View not up to date, check to see if active function is ready
1416-
if(this->analysis.functions.count(this->function))
1417-
{
1418-
if(this->analysis.functions[this->function].ready)
1419-
{
1420-
//Active function now ready, generate graph
1421-
this->renderFunction(this->analysis.functions[this->function]);
1422-
}
1423-
}
1424-
}
1425-
14261395
void DisassemblerGraphView::show_cur_instr(bool force)
14271396
{
14281397
for(auto & blockIt : this->blocks)
@@ -1527,14 +1496,12 @@ void DisassemblerGraphView::loadCurrentGraph()
15271496
{
15281497
bool showGraphRva = ConfigBool("Gui", "ShowGraphRva");
15291498
Analysis anal;
1530-
anal.update_id = this->update_id + 1;
15311499
anal.entry = currentGraph.entryPoint;
15321500
anal.ready = true;
15331501
{
15341502
Function func;
15351503
func.entry = currentGraph.entryPoint;
15361504
func.ready = true;
1537-
func.update_id = anal.update_id;
15381505
{
15391506
for(const auto & nodeIt : currentGraph.nodes)
15401507
{
@@ -1629,6 +1596,7 @@ void DisassemblerGraphView::loadCurrentGraph()
16291596
}
16301597
this->analysis = anal;
16311598
this->function = this->analysis.entry;
1599+
this->renderFunction(this->analysis.functions[this->function]);
16321600
}
16331601

16341602
void DisassemblerGraphView::loadGraphSlot(BridgeCFGraphList* graphList, duint addr)

src/gui/Src/Gui/DisassemblerGraphView.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ class DisassemblerGraphView : public QAbstractScrollArea, public ActionHelper<Di
171171
{
172172
bool ready;
173173
duint entry;
174-
duint update_id;
175174
std::vector<Block> blocks;
176175
};
177176

@@ -180,7 +179,6 @@ class DisassemblerGraphView : public QAbstractScrollArea, public ActionHelper<Di
180179
duint entry = 0;
181180
std::unordered_map<duint, Function> functions;
182181
bool ready = false;
183-
duint update_id = 0;
184182
QString status = "Analyzing...";
185183

186184
bool find_instr(duint addr, duint & func, duint & instr)
@@ -251,7 +249,6 @@ class DisassemblerGraphView : public QAbstractScrollArea, public ActionHelper<Di
251249
void displaySnowmanWidget();
252250

253251
public slots:
254-
void updateTimerEvent();
255252
void loadGraphSlot(BridgeCFGraphList* graph, duint addr);
256253
void graphAtSlot(duint addr);
257254
void updateGraphSlot();
@@ -296,7 +293,6 @@ public slots:
296293
duint cur_instr;
297294
int scroll_base_x;
298295
int scroll_base_y;
299-
duint update_id;
300296
bool scroll_mode;
301297
bool ready;
302298
int* desired_pos;

0 commit comments

Comments
 (0)