From ca164110d0c5cc54436c425311f0c41e1973abe8 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 11 Apr 2011 02:23:09 -0400 Subject: [PATCH] Implement tracing from the ui. --- gui/CMakeLists.txt | 1 + gui/apitrace.cpp | 2 + gui/apitracemodel.cpp | 2 + gui/mainwindow.cpp | 32 ++++++++++ gui/mainwindow.h | 5 ++ gui/tracedialog.cpp | 2 +- gui/traceprocess.cpp | 137 ++++++++++++++++++++++++++++++++++++++++++ gui/traceprocess.h | 42 +++++++++++++ 8 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 gui/traceprocess.cpp create mode 100644 gui/traceprocess.h diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 1ed291f..d12c9b3 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -17,6 +17,7 @@ set(qapitrace_SRCS settingsdialog.cpp shaderssourcewidget.cpp tracedialog.cpp + traceprocess.cpp vertexdatainterpreter.cpp ) diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp index 45fbfda..6cc360b 100644 --- a/gui/apitrace.cpp +++ b/gui/apitrace.cpp @@ -106,6 +106,8 @@ void ApiTrace::setFileName(const QString &name) m_loader->terminate(); m_loader->wait(); } + m_frames.clear(); + m_calls.clear(); emit invalidated(); m_loader->loadFile(m_fileName); diff --git a/gui/apitracemodel.cpp b/gui/apitracemodel.cpp index 39459ce..eb29a0e 100644 --- a/gui/apitracemodel.cpp +++ b/gui/apitracemodel.cpp @@ -200,6 +200,8 @@ void ApiTraceModel::setApiTrace(ApiTrace *trace) if (m_trace) disconnect(m_trace); m_trace = trace; + connect(m_trace, SIGNAL(invalidated()), + this, SLOT(invalidateFrames())); connect(m_trace, SIGNAL(framesInvalidated()), this, SLOT(invalidateFrames())); connect(m_trace, SIGNAL(framesAdded(int, int)), diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 0ca51b8..f234527 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -11,6 +11,7 @@ #include "settingsdialog.h" #include "shaderssourcewidget.h" #include "tracedialog.h" +#include "traceprocess.h" #include "ui_retracerdialog.h" #include "vertexdatainterpreter.h" @@ -44,9 +45,20 @@ void MainWindow::createTrace() { TraceDialog dialog; + if (!m_traceProcess->canTrace()) { + QMessageBox::warning( + this, + tr("Unsupported"), + tr("Current configuration doesn't support tracing.")); + return; + } + if (dialog.exec() == QDialog::Accepted) { qDebug()<< "App : " <setExecutablePath(dialog.applicationPath()); + m_traceProcess->setArguments(dialog.arguments()); + m_traceProcess->start(); } } @@ -500,6 +512,7 @@ void MainWindow::initObjects() m_ui.centralLayout->addWidget(m_jumpWidget); m_jumpWidget->hide(); + m_traceProcess = new TraceProcess(this); new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_G), this, SLOT(slotGoTo())); @@ -564,6 +577,11 @@ void MainWindow::initConnections() connect(m_jumpWidget, SIGNAL(jumpTo(int)), SLOT(slotJumpTo(int))); + + connect(m_traceProcess, SIGNAL(tracedFile(const QString&)), + SLOT(createdTrace(const QString&))); + connect(m_traceProcess, SIGNAL(error(const QString&)), + SLOT(traceError(const QString&))); } void MainWindow::replayStateFound(const ApiTraceState &state) @@ -590,4 +608,18 @@ void MainWindow::slotJumpTo(int callNum) } } +void MainWindow::createdTrace(const QString &path) +{ + qDebug()<<"Done tracing "<text().split(';'); + argumentsEdit->text().split(';', QString::SkipEmptyParts); return args; } diff --git a/gui/traceprocess.cpp b/gui/traceprocess.cpp new file mode 100644 index 0000000..8074fa1 --- /dev/null +++ b/gui/traceprocess.cpp @@ -0,0 +1,137 @@ +#include "traceprocess.h" + +#include +#include +#include +#include + +static QString +findPreloader() +{ + QString libPath = QString::fromLatin1("%1/libglxtrace.so") + .arg(BUILD_DIR); + + QFileInfo fi(libPath); + if (fi.exists()) + return libPath; + + libPath = QString::fromLatin1("/usr/local/lib/libglxtrace.so"); + fi = QFileInfo(libPath); + if (fi.exists()) + return libPath; + + libPath = QString::fromLatin1("/usr/lib/libglxtrace.so"); + fi = QFileInfo(libPath); + if (fi.exists()) + return libPath; + + return QString(); +} + +TraceProcess::TraceProcess(QObject *parent) + : QObject(parent), + m_canTrace(true) +{ + m_process = new QProcess(this); + + connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(traceFinished())); + connect(m_process, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(traceError(QProcess::ProcessError))); + +#ifdef Q_OS_WIN + qWarning()<<"Windows tracing isn't supported right now!"; + m_canTrace = false; +#else + QString var = QLatin1String("LD_PRELOAD"); + QString libPath = findPreloader(); + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + + if (libPath.isEmpty()) { + m_canTrace = false; + } + + env.insert("LD_PRELOAD", libPath); + qputenv("LD_PRELOAD", env.value("LD_PRELOAD").toLatin1()); + + m_process->setProcessEnvironment(env); +#endif +} + +TraceProcess::~TraceProcess() +{ +} + +void TraceProcess::setExecutablePath(const QString &str) +{ + m_execPath = str; + + QFileInfo fi(m_execPath); + + m_process->setWorkingDirectory(fi.absolutePath()); + + QString format = QString::fromLatin1("%1%2%3.trace"); + + m_tracePath = format + .arg(fi.absolutePath()) + .arg(QDir::separator()) + .arg(fi.baseName()); + + int i = 1; + while (QFile::exists(m_tracePath)) { + QString format = QString::fromLatin1("%1%2%3.%4.trace"); + m_tracePath = format + .arg(fi.absolutePath()) + .arg(QDir::separator()) + .arg(fi.baseName()) + .arg(i++); + } +} + +QString TraceProcess::executablePath() const +{ + return m_execPath; +} + +void TraceProcess::setArguments(const QStringList &args) +{ + m_args = args; +} + +QStringList TraceProcess::arguments() const +{ + return m_args; +} + +void TraceProcess::traceFinished() +{ +#if 0 + qDebug()<<"trace finished on " << m_tracePath; + qDebug()<<"\terr = "<readAllStandardError(); + qDebug()<<"\tout = "<readAllStandardOutput(); +#endif + emit tracedFile(m_tracePath); +} + +void TraceProcess::traceError(QProcess::ProcessError err) +{ +#if 1 + qDebug()<<"trace error = "< +#include + +class TraceProcess : public QObject +{ + Q_OBJECT +public: + TraceProcess(QObject *parent=0); + ~TraceProcess(); + + bool canTrace() const; + + void setExecutablePath(const QString &str); + QString executablePath() const; + + void setArguments(const QStringList &args); + QStringList arguments() const; + +public slots: + void start(); + +signals: + void tracedFile(const QString &tracePath); + void error(const QString &msg); + +private slots: + void traceFinished(); + void traceError(QProcess::ProcessError err); + +private: + QString m_execPath; + QStringList m_args; + QString m_tracePath; + QProcess *m_process; + + bool m_canTrace; +}; + +#endif -- 2.43.0