blob: 89385b9c58cfe200f4ba80e4cd4eec15bad2574b [file] [log] [blame]
Zack Rusinf6667d12011-03-30 11:03:37 -04001#include "apitrace.h"
2
Zack Rusinebf971e2011-09-06 17:44:43 -04003#include "traceloader.h"
Zack Rusind809a062011-04-17 23:30:58 -04004#include "saverthread.h"
Zack Rusinf6667d12011-03-30 11:03:37 -04005
Zack Rusin3176ebe2011-09-06 21:11:36 -04006#include <QDebug>
Zack Rusin63efea82011-04-17 17:10:45 -04007#include <QDir>
Zack Rusinebf971e2011-09-06 17:44:43 -04008#include <QThread>
Zack Rusin63efea82011-04-17 17:10:45 -04009
Zack Rusinf6667d12011-03-30 11:03:37 -040010ApiTrace::ApiTrace()
Zack Rusin63efea82011-04-17 17:10:45 -040011 : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
12 m_needsSaving(false)
Zack Rusinf6667d12011-03-30 11:03:37 -040013{
Zack Rusinebf971e2011-09-06 17:44:43 -040014 m_loader = new TraceLoader();
Zack Rusinf682e192011-09-07 01:36:41 -040015
Zack Rusinebf971e2011-09-06 17:44:43 -040016 connect(this, SIGNAL(loadTrace(QString)),
17 m_loader, SLOT(loadTrace(QString)));
Zack Rusin3176ebe2011-09-06 21:11:36 -040018 connect(this, SIGNAL(requestFrame(ApiTraceFrame*)),
19 m_loader, SLOT(loadFrame(ApiTraceFrame*)));
Zack Rusinebf971e2011-09-06 17:44:43 -040020 connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
Zack Rusinf6667d12011-03-30 11:03:37 -040021 this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040022 connect(m_loader,
23 SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)),
24 this,
25 SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)));
Zack Rusinf682e192011-09-07 01:36:41 -040026 connect(m_loader, SIGNAL(finishedParsing()),
27 this, SLOT(finishedParsing()));
Zack Rusinad513b32011-09-25 14:33:41 -040028 connect(this, SIGNAL(loaderSearch(ApiTrace::SearchRequest)),
29 m_loader, SLOT(search(ApiTrace::SearchRequest)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040030 connect(m_loader,
Zack Rusinad513b32011-09-25 14:33:41 -040031 SIGNAL(searchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)),
Zack Rusin8f98c3a2011-09-11 18:21:29 -040032 this,
Zack Rusinad513b32011-09-25 14:33:41 -040033 SLOT(loaderSearchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)));
Zack Rusin93e4d152011-09-13 02:23:39 -040034 connect(this, SIGNAL(loaderFindFrameStart(ApiTraceFrame*)),
35 m_loader, SLOT(findFrameStart(ApiTraceFrame*)));
36 connect(this, SIGNAL(loaderFindFrameEnd(ApiTraceFrame*)),
37 m_loader, SLOT(findFrameEnd(ApiTraceFrame*)));
38 connect(m_loader, SIGNAL(foundFrameStart(ApiTraceFrame*)),
39 this, SIGNAL(foundFrameStart(ApiTraceFrame*)));
40 connect(m_loader, SIGNAL(foundFrameEnd(ApiTraceFrame*)),
41 this, SIGNAL(foundFrameEnd(ApiTraceFrame*)));
Zack Rusinda7579b2011-09-13 17:33:05 -040042 connect(this, SIGNAL(loaderFindCallIndex(int)),
43 m_loader, SLOT(findCallIndex(int)));
44 connect(m_loader, SIGNAL(foundCallIndex(ApiTraceCall*)),
45 this, SIGNAL(foundCallIndex(ApiTraceCall*)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040046
Zack Rusinebf971e2011-09-06 17:44:43 -040047
48 connect(m_loader, SIGNAL(startedParsing()),
Zack Rusinde4ea412011-03-30 11:30:08 -040049 this, SIGNAL(startedLoadingTrace()));
Zack Rusinebf971e2011-09-06 17:44:43 -040050 connect(m_loader, SIGNAL(parsed(int)),
51 this, SIGNAL(loaded(int)));
52 connect(m_loader, SIGNAL(finishedParsing()),
Zack Rusinde4ea412011-03-30 11:30:08 -040053 this, SIGNAL(finishedLoadingTrace()));
Zack Rusind809a062011-04-17 23:30:58 -040054
Zack Rusinebf971e2011-09-06 17:44:43 -040055
Zack Rusind809a062011-04-17 23:30:58 -040056 m_saver = new SaverThread(this);
Zack Rusin9af5bff2011-04-18 01:05:50 -040057 connect(m_saver, SIGNAL(traceSaved()),
58 this, SLOT(slotSaved()));
59 connect(m_saver, SIGNAL(traceSaved()),
60 this, SIGNAL(saved()));
Zack Rusinebf971e2011-09-06 17:44:43 -040061
62 m_loaderThread = new QThread();
63 m_loader->moveToThread(m_loaderThread);
64 m_loaderThread->start();
Zack Rusinf6667d12011-03-30 11:03:37 -040065}
66
67ApiTrace::~ApiTrace()
68{
Zack Rusinebf971e2011-09-06 17:44:43 -040069 m_loaderThread->quit();
70 m_loaderThread->deleteLater();
Zack Rusinf6667d12011-03-30 11:03:37 -040071 qDeleteAll(m_frames);
72 delete m_loader;
Zack Rusind809a062011-04-17 23:30:58 -040073 delete m_saver;
Zack Rusinf6667d12011-03-30 11:03:37 -040074}
75
76bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
77 ApiTrace::FrameMarker marker)
78{
Zack Rusinc5929572011-09-19 03:04:40 -040079 if (!call) {
Zack Rusinf6667d12011-03-30 11:03:37 -040080 return false;
Zack Rusinc5929572011-09-19 03:04:40 -040081 }
Zack Rusinf6667d12011-03-30 11:03:37 -040082
83 switch (marker) {
84 case FrameMarker_SwapBuffers:
José Fonseca340f5692011-11-30 07:04:44 +000085 return call->flags() & trace::CALL_FLAG_END_FRAME;
Zack Rusinf6667d12011-03-30 11:03:37 -040086 case FrameMarker_Flush:
Zack Rusinead6aad2011-04-15 22:16:18 -040087 return call->name() == QLatin1String("glFlush");
Zack Rusinf6667d12011-03-30 11:03:37 -040088 case FrameMarker_Finish:
Zack Rusinead6aad2011-04-15 22:16:18 -040089 return call->name() == QLatin1String("glFinish");
Zack Rusinf6667d12011-03-30 11:03:37 -040090 case FrameMarker_Clear:
Zack Rusinead6aad2011-04-15 22:16:18 -040091 return call->name() == QLatin1String("glClear");
Zack Rusinf6667d12011-03-30 11:03:37 -040092 }
93
94 Q_ASSERT(!"unknown frame marker");
95
96 return false;
97}
98
99bool ApiTrace::isEmpty() const
100{
Zack Rusinc1743432011-09-13 17:58:58 -0400101 return m_frames.isEmpty();
Zack Rusinf6667d12011-03-30 11:03:37 -0400102}
103
104QString ApiTrace::fileName() const
105{
Zack Rusinc5929572011-09-19 03:04:40 -0400106 if (edited()) {
Zack Rusin63efea82011-04-17 17:10:45 -0400107 return m_tempFileName;
Zack Rusinc5929572011-09-19 03:04:40 -0400108 }
Zack Rusin63efea82011-04-17 17:10:45 -0400109
Zack Rusinf6667d12011-03-30 11:03:37 -0400110 return m_fileName;
111}
112
113ApiTrace::FrameMarker ApiTrace::frameMarker() const
114{
115 return m_frameMarker;
116}
117
José Fonseca34500442012-03-24 07:56:45 +0000118const QList<ApiTraceFrame*> & ApiTrace::frames() const
Zack Rusinf6667d12011-03-30 11:03:37 -0400119{
120 return m_frames;
121}
122
123ApiTraceFrame * ApiTrace::frameAt(int idx) const
124{
125 return m_frames.value(idx);
126}
127
128int ApiTrace::numFrames() const
129{
130 return m_frames.count();
131}
132
133int ApiTrace::numCallsInFrame(int idx) const
134{
135 const ApiTraceFrame *frame = frameAt(idx);
Zack Rusinc5929572011-09-19 03:04:40 -0400136 if (frame) {
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400137 return frame->numChildren();
Zack Rusinc5929572011-09-19 03:04:40 -0400138 } else {
Zack Rusinf6667d12011-03-30 11:03:37 -0400139 return 0;
Zack Rusinc5929572011-09-19 03:04:40 -0400140 }
Zack Rusinf6667d12011-03-30 11:03:37 -0400141}
142
143void ApiTrace::setFileName(const QString &name)
144{
145 if (m_fileName != name) {
146 m_fileName = name;
Zack Rusindaf82af2011-09-24 13:42:53 -0400147 m_tempFileName = QString();
Zack Rusinf6667d12011-03-30 11:03:37 -0400148
Zack Rusinca164112011-04-11 02:23:09 -0400149 m_frames.clear();
Zack Rusin30069572011-04-20 18:21:11 -0400150 m_errors.clear();
151 m_editedCalls.clear();
Zack Rusindaf82af2011-09-24 13:42:53 -0400152 m_queuedErrors.clear();
Zack Rusin30069572011-04-20 18:21:11 -0400153 m_needsSaving = false;
Zack Rusinf6667d12011-03-30 11:03:37 -0400154 emit invalidated();
155
Zack Rusinebf971e2011-09-06 17:44:43 -0400156 emit loadTrace(m_fileName);
Zack Rusinf6667d12011-03-30 11:03:37 -0400157 }
158}
159
Zack Rusinf6667d12011-03-30 11:03:37 -0400160void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
161{
162 int currentFrames = m_frames.count();
163 int numNewFrames = frames.count();
Zack Rusinb56e03d2011-04-20 23:58:52 -0400164
165 emit beginAddingFrames(currentFrames, numNewFrames);
166
Zack Rusinf6667d12011-03-30 11:03:37 -0400167 m_frames += frames;
168
Zack Rusinf6667d12011-03-30 11:03:37 -0400169 foreach(ApiTraceFrame *frame, frames) {
Zack Rusinebf971e2011-09-06 17:44:43 -0400170 frame->setParentTrace(this);
Zack Rusinf6667d12011-03-30 11:03:37 -0400171 }
172
Zack Rusinb56e03d2011-04-20 23:58:52 -0400173 emit endAddingFrames();
Zack Rusinf6667d12011-03-30 11:03:37 -0400174}
175
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400176ApiTraceCall * ApiTrace::callWithIndex(int idx) const
177{
Zack Rusinc1743432011-09-13 17:58:58 -0400178 for (int i = 0; i < m_frames.count(); ++i) {
179 ApiTraceCall *call = m_frames[i]->callWithIndex(idx);
Zack Rusinc5929572011-09-19 03:04:40 -0400180 if (call) {
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400181 return call;
Zack Rusinc5929572011-09-19 03:04:40 -0400182 }
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400183 }
184 return NULL;
185}
186
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400187ApiTraceState ApiTrace::defaultState() const
188{
189 ApiTraceFrame *frame = frameAt(0);
Zack Rusinc5929572011-09-19 03:04:40 -0400190 if (!frame || !frame->isLoaded() || frame->isEmpty()) {
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400191 return ApiTraceState();
Zack Rusinc5929572011-09-19 03:04:40 -0400192 }
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400193
Zack Rusin851d0b02011-09-14 22:04:07 -0400194 ApiTraceCall *firstCall = frame->calls().first();
195 if (!firstCall->hasState()) {
196 return ApiTraceState();
197 }
198
199 return *firstCall->state();
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400200}
201
Zack Rusin661842d2011-04-17 01:59:16 -0400202void ApiTrace::callEdited(ApiTraceCall *call)
203{
Zack Rusin63efea82011-04-17 17:10:45 -0400204 if (!m_editedCalls.contains(call)) {
205 //lets generate a temp filename
206 QString tempPath = QDir::tempPath();
Zack Rusin63efea82011-04-17 17:10:45 -0400207 m_tempFileName = QString::fromLatin1("%1/%2.edited")
208 .arg(tempPath)
209 .arg(m_fileName);
Zack Rusin63efea82011-04-17 17:10:45 -0400210 }
Zack Rusin661842d2011-04-17 01:59:16 -0400211 m_editedCalls.insert(call);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400212 m_needsSaving = true;
Zack Rusin63efea82011-04-17 17:10:45 -0400213
Zack Rusin661842d2011-04-17 01:59:16 -0400214 emit changed(call);
215}
216
217void ApiTrace::callReverted(ApiTraceCall *call)
218{
219 m_editedCalls.remove(call);
Zack Rusin63efea82011-04-17 17:10:45 -0400220
221 if (m_editedCalls.isEmpty()) {
222 m_needsSaving = false;
223 }
Zack Rusin661842d2011-04-17 01:59:16 -0400224 emit changed(call);
225}
226
Zack Rusin0ddd2502011-04-17 02:34:45 -0400227bool ApiTrace::edited() const
Zack Rusin661842d2011-04-17 01:59:16 -0400228{
229 return !m_editedCalls.isEmpty();
230}
231
Zack Rusin63efea82011-04-17 17:10:45 -0400232bool ApiTrace::needsSaving() const
233{
234 return m_needsSaving;
235}
236
237void ApiTrace::save()
238{
239 QFileInfo fi(m_tempFileName);
240 QDir dir;
Zack Rusin9af5bff2011-04-18 01:05:50 -0400241 emit startedSaving();
Zack Rusin63efea82011-04-17 17:10:45 -0400242 dir.mkpath(fi.absolutePath());
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400243 m_saver->saveFile(m_tempFileName,
244 m_fileName,
245 m_editedCalls);
Zack Rusin63efea82011-04-17 17:10:45 -0400246}
247
Zack Rusin9af5bff2011-04-18 01:05:50 -0400248void ApiTrace::slotSaved()
249{
250 m_needsSaving = false;
251}
252
253bool ApiTrace::isSaving() const
254{
255 return m_saver->isRunning();
256}
257
Zack Rusincc0b4912011-04-19 01:59:20 -0400258bool ApiTrace::hasErrors() const
259{
260 return !m_errors.isEmpty();
261}
262
Zack Rusin3176ebe2011-09-06 21:11:36 -0400263void ApiTrace::loadFrame(ApiTraceFrame *frame)
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400264{
Zack Rusin18d094e2011-10-07 23:55:55 -0400265 if (!isFrameLoading(frame)) {
266 Q_ASSERT(!frame->isLoaded());
267 m_loadingFrames.insert(frame);
268 emit requestFrame(frame);
269 }
Zack Rusin35c27932011-08-28 21:16:22 -0400270}
271
Zack Rusinf682e192011-09-07 01:36:41 -0400272void ApiTrace::finishedParsing()
273{
José Fonseca0b08bc62012-03-22 16:22:33 +0000274 if (!m_frames.isEmpty()) {
275 ApiTraceFrame *firstFrame = m_frames[0];
276 if (firstFrame && !firstFrame->isLoaded()) {
277 loadFrame(firstFrame);
278 }
Zack Rusinf682e192011-09-07 01:36:41 -0400279 }
280}
281
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400282void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
283 const QVector<ApiTraceCall*> &calls,
284 quint64 binaryDataSize)
Zack Rusinf682e192011-09-07 01:36:41 -0400285{
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400286 Q_ASSERT(frame->numChildrenToLoad() == calls.size());
Zack Rusin18d094e2011-10-07 23:55:55 -0400287
288 if (!frame->isLoaded()) {
289 emit beginLoadingFrame(frame, calls.size());
290 frame->setCalls(calls, binaryDataSize);
291 emit endLoadingFrame(frame);
292 m_loadingFrames.remove(frame);
293 }
Zack Rusin10fd4772011-09-14 01:45:12 -0400294
295 if (!m_queuedErrors.isEmpty()) {
296 QList< QPair<ApiTraceFrame*, ApiTraceError> >::iterator itr;
297 for (itr = m_queuedErrors.begin(); itr != m_queuedErrors.end();
298 ++itr) {
299 const ApiTraceError &error = (*itr).second;
300 if ((*itr).first == frame) {
301 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
302
303 if (!call) {
304 continue;
305 }
306
307 call->setError(error.message);
308 m_queuedErrors.erase(itr);
309
310 if (call->hasError()) {
311 m_errors.insert(call);
312 } else {
313 m_errors.remove(call);
314 }
315 emit changed(call);
316 }
317 }
318 }
Zack Rusinf682e192011-09-07 01:36:41 -0400319}
320
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400321void ApiTrace::findNext(ApiTraceFrame *frame,
322 ApiTraceCall *from,
323 const QString &str,
324 Qt::CaseSensitivity sensitivity)
325{
326 ApiTraceCall *foundCall = 0;
327 int frameIdx = m_frames.indexOf(frame);
Zack Rusinad513b32011-09-25 14:33:41 -0400328 SearchRequest request(SearchRequest::Next,
329 frame, from, str, sensitivity);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400330
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400331 if (frame->isLoaded()) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400332 foundCall = frame->findNextCall(from, str, sensitivity);
333 if (foundCall) {
Zack Rusinad513b32011-09-25 14:33:41 -0400334 emit findResult(request, SearchResult_Found, foundCall);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400335 return;
336 }
337
338 //if the frame is loaded we already searched it above
339 // so skip it
340 frameIdx += 1;
341 }
342
Zack Rusinad513b32011-09-25 14:33:41 -0400343 //for the rest of the frames we search from beginning
344 request.from = 0;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400345 for (int i = frameIdx; i < m_frames.count(); ++i) {
346 ApiTraceFrame *frame = m_frames[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400347 request.frame = frame;
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400348 if (!frame->isLoaded()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400349 emit loaderSearch(request);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400350 return;
351 } else {
352 ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
353 if (call) {
Zack Rusinad513b32011-09-25 14:33:41 -0400354 emit findResult(request, SearchResult_Found, call);
Zack Rusin121e3162011-09-13 01:35:12 -0400355 return;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400356 }
357 }
358 }
Zack Rusinad513b32011-09-25 14:33:41 -0400359 emit findResult(request, SearchResult_Wrapped, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400360}
361
362void ApiTrace::findPrev(ApiTraceFrame *frame,
363 ApiTraceCall *from,
364 const QString &str,
365 Qt::CaseSensitivity sensitivity)
366{
367 ApiTraceCall *foundCall = 0;
368 int frameIdx = m_frames.indexOf(frame);
Zack Rusinad513b32011-09-25 14:33:41 -0400369 SearchRequest request(SearchRequest::Prev,
370 frame, from, str, sensitivity);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400371
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400372 if (frame->isLoaded()) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400373 foundCall = frame->findPrevCall(from, str, sensitivity);
374 if (foundCall) {
Zack Rusinad513b32011-09-25 14:33:41 -0400375 emit findResult(request, SearchResult_Found, foundCall);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400376 return;
377 }
378
379 //if the frame is loaded we already searched it above
380 // so skip it
381 frameIdx -= 1;
382 }
383
Zack Rusinad513b32011-09-25 14:33:41 -0400384 request.from = 0;
Zack Rusin121e3162011-09-13 01:35:12 -0400385 for (int i = frameIdx; i >= 0; --i) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400386 ApiTraceFrame *frame = m_frames[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400387 request.frame = frame;
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400388 if (!frame->isLoaded()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400389 emit loaderSearch(request);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400390 return;
391 } else {
392 ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
393 if (call) {
Zack Rusinad513b32011-09-25 14:33:41 -0400394 emit findResult(request, SearchResult_Found, call);
Zack Rusin121e3162011-09-13 01:35:12 -0400395 return;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400396 }
397 }
398 }
Zack Rusinad513b32011-09-25 14:33:41 -0400399 emit findResult(request, SearchResult_Wrapped, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400400}
401
Zack Rusinad513b32011-09-25 14:33:41 -0400402void ApiTrace::loaderSearchResult(const ApiTrace::SearchRequest &request,
403 ApiTrace::SearchResult result,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400404 ApiTraceCall *call)
405{
406 //qDebug()<<"Search result = "<<result
407 // <<", call is = "<<call;
Zack Rusinad513b32011-09-25 14:33:41 -0400408 emit findResult(request, result, call);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400409}
410
Zack Rusin93e4d152011-09-13 02:23:39 -0400411void ApiTrace::findFrameStart(ApiTraceFrame *frame)
412{
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400413 if (frame->isLoaded()) {
Zack Rusin93e4d152011-09-13 02:23:39 -0400414 emit foundFrameStart(frame);
415 } else {
416 emit loaderFindFrameStart(frame);
417 }
418}
419
420void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
421{
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400422 if (frame->isLoaded()) {
Zack Rusin93e4d152011-09-13 02:23:39 -0400423 emit foundFrameEnd(frame);
424 } else {
425 emit loaderFindFrameEnd(frame);
426 }
427}
428
Zack Rusinda7579b2011-09-13 17:33:05 -0400429void ApiTrace::findCallIndex(int index)
430{
431 int frameIdx = callInFrame(index);
432 ApiTraceFrame *frame = 0;
433
434 if (frameIdx < 0) {
435 emit foundCallIndex(0);
436 return;
437 }
438
439 frame = m_frames[frameIdx];
440
441 if (frame) {
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400442 if (frame->isLoaded()) {
Zack Rusinda7579b2011-09-13 17:33:05 -0400443 ApiTraceCall *call = frame->callWithIndex(index);
444 emit foundCallIndex(call);
445 } else {
446 emit loaderFindCallIndex(index);
447 }
448 }
449}
450
451int ApiTrace::callInFrame(int callIdx) const
452{
453 unsigned numCalls = 0;
454
Dan McCabe6cc6dac2012-03-22 12:18:55 +0000455 for (int frameIdx = 0; frameIdx < m_frames.size(); ++frameIdx) {
Zack Rusinda7579b2011-09-13 17:33:05 -0400456 const ApiTraceFrame *frame = m_frames[frameIdx];
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400457 unsigned numCallsInFrame = frame->isLoaded()
Zack Rusinda7579b2011-09-13 17:33:05 -0400458 ? frame->numChildren()
459 : frame->numChildrenToLoad();
460 unsigned firstCall = numCalls;
461 unsigned endCall = numCalls + numCallsInFrame;
462 if (firstCall <= callIdx && endCall > callIdx) {
463 return frameIdx;
464 }
465 numCalls = endCall;
466 }
467
468 return -1;
469}
470
Zack Rusin10fd4772011-09-14 01:45:12 -0400471void ApiTrace::setCallError(const ApiTraceError &error)
472{
473 int frameIdx = callInFrame(error.callIndex);
474 ApiTraceFrame *frame = 0;
475
476 if (frameIdx < 0) {
477 return;
478 }
479 frame = m_frames[frameIdx];
480
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400481 if (frame->isLoaded()) {
Zack Rusin10fd4772011-09-14 01:45:12 -0400482 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
483 call->setError(error.message);
484 if (call->hasError()) {
485 m_errors.insert(call);
486 } else {
487 m_errors.remove(call);
488 }
489 emit changed(call);
490 } else {
Zack Rusin18d094e2011-10-07 23:55:55 -0400491 loadFrame(frame);
Zack Rusin10fd4772011-09-14 01:45:12 -0400492 m_queuedErrors.append(qMakePair(frame, error));
493 }
494}
495
Zack Rusin18d094e2011-10-07 23:55:55 -0400496bool ApiTrace::isFrameLoading(ApiTraceFrame *frame) const
497{
498 return m_loadingFrames.contains(frame);
499}
500
Dan McCabe10bd4242012-03-05 17:20:40 -0800501void ApiTrace::bindThumbnailsToFrames(const QList<QImage> &thumbnails)
502{
503 QList<ApiTraceFrame *> frames = m_frames;
504
505 QList<QImage>::const_iterator thumbnail = thumbnails.begin();
506
507 foreach (ApiTraceFrame *frame, frames) {
508 if (thumbnail != thumbnails.end()) {
509 frame->setThumbnail(*thumbnail);
510
511 ++thumbnail;
512
513 emit changed(frame);
514 }
515 }
516}
517
Zack Rusinf6667d12011-03-30 11:03:37 -0400518#include "apitrace.moc"