3 #include "traceloader.h"
4 #include "saverthread.h"
11 : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
14 m_loader = new TraceLoader();
16 connect(this, SIGNAL(loadTrace(QString)),
17 m_loader, SLOT(loadTrace(QString)));
18 connect(this, SIGNAL(requestFrame(ApiTraceFrame*)),
19 m_loader, SLOT(loadFrame(ApiTraceFrame*)));
20 connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
21 this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
23 SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)),
25 SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)));
26 connect(m_loader, SIGNAL(finishedParsing()),
27 this, SLOT(finishedParsing()));
28 connect(this, SIGNAL(loaderSearchNext(int,QString,Qt::CaseSensitivity)),
29 m_loader, SLOT(searchNext(int,QString,Qt::CaseSensitivity)));
30 connect(this, SIGNAL(loaderSearchPrev(int,QString,Qt::CaseSensitivity)),
31 m_loader, SLOT(searchPrev(int,QString,Qt::CaseSensitivity)));
33 SIGNAL(searchResult(ApiTrace::SearchResult,ApiTraceCall*)),
35 SLOT(loaderSearchResult(ApiTrace::SearchResult,ApiTraceCall*)));
36 connect(this, SIGNAL(loaderFindFrameStart(ApiTraceFrame*)),
37 m_loader, SLOT(findFrameStart(ApiTraceFrame*)));
38 connect(this, SIGNAL(loaderFindFrameEnd(ApiTraceFrame*)),
39 m_loader, SLOT(findFrameEnd(ApiTraceFrame*)));
40 connect(m_loader, SIGNAL(foundFrameStart(ApiTraceFrame*)),
41 this, SIGNAL(foundFrameStart(ApiTraceFrame*)));
42 connect(m_loader, SIGNAL(foundFrameEnd(ApiTraceFrame*)),
43 this, SIGNAL(foundFrameEnd(ApiTraceFrame*)));
44 connect(this, SIGNAL(loaderFindCallIndex(int)),
45 m_loader, SLOT(findCallIndex(int)));
46 connect(m_loader, SIGNAL(foundCallIndex(ApiTraceCall*)),
47 this, SIGNAL(foundCallIndex(ApiTraceCall*)));
50 connect(m_loader, SIGNAL(startedParsing()),
51 this, SIGNAL(startedLoadingTrace()));
52 connect(m_loader, SIGNAL(parsed(int)),
53 this, SIGNAL(loaded(int)));
54 connect(m_loader, SIGNAL(finishedParsing()),
55 this, SIGNAL(finishedLoadingTrace()));
58 m_saver = new SaverThread(this);
59 connect(m_saver, SIGNAL(traceSaved()),
60 this, SLOT(slotSaved()));
61 connect(m_saver, SIGNAL(traceSaved()),
62 this, SIGNAL(saved()));
64 m_loaderThread = new QThread();
65 m_loader->moveToThread(m_loaderThread);
66 m_loaderThread->start();
71 m_loaderThread->quit();
72 m_loaderThread->deleteLater();
78 bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
79 ApiTrace::FrameMarker marker)
86 case FrameMarker_SwapBuffers:
87 return call->name().contains(QLatin1String("SwapBuffers")) ||
88 call->name() == QLatin1String("CGLFlushDrawable") ||
89 call->name() == QLatin1String("glFrameTerminatorGREMEDY");
90 case FrameMarker_Flush:
91 return call->name() == QLatin1String("glFlush");
92 case FrameMarker_Finish:
93 return call->name() == QLatin1String("glFinish");
94 case FrameMarker_Clear:
95 return call->name() == QLatin1String("glClear");
98 Q_ASSERT(!"unknown frame marker");
103 bool ApiTrace::isEmpty() const
105 return m_frames.isEmpty();
108 QString ApiTrace::fileName() const
111 return m_tempFileName;
117 ApiTrace::FrameMarker ApiTrace::frameMarker() const
119 return m_frameMarker;
122 QList<ApiTraceFrame*> ApiTrace::frames() const
127 ApiTraceFrame * ApiTrace::frameAt(int idx) const
129 return m_frames.value(idx);
132 int ApiTrace::numFrames() const
134 return m_frames.count();
137 int ApiTrace::numCallsInFrame(int idx) const
139 const ApiTraceFrame *frame = frameAt(idx);
141 return frame->numChildren();
147 void ApiTrace::setFileName(const QString &name)
149 if (m_fileName != name) {
154 m_editedCalls.clear();
155 m_needsSaving = false;
158 emit loadTrace(m_fileName);
162 void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
164 int currentFrames = m_frames.count();
165 int numNewFrames = frames.count();
167 emit beginAddingFrames(currentFrames, numNewFrames);
171 foreach(ApiTraceFrame *frame, frames) {
172 frame->setParentTrace(this);
175 emit endAddingFrames();
178 ApiTraceCall * ApiTrace::callWithIndex(int idx) const
180 for (int i = 0; i < m_frames.count(); ++i) {
181 ApiTraceCall *call = m_frames[i]->callWithIndex(idx);
189 ApiTraceState ApiTrace::defaultState() const
191 ApiTraceFrame *frame = frameAt(0);
192 if (!frame || !frame->isLoaded() || frame->isEmpty()) {
193 return ApiTraceState();
196 ApiTraceCall *firstCall = frame->calls().first();
197 if (!firstCall->hasState()) {
198 return ApiTraceState();
201 return *firstCall->state();
204 void ApiTrace::callEdited(ApiTraceCall *call)
206 if (!m_editedCalls.contains(call)) {
207 //lets generate a temp filename
208 QString tempPath = QDir::tempPath();
209 m_tempFileName = QString::fromLatin1("%1/%2.edited")
213 m_editedCalls.insert(call);
214 m_needsSaving = true;
219 void ApiTrace::callReverted(ApiTraceCall *call)
221 m_editedCalls.remove(call);
223 if (m_editedCalls.isEmpty()) {
224 m_needsSaving = false;
229 bool ApiTrace::edited() const
231 return !m_editedCalls.isEmpty();
234 bool ApiTrace::needsSaving() const
236 return m_needsSaving;
239 void ApiTrace::save()
241 QFileInfo fi(m_tempFileName);
243 emit startedSaving();
244 dir.mkpath(fi.absolutePath());
245 m_saver->saveFile(m_tempFileName,
250 void ApiTrace::slotSaved()
252 m_needsSaving = false;
255 bool ApiTrace::isSaving() const
257 return m_saver->isRunning();
260 bool ApiTrace::hasErrors() const
262 return !m_errors.isEmpty();
265 void ApiTrace::loadFrame(ApiTraceFrame *frame)
267 Q_ASSERT(!frame->isLoaded());
268 emit requestFrame(frame);
271 void ApiTrace::finishedParsing()
273 ApiTraceFrame *firstFrame = m_frames[0];
274 if (firstFrame && !firstFrame->isLoaded()) {
275 loadFrame(firstFrame);
279 void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
280 const QVector<ApiTraceCall*> &calls,
281 quint64 binaryDataSize)
283 Q_ASSERT(frame->numChildrenToLoad() == calls.size());
284 emit beginLoadingFrame(frame, calls.size());
285 frame->setCalls(calls, binaryDataSize);
286 emit endLoadingFrame(frame);
288 if (!m_queuedErrors.isEmpty()) {
289 QList< QPair<ApiTraceFrame*, ApiTraceError> >::iterator itr;
290 for (itr = m_queuedErrors.begin(); itr != m_queuedErrors.end();
292 const ApiTraceError &error = (*itr).second;
293 if ((*itr).first == frame) {
294 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
300 call->setError(error.message);
301 m_queuedErrors.erase(itr);
303 if (call->hasError()) {
304 m_errors.insert(call);
306 m_errors.remove(call);
314 void ApiTrace::findNext(ApiTraceFrame *frame,
317 Qt::CaseSensitivity sensitivity)
319 ApiTraceCall *foundCall = 0;
320 int frameIdx = m_frames.indexOf(frame);
322 if (frame->isLoaded()) {
323 foundCall = frame->findNextCall(from, str, sensitivity);
325 emit findResult(SearchResult_Found, foundCall);
329 //if the frame is loaded we already searched it above
334 for (int i = frameIdx; i < m_frames.count(); ++i) {
335 ApiTraceFrame *frame = m_frames[i];
336 if (!frame->isLoaded()) {
337 emit loaderSearchNext(i, str, sensitivity);
340 ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
342 emit findResult(SearchResult_Found, call);
347 emit findResult(SearchResult_Wrapped, 0);
350 void ApiTrace::findPrev(ApiTraceFrame *frame,
353 Qt::CaseSensitivity sensitivity)
355 ApiTraceCall *foundCall = 0;
356 int frameIdx = m_frames.indexOf(frame);
358 if (frame->isLoaded()) {
359 foundCall = frame->findPrevCall(from, str, sensitivity);
361 emit findResult(SearchResult_Found, foundCall);
365 //if the frame is loaded we already searched it above
370 for (int i = frameIdx; i >= 0; --i) {
371 ApiTraceFrame *frame = m_frames[i];
372 if (!frame->isLoaded()) {
373 emit loaderSearchPrev(i, str, sensitivity);
376 ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
378 emit findResult(SearchResult_Found, call);
383 emit findResult(SearchResult_Wrapped, 0);
386 void ApiTrace::loaderSearchResult(ApiTrace::SearchResult result,
389 //qDebug()<<"Search result = "<<result
390 // <<", call is = "<<call;
391 emit findResult(result, call);
394 void ApiTrace::findFrameStart(ApiTraceFrame *frame)
396 if (frame->isLoaded()) {
397 emit foundFrameStart(frame);
399 emit loaderFindFrameStart(frame);
403 void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
405 if (frame->isLoaded()) {
406 emit foundFrameEnd(frame);
408 emit loaderFindFrameEnd(frame);
412 void ApiTrace::findCallIndex(int index)
414 int frameIdx = callInFrame(index);
415 ApiTraceFrame *frame = 0;
418 emit foundCallIndex(0);
422 frame = m_frames[frameIdx];
425 if (frame->isLoaded()) {
426 ApiTraceCall *call = frame->callWithIndex(index);
427 emit foundCallIndex(call);
429 emit loaderFindCallIndex(index);
434 int ApiTrace::callInFrame(int callIdx) const
436 unsigned numCalls = 0;
438 for (int frameIdx = 0; frameIdx <= m_frames.size(); ++frameIdx) {
439 const ApiTraceFrame *frame = m_frames[frameIdx];
440 unsigned numCallsInFrame = frame->isLoaded()
441 ? frame->numChildren()
442 : frame->numChildrenToLoad();
443 unsigned firstCall = numCalls;
444 unsigned endCall = numCalls + numCallsInFrame;
445 if (firstCall <= callIdx && endCall > callIdx) {
454 void ApiTrace::setCallError(const ApiTraceError &error)
456 int frameIdx = callInFrame(error.callIndex);
457 ApiTraceFrame *frame = 0;
462 frame = m_frames[frameIdx];
464 if (frame->isLoaded()) {
465 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
466 call->setError(error.message);
467 if (call->hasError()) {
468 m_errors.insert(call);
470 m_errors.remove(call);
474 emit requestFrame(frame);
475 m_queuedErrors.append(qMakePair(frame, error));
479 #include "apitrace.moc"