]> git.cworth.org Git - apitrace/commitdiff
Add trim support to qapitrace GUI app.
authorDan McCabe <zen3d.linux@gmail.com>
Wed, 21 Mar 2012 16:53:45 +0000 (09:53 -0700)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Wed, 11 Apr 2012 21:21:33 +0000 (22:21 +0100)
This patch adds support for trimming of traces via the qapitrace GUI.
We enhance the GUI by adding a Trim entry to the Trace menu. When the
user selects either a frame or a call, the "apitrace trim" command
will be invoked to trim all calls after the selected call or frame.
New trace files are created automatically and named according to the
last call number in the trimmed trace.

For example, if the original trace file is:
   /path/foo.trace
and the trace is trimmed after call 1234, the name of the trimmed trace
file will be named:
   /path/foo.1234.trim.trace

Upon trimming, the trimmed trace file will be loaded into qapitrace.

First, we enhance the Trace menu of the GUI app.

Next, we add a TrimProcess class. This is modelled on the TraceProcess
class, but takes into account differences and simplifications.

Next, we tie the TrimProcess class into the main window by accessing
that class and its members appropriately as well as tieing in message
communication with that class.

Finally, we add a reference to the source of TrimProcess to the make
system.

Signed-off-by: José Fonseca <jose.r.fonseca@gmail.com>
gui/CMakeLists.txt
gui/mainwindow.cpp
gui/mainwindow.h
gui/trimprocess.cpp [new file with mode: 0644]
gui/trimprocess.h [new file with mode: 0644]
gui/ui/mainwindow.ui

index 26346f25ed14d4b1a5c0317bda56b376ba9d2a32..070aca70faaac02b58a1f9195506a8cd3a4ccbbd 100644 (file)
@@ -22,6 +22,7 @@ set(qapitrace_SRCS
    tracedialog.cpp
    traceloader.cpp
    traceprocess.cpp
+   trimprocess.cpp
    vertexdatainterpreter.cpp
  )
 
index 5e2a55db7fc7af4e4e3df59dfc010b0394ff0e35..2e39bb8134099a1d1691baddd4428aa188fb8e97 100644 (file)
@@ -14,6 +14,7 @@
 #include "shaderssourcewidget.h"
 #include "tracedialog.h"
 #include "traceprocess.h"
+#include "trimprocess.h"
 #include "thumbnail.h"
 #include "ui_retracerdialog.h"
 #include "vertexdatainterpreter.h"
@@ -207,6 +208,7 @@ void MainWindow::newTraceFile(const QString &fileName)
         m_ui.actionReplay->setEnabled(true);
         m_ui.actionLookupState->setEnabled(true);
         m_ui.actionShowThumbnails->setEnabled(true);
+        m_ui.actionTrim->setEnabled(true);
         setWindowTitle(
             tr("QApiTrace - %1").arg(info.fileName()));
     }
@@ -320,6 +322,25 @@ void MainWindow::replayTrace(bool dumpState, bool dumpThumbnails)
     }
 }
 
+void MainWindow::trimEvent()
+{
+
+    int trimIndex;
+    if (m_trimEvent->type() == ApiTraceEvent::Call) {
+        ApiTraceCall *call = static_cast<ApiTraceCall*>(m_trimEvent);
+        trimIndex = call->index();
+    } else if (m_trimEvent->type() == ApiTraceEvent::Frame) {
+        ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(m_trimEvent);
+        const QList<ApiTraceFrame*> frames = m_trace->frames();
+        trimIndex = frame->lastCallIndex();
+    }
+
+    m_trimProcess->setTracePath(m_trace->fileName());
+    m_trimProcess->setTrimIndex(trimIndex);
+
+    m_trimProcess->start();
+}
+
 void MainWindow::lookupState()
 {
     if (!m_selectedEvent) {
@@ -345,6 +366,18 @@ void MainWindow::showThumbnails()
     replayTrace(false, true);
 }
 
+void MainWindow::trim()
+{
+    if (!m_selectedEvent) {
+        QMessageBox::warning(
+            this, tr("Unknown Event"),
+            tr("To trim select a frame or an event in the event list."));
+        return;
+    }
+    m_trimEvent = m_selectedEvent;
+    trimEvent();
+}
+
 MainWindow::~MainWindow()
 {
     delete m_trace;
@@ -726,6 +759,7 @@ void MainWindow::initObjects()
     m_searchWidget->hide();
 
     m_traceProcess = new TraceProcess(this);
+    m_trimProcess = new TrimProcess(this);
 }
 
 void MainWindow::initConnections()
@@ -796,6 +830,8 @@ void MainWindow::initConnections()
             this, SLOT(replayStop()));
     connect(m_ui.actionLookupState, SIGNAL(triggered()),
             this, SLOT(lookupState()));
+    connect(m_ui.actionTrim, SIGNAL(triggered()),
+            this, SLOT(trim()));
     connect(m_ui.actionShowThumbnails, SIGNAL(triggered()),
             this, SLOT(showThumbnails()));
     connect(m_ui.actionOptions, SIGNAL(triggered()),
@@ -836,6 +872,11 @@ void MainWindow::initConnections()
     connect(m_traceProcess, SIGNAL(error(const QString&)),
             SLOT(traceError(const QString&)));
 
+    connect(m_trimProcess, SIGNAL(trimmedFile(const QString&)),
+            SLOT(createdTrim(const QString&)));
+    connect(m_trimProcess, SIGNAL(error(const QString&)),
+            SLOT(trimError(const QString&)));
+
     connect(m_ui.errorsDock, SIGNAL(visibilityChanged(bool)),
             m_ui.actionShowErrorsDock, SLOT(setChecked(bool)));
     connect(m_ui.actionShowErrorsDock, SIGNAL(triggered(bool)),
@@ -889,6 +930,21 @@ void MainWindow::traceError(const QString &msg)
             msg);
 }
 
+void MainWindow::createdTrim(const QString &path)
+{
+    qDebug()<<"Done trimming "<<path;
+
+    newTraceFile(path);
+}
+
+void MainWindow::trimError(const QString &msg)
+{
+    QMessageBox::warning(
+            this,
+            tr("Trim Error"),
+            msg);
+}
+
 void MainWindow::slotSearch()
 {
     m_jumpWidget->hide();
index a8f8c1d4658f3ccfc36f45223a7164e3991cbe38..1346b86377415ba5e16a1c625a0480683fcd59eb 100644 (file)
@@ -29,6 +29,7 @@ class Retracer;
 class SearchWidget;
 class ShadersSourceWidget;
 class TraceProcess;
+class TrimProcess;
 class VertexDataInterpreter;
 
 class MainWindow : public QMainWindow
@@ -57,6 +58,7 @@ private slots:
     void finishedLoadingTrace();
     void lookupState();
     void showThumbnails();
+    void trim();
     void showSettings();
     void openHelp(const QUrl &url);
     void showSurfacesMenu(const QPoint &pos);
@@ -66,6 +68,8 @@ private slots:
     void slotJumpTo(int callNum);
     void createdTrace(const QString &path);
     void traceError(const QString &msg);
+    void createdTrim(const QString &path);
+    void trimError(const QString &msg);
     void slotSearch();
     void slotSearchNext(const QString &str, Qt::CaseSensitivity sensitivity);
     void slotSearchPrev(const QString &str, Qt::CaseSensitivity sensitivity);
@@ -91,6 +95,7 @@ private:
     void initConnections();
     void newTraceFile(const QString &fileName);
     void replayTrace(bool dumpState, bool dumpThumbnails);
+    void trimEvent();
     void fillStateForFrame();
 
     /* there's a difference between selected frame/call and
@@ -120,6 +125,8 @@ private:
 
     ApiTraceEvent *m_stateEvent;
 
+    ApiTraceEvent *m_trimEvent;
+
     Retracer *m_retracer;
 
     VertexDataInterpreter *m_vdataInterpreter;
@@ -129,6 +136,8 @@ private:
 
     TraceProcess *m_traceProcess;
 
+    TrimProcess *m_trimProcess;
+
     ArgumentsEditor *m_argsEditor;
 
     ApiTraceEvent *m_nonDefaultsLookupEvent;
diff --git a/gui/trimprocess.cpp b/gui/trimprocess.cpp
new file mode 100644 (file)
index 0000000..c23475d
--- /dev/null
@@ -0,0 +1,120 @@
+#include "trimprocess.h"
+#include "apitrace.h"
+
+#include <QDebug>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+
+TrimProcess::TrimProcess(QObject *parent)
+    : QObject(parent)
+{
+    m_process = new QProcess(this);
+
+    connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
+            this, SLOT(trimFinished()));
+    connect(m_process, SIGNAL(error(QProcess::ProcessError)),
+            this, SLOT(trimError(QProcess::ProcessError)));
+
+#ifdef Q_OS_WIN
+    QString format = QLatin1String("%1;");
+#else
+    QString format = QLatin1String("%1:");
+#endif
+    QString buildPath = format.arg(APITRACE_BINARY_DIR);
+    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+    env.insert("PATH", buildPath + env.value("PATH"));
+    qputenv("PATH", env.value("PATH").toLatin1());
+}
+
+TrimProcess::~TrimProcess()
+{
+}
+
+void TrimProcess::trimFinished()
+{
+    // consume verbose output spew
+    QByteArray outputStrings = m_process->readAllStandardOutput();
+    QByteArray errorStrings = m_process->readAllStandardError();
+#if 0
+    qDebug()<<"trim finished on " << m_trimPath;
+    qDebug()<<"\terr = "<<errorStrings;
+    qDebug()<<"\tout = "<<outputStrings;
+#endif
+    emit trimmedFile(m_trimPath);
+}
+
+void TrimProcess::trimError(QProcess::ProcessError err)
+{
+    // consume verbose output spew
+    QByteArray outputStrings = m_process->readAllStandardOutput();
+    QByteArray errorStrings = m_process->readAllStandardError();
+#if 1
+    qDebug()<<"trace error = "<<m_tracePath;
+    qDebug()<<"\terr = "<<errorStrings;
+    qDebug()<<"\tout = "<<outputStrings;
+#endif
+    emit error(errorStrings);
+}
+
+
+void TrimProcess::start()
+{
+    QStringList arguments;
+
+    QString outputFormat = QLatin1String("--output=%1");
+    QString outputArgument = outputFormat
+                                .arg(m_trimPath);
+
+    QString callSetFormat = QLatin1String("--calls=0-%1");
+    QString callSetArgument = callSetFormat
+                                .arg(m_trimIndex);
+
+    arguments << QLatin1String("trim");
+    arguments << outputArgument;
+    arguments << callSetArgument;
+    arguments << m_tracePath;
+
+    m_process->start(QLatin1String("apitrace"), arguments);
+}
+
+int TrimProcess::trimIndex()
+{
+    return m_trimIndex;
+}
+
+void TrimProcess::setTrimIndex(int trimIndex)
+{
+    m_trimIndex = trimIndex;
+
+    updateTrimPath();
+}
+
+void TrimProcess::setTracePath(const QString &str)
+{
+    m_tracePath = str;
+
+    updateTrimPath();
+}
+
+QString TrimProcess::tracePath() const
+{
+    return m_tracePath;
+}
+
+void TrimProcess::updateTrimPath()
+{
+
+    QFileInfo fi(m_tracePath);
+    QString baseName = fi.baseName();
+    QString path = fi.path();
+
+    QString format = QString::fromLatin1("%1/%2.%3.trim.trace");
+
+    m_trimPath = format
+                  .arg(path)
+                  .arg(baseName)
+                  .arg(m_trimIndex);
+}
+
+#include "trimprocess.moc"
diff --git a/gui/trimprocess.h b/gui/trimprocess.h
new file mode 100644 (file)
index 0000000..1cc796c
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef TRIMPROCESS_H
+#define TRIMPROCESS_H
+
+#include "apitrace.h"
+
+#include <QObject>
+#include <QProcess>
+
+class TrimProcess : public QObject
+{
+    Q_OBJECT
+public:
+    TrimProcess(QObject *parent=0);
+    ~TrimProcess();
+
+    void setTrimIndex(int trimIndex);
+    int trimIndex();
+
+    void setTracePath(const QString &str);
+    QString tracePath() const;
+
+private:
+    void updateTrimPath();
+
+public slots:
+    void start();
+
+signals:
+    void trimmedFile(const QString &trimPath);
+    void error(const QString &msg);
+
+private slots:
+    void trimFinished();
+    void trimError(QProcess::ProcessError err);
+
+private:
+    QStringList m_args;
+    QString m_tracePath;
+    QString m_trimPath;
+    ApiTraceEvent *m_trimEvent;
+    int m_trimIndex;
+    QProcess *m_process;
+};
+
+#endif
index 52cf49ed85040f7fe2bb4c6eb550667589c24914..cb60ad9f3b36214d6f3cf02cbe847cb54d42d286 100644 (file)
@@ -76,6 +76,7 @@
     <addaction name="actionStop"/>
     <addaction name="actionLookupState"/>
     <addaction name="actionShowThumbnails"/>
+    <addaction name="actionTrim"/>
     <addaction name="separator"/>
     <addaction name="actionOptions"/>
    </widget>
     <string>Ctrl+T</string>
    </property>
   </action>
+  <action name="actionTrim">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>Tr&amp;im</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+I</string>
+   </property>
+  </action>
   <action name="actionOptions">
    <property name="text">
     <string>Options</string>