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*)));
46 connect(m_loader, SIGNAL(startedParsing()),
47 this, SIGNAL(startedLoadingTrace()));
48 connect(m_loader, SIGNAL(parsed(int)),
49 this, SIGNAL(loaded(int)));
50 connect(m_loader, SIGNAL(finishedParsing()),
51 this, SIGNAL(finishedLoadingTrace()));
54 m_saver = new SaverThread(this);
55 connect(m_saver, SIGNAL(traceSaved()),
56 this, SLOT(slotSaved()));
57 connect(m_saver, SIGNAL(traceSaved()),
58 this, SIGNAL(saved()));
60 m_loaderThread = new QThread();
61 m_loader->moveToThread(m_loaderThread);
62 m_loaderThread->start();
67 m_loaderThread->quit();
68 m_loaderThread->deleteLater();
75 bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
76 ApiTrace::FrameMarker marker)
82 case FrameMarker_SwapBuffers:
83 return call->name().contains(QLatin1String("SwapBuffers")) ||
84 call->name() == QLatin1String("CGLFlushDrawable") ||
85 call->name() == QLatin1String("glFrameTerminatorGREMEDY");
86 case FrameMarker_Flush:
87 return call->name() == QLatin1String("glFlush");
88 case FrameMarker_Finish:
89 return call->name() == QLatin1String("glFinish");
90 case FrameMarker_Clear:
91 return call->name() == QLatin1String("glClear");
94 Q_ASSERT(!"unknown frame marker");
99 bool ApiTrace::isEmpty() const
101 return m_calls.isEmpty();
104 QString ApiTrace::fileName() const
107 return m_tempFileName;
112 ApiTrace::FrameMarker ApiTrace::frameMarker() const
114 return m_frameMarker;
117 QVector<ApiTraceCall*> ApiTrace::calls() const
122 int ApiTrace::numCalls() const
124 return m_calls.count();
127 QList<ApiTraceFrame*> ApiTrace::frames() const
132 ApiTraceFrame * ApiTrace::frameAt(int idx) const
134 return m_frames.value(idx);
137 int ApiTrace::numFrames() const
139 return m_frames.count();
142 int ApiTrace::numCallsInFrame(int idx) const
144 const ApiTraceFrame *frame = frameAt(idx);
146 return frame->numChildren();
151 void ApiTrace::setFileName(const QString &name)
153 if (m_fileName != name) {
159 m_editedCalls.clear();
160 m_needsSaving = false;
163 // m_loader->loadTrace(m_fileName);
164 emit loadTrace(m_fileName);
168 void ApiTrace::setFrameMarker(FrameMarker marker)
170 if (m_frameMarker != marker) {
171 emit framesInvalidated();
173 qDeleteAll(m_frames);
179 void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
181 QVector<ApiTraceCall*> calls;
182 int currentFrames = m_frames.count();
183 int numNewFrames = frames.count();
185 emit beginAddingFrames(currentFrames, numNewFrames);
189 int currentCalls = m_calls.count();
191 foreach(ApiTraceFrame *frame, frames) {
192 frame->setParentTrace(this);
193 numNewCalls += frame->numChildren();
194 calls += frame->calls();
196 m_calls.reserve(m_calls.count() + calls.count() + 1);
199 emit endAddingFrames();
200 emit callsAdded(currentCalls, numNewCalls);
203 void ApiTrace::detectFrames()
205 if (m_calls.isEmpty())
208 emit beginAddingFrames(0, m_frames.count());
210 ApiTraceFrame *currentFrame = 0;
211 foreach(ApiTraceCall *apiCall, m_calls) {
213 currentFrame = new ApiTraceFrame(this);
214 currentFrame->number = m_frames.count();
215 currentFrame->setLoaded(true);
217 apiCall->setParentFrame(currentFrame);
218 currentFrame->addCall(apiCall);
219 if (ApiTrace::isCallAFrameMarker(apiCall,
221 m_frames.append(currentFrame);
225 //last frames won't have markers
226 // it's just a bunch of Delete calls for every object
227 // after the last SwapBuffers
229 m_frames.append(currentFrame);
232 emit endAddingFrames();
235 ApiTraceCall * ApiTrace::callWithIndex(int idx) const
237 for (int i = 0; i < m_calls.count(); ++i) {
238 ApiTraceCall *call = m_calls[i];
239 if (call->index() == idx)
245 ApiTraceState ApiTrace::defaultState() const
247 ApiTraceFrame *frame = frameAt(0);
248 if (!frame || !frame->hasState())
249 return ApiTraceState();
251 return *frame->state();
254 void ApiTrace::callEdited(ApiTraceCall *call)
256 if (!m_editedCalls.contains(call)) {
257 //lets generate a temp filename
258 QString tempPath = QDir::tempPath();
259 m_tempFileName = QString::fromLatin1("%1/%2.edited")
263 m_editedCalls.insert(call);
264 m_needsSaving = true;
269 void ApiTrace::callReverted(ApiTraceCall *call)
271 m_editedCalls.remove(call);
273 if (m_editedCalls.isEmpty()) {
274 m_needsSaving = false;
279 bool ApiTrace::edited() const
281 return !m_editedCalls.isEmpty();
284 bool ApiTrace::needsSaving() const
286 return m_needsSaving;
289 void ApiTrace::save()
291 QFileInfo fi(m_tempFileName);
293 emit startedSaving();
294 dir.mkpath(fi.absolutePath());
295 m_saver->saveFile(m_tempFileName, m_calls);
298 void ApiTrace::slotSaved()
300 m_needsSaving = false;
303 bool ApiTrace::isSaving() const
305 return m_saver->isRunning();
308 void ApiTrace::callError(ApiTraceCall *call)
312 if (call->hasError())
313 m_errors.insert(call);
315 m_errors.remove(call);
320 bool ApiTrace::hasErrors() const
322 return !m_errors.isEmpty();
325 void ApiTrace::loadFrame(ApiTraceFrame *frame)
327 Q_ASSERT(!frame->loaded());
328 emit requestFrame(frame);
331 void ApiTrace::finishedParsing()
333 ApiTraceFrame *firstFrame = m_frames[0];
334 if (firstFrame && !firstFrame->loaded()) {
335 loadFrame(firstFrame);
339 void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
340 const QVector<ApiTraceCall*> &calls,
341 quint64 binaryDataSize)
343 Q_ASSERT(frame->numChildrenToLoad() == calls.size());
344 emit beginLoadingFrame(frame, calls.size());
345 frame->setCalls(calls, binaryDataSize);
346 emit endLoadingFrame(frame);
349 void ApiTrace::findNext(ApiTraceFrame *frame,
352 Qt::CaseSensitivity sensitivity)
354 ApiTraceCall *foundCall = 0;
355 int frameIdx = m_frames.indexOf(frame);
357 if (frame->loaded()) {
358 foundCall = frame->findNextCall(from, str, sensitivity);
360 emit findResult(SearchFound, foundCall);
364 //if the frame is loaded we already searched it above
369 for (int i = frameIdx; i < m_frames.count(); ++i) {
370 ApiTraceFrame *frame = m_frames[i];
371 if (!frame->loaded()) {
372 emit loaderSearchNext(i, str, sensitivity);
375 ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
377 emit findResult(SearchFound, call);
382 emit findResult(SearchWrapped, 0);
385 void ApiTrace::findPrev(ApiTraceFrame *frame,
388 Qt::CaseSensitivity sensitivity)
390 ApiTraceCall *foundCall = 0;
391 int frameIdx = m_frames.indexOf(frame);
393 if (frame->loaded()) {
394 foundCall = frame->findPrevCall(from, str, sensitivity);
396 emit findResult(SearchFound, foundCall);
400 //if the frame is loaded we already searched it above
405 for (int i = frameIdx; i >= 0; --i) {
406 ApiTraceFrame *frame = m_frames[i];
407 if (!frame->loaded()) {
408 emit loaderSearchPrev(i, str, sensitivity);
411 ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
413 emit findResult(SearchFound, call);
418 emit findResult(SearchWrapped, 0);
421 void ApiTrace::loaderSearchResult(ApiTrace::SearchResult result,
424 //qDebug()<<"Search result = "<<result
425 // <<", call is = "<<call;
426 emit findResult(result, call);
429 void ApiTrace::findFrameStart(ApiTraceFrame *frame)
431 if (frame->loaded()) {
432 emit foundFrameStart(frame);
434 emit loaderFindFrameStart(frame);
438 void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
440 if (frame->loaded()) {
441 emit foundFrameEnd(frame);
443 emit loaderFindFrameEnd(frame);
447 #include "apitrace.moc"