]> git.cworth.org Git - apitrace/commitdiff
Implement tracing from the ui.
authorZack Rusin <zack@kde.org>
Mon, 11 Apr 2011 06:23:09 +0000 (02:23 -0400)
committerZack Rusin <zack@kde.org>
Mon, 11 Apr 2011 06:23:09 +0000 (02:23 -0400)
gui/CMakeLists.txt
gui/apitrace.cpp
gui/apitracemodel.cpp
gui/mainwindow.cpp
gui/mainwindow.h
gui/tracedialog.cpp
gui/traceprocess.cpp [new file with mode: 0644]
gui/traceprocess.h [new file with mode: 0644]

index 1ed291f8027c0bc9db4955ef6b2f16ed66e06a30..d12c9b3da8966b60eaf2cf6cf986c59bf887a7fc 100644 (file)
@@ -17,6 +17,7 @@ set(qapitrace_SRCS
    settingsdialog.cpp
    shaderssourcewidget.cpp
    tracedialog.cpp
+   traceprocess.cpp
    vertexdatainterpreter.cpp
  )
 
index 45fbfda9004f4ee2944607dc879b29148bd7a72d..6cc360b642e3b8fe3f8d24824ffe5670a7bfd7ba 100644 (file)
@@ -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);
index 39459ce1c7d804aff44d0a64a2bef7903ba8a405..eb29a0e2e2f21c7d97ed4c04789b6cc6378c3246 100644 (file)
@@ -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)),
index 0ca51b8119e829d3936f5c30474dfc327033ad6f..f234527609064b4567411fbd941a4b86d496b7a7 100644 (file)
@@ -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 : " <<dialog.applicationPath();
         qDebug()<< "  Arguments: "<<dialog.arguments();
+        m_traceProcess->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 "<<path;
+    newTraceFile(path);
+}
+
+void MainWindow::traceError(const QString &msg)
+{
+    QMessageBox::warning(
+            this,
+            tr("Tracing Error"),
+            msg);
+}
+
 #include "mainwindow.moc"
index 88017f65981e4a3f084651d288ccf71098a91859..bd483ed2dab1cb1a4149d5ec4b4f4d6b31cf190f 100644 (file)
@@ -20,6 +20,7 @@ class QProgressBar;
 class QUrl;
 class Retracer;
 class ShadersSourceWidget;
+class TraceProcess;
 class VertexDataInterpreter;
 
 class MainWindow : public QMainWindow
@@ -51,6 +52,8 @@ private slots:
     void showSelectedSurface();
     void slotGoTo();
     void slotJumpTo(int callNum);
+    void createdTrace(const QString &path);
+    void traceError(const QString &msg);
 
 private:
     void initObjects();
@@ -83,6 +86,8 @@ private:
     ImageViewer *m_imageViewer;
 
     JumpWidget *m_jumpWidget;
+
+    TraceProcess *m_traceProcess;
 };
 
 
index a25c7aca9ad133977dc960fc12a3508c3ad68710..bed517368ff243c147774b3f254ddd1e25b0e86f 100644 (file)
@@ -21,7 +21,7 @@ QString TraceDialog::applicationPath() const
 QStringList TraceDialog::arguments() const
 {
     QStringList args =
-        argumentsEdit->text().split(';');
+        argumentsEdit->text().split(';', QString::SkipEmptyParts);
     return args;
 }
 
diff --git a/gui/traceprocess.cpp b/gui/traceprocess.cpp
new file mode 100644 (file)
index 0000000..8074fa1
--- /dev/null
@@ -0,0 +1,137 @@
+#include "traceprocess.h"
+
+#include <QDebug>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+
+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 = "<<m_process->readAllStandardError();
+    qDebug()<<"\tout = "<<m_process->readAllStandardOutput();
+#endif
+    emit tracedFile(m_tracePath);
+}
+
+void TraceProcess::traceError(QProcess::ProcessError err)
+{
+#if 1
+    qDebug()<<"trace error = "<<m_tracePath;
+    qDebug()<<"\terr = "<<m_process->readAllStandardError();
+    qDebug()<<"\tout = "<<m_process->readAllStandardOutput();
+#endif
+    emit error(m_process->readAllStandardError());
+}
+
+
+void TraceProcess::start()
+{
+    m_process->start(m_execPath, m_args);
+}
+
+bool TraceProcess::canTrace() const
+{
+    return m_canTrace;
+}
+
+#include "traceprocess.moc"
diff --git a/gui/traceprocess.h b/gui/traceprocess.h
new file mode 100644 (file)
index 0000000..b65f41c
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef TRACEPROCESS_H
+#define TRACEPROCESS_H
+
+#include <QObject>
+#include <QProcess>
+
+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