diff options
author | Zack Rusin <zack@kde.org> | 2011-03-30 11:03:37 -0400 |
---|---|---|
committer | Zack Rusin <zack@kde.org> | 2011-03-30 22:48:42 -0400 |
commit | f6667d1331849a8534ead1c653ab4a1aeaeddcc8 (patch) | |
tree | af41a4e0aba4d309e05637bb706cbb1058b132a4 /gui | |
parent | 27cb2c4e9d10cfd6236162b6f84109a5ca2eda49 (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.txt | 1 | ||||
-rw-r--r-- | gui/apicalldelegate.cpp | 22 | ||||
-rw-r--r-- | gui/apicalldelegate.h | 2 | ||||
-rw-r--r-- | gui/apitrace.cpp | 169 | ||||
-rw-r--r-- | gui/apitrace.h | 67 | ||||
-rw-r--r-- | gui/apitracecall.cpp | 51 | ||||
-rw-r--r-- | gui/apitracecall.h | 49 | ||||
-rw-r--r-- | gui/apitracefilter.cpp | 8 | ||||
-rw-r--r-- | gui/apitracemodel.cpp | 163 | ||||
-rw-r--r-- | gui/apitracemodel.h | 25 | ||||
-rw-r--r-- | gui/loaderthread.cpp | 79 | ||||
-rw-r--r-- | gui/loaderthread.h | 10 | ||||
-rw-r--r-- | gui/main.cpp | 6 | ||||
-rw-r--r-- | gui/mainwindow.cpp | 7 | ||||
-rw-r--r-- | gui/mainwindow.h | 3 | ||||
-rw-r--r-- | gui/ui/mainwindow.ui | 18 |
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> |