]> git.cworth.org Git - apitrace/blob - gui/retracer.cpp
Respect the double buffered option when looking up the state.
[apitrace] / gui / retracer.cpp
1 #include "retracer.h"
2
3 #include "apitracecall.h"
4
5 #include <QDebug>
6 #include <QVariant>
7
8 #include <qjson/parser.h>
9
10 Retracer::Retracer(QObject *parent)
11     : QThread(parent),
12       m_benchmarking(true),
13       m_doubleBuffered(true),
14       m_captureState(false),
15       m_captureCall(0)
16 {
17 #ifdef Q_OS_WIN
18     QString format = QLatin1String("%1;");
19 #else
20     QString format = QLatin1String("%1:");
21 #endif
22     QString buildPath = format.arg(BUILD_DIR);
23     m_processEnvironment = QProcessEnvironment::systemEnvironment();
24     m_processEnvironment.insert("PATH", buildPath +
25                                 m_processEnvironment.value("PATH"));
26
27     qputenv("PATH",
28             m_processEnvironment.value("PATH").toLatin1());
29 }
30
31 QString Retracer::fileName() const
32 {
33     return m_fileName;
34 }
35
36 void Retracer::setFileName(const QString &name)
37 {
38     m_fileName = name;
39 }
40
41 bool Retracer::isBenchmarking() const
42 {
43     return m_benchmarking;
44 }
45
46 void Retracer::setBenchmarking(bool bench)
47 {
48     m_benchmarking = bench;
49 }
50
51 bool Retracer::isDoubleBuffered() const
52 {
53     return m_doubleBuffered;
54 }
55
56 void Retracer::setDoubleBuffered(bool db)
57 {
58     m_doubleBuffered = db;
59 }
60
61 void Retracer::setCaptureAtCallNumber(qlonglong num)
62 {
63     m_captureCall = num;
64 }
65
66 qlonglong Retracer::captureAtCallNumber() const
67 {
68     return m_captureCall;
69 }
70
71 bool Retracer::captureState() const
72 {
73     return m_captureState;
74 }
75
76 void Retracer::setCaptureState(bool enable)
77 {
78     m_captureState = enable;
79 }
80
81
82 void Retracer::run()
83 {
84     RetraceProcess *retrace = new RetraceProcess();
85     retrace->process()->setProcessEnvironment(m_processEnvironment);
86
87     retrace->setFileName(m_fileName);
88     retrace->setBenchmarking(m_benchmarking);
89     retrace->setDoubleBuffered(m_doubleBuffered);
90     retrace->setCaptureState(m_captureState);
91     retrace->setCaptureAtCallNumber(m_captureCall);
92
93     connect(retrace, SIGNAL(finished(const QString&)),
94             this, SLOT(cleanup()));
95     connect(retrace, SIGNAL(error(const QString&)),
96             this, SLOT(cleanup()));
97     connect(retrace, SIGNAL(finished(const QString&)),
98             this, SIGNAL(finished(const QString&)));
99     connect(retrace, SIGNAL(error(const QString&)),
100             this, SIGNAL(error(const QString&)));
101     connect(retrace, SIGNAL(foundState(const ApiTraceState&)),
102             this, SIGNAL(foundState(const ApiTraceState&)));
103
104     retrace->start();
105
106     exec();
107
108     /* means we need to kill the process */
109     if (retrace->process()->state() != QProcess::NotRunning) {
110         retrace->terminate();
111     }
112
113     delete retrace;
114 }
115
116
117 void RetraceProcess::start()
118 {
119     QStringList arguments;
120
121     if (m_doubleBuffered) {
122         arguments << QLatin1String("-db");
123     }
124
125     if (m_captureState) {
126         arguments << QLatin1String("-D");
127         arguments << QString::number(m_captureCall);
128     } else {
129         if (m_benchmarking) {
130             arguments << QLatin1String("-b");
131         }
132     }
133
134     arguments << m_fileName;
135
136     m_process->start(QLatin1String("glretrace"), arguments);
137 }
138
139
140 void RetraceProcess::replayFinished()
141 {
142     QByteArray output = m_process->readAllStandardOutput();
143     QString msg;
144
145 #if 0
146     qDebug()<<"Process finished = ";
147     qDebug()<<"\terr = "<<m_process->readAllStandardError();
148     qDebug()<<"\tout = "<<output;
149 #endif
150     if (m_captureState) {
151         bool ok = false;
152         QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap();
153         ApiTraceState state(parsedJson);
154         emit foundState(state);
155         msg = tr("State fetched.");
156     } else {
157         msg = QString::fromUtf8(output);
158     }
159
160     emit finished(msg);
161 }
162
163 void RetraceProcess::replayError(QProcess::ProcessError err)
164 {
165     qDebug()<<"Process error = "<<err;
166     qDebug()<<"\terr = "<<m_process->readAllStandardError();
167     qDebug()<<"\tout = "<<m_process->readAllStandardOutput();
168
169     emit error(
170         tr("Couldn't execute the replay file '%1'").arg(m_fileName));
171 }
172
173
174 RetraceProcess::RetraceProcess(QObject *parent)
175     : QObject(parent)
176 {
177     m_process = new QProcess(this);
178     m_jsonParser = new QJson::Parser();
179
180     connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
181             this, SLOT(replayFinished()));
182     connect(m_process, SIGNAL(error(QProcess::ProcessError)),
183             this, SLOT(replayError(QProcess::ProcessError)));
184 }
185
186 QProcess * RetraceProcess::process() const
187 {
188     return m_process;
189 }
190
191 QString RetraceProcess::fileName() const
192 {
193     return m_fileName;
194 }
195
196 void RetraceProcess::setFileName(const QString &name)
197 {
198     m_fileName = name;
199 }
200
201 bool RetraceProcess::isBenchmarking() const
202 {
203     return m_benchmarking;
204 }
205
206 void RetraceProcess::setBenchmarking(bool bench)
207 {
208     m_benchmarking = bench;
209 }
210
211 bool RetraceProcess::isDoubleBuffered() const
212 {
213     return m_doubleBuffered;
214 }
215
216 void RetraceProcess::setDoubleBuffered(bool db)
217 {
218     m_doubleBuffered = db;
219 }
220
221 void RetraceProcess::setCaptureAtCallNumber(qlonglong num)
222 {
223     m_captureCall = num;
224 }
225
226 qlonglong RetraceProcess::captureAtCallNumber() const
227 {
228     return m_captureCall;
229 }
230
231 bool RetraceProcess::captureState() const
232 {
233     return m_captureState;
234 }
235
236 void RetraceProcess::setCaptureState(bool enable)
237 {
238     m_captureState = enable;
239 }
240
241 void RetraceProcess::terminate()
242 {
243     if (m_process) {
244         m_process->terminate();
245         emit finished(tr("Process terminated."));
246     }
247 }
248
249 void Retracer::cleanup()
250 {
251     quit();
252 }
253
254 RetraceProcess::~RetraceProcess()
255 {
256     delete m_jsonParser;
257 }
258
259 #include "retracer.moc"