summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Rusin <zack@kde.org>2011-04-10 19:27:28 -0400
committerZack Rusin <zack@kde.org>2011-04-10 19:28:00 -0400
commitf389ae8b54b138848a099b82d6103e006dbbd9e6 (patch)
treed181a3a831cabe7916ffe8e8e11ed35a8f854129
parent46678421e19ac25220f1470d074ef55d8b23440a (diff)
Replay and parse json in a thread.
-rw-r--r--gui/apitracecall.h1
-rw-r--r--gui/main.cpp1
-rw-r--r--gui/mainwindow.cpp60
-rw-r--r--gui/mainwindow.h11
-rw-r--r--gui/retracer.cpp207
-rw-r--r--gui/retracer.h62
6 files changed, 261 insertions, 81 deletions
diff --git a/gui/apitracecall.h b/gui/apitracecall.h
index 94bd234b..dd69b0e4 100644
--- a/gui/apitracecall.h
+++ b/gui/apitracecall.h
@@ -118,6 +118,7 @@ private:
QStringList m_shaderSources;
QList<ApiTexture> m_textures;
};
+Q_DECLARE_METATYPE(ApiTraceState);
class ApiTraceEvent
{
diff --git a/gui/main.cpp b/gui/main.cpp
index bee35d37..3f8cfa6b 100644
--- a/gui/main.cpp
+++ b/gui/main.cpp
@@ -13,6 +13,7 @@ int main(int argc, char **argv)
QApplication app(argc, argv);
qRegisterMetaType<QList<ApiTraceFrame*> >();
+ qRegisterMetaType<ApiTraceState>();
MainWindow window;
window.show();
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index b19a559f..4fc13628 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -12,8 +12,6 @@
#include "ui_retracerdialog.h"
#include "vertexdatainterpreter.h"
-#include <qjson/parser.h>
-
#include <QAction>
#include <QDebug>
#include <QDesktopServices>
@@ -32,8 +30,7 @@
MainWindow::MainWindow()
: QMainWindow(),
m_selectedEvent(0),
- m_stateEvent(0),
- m_jsonParser(new QJson::Parser())
+ m_stateEvent(0)
{
m_ui.setupUi(this);
initObjects();
@@ -140,7 +137,7 @@ void MainWindow::replayStart()
void MainWindow::replayStop()
{
- m_retracer->terminate();
+ m_retracer->quit();
m_ui.actionStop->setEnabled(false);
m_ui.actionReplay->setEnabled(true);
m_ui.actionLookupState->setEnabled(true);
@@ -164,20 +161,19 @@ void MainWindow::newTraceFile(const QString &fileName)
}
}
-void MainWindow::replayFinished(const QByteArray &output)
+void MainWindow::replayFinished(const QString &output)
{
m_ui.actionStop->setEnabled(false);
m_ui.actionReplay->setEnabled(true);
m_ui.actionLookupState->setEnabled(true);
- if (m_retracer->captureState()) {
- bool ok = false;
- QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap();
- parseState(parsedJson);
- } else if (output.length() < 80) {
+ m_progressBar->hide();
+ if (output.length() < 80) {
statusBar()->showMessage(output);
}
m_stateEvent = 0;
+ statusBar()->showMessage(
+ tr("Replaying finished!"), 2000);
}
void MainWindow::replayError(const QString &message)
@@ -187,6 +183,9 @@ void MainWindow::replayError(const QString &message)
m_ui.actionLookupState->setEnabled(true);
m_stateEvent = 0;
+ m_progressBar->hide();
+ statusBar()->showMessage(
+ tr("Replaying unsuccessful."), 2000);
QMessageBox::warning(
this, tr("Replay Failed"), message);
}
@@ -223,7 +222,8 @@ void MainWindow::replayTrace(bool dumpState)
if (m_selectedEvent->type() == ApiTraceEvent::Call) {
index = static_cast<ApiTraceCall*>(m_selectedEvent)->index;
} else if (m_selectedEvent->type() == ApiTraceEvent::Frame) {
- ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(m_selectedEvent);
+ ApiTraceFrame *frame =
+ static_cast<ApiTraceFrame*>(m_selectedEvent);
if (frame->calls.isEmpty()) {
//XXX i guess we could still get the current state
qDebug()<<"tried to get a state for an empty frame";
@@ -239,6 +239,13 @@ void MainWindow::replayTrace(bool dumpState)
m_retracer->start();
m_ui.actionStop->setEnabled(true);
+ m_progressBar->show();
+ if (dumpState)
+ statusBar()->showMessage(
+ tr("Looking up the state..."));
+ else
+ statusBar()->showMessage(
+ tr("Replaying the trace file..."));
}
void MainWindow::lookupState()
@@ -255,18 +262,6 @@ void MainWindow::lookupState()
MainWindow::~MainWindow()
{
- delete m_jsonParser;
-}
-
-void MainWindow::parseState(const QVariantMap &parsedJson)
-{
- m_stateEvent->setState(ApiTraceState(parsedJson));
- m_model->stateSetOnEvent(m_stateEvent);
- if (m_selectedEvent == m_stateEvent) {
- fillStateForFrame();
- } else {
- m_ui.stateDock->hide();
- }
}
static void
@@ -469,10 +464,12 @@ void MainWindow::initConnections()
connect(m_trace, SIGNAL(finishedLoadingTrace()),
this, SLOT(finishedLoadingTrace()));
- connect(m_retracer, SIGNAL(finished(const QByteArray&)),
- this, SLOT(replayFinished(const QByteArray&)));
+ connect(m_retracer, SIGNAL(finished(const QString&)),
+ this, SLOT(replayFinished(const QString&)));
connect(m_retracer, SIGNAL(error(const QString&)),
this, SLOT(replayError(const QString&)));
+ connect(m_retracer, SIGNAL(foundState(const ApiTraceState&)),
+ this, SLOT(replayStateFound(const ApiTraceState&)));
connect(m_ui.vertexInterpretButton, SIGNAL(clicked()),
m_vdataInterpreter, SLOT(interpretData()));
@@ -516,4 +513,15 @@ void MainWindow::initConnections()
this, SLOT(openHelp(const QUrl&)));
}
+void MainWindow::replayStateFound(const ApiTraceState &state)
+{
+ m_stateEvent->setState(state);
+ m_model->stateSetOnEvent(m_stateEvent);
+ if (m_selectedEvent == m_stateEvent) {
+ fillStateForFrame();
+ } else {
+ m_ui.stateDock->hide();
+ }
+}
+
#include "mainwindow.moc"
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index 55326bf5..313180a1 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -11,6 +11,7 @@ class ApiTraceEvent;
class ApiTraceFilter;
class ApiTraceFrame;
class ApiTraceModel;
+class ApiTraceState;
class ImageViewer;
class QLineEdit;
class QModelIndex;
@@ -20,10 +21,6 @@ class Retracer;
class ShadersSourceWidget;
class VertexDataInterpreter;
-namespace QJson {
- class Parser;
-}
-
class MainWindow : public QMainWindow
{
Q_OBJECT
@@ -40,7 +37,8 @@ private slots:
void filterTrace();
void replayStart();
void replayStop();
- void replayFinished(const QByteArray &output);
+ void replayFinished(const QString &output);
+ void replayStateFound(const ApiTraceState &state);
void replayError(const QString &msg);
void startedLoadingTrace();
void finishedLoadingTrace();
@@ -55,7 +53,6 @@ private:
void initConnections();
void newTraceFile(const QString &fileName);
void replayTrace(bool dumpState);
- void parseState(const QVariantMap &params);
void fillStateForFrame();
private:
@@ -75,8 +72,6 @@ private:
ApiTraceEvent *m_stateEvent;
- QJson::Parser *m_jsonParser;
-
Retracer *m_retracer;
VertexDataInterpreter *m_vdataInterpreter;
diff --git a/gui/retracer.cpp b/gui/retracer.cpp
index b9d74b62..8f350877 100644
--- a/gui/retracer.cpp
+++ b/gui/retracer.cpp
@@ -1,15 +1,31 @@
#include "retracer.h"
+#include "apitracecall.h"
+
#include <QDebug>
+#include <QVariant>
+
+#include <qjson/parser.h>
Retracer::Retracer(QObject *parent)
- : QObject(parent),
+ : QThread(parent),
m_benchmarking(true),
m_doubleBuffered(true),
m_captureState(false),
- m_captureCall(0),
- m_process(0)
+ m_captureCall(0)
{
+#ifdef Q_OS_WIN
+ QString format = QLatin1String("%1;");
+#else
+ QString format = QLatin1String("%1:");
+#endif
+ QString buildPath = format.arg(BUILD_DIR);
+ m_processEnvironment = QProcessEnvironment::systemEnvironment();
+ m_processEnvironment.insert("PATH", buildPath +
+ m_processEnvironment.value("PATH"));
+
+ qputenv("PATH",
+ m_processEnvironment.value("PATH").toLatin1());
}
QString Retracer::fileName() const
@@ -42,31 +58,65 @@ void Retracer::setDoubleBuffered(bool db)
m_doubleBuffered = db;
}
-void Retracer::start()
+void Retracer::setCaptureAtCallNumber(qlonglong num)
{
- if (!m_process) {
-#ifdef Q_OS_WIN
- QString format = QLatin1String("%1;");
-#else
- QString format = QLatin1String("%1:");
-#endif
- QString buildPath = format.arg(BUILD_DIR);
- QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
- env.insert("PATH", buildPath + env.value("PATH"));
+ m_captureCall = num;
+}
+
+qlonglong Retracer::captureAtCallNumber() const
+{
+ return m_captureCall;
+}
+
+bool Retracer::captureState() const
+{
+ return m_captureState;
+}
+
+void Retracer::setCaptureState(bool enable)
+{
+ m_captureState = enable;
+}
+
- qputenv("PATH", env.value("PATH").toLatin1());
+void Retracer::run()
+{
+ RetraceProcess *retrace = new RetraceProcess();
+ retrace->process()->setProcessEnvironment(m_processEnvironment);
+
+ retrace->setFileName(m_fileName);
+ retrace->setBenchmarking(m_benchmarking);
+ retrace->setDoubleBuffered(m_doubleBuffered);
+ retrace->setCaptureState(m_captureState);
+ retrace->setCaptureAtCallNumber(m_captureCall);
+
+ connect(retrace, SIGNAL(finished(const QString&)),
+ this, SLOT(cleanup()));
+ connect(retrace, SIGNAL(error(const QString&)),
+ this, SLOT(cleanup()));
+ connect(retrace, SIGNAL(finished(const QString&)),
+ this, SIGNAL(finished(const QString&)));
+ connect(retrace, SIGNAL(error(const QString&)),
+ this, SIGNAL(error(const QString&)));
+ connect(retrace, SIGNAL(foundState(const ApiTraceState&)),
+ this, SIGNAL(foundState(const ApiTraceState&)));
+
+ retrace->start();
- m_process = new QProcess(this);
- m_process->setProcessEnvironment(env);
+ exec();
- connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
- this, SLOT(replayFinished()));
- connect(m_process, SIGNAL(error(QProcess::ProcessError)),
- this, SLOT(replayError(QProcess::ProcessError)));
+ /* means we need to kill the process */
+ if (retrace->process()->state() != QProcess::NotRunning) {
+ retrace->terminate();
}
- QStringList arguments;
+ delete retrace;
+}
+
+void RetraceProcess::start()
+{
+ QStringList arguments;
if (m_captureState) {
arguments << QLatin1String("-D");
arguments << QString::number(m_captureCall);
@@ -84,53 +134,124 @@ void Retracer::start()
m_process->start(QLatin1String("glretrace"), arguments);
}
-void Retracer::terminate()
+
+void RetraceProcess::replayFinished()
{
- if (m_process) {
- m_process->terminate();
+ QByteArray output = m_process->readAllStandardOutput();
+ QString msg;
+
+#if 0
+ qDebug()<<"Process finished = ";
+ qDebug()<<"\terr = "<<m_process->readAllStandardError();
+ qDebug()<<"\tout = "<<output;
+#endif
+ if (m_captureState) {
+ bool ok = false;
+ QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap();
+ ApiTraceState state(parsedJson);
+ emit foundState(state);
+ msg = tr("State fetched.");
+ } else {
+ msg = QString::fromUtf8(output);
}
+
+ emit finished(msg);
}
-void Retracer::setCaptureAtCallNumber(qlonglong num)
+void RetraceProcess::replayError(QProcess::ProcessError err)
+{
+ qDebug()<<"Process error = "<<err;
+ qDebug()<<"\terr = "<<m_process->readAllStandardError();
+ qDebug()<<"\tout = "<<m_process->readAllStandardOutput();
+
+ emit error(
+ tr("Couldn't execute the replay file '%1'").arg(m_fileName));
+}
+
+
+RetraceProcess::RetraceProcess(QObject *parent)
+ : QObject(parent)
+{
+ m_process = new QProcess(this);
+ m_jsonParser = new QJson::Parser();
+
+ connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(replayFinished()));
+ connect(m_process, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(replayError(QProcess::ProcessError)));
+}
+
+QProcess * RetraceProcess::process() const
+{
+ return m_process;
+}
+
+QString RetraceProcess::fileName() const
+{
+ return m_fileName;
+}
+
+void RetraceProcess::setFileName(const QString &name)
+{
+ m_fileName = name;
+}
+
+bool RetraceProcess::isBenchmarking() const
+{
+ return m_benchmarking;
+}
+
+void RetraceProcess::setBenchmarking(bool bench)
+{
+ m_benchmarking = bench;
+}
+
+bool RetraceProcess::isDoubleBuffered() const
+{
+ return m_doubleBuffered;
+}
+
+void RetraceProcess::setDoubleBuffered(bool db)
+{
+ m_doubleBuffered = db;
+}
+
+void RetraceProcess::setCaptureAtCallNumber(qlonglong num)
{
m_captureCall = num;
}
-qlonglong Retracer::captureAtCallNumber() const
+qlonglong RetraceProcess::captureAtCallNumber() const
{
return m_captureCall;
}
-bool Retracer::captureState() const
+bool RetraceProcess::captureState() const
{
return m_captureState;
}
-void Retracer::setCaptureState(bool enable)
+void RetraceProcess::setCaptureState(bool enable)
{
m_captureState = enable;
}
-void Retracer::replayFinished()
+void RetraceProcess::terminate()
{
- QByteArray output = m_process->readAllStandardOutput();
-
-#if 0
- qDebug()<<"Process finished = ";
- qDebug()<<"\terr = "<<m_process->readAllStandardError();
- qDebug()<<"\tout = "<<output;
-#endif
- emit finished(output);
+ if (m_process) {
+ m_process->terminate();
+ emit finished(tr("Process terminated."));
+ }
}
-void Retracer::replayError(QProcess::ProcessError err)
+void Retracer::cleanup()
{
- qDebug()<<"Process error = "<<err;
- qDebug()<<"\terr = "<<m_process->readAllStandardError();
- qDebug()<<"\tout = "<<m_process->readAllStandardOutput();
+ quit();
+}
- emit error(
- tr("Couldn't execute the replay file '%1'").arg(m_fileName));
+RetraceProcess::~RetraceProcess()
+{
+ delete m_jsonParser;
}
#include "retracer.moc"
diff --git a/gui/retracer.h b/gui/retracer.h
index 37502e45..617861e6 100644
--- a/gui/retracer.h
+++ b/gui/retracer.h
@@ -1,14 +1,24 @@
#ifndef RETRACER_H
#define RETRACER_H
-#include <QObject>
+#include <QThread>
#include <QProcess>
-class Retracer : public QObject
+class ApiTraceState;
+namespace QJson {
+ class Parser;
+}
+
+/* internal class used by the retracer to run
+ * in the thread */
+class RetraceProcess : public QObject
{
Q_OBJECT
public:
- Retracer(QObject *parent=0);
+ RetraceProcess(QObject *parent=0);
+ ~RetraceProcess();
+
+ QProcess *process() const;
QString fileName() const;
void setFileName(const QString &name);
@@ -30,12 +40,14 @@ public slots:
void terminate();
signals:
- void finished(const QByteArray &output);
+ void finished(const QString &output);
void error(const QString &msg);
+ void foundState(const ApiTraceState &state);
private slots:
void replayFinished();
void replayError(QProcess::ProcessError err);
+
private:
QString m_fileName;
bool m_benchmarking;
@@ -44,6 +56,48 @@ private:
qlonglong m_captureCall;
QProcess *m_process;
+ QJson::Parser *m_jsonParser;
+};
+
+class Retracer : public QThread
+{
+ Q_OBJECT
+public:
+ Retracer(QObject *parent=0);
+
+ QString fileName() const;
+ void setFileName(const QString &name);
+
+ bool isBenchmarking() const;
+ void setBenchmarking(bool bench);
+
+ bool isDoubleBuffered() const;
+ void setDoubleBuffered(bool db);
+
+ void setCaptureAtCallNumber(qlonglong num);
+ qlonglong captureAtCallNumber() const;
+
+ bool captureState() const;
+ void setCaptureState(bool enable);
+
+signals:
+ void finished(const QString &output);
+ void foundState(const ApiTraceState &state);
+ void error(const QString &msg);
+
+protected:
+ virtual void run();
+
+private slots:
+ void cleanup();
+private:
+ QString m_fileName;
+ bool m_benchmarking;
+ bool m_doubleBuffered;
+ bool m_captureState;
+ qlonglong m_captureCall;
+
+ QProcessEnvironment m_processEnvironment;
};
#endif