blob: 8f3508770457b6ac36fcaf6ff31de4d393904703 [file] [log] [blame]
Zack Rusin3acde362011-04-06 01:11:55 -04001#include "retracer.h"
2
Zack Rusinf389ae82011-04-10 19:27:28 -04003#include "apitracecall.h"
4
Zack Rusin3acde362011-04-06 01:11:55 -04005#include <QDebug>
Zack Rusinf389ae82011-04-10 19:27:28 -04006#include <QVariant>
7
8#include <qjson/parser.h>
Zack Rusin3acde362011-04-06 01:11:55 -04009
10Retracer::Retracer(QObject *parent)
Zack Rusinf389ae82011-04-10 19:27:28 -040011 : QThread(parent),
Zack Rusin3acde362011-04-06 01:11:55 -040012 m_benchmarking(true),
13 m_doubleBuffered(true),
14 m_captureState(false),
Zack Rusinf389ae82011-04-10 19:27:28 -040015 m_captureCall(0)
Zack Rusin3acde362011-04-06 01:11:55 -040016{
Zack Rusinf389ae82011-04-10 19:27:28 -040017#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());
Zack Rusin3acde362011-04-06 01:11:55 -040029}
30
31QString Retracer::fileName() const
32{
33 return m_fileName;
34}
35
36void Retracer::setFileName(const QString &name)
37{
38 m_fileName = name;
39}
40
41bool Retracer::isBenchmarking() const
42{
43 return m_benchmarking;
44}
45
46void Retracer::setBenchmarking(bool bench)
47{
48 m_benchmarking = bench;
49}
50
51bool Retracer::isDoubleBuffered() const
52{
53 return m_doubleBuffered;
54}
55
56void Retracer::setDoubleBuffered(bool db)
57{
58 m_doubleBuffered = db;
59}
60
Zack Rusin3acde362011-04-06 01:11:55 -040061void Retracer::setCaptureAtCallNumber(qlonglong num)
62{
63 m_captureCall = num;
64}
65
66qlonglong Retracer::captureAtCallNumber() const
67{
68 return m_captureCall;
69}
70
71bool Retracer::captureState() const
72{
73 return m_captureState;
74}
75
76void Retracer::setCaptureState(bool enable)
77{
78 m_captureState = enable;
79}
80
Zack Rusinf389ae82011-04-10 19:27:28 -040081
82void 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
117void RetraceProcess::start()
118{
119 QStringList arguments;
120 if (m_captureState) {
121 arguments << QLatin1String("-D");
122 arguments << QString::number(m_captureCall);
123 } else {
124 if (m_benchmarking) {
125 arguments << QLatin1String("-b");
126 }
127 if (m_doubleBuffered) {
128 arguments << QLatin1String("-db");
129 }
130 }
131
132 arguments << m_fileName;
133
134 m_process->start(QLatin1String("glretrace"), arguments);
135}
136
137
138void RetraceProcess::replayFinished()
Zack Rusin3acde362011-04-06 01:11:55 -0400139{
140 QByteArray output = m_process->readAllStandardOutput();
Zack Rusinf389ae82011-04-10 19:27:28 -0400141 QString msg;
Zack Rusin3acde362011-04-06 01:11:55 -0400142
143#if 0
144 qDebug()<<"Process finished = ";
145 qDebug()<<"\terr = "<<m_process->readAllStandardError();
146 qDebug()<<"\tout = "<<output;
147#endif
Zack Rusinf389ae82011-04-10 19:27:28 -0400148 if (m_captureState) {
149 bool ok = false;
150 QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap();
151 ApiTraceState state(parsedJson);
152 emit foundState(state);
153 msg = tr("State fetched.");
154 } else {
155 msg = QString::fromUtf8(output);
156 }
157
158 emit finished(msg);
Zack Rusin3acde362011-04-06 01:11:55 -0400159}
160
Zack Rusinf389ae82011-04-10 19:27:28 -0400161void RetraceProcess::replayError(QProcess::ProcessError err)
Zack Rusin3acde362011-04-06 01:11:55 -0400162{
163 qDebug()<<"Process error = "<<err;
164 qDebug()<<"\terr = "<<m_process->readAllStandardError();
165 qDebug()<<"\tout = "<<m_process->readAllStandardOutput();
166
167 emit error(
168 tr("Couldn't execute the replay file '%1'").arg(m_fileName));
169}
170
Zack Rusinf389ae82011-04-10 19:27:28 -0400171
172RetraceProcess::RetraceProcess(QObject *parent)
173 : QObject(parent)
174{
175 m_process = new QProcess(this);
176 m_jsonParser = new QJson::Parser();
177
178 connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
179 this, SLOT(replayFinished()));
180 connect(m_process, SIGNAL(error(QProcess::ProcessError)),
181 this, SLOT(replayError(QProcess::ProcessError)));
182}
183
184QProcess * RetraceProcess::process() const
185{
186 return m_process;
187}
188
189QString RetraceProcess::fileName() const
190{
191 return m_fileName;
192}
193
194void RetraceProcess::setFileName(const QString &name)
195{
196 m_fileName = name;
197}
198
199bool RetraceProcess::isBenchmarking() const
200{
201 return m_benchmarking;
202}
203
204void RetraceProcess::setBenchmarking(bool bench)
205{
206 m_benchmarking = bench;
207}
208
209bool RetraceProcess::isDoubleBuffered() const
210{
211 return m_doubleBuffered;
212}
213
214void RetraceProcess::setDoubleBuffered(bool db)
215{
216 m_doubleBuffered = db;
217}
218
219void RetraceProcess::setCaptureAtCallNumber(qlonglong num)
220{
221 m_captureCall = num;
222}
223
224qlonglong RetraceProcess::captureAtCallNumber() const
225{
226 return m_captureCall;
227}
228
229bool RetraceProcess::captureState() const
230{
231 return m_captureState;
232}
233
234void RetraceProcess::setCaptureState(bool enable)
235{
236 m_captureState = enable;
237}
238
239void RetraceProcess::terminate()
240{
241 if (m_process) {
242 m_process->terminate();
243 emit finished(tr("Process terminated."));
244 }
245}
246
247void Retracer::cleanup()
248{
249 quit();
250}
251
252RetraceProcess::~RetraceProcess()
253{
254 delete m_jsonParser;
255}
256
Zack Rusin3acde362011-04-06 01:11:55 -0400257#include "retracer.moc"