summaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
authorZack Rusin <zack@kde.org>2011-03-30 11:03:37 -0400
committerZack Rusin <zack@kde.org>2011-03-30 22:48:42 -0400
commitf6667d1331849a8534ead1c653ab4a1aeaeddcc8 (patch)
treeaf41a4e0aba4d309e05637bb706cbb1058b132a4 /gui
parent27cb2c4e9d10cfd6236162b6f84109a5ca2eda49 (diff)
Introduce ApiTrace which encapsulates the data.
allows us to split calls into frames and do other postprocessing.
Diffstat (limited to 'gui')
-rw-r--r--gui/CMakeLists.txt1
-rw-r--r--gui/apicalldelegate.cpp22
-rw-r--r--gui/apicalldelegate.h2
-rw-r--r--gui/apitrace.cpp169
-rw-r--r--gui/apitrace.h67
-rw-r--r--gui/apitracecall.cpp51
-rw-r--r--gui/apitracecall.h49
-rw-r--r--gui/apitracefilter.cpp8
-rw-r--r--gui/apitracemodel.cpp163
-rw-r--r--gui/apitracemodel.h25
-rw-r--r--gui/loaderthread.cpp79
-rw-r--r--gui/loaderthread.h10
-rw-r--r--gui/main.cpp6
-rw-r--r--gui/mainwindow.cpp7
-rw-r--r--gui/mainwindow.h3
-rw-r--r--gui/ui/mainwindow.ui18
16 files changed, 568 insertions, 112 deletions
diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt
index 86f60d9..12ed63e 100644
--- a/gui/CMakeLists.txt
+++ b/gui/CMakeLists.txt
@@ -1,4 +1,5 @@
set(qapitrace_SRCS
+ apitrace.cpp
apicalldelegate.cpp
apitracecall.cpp
apitracefilter.cpp
diff --git a/gui/apicalldelegate.cpp b/gui/apicalldelegate.cpp
index a681c75..5376c0d 100644
--- a/gui/apicalldelegate.cpp
+++ b/gui/apicalldelegate.cpp
@@ -12,7 +12,8 @@ ApiCallDelegate::ApiCallDelegate(QWidget *parent)
{
}
-void ApiCallDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+void ApiCallDelegate::paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
ApiTraceCall *call = index.data().value<ApiTraceCall*>();
@@ -21,8 +22,16 @@ void ApiCallDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optio
//text.setTextWidth(option.rect.width());
QStyledItemDelegate::paint(painter, option, index);
painter->drawStaticText(option.rect.topLeft(), text);
- } else{
- QStyledItemDelegate::paint(painter, option, index);
+ } else {
+ ApiTraceFrame *frame = index.data().value<ApiTraceFrame*>();
+ if (frame) {
+ QStaticText text = frame->staticText();
+ //text.setTextWidth(option.rect.width());
+ QStyledItemDelegate::paint(painter, option, index);
+ painter->drawStaticText(option.rect.topLeft(), text);
+ } else {
+ QStyledItemDelegate::paint(painter, option, index);
+ }
}
}
@@ -34,6 +43,13 @@ QSize ApiCallDelegate::sizeHint(const QStyleOptionViewItem &option,
QStaticText text = call->staticText();
//text.setTextWidth(option.rect.width());
return text.size().toSize();
+ } else {
+ ApiTraceFrame *frame = index.data().value<ApiTraceFrame*>();
+ if (frame) {
+ QStaticText text = frame->staticText();
+ //text.setTextWidth(option.rect.width());
+ return text.size().toSize();
+ }
}
return QStyledItemDelegate::sizeHint(option, index);
}
diff --git a/gui/apicalldelegate.h b/gui/apicalldelegate.h
index 0329839..a29a178 100644
--- a/gui/apicalldelegate.h
+++ b/gui/apicalldelegate.h
@@ -1,8 +1,6 @@
#ifndef APICALLDELEGATE_H
#define APICALLDELEGATE_H
-
-
#include <QStyledItemDelegate>
class ApiCallDelegate : public QStyledItemDelegate
diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp
new file mode 100644
index 0000000..51e83b2
--- /dev/null
+++ b/gui/apitrace.cpp
@@ -0,0 +1,169 @@
+#include "apitrace.h"
+
+#include "loaderthread.h"
+
+ApiTrace::ApiTrace()
+ : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers)
+{
+ m_loader = new LoaderThread(this);
+ connect(m_loader, SIGNAL(parsedFrames(const QList<ApiTraceFrame*>)),
+ this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
+}
+
+ApiTrace::~ApiTrace()
+{
+ qDeleteAll(m_calls);
+ qDeleteAll(m_frames);
+ delete m_loader;
+}
+
+bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
+ ApiTrace::FrameMarker marker)
+{
+ if (!call)
+ return false;
+
+ switch (marker) {
+ case FrameMarker_SwapBuffers:
+ return call->name.contains(QLatin1String("SwapBuffers"));
+ case FrameMarker_Flush:
+ return call->name == QLatin1String("glFlush");
+ case FrameMarker_Finish:
+ return call->name == QLatin1String("glFinish");
+ case FrameMarker_Clear:
+ return call->name == QLatin1String("glClear");
+ }
+
+ Q_ASSERT(!"unknown frame marker");
+
+ return false;
+}
+
+bool ApiTrace::isEmpty() const
+{
+ return m_calls.isEmpty();
+}
+
+QString ApiTrace::fileName() const
+{
+ return m_fileName;
+}
+
+ApiTrace::FrameMarker ApiTrace::frameMarker() const
+{
+ return m_frameMarker;
+}
+
+QList<ApiTraceCall*> ApiTrace::calls() const
+{
+ return m_calls;
+}
+
+ApiTraceCall * ApiTrace::callAt(int idx) const
+{
+ return m_calls.value(idx);
+}
+
+int ApiTrace::numCalls() const
+{
+ return m_calls.count();
+}
+
+QList<ApiTraceFrame*> ApiTrace::frames() const
+{
+ return m_frames;
+}
+
+ApiTraceFrame * ApiTrace::frameAt(int idx) const
+{
+ return m_frames.value(idx);
+}
+
+int ApiTrace::numFrames() const
+{
+ return m_frames.count();
+}
+
+int ApiTrace::numCallsInFrame(int idx) const
+{
+ const ApiTraceFrame *frame = frameAt(idx);
+ if (frame)
+ return frame->calls.count();
+ else
+ return 0;
+}
+
+void ApiTrace::setFileName(const QString &name)
+{
+ if (m_fileName != name) {
+ m_fileName = name;
+
+ if (m_loader->isRunning()) {
+ m_loader->terminate();
+ m_loader->wait();
+ }
+ emit invalidated();
+
+ m_loader->loadFile(m_fileName);
+ }
+}
+
+void ApiTrace::setFrameMarker(FrameMarker marker)
+{
+ if (m_frameMarker != marker) {
+ emit framesInvalidated();
+
+ qDeleteAll(m_frames);
+ m_frames.clear();
+ detectFrames();
+ }
+}
+
+void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
+{
+ int currentFrames = m_frames.count();
+ int numNewFrames = frames.count();
+ m_frames += frames;
+
+ int currentCalls = m_calls.count();
+ int numNewCalls = 0;
+ foreach(ApiTraceFrame *frame, frames) {
+ numNewCalls += frame->calls.count();
+ m_calls += frame->calls;
+ }
+
+ emit framesAdded(currentFrames, numNewFrames);
+ emit callsAdded(currentCalls, numNewCalls);
+}
+
+void ApiTrace::detectFrames()
+{
+ if (m_calls.isEmpty())
+ return;
+
+ ApiTraceFrame *currentFrame = 0;
+ foreach(ApiTraceCall *apiCall, m_calls) {
+ if (!currentFrame) {
+ currentFrame = new ApiTraceFrame();
+ currentFrame->number = m_frames.count();
+ }
+ apiCall->parentFrame = currentFrame;
+ apiCall->index = currentFrame->calls.count();
+ currentFrame->calls.append(apiCall);
+ if (ApiTrace::isCallAFrameMarker(apiCall,
+ m_frameMarker)) {
+ m_frames.append(currentFrame);
+ currentFrame = 0;
+ }
+ }
+ //last frames won't have markers
+ // it's just a bunch of Delete calls for every object
+ // after the last SwapBuffers
+ if (currentFrame) {
+ m_frames.append(currentFrame);
+ currentFrame = 0;
+ }
+ emit framesAdded(0, m_frames.count());
+}
+
+#include "apitrace.moc"
diff --git a/gui/apitrace.h b/gui/apitrace.h
new file mode 100644
index 0000000..c400deb
--- /dev/null
+++ b/gui/apitrace.h
@@ -0,0 +1,67 @@
+#ifndef APITRACE_H
+#define APITRACE_H
+
+#include "apitracecall.h"
+
+#include <QObject>
+
+class LoaderThread;
+
+class ApiTrace : public QObject
+{
+ Q_OBJECT
+public:
+ enum FrameMarker {
+ FrameMarker_SwapBuffers,
+ FrameMarker_Flush,
+ FrameMarker_Finish,
+ FrameMarker_Clear
+ };
+ static bool isCallAFrameMarker(const ApiTraceCall *call,
+ FrameMarker marker);
+public:
+ ApiTrace();
+ ~ApiTrace();
+
+ bool isEmpty() const;
+
+ QString fileName() const;
+
+ FrameMarker frameMarker() const;
+
+ QList<ApiTraceCall*> calls() const;
+ ApiTraceCall *callAt(int idx) const;
+ int numCalls() const;
+
+ QList<ApiTraceFrame*> frames() const;
+ ApiTraceFrame *frameAt(int idx) const;
+ int numFrames() const;
+ int numCallsInFrame(int idx) const;
+
+public slots:
+ void setFileName(const QString &name);
+ void setFrameMarker(FrameMarker marker);
+
+signals:
+ void invalidated();
+ void framesInvalidated();
+
+ void framesAdded(int oldCount, int numAdded);
+ void callsAdded(int oldCount, int numAdded);
+
+private slots:
+ void addFrames(const QList<ApiTraceFrame*> &frames);
+private:
+ void detectFrames();
+private:
+ QString m_fileName;
+
+ QList<ApiTraceFrame*> m_frames;
+ QList<ApiTraceCall*> m_calls;
+
+ FrameMarker m_frameMarker;
+
+ LoaderThread *m_loader;
+};
+
+#endif
diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp
index 313d9ea..b772b66 100644
--- a/gui/apitracecall.cpp
+++ b/gui/apitracecall.cpp
@@ -296,3 +296,54 @@ QString ApiTraceCall::filterText() const
}
return m_filterText;
}
+
+QStaticText ApiTraceFrame::staticText() const
+{
+ if (!m_staticText.text().isEmpty())
+ return m_staticText;
+
+ QString richText =
+ QString::fromLatin1("<span style=\"font-weight:bold\">Frame %1</span>").arg(number);
+
+ m_staticText.setText(richText);
+ QTextOption opt;
+ opt.setWrapMode(QTextOption::NoWrap);
+ m_staticText.setTextOption(opt);
+ m_staticText.prepare();
+
+ return m_staticText;
+}
+
+int ApiTraceCall::numChildren() const
+{
+ return 0;
+}
+
+int ApiTraceFrame::numChildren() const
+{
+ return calls.count();
+}
+
+ApiTraceFrame::ApiTraceFrame()
+ : ApiTraceEvent(ApiTraceEvent::Frame)
+{
+}
+
+ApiTraceCall::ApiTraceCall()
+ : ApiTraceEvent(ApiTraceEvent::Call)
+{
+}
+
+ApiTraceEvent::ApiTraceEvent()
+ : m_type(ApiTraceEvent::None)
+{
+}
+
+ApiTraceEvent::ApiTraceEvent(Type t)
+ : m_type(t)
+{
+}
+
+ApiTraceCall::~ApiTraceCall()
+{
+}
diff --git a/gui/apitracecall.h b/gui/apitracecall.h
index 8b925e8..8f38bda 100644
--- a/gui/apitracecall.h
+++ b/gui/apitracecall.h
@@ -98,23 +98,68 @@ Q_DECLARE_METATYPE(ApiArray);
QString apiVariantToString(const QVariant &variant);
-class ApiTraceCall
+class ApiTraceFrame;
+
+class ApiTraceEvent
{
public:
+ enum Type {
+ None,
+ Call,
+ Frame
+ };
+public:
+ ApiTraceEvent();
+ ApiTraceEvent(Type t);
+
+ Type type() const { return m_type; }
+
+ virtual QStaticText staticText() const = 0;
+ virtual int numChildren() const = 0;
+
+protected:
+ Type m_type;
+};
+Q_DECLARE_METATYPE(ApiTraceEvent*);
+
+class ApiTraceCall : public ApiTraceEvent
+{
+public:
+ ApiTraceCall();
+ ~ApiTraceCall();
+
+ int index;
QString name;
QStringList argNames;
QVariantList argValues;
QVariant returnValue;
+ ApiTraceFrame *parentFrame;
QString toHtml() const;
QString filterText() const;
QStaticText staticText() const;
+ int numChildren() const;
private:
mutable QString m_richText;
mutable QString m_filterText;
mutable QStaticText m_staticText;
};
-Q_DECLARE_METATYPE(ApiTraceCall);
Q_DECLARE_METATYPE(ApiTraceCall*);
+class ApiTraceFrame : public ApiTraceEvent
+{
+public:
+ ApiTraceFrame();
+ int number;
+ QList<ApiTraceCall*> calls;
+
+
+ int numChildren() const;
+ QStaticText staticText() const;
+private:
+ mutable QStaticText m_staticText;
+};
+Q_DECLARE_METATYPE(ApiTraceFrame*);
+
+
#endif
diff --git a/gui/apitracefilter.cpp b/gui/apitracefilter.cpp
index 5542ea9..24c56bf 100644
--- a/gui/apitracefilter.cpp
+++ b/gui/apitracefilter.cpp
@@ -4,7 +4,7 @@
#include <QDebug>
-ApiTraceFilter::ApiTraceFilter(QObject *parent )
+ApiTraceFilter::ApiTraceFilter(QObject *parent)
: QSortFilterProxyModel()
{
}
@@ -16,8 +16,10 @@ bool ApiTraceFilter::filterAcceptsRow(int sourceRow,
QVariant varientData = sourceModel()->data(index0);
ApiTraceCall *call = varientData.value<ApiTraceCall*>();
- if (!call)
- return false;
+ if (!call) {
+ ApiTraceFrame *frame = varientData.value<ApiTraceFrame*>();
+ return frame != 0;
+ }
QString function = call->name;
diff --git a/gui/apitracemodel.cpp b/gui/apitracemodel.cpp
index 0a31ce8..c135bc1 100644
--- a/gui/apitracemodel.cpp
+++ b/gui/apitracemodel.cpp
@@ -9,18 +9,14 @@
ApiTraceModel::ApiTraceModel(QObject *parent)
- : QAbstractItemModel(parent)
+ : QAbstractItemModel(parent),
+ m_trace(0)
{
- m_loader = new LoaderThread();
-
- connect(m_loader, SIGNAL(parsedCalls(const QList<Trace::Call*>&)),
- SLOT(appendCalls(const QList<Trace::Call*>&)));
}
ApiTraceModel::~ApiTraceModel()
{
- qDeleteAll(m_calls);
- delete m_loader;
+ m_trace = 0;
}
QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
@@ -31,18 +27,24 @@ QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
if (role != Qt::DisplayRole)
return QVariant();
- ApiTraceCall *item = m_calls.value(index.row());
-
- if (!item)
+ //data only in the first column
+ if (index.column() != 0)
return QVariant();
- switch (index.column()) {
- case 0: {
- return QVariant::fromValue(item);
- }
- default:
- return QVariant();
+ ApiTraceEvent *itm = item(index);
+ if (itm) {
+ if (itm->type() == ApiTraceEvent::Frame) {
+ ApiTraceFrame *frame =
+ static_cast<ApiTraceFrame *>(itm);
+ return QVariant::fromValue(frame);
+ } else if (itm->type() == ApiTraceEvent::Call) {
+ ApiTraceCall *call =
+ static_cast<ApiTraceCall *>(itm);
+ return QVariant::fromValue(call);
+ }
}
+
+ return QVariant();
}
Qt::ItemFlags ApiTraceModel::flags(const QModelIndex &index) const
@@ -59,7 +61,7 @@ QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation,
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch (section) {
case 0:
- return tr("Function");
+ return tr("Event");
default:
//fall through
break;
@@ -75,17 +77,39 @@ QModelIndex ApiTraceModel::index(int row, int column,
if (parent.isValid() && parent.column() != 0)
return QModelIndex();
- ApiTraceCall *call = m_calls.value(row);
-
- if (call)
- return createIndex(row, column, call);
- else
- return QModelIndex();
+ if (parent.isValid()) {
+ QVariant data = parent.data();
+ ApiTraceFrame *frame = data.value<ApiTraceFrame*>();
+ if (!frame) {
+ qDebug()<<"got a valid parent but it's not a frame "<<data;
+ return QModelIndex();
+ }
+ ApiTraceCall *call = frame->calls.value(row);
+ if (call)
+ return createIndex(row, column, call);
+ else
+ return QModelIndex();
+ } else {
+ ApiTraceFrame *frame = m_trace->frameAt(row);
+ if (frame)
+ return createIndex(row, column, frame);
+ else
+ return QModelIndex();
+ }
+ return QModelIndex();
}
bool ApiTraceModel::hasChildren(const QModelIndex &parent) const
{
- return parent.isValid() ? false : (rowCount() > 0);
+ if (parent.isValid()) {
+ ApiTraceFrame *frame = parent.data().value<ApiTraceFrame*>();
+ if (frame)
+ return !frame->calls.isEmpty();
+ else
+ return false;
+ } else {
+ return (rowCount() > 0);
+ }
}
QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
@@ -93,18 +117,34 @@ QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
if (!index.isValid())
return QModelIndex();
- //list for now
+ ApiTraceCall *call = index.data().value<ApiTraceCall*>();
+ if (call) {
+ Q_ASSERT(call->parentFrame);
+ return createIndex(call->parentFrame->number,
+ 0, call->parentFrame);
+ }
return QModelIndex();
}
int ApiTraceModel::rowCount(const QModelIndex &parent) const
{
- return m_calls.count();
+ if (!parent.isValid())
+ return m_trace->numFrames();
+
+ ApiTraceCall *call = parent.data().value<ApiTraceCall*>();
+ if (call)
+ return 0;
+
+ ApiTraceFrame *frame = parent.data().value<ApiTraceFrame*>();
+ if (frame)
+ return frame->calls.count();
+
+ return 0;
}
int ApiTraceModel::columnCount(const QModelIndex &parent) const
{
- return parent.isValid() ? 0 : 1;
+ return 1;
}
@@ -121,60 +161,49 @@ bool ApiTraceModel::removeRows(int position, int rows,
Q_UNUSED(parent);
- if (m_calls.count() <= position)
- return false;
-
beginRemoveRows(parent, position, position + rows - 1);
- for (int i = 0; i < rows; ++i) {
- ApiTraceCall *call = m_calls.value(i);
- m_calls.removeAt(i);
- delete call;
- }
+ //XXX remove it from ApiTrace
endRemoveRows();
return success;
}
-void ApiTraceModel::loadTraceFile(const QString &fileName)
+void ApiTraceModel::setApiTrace(ApiTrace *trace)
{
- if (m_loader->isRunning()) {
- m_loader->terminate();
- m_loader->wait();
- }
- removeRows(0, m_calls.count(), QModelIndex());
-
- m_loader->loadFile(fileName);
+ if (m_trace == trace)
+ return;
+ if (m_trace)
+ disconnect(m_trace);
+ m_trace = trace;
+ connect(m_trace, SIGNAL(framesInvalidated()),
+ this, SLOT(invalidateFrames()));
+ connect(m_trace, SIGNAL(framesAdded(int, int)),
+ this, SLOT(appendFrames(int, int)));
}
-void ApiTraceModel::appendCalls(const QList<Trace::Call*> traceCalls)
+const ApiTrace * ApiTraceModel::apiTrace() const
{
- beginInsertRows(QModelIndex(), m_calls.count(),
- m_calls.count() + traceCalls.count());
- foreach(Trace::Call *call, traceCalls) {
- ApiTraceCall *apiCall = new ApiTraceCall;
- apiCall->name = QString::fromStdString(call->sig->name);
+ return m_trace;
+}
- QString argumentsText;
- for (int i = 0; i < call->sig->arg_names.size(); ++i) {
- apiCall->argNames +=
- QString::fromStdString(call->sig->arg_names[i]);
- }
- if (call->ret) {
- VariantVisitor retVisitor;
- call->ret->visit(retVisitor);
- apiCall->returnValue = retVisitor.variant();
- }
- for (int i = 0; i < call->args.size(); ++i) {
- VariantVisitor argVisitor;
- call->args[i]->visit(argVisitor);
- apiCall->argValues += argVisitor.variant();
- }
+void ApiTraceModel::invalidateFrames()
+{
+ beginResetModel();
+ endResetModel();
+}
- m_calls.append(apiCall);
- }
+void ApiTraceModel::appendFrames(int oldCount, int numAdded)
+{
+ beginInsertRows(QModelIndex(), oldCount,
+ oldCount + numAdded);
endInsertRows();
+}
- qDeleteAll(traceCalls);
+ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+ return static_cast<ApiTraceEvent*>(index.internalPointer());
}
#include "apitracemodel.moc"
diff --git a/gui/apitracemodel.h b/gui/apitracemodel.h
index 422259e..d9ac9dd 100644
--- a/gui/apitracemodel.h
+++ b/gui/apitracemodel.h
@@ -6,20 +6,22 @@
#include <QModelIndex>
#include <QVariant>
+class ApiTrace;
class ApiTraceCall;
-class LoaderThread;
-namespace Trace {
- class Call;
-}
+class ApiTraceEvent;
class ApiTraceModel : public QAbstractItemModel
{
Q_OBJECT
-
public:
ApiTraceModel(QObject *parent = 0);
~ApiTraceModel();
+ void setApiTrace(ApiTrace *trace);
+ const ApiTrace *apiTrace() const;
+
+public:
+ /* QAbstractItemModel { */
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation,
@@ -35,14 +37,17 @@ public:
const QModelIndex &parent = QModelIndex());
bool removeRows(int position, int rows,
const QModelIndex &parent = QModelIndex());
+ /* } QAbstractItemModel; */
-public slots:
- void loadTraceFile(const QString &fileName);
- void appendCalls(const QList<Trace::Call*> traceCalls);
+private slots:
+ void invalidateFrames();
+ void appendFrames(int oldCount, int numAdded);
+
+private:
+ ApiTraceEvent *item(const QModelIndex &index) const;
private:
- QList<ApiTraceCall*> m_calls;
- LoaderThread *m_loader;
+ ApiTrace *m_trace;
};
#endif
diff --git a/gui/loaderthread.cpp b/gui/loaderthread.cpp
index c8cbe57..2ec06ec 100644
--- a/gui/loaderthread.cpp
+++ b/gui/loaderthread.cpp
@@ -2,31 +2,81 @@
#include "trace_parser.hpp"
+#define FRAMES_TO_CACHE 100
+
+static ApiTraceCall *
+apiCallFromTraceCall(const Trace::Call *call)
+{
+ ApiTraceCall *apiCall = new ApiTraceCall();
+ apiCall->name = QString::fromStdString(call->sig->name);
+
+ QString argumentsText;
+ for (int i = 0; i < call->sig->arg_names.size(); ++i) {
+ apiCall->argNames +=
+ QString::fromStdString(call->sig->arg_names[i]);
+ }
+ if (call->ret) {
+ VariantVisitor retVisitor;
+ call->ret->visit(retVisitor);
+ apiCall->returnValue = retVisitor.variant();
+ }
+ for (int i = 0; i < call->args.size(); ++i) {
+ VariantVisitor argVisitor;
+ call->args[i]->visit(argVisitor);
+ apiCall->argValues += argVisitor.variant();
+ }
+
+ return apiCall;
+}
+
LoaderThread::LoaderThread(QObject *parent)
- : QThread(parent)
+ : QThread(parent),
+ m_frameMarker(ApiTrace::FrameMarker_SwapBuffers)
{
}
void LoaderThread::run()
{
- QList<Trace::Call*> traceCalls;
+ QList<ApiTraceFrame*> frames;
+ ApiTraceFrame *currentFrame = 0;
+ int frameCount = 0;
Trace::Parser p;
if (p.open(m_fileName.toLatin1().constData())) {
Trace::Call *call;
call = p.parse_call();
while (call) {
//std::cout << *call;
- traceCalls.append(call);
- if (traceCalls.count() >= 1000) {
- emit parsedCalls(traceCalls);
- traceCalls.clear();
+ if (!currentFrame) {
+ currentFrame = new ApiTraceFrame();
+ currentFrame->number = frameCount;
+ ++frameCount;
+ }
+ ApiTraceCall *apiCall =
+ apiCallFromTraceCall(call);
+ apiCall->parentFrame = currentFrame;
+ apiCall->index = currentFrame->calls.count();
+ currentFrame->calls.append(apiCall);
+ if (ApiTrace::isCallAFrameMarker(apiCall,
+ m_frameMarker)) {
+ frames.append(currentFrame);
+ currentFrame = 0;
+ if (frames.count() >= FRAMES_TO_CACHE) {
+ emit parsedFrames(frames);
+ frames.clear();
+ }
}
call = p.parse_call();
}
}
- if (traceCalls.count()) {
- emit parsedCalls(traceCalls);
- traceCalls.clear();
+ //last frames won't have markers
+ // it's just a bunch of Delete calls for every object
+ // after the last SwapBuffers
+ if (currentFrame) {
+ frames.append(currentFrame);
+ currentFrame = 0;
+ }
+ if (frames.count()) {
+ emit parsedFrames(frames);
}
}
@@ -36,4 +86,15 @@ void LoaderThread::loadFile(const QString &fileName)
start();
}
+ApiTrace::FrameMarker LoaderThread::frameMarker() const
+{
+ return m_frameMarker;
+}
+
+void LoaderThread::setFrameMarker(ApiTrace::FrameMarker marker)
+{
+ Q_ASSERT(!isRunning());
+ m_frameMarker = marker;
+}
+
#include "loaderthread.moc"
diff --git a/gui/loaderthread.h b/gui/loaderthread.h
index 4914815..5073e14 100644
--- a/gui/loaderthread.h
+++ b/gui/loaderthread.h
@@ -1,13 +1,12 @@
#ifndef LOADERTHREAD_H
#define LOADERTHREAD_H
+#include "apitrace.h"
#include <QThread>
#include <QList>
class ApiTraceCall;
-namespace Trace {
- class Call;
-}
+class ApiTraceFrame;
class LoaderThread : public QThread
{
@@ -15,17 +14,20 @@ class LoaderThread : public QThread
public:
LoaderThread(QObject *parent=0);
+ ApiTrace::FrameMarker frameMarker() const;
+ void setFrameMarker(ApiTrace::FrameMarker marker);
public slots:
void loadFile(const QString &fileName);
signals:
- void parsedCalls(const QList<Trace::Call*> &calls);
+ void parsedFrames(const QList<ApiTraceFrame*> &frames);
protected:
virtual void run();
private:
QString m_fileName;
+ ApiTrace::FrameMarker m_frameMarker;
};
#endif
diff --git a/gui/main.cpp b/gui/main.cpp
index dcfb6c2..bee35d3 100644
--- a/gui/main.cpp
+++ b/gui/main.cpp
@@ -1,18 +1,18 @@
#include "mainwindow.h"
-#include "trace_model.hpp"
+#include "apitracecall.h"
#include <QApplication>
#include <QMetaType>
#include <QVariant>
-Q_DECLARE_METATYPE(QList<Trace::Call*>);
+Q_DECLARE_METATYPE(QList<ApiTraceFrame*>);
int main(int argc, char **argv)
{
QApplication app(argc, argv);
- qRegisterMetaType<QList<Trace::Call*> >();
+ qRegisterMetaType<QList<ApiTraceFrame*> >();
MainWindow window;
window.show();
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index 74d9f94..a469148 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -1,5 +1,6 @@
#include "mainwindow.h"
+#include "apitrace.h"
#include "apitracecall.h"
#include "apicalldelegate.h"
#include "apitracemodel.h"
@@ -22,7 +23,10 @@ MainWindow::MainWindow()
{
m_ui.setupUi(this);
+ m_trace = new ApiTrace();
+
m_model = new ApiTraceModel();
+ m_model->setApiTrace(m_trace);
m_proxyModel = new ApiTraceFilter();
m_proxyModel->setSourceModel(m_model);
m_ui.callView->setModel(m_proxyModel);
@@ -64,7 +68,6 @@ void MainWindow::openTrace()
qDebug()<< "File name : " <<fileName;
newTraceFile(fileName);
- m_model->loadTraceFile(fileName);
}
void MainWindow::loadTrace(const QString &fileName)
@@ -76,7 +79,6 @@ void MainWindow::loadTrace(const QString &fileName)
}
qDebug()<< "Loading : " <<fileName;
- m_model->loadTraceFile(fileName);
newTraceFile(fileName);
}
@@ -145,6 +147,7 @@ void MainWindow::replayStop()
void MainWindow::newTraceFile(const QString &fileName)
{
m_traceFileName = fileName;
+ m_trace->setFileName(fileName);
if (m_traceFileName.isEmpty()) {
m_ui.actionReplay->setEnabled(false);
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index 56c1195..11290e6 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -6,7 +6,7 @@
#include <QMainWindow>
#include <QProcess>
-
+class ApiTrace;
class ApiTraceModel;
class ApiTraceFilter;
class QLineEdit;
@@ -36,6 +36,7 @@ private:
private:
Ui_MainWindow m_ui;
+ ApiTrace *m_trace;
ApiTraceModel *m_model;
ApiTraceFilter *m_proxyModel;
QLineEdit *m_filterEdit;
diff --git a/gui/ui/mainwindow.ui b/gui/ui/mainwindow.ui
index a6f17b3..f60042c 100644
--- a/gui/ui/mainwindow.ui
+++ b/gui/ui/mainwindow.ui
@@ -62,6 +62,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>77</width>
+ <height>100</height>
+ </size>
+ </property>
<property name="floating">
<bool>false</bool>
</property>
@@ -74,14 +80,14 @@
<widget class="QWidget" name="dockWidgetContents">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
- <widget class="QWebView" name="detailsWebView">
+ <widget class="QWebView" name="detailsWebView" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="url">
+ <property name="url" stdset="0">
<url>
<string>about:blank</string>
</url>
@@ -103,7 +109,7 @@
</action>
<action name="actionOpen">
<property name="icon">
- <iconset theme="document-open">
+ <iconset>
<normaloff/>
</iconset>
</property>
@@ -116,7 +122,7 @@
</action>
<action name="actionQuit">
<property name="icon">
- <iconset theme="application-exit">
+ <iconset>
<normaloff/>
</iconset>
</property>
@@ -138,7 +144,7 @@
<bool>false</bool>
</property>
<property name="icon">
- <iconset theme="media-playback-start">
+ <iconset>
<normaloff/>
</iconset>
</property>
@@ -151,7 +157,7 @@
<bool>false</bool>
</property>
<property name="icon">
- <iconset theme="media-playback-stop">
+ <iconset>
<normaloff/>
</iconset>
</property>