From d9d9d22837705de6a2c42ad3f9b23223a2b98fe0 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 11 Oct 2013 18:02:26 -0400 Subject: [PATCH] Implement grouping of calls. Use glPushDebugGroup and glPopDebugGroup to create nested groups of calls. It makes it easy to neatly group related calls (e.g. from nested function calls) into subgroups. --- common/trace_model.hpp | 7 +++ common/trace_parser_flags.cpp | 6 +- gui/apitrace.cpp | 11 ++-- gui/apitrace.h | 1 + gui/apitracecall.cpp | 108 +++++++++++++++++++++++++++------- gui/apitracecall.h | 29 +++++++-- gui/apitracemodel.cpp | 69 +++++++++++----------- gui/mainwindow.cpp | 3 +- gui/traceloader.cpp | 89 ++++++++++++++++++++++------ gui/traceloader.h | 1 + 10 files changed, 237 insertions(+), 87 deletions(-) diff --git a/common/trace_model.hpp b/common/trace_model.hpp index ba7c845..2ce1339 100644 --- a/common/trace_model.hpp +++ b/common/trace_model.hpp @@ -515,6 +515,13 @@ enum { * Whether this call is verbose (i.e., not usually interesting). */ CALL_FLAG_VERBOSE = (1 << 7), + + /** + * String markers. + */ + CALL_FLAG_MARKER = (1 << 8), + CALL_FLAG_MARKER_PUSH = (1 << 9), + CALL_FLAG_MARKER_POP = (1 << 10), }; diff --git a/common/trace_parser_flags.cpp b/common/trace_parser_flags.cpp index 0a63649..2cf55a2 100644 --- a/common/trace_parser_flags.cpp +++ b/common/trace_parser_flags.cpp @@ -519,9 +519,9 @@ callFlagTable[] = { { "glMultiModeDrawElementsIBM", CALL_FLAG_RENDER }, { "glObjectLabel", CALL_FLAG_NO_SIDE_EFFECTS }, { "glObjectPtrLabel", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glPopDebugGroup", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glPushDebugGroup", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glStringMarkerGREMEDY", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glPopDebugGroup", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, + { "glPushDebugGroup", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "glStringMarkerGREMEDY", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, { "glXGetClientString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "glXGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "glXGetCurrentDisplay", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp index 671fc68..db57417 100644 --- a/gui/apitrace.cpp +++ b/gui/apitrace.cpp @@ -19,9 +19,9 @@ ApiTrace::ApiTrace() connect(m_loader, SIGNAL(framesLoaded(const QList)), this, SLOT(addFrames(const QList))); connect(m_loader, - SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector,quint64)), + SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector, QVector,quint64)), this, - SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector,quint64))); + SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector,QVector,quint64))); connect(m_loader, SIGNAL(guessedApi(int)), this, SLOT(guessedApi(int))); connect(m_loader, SIGNAL(finishedParsing()), @@ -107,7 +107,7 @@ int ApiTrace::numCallsInFrame(int idx) const { const ApiTraceFrame *frame = frameAt(idx); if (frame) { - return frame->numChildren(); + return frame->numTotalCalls(); } else { return 0; } @@ -263,6 +263,7 @@ void ApiTrace::finishedParsing() } void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame, + const QVector &topLevelItems, const QVector &calls, quint64 binaryDataSize) { @@ -270,7 +271,7 @@ void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame, if (!frame->isLoaded()) { emit beginLoadingFrame(frame, calls.size()); - frame->setCalls(calls, binaryDataSize); + frame->setCalls(topLevelItems, calls, binaryDataSize); emit endLoadingFrame(frame); m_loadingFrames.remove(frame); } @@ -444,7 +445,7 @@ int ApiTrace::callInFrame(int callIdx) const for (int frameIdx = 0; frameIdx < m_frames.size(); ++frameIdx) { const ApiTraceFrame *frame = m_frames[frameIdx]; unsigned numCallsInFrame = frame->isLoaded() - ? frame->numChildren() + ? frame->numTotalCalls() : frame->numChildrenToLoad(); unsigned firstCall = numCalls; unsigned endCall = numCalls + numCallsInFrame; diff --git a/gui/apitrace.h b/gui/apitrace.h index 04e295c..a7b72d8 100644 --- a/gui/apitrace.h +++ b/gui/apitrace.h @@ -131,6 +131,7 @@ private slots: void guessedApi(int api); void finishedParsing(); void loaderFrameLoaded(ApiTraceFrame *frame, + const QVector &topLevelItems, const QVector &calls, quint64 binaryDataSize); void loaderSearchResult(const ApiTrace::SearchRequest &request, diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp index 0175bff..7987635 100644 --- a/gui/apitracecall.cpp +++ b/gui/apitracecall.cpp @@ -648,7 +648,31 @@ ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame, TraceLoader *loader, const trace::Call *call) : ApiTraceEvent(ApiTraceEvent::Call), - m_parentFrame(parentFrame) + m_parentFrame(parentFrame), + m_parentCall(0) +{ + loadData(loader, call); +} + +ApiTraceCall::ApiTraceCall(ApiTraceCall *parentCall, + TraceLoader *loader, + const trace::Call *call) + : ApiTraceEvent(ApiTraceEvent::Call), + m_parentFrame(parentCall->parentFrame()), + m_parentCall(parentCall) +{ + loadData(loader, call); +} + + +ApiTraceCall::~ApiTraceCall() +{ +} + + +void +ApiTraceCall::loadData(TraceLoader *loader, + const trace::Call *call) { m_index = call->no; @@ -712,10 +736,46 @@ ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame, } } -ApiTraceCall::~ApiTraceCall() +ApiTraceCall * +ApiTraceCall::parentCall() const +{ + return m_parentCall; +} + + +ApiTraceEvent * +ApiTraceCall::parentEvent() const +{ + if (m_parentCall) + return m_parentCall; + else + return m_parentFrame; +} + +QVector +ApiTraceCall::children() const { + return m_children; } +void +ApiTraceCall::addChild(ApiTraceCall *call) +{ + m_children.append(call); +} + + +int +ApiTraceCall::callIndex(ApiTraceCall *call) const +{ + return m_children.indexOf(call); +} + +void +ApiTraceCall::finishedAddingChildren() +{ + m_children.squeeze(); +} bool ApiTraceCall::hasError() const { @@ -820,6 +880,15 @@ QVector ApiTraceCall::arguments() const return m_editedValues; } +ApiTraceEvent * +ApiTraceCall::eventAtRow(int row) const +{ + if (row < m_children.count()) + return m_children.value(row); + else + return NULL; +} + QVariant ApiTraceCall::returnValue() const { return m_returnValue; @@ -1011,7 +1080,7 @@ QString ApiTraceCall::searchText() const int ApiTraceCall::numChildren() const { - return 0; + return m_children.count(); } bool ApiTraceCall::contains(const QString &str, @@ -1074,22 +1143,17 @@ QStaticText ApiTraceFrame::staticText() const int ApiTraceFrame::numChildren() const { - return m_calls.count(); + return m_children.count(); } -ApiTrace * ApiTraceFrame::parentTrace() const +int ApiTraceFrame::numTotalCalls() const { - return m_parentTrace; + return m_calls.count(); } -void ApiTraceFrame::addCall(ApiTraceCall *call) +ApiTrace * ApiTraceFrame::parentTrace() const { - m_calls.append(call); - if (call->hasBinaryData()) { - QByteArray data = - call->arguments()[call->binaryDataIndex()].toByteArray(); - m_binaryDataSize += data.size(); - } + return m_parentTrace; } QVector ApiTraceFrame::calls() const @@ -1097,9 +1161,12 @@ QVector ApiTraceFrame::calls() const return m_calls; } -ApiTraceCall * ApiTraceFrame::call(int idx) const +ApiTraceEvent * ApiTraceFrame::eventAtRow(int row) const { - return m_calls.value(idx); + if (row < m_children.count()) + return m_children.value(row); + else + return NULL; } @@ -1116,7 +1183,7 @@ ApiTraceCall * ApiTraceFrame::callWithIndex(int index) const int ApiTraceFrame::callIndex(ApiTraceCall *call) const { - return m_calls.indexOf(call); + return m_children.indexOf(call); } bool ApiTraceFrame::isEmpty() const @@ -1133,9 +1200,11 @@ int ApiTraceFrame::binaryDataSize() const return m_binaryDataSize; } -void ApiTraceFrame::setCalls(const QVector &calls, +void ApiTraceFrame::setCalls(const QVector &children, + const QVector &calls, quint64 binaryDataSize) { + m_children = children; m_calls = calls; m_binaryDataSize = binaryDataSize; m_loaded = true; @@ -1148,11 +1217,6 @@ bool ApiTraceFrame::isLoaded() const return m_loaded; } -void ApiTraceFrame::setLoaded(bool l) -{ - m_loaded = l; -} - void ApiTraceFrame::setNumChildren(int num) { m_callsToLoad = num; diff --git a/gui/apitracecall.h b/gui/apitracecall.h index 8004ced..15bc627 100644 --- a/gui/apitracecall.h +++ b/gui/apitracecall.h @@ -203,6 +203,8 @@ private: QUrl m_helpUrl; }; +class ApiTraceCall; + class ApiTraceEvent { public: @@ -220,6 +222,8 @@ public: virtual QStaticText staticText() const = 0; virtual int numChildren() const = 0; + virtual int callIndex(ApiTraceCall *call) const = 0; + virtual ApiTraceEvent *eventAtRow(int row) const = 0; QVariantMap stateParameters() const; ApiTraceState *state() const; @@ -242,6 +246,8 @@ Q_DECLARE_METATYPE(ApiTraceEvent*); class ApiTraceCall : public ApiTraceEvent { public: + ApiTraceCall(ApiTraceCall *parentCall, TraceLoader *loader, + const trace::Call *tcall); ApiTraceCall(ApiTraceFrame *parentFrame, TraceLoader *loader, const trace::Call *tcall); ~ApiTraceCall(); @@ -257,6 +263,15 @@ public: ApiTraceFrame *parentFrame()const; void setParentFrame(ApiTraceFrame *frame); + int callIndex(ApiTraceCall *call) const; + + ApiTraceEvent *parentEvent() const; + ApiTraceCall *parentCall() const; + QVector children() const; + ApiTraceEvent *eventAtRow(int row) const; + void addChild(ApiTraceCall *call); + void finishedAddingChildren(); + bool hasError() const; QString error() const; void setError(const QString &msg); @@ -282,6 +297,9 @@ public: QString backtrace() const; void setBacktrace(QString backtrace); +private: + void loadData(TraceLoader *loader, + const trace::Call *tcall); private: int m_index; ApiTraceCallSignature *m_signature; @@ -289,6 +307,8 @@ private: QVariant m_returnValue; trace::CallFlags m_flags; ApiTraceFrame *m_parentFrame; + ApiTraceCall *m_parentCall; + QVector m_children; QVector m_editedValues; @@ -316,14 +336,15 @@ public: void setNumChildren(int num); int numChildren() const; int numChildrenToLoad() const; + int numTotalCalls() const; QStaticText staticText() const; + ApiTraceEvent *eventAtRow(int row) const; int callIndex(ApiTraceCall *call) const; - ApiTraceCall *call(int idx) const; ApiTraceCall *callWithIndex(int index) const; - void addCall(ApiTraceCall *call); QVector calls() const; - void setCalls(const QVector &calls, + void setCalls(const QVector &topLevelCalls, + const QVector &allCalls, quint64 binaryDataSize); ApiTraceCall *findNextCall(ApiTraceCall *from, @@ -337,7 +358,6 @@ public: int binaryDataSize() const; bool isLoaded() const; - void setLoaded(bool l); void setLastCallIndex(unsigned index); unsigned lastCallIndex() const; @@ -348,6 +368,7 @@ public: private: ApiTrace *m_parentTrace; quint64 m_binaryDataSize; + QVector m_children; QVector m_calls; bool m_loaded; unsigned m_callsToLoad; diff --git a/gui/apitracemodel.cpp b/gui/apitracemodel.cpp index 0863c1b..fb33967 100644 --- a/gui/apitracemodel.cpp +++ b/gui/apitracemodel.cpp @@ -92,7 +92,7 @@ QVariant ApiTraceModel::data(const QModelIndex &index, int role) const } int numCalls = frame->isLoaded() - ? frame->numChildren() + ? frame->numTotalCalls() : frame->numChildrenToLoad(); return tr(htmlTempl) @@ -141,18 +141,16 @@ QModelIndex ApiTraceModel::index(int row, int column, if ((parent.isValid() && parent.column() != 0) || column != 0) return QModelIndex(); - ApiTraceEvent *event = item(parent); - if (event) { - if (event->type() != ApiTraceEvent::Frame) { - qDebug()<<"got a valid parent but it's not a frame "<type(); + //qDebug()<<"At row = "<eventAtRow(row); + if (event) { + Q_ASSERT(event->type() == ApiTraceEvent::Call); + return createIndex(row, column, event); + } else { return QModelIndex(); } - ApiTraceFrame *frame = static_cast(event); - ApiTraceCall *call = frame->call(row); - if (call) - return createIndex(row, column, call); - else - return QModelIndex(); } else { ApiTraceFrame *frame = m_trace->frameAt(row); if (frame) @@ -167,11 +165,16 @@ bool ApiTraceModel::hasChildren(const QModelIndex &parent) const { if (parent.isValid()) { ApiTraceEvent *event = item(parent); - if (event && event->type() == ApiTraceEvent::Frame) { + if (!event) + return false; + if (event->type() == ApiTraceEvent::Frame) { ApiTraceFrame *frame = static_cast(event); return !frame->isEmpty(); - } else - return false; + } else { + Q_ASSERT(event->type() == ApiTraceEvent::Call); + ApiTraceCall *call = static_cast(event); + return call->numChildren() != 0; + } } else { return (rowCount() > 0); } @@ -183,11 +186,19 @@ QModelIndex ApiTraceModel::parent(const QModelIndex &index) const return QModelIndex(); ApiTraceEvent *event = item(index); - if (event && event->type() == ApiTraceEvent::Call) { + + if (event->type() == ApiTraceEvent::Call) { ApiTraceCall *call = static_cast(event); - Q_ASSERT(call->parentFrame()); - return createIndex(call->parentFrame()->number, - 0, call->parentFrame()); + + if (call->parentCall()) { + ApiTraceCall *parentCall = call->parentCall(); + ApiTraceEvent *topEvent = parentCall->parentEvent(); + return createIndex(topEvent->callIndex(parentCall), 0, parentCall); + } else { + Q_ASSERT(call->parentFrame()); + return createIndex(call->parentFrame()->number, + 0, call->parentFrame()); + } } return QModelIndex(); } @@ -198,14 +209,10 @@ int ApiTraceModel::rowCount(const QModelIndex &parent) const return m_trace->numFrames(); ApiTraceEvent *event = item(parent); - if (!event || event->type() == ApiTraceEvent::Call) + if (!event) return 0; - ApiTraceFrame *frame = static_cast(event); - if (frame) - return frame->numChildren(); - - return 0; + return event->numChildren(); } int ApiTraceModel::columnCount(const QModelIndex &parent) const @@ -288,9 +295,7 @@ void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event) if (event->type() == ApiTraceEvent::Call) { ApiTraceCall *call = static_cast(event); - ApiTraceFrame *frame = call->parentFrame(); - int row = frame->callIndex(call); - QModelIndex index = createIndex(row, 0, call); + QModelIndex index = indexForCall(call); emit dataChanged(index, index); } else if (event->type() == ApiTraceEvent::Frame) { ApiTraceFrame *frame = static_cast(event); @@ -307,10 +312,10 @@ QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const return QModelIndex(); } - ApiTraceFrame *frame = call->parentFrame(); - Q_ASSERT(frame); + ApiTraceEvent *parentEvent = call->parentEvent(); + Q_ASSERT(parentEvent); - int row = frame->callIndex(call); + int row = parentEvent->callIndex(call); if (row < 0) { qDebug() << "Couldn't find call num "<index()<<" inside parent!"; return QModelIndex(); @@ -342,9 +347,7 @@ void ApiTraceModel::callChanged(ApiTraceCall *call) if (trace->needsSaving()) trace->save(); - ApiTraceFrame *frame = call->parentFrame(); - int row = frame->callIndex(call); - QModelIndex index = createIndex(row, 0, call); + QModelIndex index = indexForCall(call); emit dataChanged(index, index); } diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 3278330..3accf6e 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -1265,7 +1265,8 @@ void MainWindow::saveSelectedSurface() imageIndex = tr("_call_%1") .arg(selectedCall()->index()); } else if (selectedFrame()) { - ApiTraceCall *firstCall = selectedFrame()->call(0); + ApiTraceCall *firstCall = + static_cast(selectedFrame()->eventAtRow(0)); if (firstCall) { imageIndex = tr("_frame_%1") .arg(firstCall->index()); diff --git a/gui/traceloader.cpp b/gui/traceloader.cpp index 6110c59..d09f0fe 100644 --- a/gui/traceloader.cpp +++ b/gui/traceloader.cpp @@ -3,6 +3,7 @@ #include "apitrace.h" #include #include +#include #define FRAMES_TO_CACHE 100 @@ -10,9 +11,15 @@ static ApiTraceCall * apiCallFromTraceCall(const trace::Call *call, const QHash &helpHash, ApiTraceFrame *frame, + ApiTraceCall *parentCall, TraceLoader *loader) { - ApiTraceCall *apiCall = new ApiTraceCall(frame, loader, call); + ApiTraceCall *apiCall; + + if (parentCall) + apiCall = new ApiTraceCall(parentCall, loader, call); + else + apiCall = new ApiTraceCall(frame, loader, call); apiCall->setHelpUrl(helpHash.value(apiCall->name())); @@ -168,7 +175,9 @@ void TraceLoader::parseTrace() QList frames; ApiTraceFrame *currentFrame = 0; int frameCount = 0; - QVector calls; + QStack groups; + QVector topLevelItems; + QVector allCalls; quint64 binaryDataSize = 0; int lastPercentReport = 0; @@ -182,17 +191,36 @@ void TraceLoader::parseTrace() ++frameCount; } ApiTraceCall *apiCall = - apiCallFromTraceCall(call, m_helpHash, currentFrame, this); - calls.append(apiCall); + apiCallFromTraceCall(call, m_helpHash, currentFrame, groups.isEmpty() ? 0 : groups.top(), this); + allCalls.append(apiCall); + if (groups.count() == 0) { + topLevelItems.append(apiCall); + } + if (call->flags & trace::CALL_FLAG_MARKER_PUSH) { + groups.push(apiCall); + } else if (call->flags & trace::CALL_FLAG_MARKER_POP) { + groups.top()->finishedAddingChildren(); + groups.pop(); + } + if (!groups.isEmpty()) { + groups.top()->addChild(apiCall); + } if (apiCall->hasBinaryData()) { QByteArray data = - apiCall->arguments()[apiCall->binaryDataIndex()].toByteArray(); + apiCall->arguments()[apiCall->binaryDataIndex()].toByteArray(); binaryDataSize += data.size(); } if (call->flags & trace::CALL_FLAG_END_FRAME) { - calls.squeeze(); - currentFrame->setCalls(calls, binaryDataSize); - calls.clear(); + allCalls.squeeze(); + topLevelItems.squeeze(); + if (topLevelItems.count() == allCalls.count()) { + currentFrame->setCalls(allCalls, allCalls, binaryDataSize); + } else { + currentFrame->setCalls(topLevelItems, allCalls, binaryDataSize); + } + allCalls.clear(); + groups.clear(); + topLevelItems.clear(); frames.append(currentFrame); currentFrame = 0; binaryDataSize = 0; @@ -213,8 +241,12 @@ void TraceLoader::parseTrace() // it's just a bunch of Delete calls for every object // after the last SwapBuffers if (currentFrame) { - calls.squeeze(); - currentFrame->setCalls(calls, binaryDataSize); + allCalls.squeeze(); + if (topLevelItems.count() == allCalls.count()) { + currentFrame->setCalls(allCalls, allCalls, binaryDataSize); + } else { + currentFrame->setCalls(topLevelItems, allCalls, binaryDataSize); + } frames.append(currentFrame); currentFrame = 0; } @@ -378,7 +410,7 @@ bool TraceLoader::callContains(trace::Call *call, * FIXME: do string comparison directly on trace::Call */ ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash, - 0, this); + 0, 0, this); bool result = apiCall->contains(str, sensitivity); delete apiCall; return result; @@ -399,7 +431,9 @@ TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame) if (numOfCalls) { quint64 binaryDataSize = 0; - QVector calls(numOfCalls); + QStack groups; + QVector topLevelItems; + QVector allCalls(numOfCalls); const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx]; m_parser.setBookmark(frameBookmark.start); @@ -409,10 +443,22 @@ TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame) while ((call = m_parser.parse_call())) { ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash, - currentFrame, this); + currentFrame, groups.isEmpty() ? 0 : groups.top(), this); Q_ASSERT(apiCall); Q_ASSERT(parsedCalls < calls.size()); - calls[parsedCalls++] = apiCall; + allCalls[parsedCalls++] = apiCall; + if (groups.count() == 0) { + topLevelItems.append(apiCall); + } + if (!groups.isEmpty()) { + groups.top()->addChild(apiCall); + } + if (call->flags & trace::CALL_FLAG_MARKER_PUSH) { + groups.push(apiCall); + } else if (call->flags & trace::CALL_FLAG_MARKER_POP) { + groups.top()->finishedAddingChildren(); + groups.pop(); + } if (apiCall->hasBinaryData()) { QByteArray data = apiCall->arguments()[ @@ -431,13 +477,18 @@ TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame) // threads cross the frame boundary Q_ASSERT(parsedCalls <= numOfCalls); Q_ASSERT(parsedCalls <= calls.size()); - calls.resize(parsedCalls); - calls.squeeze(); + allCalls.resize(parsedCalls); + allCalls.squeeze(); Q_ASSERT(parsedCalls <= currentFrame->numChildrenToLoad()); - emit frameContentsLoaded(currentFrame, - calls, binaryDataSize); - return calls; + if (topLevelItems.count() == allCalls.count()) { + emit frameContentsLoaded(currentFrame, allCalls, + allCalls, binaryDataSize); + } else { + emit frameContentsLoaded(currentFrame, topLevelItems, + allCalls, binaryDataSize); + } + return allCalls; } } return QVector(); diff --git a/gui/traceloader.h b/gui/traceloader.h index 0954078..1725adb 100644 --- a/gui/traceloader.h +++ b/gui/traceloader.h @@ -40,6 +40,7 @@ signals: void framesLoaded(const QList &frames); void frameContentsLoaded(ApiTraceFrame *frame, + const QVector &topLevelItems, const QVector &calls, quint64 binaryDataSize); -- 2.43.0