summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gui/apitrace.cpp101
-rw-r--r--gui/apitrace.h32
-rw-r--r--gui/apitracecall.cpp52
-rw-r--r--gui/apitracecall.h11
-rw-r--r--gui/main.cpp8
-rw-r--r--gui/mainwindow.cpp197
-rw-r--r--gui/mainwindow.h12
-rw-r--r--gui/traceloader.cpp167
-rw-r--r--gui/traceloader.h18
9 files changed, 452 insertions, 146 deletions
diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp
index 958009b7..bff1686a 100644
--- a/gui/apitrace.cpp
+++ b/gui/apitrace.cpp
@@ -19,10 +19,21 @@ ApiTrace::ApiTrace()
m_loader, SLOT(loadFrame(ApiTraceFrame*)));
connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
- connect(m_loader, SIGNAL(frameLoaded(ApiTraceFrame*)),
- this, SLOT(frameLoadFinished(ApiTraceFrame*)));
+ connect(m_loader,
+ SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)),
+ this,
+ SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)));
connect(m_loader, SIGNAL(finishedParsing()),
this, SLOT(finishedParsing()));
+ connect(this, SIGNAL(loaderSearchNext(int,QString,Qt::CaseSensitivity)),
+ m_loader, SLOT(searchNext(int,QString,Qt::CaseSensitivity)));
+ connect(this, SIGNAL(loaderSearchPrev(int,QString,Qt::CaseSensitivity)),
+ m_loader, SLOT(searchPrev(int,QString,Qt::CaseSensitivity)));
+ connect(m_loader,
+ SIGNAL(searchResult(ApiTrace::SearchResult,ApiTraceCall*)),
+ this,
+ SLOT(loaderSearchResult(ApiTrace::SearchResult,ApiTraceCall*)));
+
connect(m_loader, SIGNAL(startedParsing()),
this, SIGNAL(startedLoadingTrace()));
@@ -306,7 +317,6 @@ bool ApiTrace::hasErrors() const
void ApiTrace::loadFrame(ApiTraceFrame *frame)
{
Q_ASSERT(!frame->loaded());
- emit beginLoadingFrame(frame, frame->numChildrenToLoad());
emit requestFrame(frame);
}
@@ -318,9 +328,92 @@ void ApiTrace::finishedParsing()
}
}
-void ApiTrace::frameLoadFinished(ApiTraceFrame *frame)
+void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
+ const QVector<ApiTraceCall*> &calls,
+ quint64 binaryDataSize)
{
+ Q_ASSERT(frame->numChildrenToLoad() == calls.size());
+ emit beginLoadingFrame(frame, calls.size());
+ frame->setCalls(calls, binaryDataSize);
emit endLoadingFrame(frame);
}
+void ApiTrace::findNext(ApiTraceFrame *frame,
+ ApiTraceCall *from,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity)
+{
+ ApiTraceCall *foundCall = 0;
+ int frameIdx = m_frames.indexOf(frame);
+
+ if (frame->loaded()) {
+ foundCall = frame->findNextCall(from, str, sensitivity);
+ if (foundCall) {
+ emit findResult(SearchFound, foundCall);
+ return;
+ }
+
+ //if the frame is loaded we already searched it above
+ // so skip it
+ frameIdx += 1;
+ }
+
+ for (int i = frameIdx; i < m_frames.count(); ++i) {
+ ApiTraceFrame *frame = m_frames[i];
+ if (!frame->loaded()) {
+ emit loaderSearchNext(i, str, sensitivity);
+ return;
+ } else {
+ ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
+ if (call) {
+ emit findResult(SearchFound, call);
+ }
+ }
+ }
+ emit findResult(SearchWrapped, 0);
+}
+
+void ApiTrace::findPrev(ApiTraceFrame *frame,
+ ApiTraceCall *from,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity)
+{
+ ApiTraceCall *foundCall = 0;
+ int frameIdx = m_frames.indexOf(frame);
+
+ if (frame->loaded()) {
+ foundCall = frame->findPrevCall(from, str, sensitivity);
+ if (foundCall) {
+ emit findResult(SearchFound, foundCall);
+ return;
+ }
+
+ //if the frame is loaded we already searched it above
+ // so skip it
+ frameIdx -= 1;
+ }
+
+ for (int i = frameIdx; i <= 0; --i) {
+ ApiTraceFrame *frame = m_frames[i];
+ if (!frame->loaded()) {
+ emit loaderSearchPrev(i, str, sensitivity);
+ return;
+ } else {
+ ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
+ if (call) {
+ emit findResult(SearchFound, call);
+ }
+ }
+ }
+ emit findResult(SearchWrapped, 0);
+}
+
+void ApiTrace::loaderSearchResult(ApiTrace::SearchResult result,
+ ApiTraceCall *call)
+{
+ //qDebug()<<"Search result = "<<result
+ // <<", call is = "<<call;
+ emit findResult(result, call);
+}
+
#include "apitrace.moc"
diff --git a/gui/apitrace.h b/gui/apitrace.h
index d01e7a0c..3edffef7 100644
--- a/gui/apitrace.h
+++ b/gui/apitrace.h
@@ -20,6 +20,12 @@ public:
FrameMarker_Finish,
FrameMarker_Clear
};
+ enum SearchResult {
+ SearchNotFound,
+ SearchFound,
+ SearchWrapped
+ };
+
static bool isCallAFrameMarker(const ApiTraceCall *call,
FrameMarker marker);
public:
@@ -59,6 +65,15 @@ public slots:
void setFrameMarker(FrameMarker marker);
void save();
void loadFrame(ApiTraceFrame *frame);
+ void findNext(ApiTraceFrame *frame,
+ ApiTraceCall *call,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity);
+ void findPrev(ApiTraceFrame *frame,
+ ApiTraceCall *call,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity);
+
signals:
void loadTrace(const QString &name);
@@ -71,6 +86,8 @@ signals:
void changed(ApiTraceCall *call);
void startedSaving();
void saved();
+ void findResult(ApiTrace::SearchResult result,
+ ApiTraceCall *call);
void beginAddingFrames(int oldCount, int numAdded);
void endAddingFrames();
@@ -78,11 +95,24 @@ signals:
void beginLoadingFrame(ApiTraceFrame *frame, int numAdded);
void endLoadingFrame(ApiTraceFrame *frame);
+
+signals:
+ void loaderSearchNext(int startFrame,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity);
+ void loaderSearchPrev(int startFrame,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity);
+
private slots:
void addFrames(const QList<ApiTraceFrame*> &frames);
void slotSaved();
void finishedParsing();
- void frameLoadFinished(ApiTraceFrame *frame);
+ void loaderFrameLoaded(ApiTraceFrame *frame,
+ const QVector<ApiTraceCall*> &calls,
+ quint64 binaryDataSize);
+ void loaderSearchResult(ApiTrace::SearchResult result,
+ ApiTraceCall *call);
private:
void detectFrames();
diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp
index 59250452..b26514dd 100644
--- a/gui/apitracecall.cpp
+++ b/gui/apitracecall.cpp
@@ -919,6 +919,14 @@ int ApiTraceCall::numChildren() const
return 0;
}
+bool ApiTraceCall::contains(const QString &str,
+ Qt::CaseSensitivity sensitivity) const
+{
+ QString txt = searchText();
+ return txt.contains(str, sensitivity);
+}
+
+
ApiTraceFrame::ApiTraceFrame(ApiTrace *parentTrace)
: ApiTraceEvent(ApiTraceEvent::Frame),
m_parentTrace(parentTrace),
@@ -1044,3 +1052,47 @@ int ApiTraceFrame::numChildrenToLoad() const
{
return m_callsToLoad;
}
+
+ApiTraceCall *
+ApiTraceFrame::findNextCall(ApiTraceCall *from,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity) const
+{
+ Q_ASSERT(m_loaded);
+
+ int callIndex = 0;
+
+ if (from) {
+ callIndex = m_calls.indexOf(from) + 1;
+ }
+
+ for (int i = callIndex; i < m_calls.count(); ++i) {
+ ApiTraceCall *call = m_calls[i];
+ if (call->contains(str, sensitivity)) {
+ return call;
+ }
+ }
+ return 0;
+}
+
+ApiTraceCall *
+ApiTraceFrame::findPrevCall(ApiTraceCall *from,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity) const
+{
+ Q_ASSERT(m_loaded);
+
+ int callIndex = m_calls.count() - 1;
+
+ if (from) {
+ callIndex = m_calls.indexOf(from) - 1;
+ }
+
+ for (int i = callIndex; i >= 0; --i) {
+ ApiTraceCall *call = m_calls[i];
+ if (call->contains(str, sensitivity)) {
+ return call;
+ }
+ }
+ return 0;
+}
diff --git a/gui/apitracecall.h b/gui/apitracecall.h
index ca4c3543..adfa1b05 100644
--- a/gui/apitracecall.h
+++ b/gui/apitracecall.h
@@ -259,6 +259,9 @@ public:
QVector<QVariant> editedValues() const;
void revert();
+ bool contains(const QString &str,
+ Qt::CaseSensitivity sensitivity) const;
+
ApiTrace *parentTrace() const;
QString toHtml() const;
@@ -306,6 +309,14 @@ public:
void setCalls(const QVector<ApiTraceCall*> &calls,
quint64 binaryDataSize);
+ ApiTraceCall *findNextCall(ApiTraceCall *from,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity) const;
+
+ ApiTraceCall *findPrevCall(ApiTraceCall *from,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity) const;
+
int binaryDataSize() const;
bool loaded() const;
diff --git a/gui/main.cpp b/gui/main.cpp
index 3f8cfa6b..6043b750 100644
--- a/gui/main.cpp
+++ b/gui/main.cpp
@@ -1,5 +1,6 @@
#include "mainwindow.h"
+#include "apitrace.h"
#include "apitracecall.h"
#include <QApplication>
@@ -7,13 +8,20 @@
#include <QVariant>
Q_DECLARE_METATYPE(QList<ApiTraceFrame*>);
+Q_DECLARE_METATYPE(QVector<ApiTraceCall*>);
+Q_DECLARE_METATYPE(Qt::CaseSensitivity);
+Q_DECLARE_METATYPE(ApiTrace::SearchResult);
+
int main(int argc, char **argv)
{
QApplication app(argc, argv);
qRegisterMetaType<QList<ApiTraceFrame*> >();
+ qRegisterMetaType<QVector<ApiTraceCall*> >();
qRegisterMetaType<ApiTraceState>();
+ qRegisterMetaType<Qt::CaseSensitivity>();
+ qRegisterMetaType<ApiTrace::SearchResult>();
MainWindow window;
window.show();
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index e5f6d9b2..9dc530db 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -592,10 +592,10 @@ void MainWindow::showSelectedSurface()
ImageViewer *viewer = new ImageViewer(this);
QString title;
- if (currentCall()) {
+ if (selectedCall()) {
title = tr("QApiTrace - Surface at %1 (%2)")
- .arg(currentCall()->name())
- .arg(currentCall()->index());
+ .arg(selectedCall()->name())
+ .arg(selectedCall()->index());
} else {
title = tr("QApiTrace - Surface Viewer");
}
@@ -692,6 +692,8 @@ void MainWindow::initConnections()
this, SLOT(slotSaved()));
connect(m_trace, SIGNAL(changed(ApiTraceCall*)),
this, SLOT(slotTraceChanged(ApiTraceCall*)));
+ connect(m_trace, SIGNAL(findResult(ApiTrace::SearchResult,ApiTraceCall*)),
+ this, SLOT(slotSearchResult(ApiTrace::SearchResult,ApiTraceCall*)));
connect(m_retracer, SIGNAL(finished(const QString&)),
this, SLOT(replayFinished(const QString&)));
@@ -831,103 +833,31 @@ void MainWindow::slotSearch()
void MainWindow::slotSearchNext(const QString &str,
Qt::CaseSensitivity sensitivity)
{
- QModelIndex index = m_ui.callView->currentIndex();
- ApiTraceEvent *event = 0;
-
-
- if (!index.isValid()) {
- index = m_proxyModel->index(0, 0, QModelIndex());
- if (!index.isValid()) {
- qDebug()<<"no currently valid index";
- m_searchWidget->setFound(false);
- return;
- }
- }
-
- event = index.data(ApiTraceModel::EventRole).value<ApiTraceEvent*>();
- ApiTraceCall *call = 0;
+ ApiTraceCall *call = currentCall();
+ ApiTraceFrame *frame = currentFrame();
- if (event->type() == ApiTraceCall::Call)
- call = static_cast<ApiTraceCall*>(event);
- else {
- Q_ASSERT(event->type() == ApiTraceCall::Frame);
- ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
- call = frame->call(0);
+ Q_ASSERT(call || frame);
+ if (!frame) {
+ frame = call->parentFrame();
}
+ Q_ASSERT(frame);
- if (!call) {
- m_searchWidget->setFound(false);
- return;
- }
- const QVector<ApiTraceCall*> &calls = m_trace->calls();
- int callNum = calls.indexOf(call);
-
- for (int i = callNum + 1; i < calls.count(); ++i) {
- ApiTraceCall *testCall = calls[i];
- QModelIndex index = m_proxyModel->indexForCall(testCall);
- /* if it's not valid it means that the proxy model has already
- * filtered it out */
- if (index.isValid()) {
- QString txt = testCall->searchText();
- if (txt.contains(str, sensitivity)) {
- m_ui.callView->setCurrentIndex(index);
- m_searchWidget->setFound(true);
- return;
- }
- }
- }
- m_searchWidget->setFound(false);
+ m_trace->findNext(frame, call, str, sensitivity);
}
void MainWindow::slotSearchPrev(const QString &str,
Qt::CaseSensitivity sensitivity)
{
- QModelIndex index = m_ui.callView->currentIndex();
- ApiTraceEvent *event = 0;
-
+ ApiTraceCall *call = currentCall();
+ ApiTraceFrame *frame = currentFrame();
- if (!index.isValid()) {
- index = m_proxyModel->index(0, 0, QModelIndex());
- if (!index.isValid()) {
- qDebug()<<"no currently valid index";
- m_searchWidget->setFound(false);
- return;
- }
+ Q_ASSERT(call || frame);
+ if (!frame) {
+ frame = call->parentFrame();
}
+ Q_ASSERT(frame);
- event = index.data(ApiTraceModel::EventRole).value<ApiTraceEvent*>();
- ApiTraceCall *call = 0;
-
- if (event->type() == ApiTraceCall::Call)
- call = static_cast<ApiTraceCall*>(event);
- else {
- Q_ASSERT(event->type() == ApiTraceCall::Frame);
- ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
- call = frame->call(0);
- }
-
- if (!call) {
- m_searchWidget->setFound(false);
- return;
- }
- const QVector<ApiTraceCall*> &calls = m_trace->calls();
- int callNum = calls.indexOf(call);
-
- for (int i = callNum - 1; i >= 0; --i) {
- ApiTraceCall *testCall = calls[i];
- QModelIndex index = m_proxyModel->indexForCall(testCall);
- /* if it's not valid it means that the proxy model has already
- * filtered it out */
- if (index.isValid()) {
- QString txt = testCall->searchText();
- if (txt.contains(str, sensitivity)) {
- m_ui.callView->setCurrentIndex(index);
- m_searchWidget->setFound(true);
- return;
- }
- }
- }
- m_searchWidget->setFound(false);
+ m_trace->findPrev(frame, call, str, sensitivity);
}
void MainWindow::fillState(bool nonDefaults)
@@ -1000,7 +930,7 @@ void MainWindow::slotSaved()
void MainWindow::slotGoFrameStart()
{
- ApiTraceFrame *frame = currentFrame();
+ ApiTraceFrame *frame = selectedFrame();
if (!frame || frame->isEmpty()) {
return;
}
@@ -1022,7 +952,7 @@ void MainWindow::slotGoFrameStart()
void MainWindow::slotGoFrameEnd()
{
- ApiTraceFrame *frame = currentFrame();
+ ApiTraceFrame *frame = selectedFrame();
if (!frame || frame->isEmpty()) {
return;
}
@@ -1041,7 +971,7 @@ void MainWindow::slotGoFrameEnd()
} while (itr != calls.constBegin());
}
-ApiTraceFrame * MainWindow::currentFrame() const
+ApiTraceFrame * MainWindow::selectedFrame() const
{
if (m_selectedEvent) {
if (m_selectedEvent->type() == ApiTraceEvent::Frame) {
@@ -1099,7 +1029,7 @@ void MainWindow::slotErrorSelected(QTreeWidgetItem *current)
}
}
-ApiTraceCall * MainWindow::currentCall() const
+ApiTraceCall * MainWindow::selectedCall() const
{
if (m_selectedEvent &&
m_selectedEvent->type() == ApiTraceEvent::Call) {
@@ -1120,11 +1050,11 @@ void MainWindow::saveSelectedSurface()
QImage img = var.value<QImage>();
QString imageIndex;
- if (currentCall()) {
+ if (selectedCall()) {
imageIndex = tr("_call_%1")
- .arg(currentCall()->index());
- } else if (currentFrame()) {
- ApiTraceCall *firstCall = currentFrame()->call(0);
+ .arg(selectedCall()->index());
+ } else if (selectedFrame()) {
+ ApiTraceCall *firstCall = selectedFrame()->call(0);
if (firstCall) {
imageIndex = tr("_frame_%1")
.arg(firstCall->index());
@@ -1166,4 +1096,77 @@ void MainWindow::loadProgess(int percent)
m_progressBar->setValue(percent);
}
+void MainWindow::slotSearchResult(ApiTrace::SearchResult result,
+ ApiTraceCall *call)
+{
+ switch (result) {
+ case ApiTrace::SearchNotFound:
+ m_searchWidget->setFound(false);
+ break;
+ case ApiTrace::SearchFound: {
+ QModelIndex index = m_proxyModel->indexForCall(call);
+ m_ui.callView->setCurrentIndex(index);
+ m_searchWidget->setFound(true);
+ }
+ break;
+ case ApiTrace::SearchWrapped:
+ m_searchWidget->setFound(false);
+ break;
+ }
+}
+
+ApiTraceFrame * MainWindow::currentFrame() const
+{
+ QModelIndex index = m_ui.callView->currentIndex();
+ ApiTraceEvent *event = 0;
+
+ if (!index.isValid()) {
+ index = m_proxyModel->index(0, 0, QModelIndex());
+ if (!index.isValid()) {
+ qDebug()<<"no currently valid index";
+ return 0;
+ }
+ }
+
+ event = index.data(ApiTraceModel::EventRole).value<ApiTraceEvent*>();
+ Q_ASSERT(event);
+ if (!event) {
+ return 0;
+ }
+
+ ApiTraceFrame *frame = 0;
+ if (event->type() == ApiTraceCall::Frame) {
+ frame = static_cast<ApiTraceFrame*>(event);
+ }
+ return frame;
+}
+
+ApiTraceCall * MainWindow::currentCall() const
+{
+ QModelIndex index = m_ui.callView->currentIndex();
+ ApiTraceEvent *event = 0;
+
+ if (!index.isValid()) {
+ index = m_proxyModel->index(0, 0, QModelIndex());
+ if (!index.isValid()) {
+ qDebug()<<"no currently valid index";
+ return 0;
+ }
+ }
+
+ event = index.data(ApiTraceModel::EventRole).value<ApiTraceEvent*>();
+ Q_ASSERT(event);
+ if (!event) {
+ return 0;
+ }
+
+ ApiTraceCall *call = 0;
+ if (event->type() == ApiTraceCall::Call) {
+ call = static_cast<ApiTraceCall*>(event);
+ }
+
+ return call;
+
+}
+
#include "mainwindow.moc"
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index 00fe04b2..e5b19b44 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -3,6 +3,8 @@
#include "ui_mainwindow.h"
+#include "apitrace.h"
+
#include <QMainWindow>
#include <QProcess>
@@ -71,6 +73,8 @@ private slots:
void slotTraceChanged(ApiTraceCall *call);
void slotRetraceErrors(const QList<RetraceError> &errors);
void slotErrorSelected(QTreeWidgetItem *current);
+ void slotSearchResult(ApiTrace::SearchResult result,
+ ApiTraceCall *call);
private:
void initObjects();
@@ -78,9 +82,17 @@ private:
void newTraceFile(const QString &fileName);
void replayTrace(bool dumpState);
void fillStateForFrame();
+
+ /* there's a difference between selected frame/call and
+ * current call/frame. the former implies actual selection
+ * the latter might be just a highlight, e.g. during searching
+ */
+ ApiTraceFrame *selectedFrame() const;
+ ApiTraceCall *selectedCall() const;
ApiTraceFrame *currentFrame() const;
ApiTraceCall *currentCall() const;
+
private:
Ui_MainWindow m_ui;
ShadersSourceWidget *m_sourcesWidget;
diff --git a/gui/traceloader.cpp b/gui/traceloader.cpp
index a6ffd297..11847fff 100644
--- a/gui/traceloader.cpp
+++ b/gui/traceloader.cpp
@@ -56,49 +56,7 @@ void TraceLoader::loadTrace(const QString &filename)
void TraceLoader::loadFrame(ApiTraceFrame *currentFrame)
{
- if (m_parser.supportsOffsets()) {
- unsigned frameIdx = currentFrame->number;
- int numOfCalls = numberOfCallsInFrame(frameIdx);
-
- if (numOfCalls) {
- quint64 binaryDataSize = 0;
- QVector<ApiTraceCall*> calls(numOfCalls);
- const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
-
- m_parser.setBookmark(frameBookmark.start);
-
- Trace::Call *call;
- int parsedCalls = 0;
- while ((call = m_parser.parse_call())) {
- ApiTraceCall *apiCall =
- apiCallFromTraceCall(call, m_helpHash,
- currentFrame, this);
- calls[parsedCalls] = apiCall;
- Q_ASSERT(calls[parsedCalls]);
- if (apiCall->hasBinaryData()) {
- QByteArray data =
- apiCall->arguments()[
- apiCall->binaryDataIndex()].toByteArray();
- binaryDataSize += data.size();
- }
-
- ++parsedCalls;
-
- delete call;
-
- if (ApiTrace::isCallAFrameMarker(apiCall, m_frameMarker)) {
- break;
- }
-
- }
- assert(parsedCalls == numOfCalls);
- Q_ASSERT(parsedCalls == calls.size());
- Q_ASSERT(parsedCalls == currentFrame->numChildrenToLoad());
- calls.squeeze();
- currentFrame->setCalls(calls, binaryDataSize);
- emit frameLoaded(currentFrame);
- }
- }
+ fetchFrameContents(currentFrame);
}
void TraceLoader::setFrameMarker(ApiTrace::FrameMarker marker)
@@ -188,6 +146,7 @@ void TraceLoader::scanTrace()
currentFrame->setNumChildren(numOfCalls);
frames.append(currentFrame);
+ m_createdFrames.append(currentFrame);
m_frameBookmarks[numOfFrames] = frameBookmark;
++numOfFrames;
@@ -211,6 +170,7 @@ void TraceLoader::scanTrace()
currentFrame->setNumChildren(numOfCalls);
frames.append(currentFrame);
+ m_createdFrames.append(currentFrame);
m_frameBookmarks[numOfFrames] = frameBookmark;
++numOfFrames;
}
@@ -312,4 +272,125 @@ void TraceLoader::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature
m_enumSignatures[id] = signature;
}
+void TraceLoader::searchNext(int startFrame,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity)
+{
+ Q_ASSERT(m_parser.supportsOffsets());
+ if (m_parser.supportsOffsets()) {
+ const FrameBookmark &frameBookmark = m_frameBookmarks[startFrame];
+ m_parser.setBookmark(frameBookmark.start);
+ Trace::Call *call = 0;
+ while ((call = m_parser.parse_call())) {
+
+ if (callContains(call, str, sensitivity)) {
+ unsigned frameIdx = callInFrame(call->no);
+ ApiTraceFrame *frame = m_createdFrames[frameIdx];
+ const QVector<ApiTraceCall*> calls =
+ fetchFrameContents(frame);
+ for (int i = 0; i < calls.count(); ++i) {
+ if (calls[i]->index() == call->no) {
+ emit searchResult(ApiTrace::SearchFound, calls[i]);
+ break;
+ }
+ }
+ delete call;
+ return;
+ }
+
+ delete call;
+ }
+ }
+ emit searchResult(ApiTrace::SearchNotFound, 0);
+}
+
+void TraceLoader::searchPrev(int startFrame,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity)
+{
+}
+
+int TraceLoader::callInFrame(int callIdx) const
+{
+ unsigned numCalls = 0;
+
+ for (int frameIdx = 0; frameIdx <= m_frameBookmarks.size(); ++frameIdx) {
+ const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
+ unsigned firstCall = numCalls;
+ unsigned endCall = numCalls + frameBookmark.numberOfCalls;
+ if (firstCall <= callIdx && endCall > callIdx) {
+ return frameIdx;
+ }
+ numCalls = endCall;
+ }
+ Q_ASSERT(!"call not in the trace");
+ return 0;
+}
+
+bool TraceLoader::callContains(Trace::Call *call,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity)
+{
+ /*
+ * FIXME: do string comparison directly on Trace::Call
+ */
+ ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash,
+ 0, this);
+ bool result = apiCall->contains(str, sensitivity);
+ delete apiCall;
+ return result;
+}
+
+QVector<ApiTraceCall*>
+TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame)
+{
+ Q_ASSERT(currentFrame);
+ if (m_parser.supportsOffsets()) {
+ unsigned frameIdx = currentFrame->number;
+ int numOfCalls = numberOfCallsInFrame(frameIdx);
+
+ if (numOfCalls) {
+ quint64 binaryDataSize = 0;
+ QVector<ApiTraceCall*> calls(numOfCalls);
+ const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
+
+ m_parser.setBookmark(frameBookmark.start);
+
+ Trace::Call *call;
+ int parsedCalls = 0;
+ while ((call = m_parser.parse_call())) {
+ ApiTraceCall *apiCall =
+ apiCallFromTraceCall(call, m_helpHash,
+ currentFrame, this);
+ calls[parsedCalls] = apiCall;
+ Q_ASSERT(calls[parsedCalls]);
+ if (apiCall->hasBinaryData()) {
+ QByteArray data =
+ apiCall->arguments()[
+ apiCall->binaryDataIndex()].toByteArray();
+ binaryDataSize += data.size();
+ }
+
+ ++parsedCalls;
+
+ delete call;
+
+ if (ApiTrace::isCallAFrameMarker(apiCall, m_frameMarker)) {
+ break;
+ }
+
+ }
+ assert(parsedCalls == numOfCalls);
+ Q_ASSERT(parsedCalls == calls.size());
+ calls.squeeze();
+
+ Q_ASSERT(parsedCalls == currentFrame->numChildrenToLoad());
+ emit frameContentsLoaded(currentFrame,
+ calls, binaryDataSize);
+ return calls;
+ }
+ }
+ return QVector<ApiTraceCall*>();
+}
+
#include "traceloader.moc"
diff --git a/gui/traceloader.h b/gui/traceloader.h
index 86b75263..c83cf47b 100644
--- a/gui/traceloader.h
+++ b/gui/traceloader.h
@@ -28,6 +28,12 @@ public slots:
void loadTrace(const QString &filename);
void loadFrame(ApiTraceFrame *frame);
void setFrameMarker(ApiTrace::FrameMarker marker);
+ void searchNext(int startFrame,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity);
+ void searchPrev(int startFrame,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity);
signals:
void startedParsing();
@@ -35,8 +41,11 @@ signals:
void finishedParsing();
void framesLoaded(const QList<ApiTraceFrame*> &frames);
- void frameLoaded(ApiTraceFrame *frame);
+ void frameContentsLoaded(ApiTraceFrame *frame,
+ const QVector<ApiTraceCall*> &calls,
+ quint64 binaryDataSize);
+ void searchResult(ApiTrace::SearchResult result, ApiTraceCall *call);
private:
struct FrameBookmark {
FrameBookmark()
@@ -58,6 +67,12 @@ private:
void scanTrace();
void parseTrace();
+ int callInFrame(int callIdx) const;
+ bool callContains(Trace::Call *call,
+ const QString &str,
+ Qt::CaseSensitivity sensitivity);
+ QVector<ApiTraceCall*> fetchFrameContents(ApiTraceFrame *frame);
+
private:
Trace::Parser m_parser;
QString m_fileName;
@@ -65,6 +80,7 @@ private:
typedef QMap<int, FrameBookmark> FrameBookmarks;
FrameBookmarks m_frameBookmarks;
+ QList<ApiTraceFrame*> m_createdFrames;
QHash<QString, QUrl> m_helpHash;