[PATCH] Add trim support to qapitrace GUI app

Dan McCabe zen3d.linux at gmail.com
Thu Mar 15 12:29:23 PDT 2012


:)

Actually, that was an approach I considered. But in the end, I took the 
path of least resistance. I did what looked like the smallest change in 
the existing code base, using as a model what was already there. But I'm 
not married to this particular implementation.

I'd be glad to reconsider the alternative. It might take a little longer 
though.

cheers, danm

On 03/15/2012 12:02 PM, José Fonseca wrote:
> Usually I'd say that trim is one of those transformations that would
> be better easily done inside the GUI process, without forking a
> separate apitrace command.
>
> But honestly I don't know any more. There's simply not enough people
> working on the GUI for me to be picky about these things. And having
> the GUI to be a layer on top of the the CLI might actually be a good
> way to ensure the GUI keeps receiving more new features, without too
> much code duplication.  At the end of the day, the GUI user doesn't
> care how we implement stuff as long as it works..
>
> What are your thoughts on this, Zack?
>
> Jose
>
> On Thu, Mar 15, 2012 at 3:33 PM, Dan McCabe<zen3d.linux at gmail.com>  wrote:
>> 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 all calls after the selected call or frame. New
>> trace files are created automatically in numerical sequence, similar
>> to how new trace files are currently created in the GUI.
>>
>> 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.
>> ---
>>   gui/CMakeLists.txt   |    1 +
>>   gui/mainwindow.cpp   |   55 +++++++++++++++++++++++
>>   gui/mainwindow.h     |    9 ++++
>>   gui/trimprocess.cpp  |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>   gui/trimprocess.h    |   42 ++++++++++++++++++
>>   gui/ui/mainwindow.ui |   12 +++++
>>   6 files changed, 238 insertions(+), 0 deletions(-)
>>   create mode 100644 gui/trimprocess.cpp
>>   create mode 100644 gui/trimprocess.h
>>
>> diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt
>> index f464cb0..3c0bee3 100644
>> --- a/gui/CMakeLists.txt
>> +++ b/gui/CMakeLists.txt
>> @@ -22,6 +22,7 @@ set(qapitrace_SRCS
>>     tracedialog.cpp
>>     traceloader.cpp
>>     traceprocess.cpp
>> +   trimprocess.cpp
>>     vertexdatainterpreter.cpp
>>   )
>>
>> diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
>> index 672ad64..0c50a77 100644
>> --- a/gui/mainwindow.cpp
>> +++ b/gui/mainwindow.cpp
>> @@ -14,6 +14,7 @@
>>   #include "shaderssourcewidget.h"
>>   #include "tracedialog.h"
>>   #include "traceprocess.h"
>> +#include "trimprocess.h"
>>   #include "ui_retracerdialog.h"
>>   #include "vertexdatainterpreter.h"
>>
>> @@ -33,6 +34,7 @@
>>   #include<QWebPage>
>>   #include<QWebView>
>>
>> +#include<iostream>
>>
>>   MainWindow::MainWindow()
>>      : QMainWindow(),
>> @@ -199,6 +201,7 @@ void MainWindow::newTraceFile(const QString&fileName)
>>          QFileInfo info(fileName);
>>          m_ui.actionReplay->setEnabled(true);
>>          m_ui.actionLookupState->setEnabled(true);
>> +        m_ui.actionTrim->setEnabled(true);
>>          setWindowTitle(
>>              tr("QApiTrace - %1").arg(info.fileName()));
>>      }
>> @@ -305,6 +308,25 @@ void MainWindow::replayTrace(bool dumpState)
>>      }
>>   }
>>
>> +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) {
>> @@ -325,6 +347,18 @@ void MainWindow::lookupState()
>>      replayTrace(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;
>> @@ -706,6 +740,7 @@ void MainWindow::initObjects()
>>      m_searchWidget->hide();
>>
>>      m_traceProcess = new TraceProcess(this);
>> +    m_trimProcess = new TrimProcess(this);
>>   }
>>
>>   void MainWindow::initConnections()
>> @@ -774,6 +809,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.actionOptions, SIGNAL(triggered()),
>>              this, SLOT(showSettings()));
>>
>> @@ -810,6 +847,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)),
>> @@ -857,6 +899,19 @@ void MainWindow::traceError(const QString&msg)
>>              msg);
>>   }
>>
>> +void MainWindow::createdTrim(const QString&path)
>> +{
>> +    qDebug()<<"Done trimming"<<path;
>> +}
>> +
>> +void MainWindow::trimError(const QString&msg)
>> +{
>> +    QMessageBox::warning(
>> +            this,
>> +            tr("Trim Error"),
>> +            msg);
>> +}
>> +
>>   void MainWindow::slotSearch()
>>   {
>>      m_jumpWidget->hide();
>> diff --git a/gui/mainwindow.h b/gui/mainwindow.h
>> index 59c9ba7..ccbcef0 100644
>> --- a/gui/mainwindow.h
>> +++ b/gui/mainwindow.h
>> @@ -27,6 +27,7 @@ class Retracer;
>>   class SearchWidget;
>>   class ShadersSourceWidget;
>>   class TraceProcess;
>> +class TrimProcess;
>>   class VertexDataInterpreter;
>>
>>   class MainWindow : public QMainWindow
>> @@ -52,6 +53,7 @@ private slots:
>>      void loadProgess(int percent);
>>      void finishedLoadingTrace();
>>      void lookupState();
>> +    void trim();
>>      void showSettings();
>>      void openHelp(const QUrl&url);
>>      void showSurfacesMenu(const QPoint&pos);
>> @@ -61,6 +63,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);
>> @@ -86,6 +90,7 @@ private:
>>      void initConnections();
>>      void newTraceFile(const QString&fileName);
>>      void replayTrace(bool dumpState);
>> +    void trimEvent();
>>      void fillStateForFrame();
>>
>>      /* there's a difference between selected frame/call and
>> @@ -115,6 +120,8 @@ private:
>>
>>      ApiTraceEvent *m_stateEvent;
>>
>> +    ApiTraceEvent *m_trimEvent;
>> +
>>      Retracer *m_retracer;
>>
>>      VertexDataInterpreter *m_vdataInterpreter;
>> @@ -124,6 +131,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
>> index 0000000..5489210
>> --- /dev/null
>> +++ b/gui/trimprocess.cpp
>> @@ -0,0 +1,119 @@
>> +#include "trimprocess.h"
>> +#include "apitrace.h"
>> +
>> +#include<iostream>
>> +
>> +#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;
>> +}
>> +
>> +void TrimProcess::setTracePath(const QString&str)
>> +{
>> +    m_tracePath = str;
>> +
>> +    QFileInfo fi(m_tracePath);
>> +    QString baseName = fi.baseName();
>> +
>> +    QString format = QString::fromLatin1("%1.trim.trace");
>> +
>> +    m_trimPath = format
>> +                  .arg(baseName);
>> +
>> +    int i = 1;
>> +    while (QFile::exists(m_trimPath)) {
>> +        format = QString::fromLatin1("%1.%2.trim.trace");
>> +        m_trimPath = format
>> +                      .arg(baseName)
>> +                      .arg(i++);
>> +    }
>> +}
>> +
>> +QString TrimProcess::tracePath() const
>> +{
>> +    return m_tracePath;
>> +}
>> +
>> +#include "trimprocess.moc"
>> diff --git a/gui/trimprocess.h b/gui/trimprocess.h
>> new file mode 100644
>> index 0000000..2252673
>> --- /dev/null
>> +++ b/gui/trimprocess.h
>> @@ -0,0 +1,42 @@
>> +#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;
>> +
>> +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
>> diff --git a/gui/ui/mainwindow.ui b/gui/ui/mainwindow.ui
>> index 5b48dc2..8e1f95a 100644
>> --- a/gui/ui/mainwindow.ui
>> +++ b/gui/ui/mainwindow.ui
>> @@ -75,6 +75,7 @@
>>      <addaction name="actionReplay"/>
>>      <addaction name="actionStop"/>
>>      <addaction name="actionLookupState"/>
>> +<addaction name="actionTrim"/>
>>      <addaction name="separator"/>
>>      <addaction name="actionOptions"/>
>>     </widget>
>> @@ -525,6 +526,17 @@
>>      <string>Ctrl+L</string>
>>     </property>
>>    </action>
>> +<action name="actionTrim">
>> +<property name="enabled">
>> +<bool>false</bool>
>> +</property>
>> +<property name="text">
>> +<string>Trim</string>
>> +</property>
>> +<property name="shortcut">
>> +<string>Ctrl+T</string>
>> +</property>
>> +</action>
>>    <action name="actionOptions">
>>     <property name="text">
>>      <string>Options</string>
>> --
>> 1.7.5.4
>>
>> _______________________________________________
>> apitrace mailing list
>> apitrace at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/apitrace



More information about the apitrace mailing list