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*>)));
22 connect(m_loader, SIGNAL(frameLoaded(ApiTraceFrame*)),
23 this, SLOT(frameLoadFinished(ApiTraceFrame*)));
24 connect(m_loader, SIGNAL(finishedParsing()),
25 this, SLOT(finishedParsing()));
27 connect(m_loader, SIGNAL(startedParsing()),
28 this, SIGNAL(startedLoadingTrace()));
29 connect(m_loader, SIGNAL(parsed(int)),
30 this, SIGNAL(loaded(int)));
31 connect(m_loader, SIGNAL(finishedParsing()),
32 this, SIGNAL(finishedLoadingTrace()));
35 m_saver = new SaverThread(this);
36 connect(m_saver, SIGNAL(traceSaved()),
37 this, SLOT(slotSaved()));
38 connect(m_saver, SIGNAL(traceSaved()),
39 this, SIGNAL(saved()));
41 m_loaderThread = new QThread();
42 m_loader->moveToThread(m_loaderThread);
43 m_loaderThread->start();
48 m_loaderThread->quit();
49 m_loaderThread->deleteLater();
56 bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
57 ApiTrace::FrameMarker marker)
63 case FrameMarker_SwapBuffers:
64 return call->name().contains(QLatin1String("SwapBuffers")) ||
65 call->name() == QLatin1String("CGLFlushDrawable") ||
66 call->name() == QLatin1String("glFrameTerminatorGREMEDY");
67 case FrameMarker_Flush:
68 return call->name() == QLatin1String("glFlush");
69 case FrameMarker_Finish:
70 return call->name() == QLatin1String("glFinish");
71 case FrameMarker_Clear:
72 return call->name() == QLatin1String("glClear");
75 Q_ASSERT(!"unknown frame marker");
80 bool ApiTrace::isEmpty() const
82 return m_calls.isEmpty();
85 QString ApiTrace::fileName() const
88 return m_tempFileName;
93 ApiTrace::FrameMarker ApiTrace::frameMarker() const
98 QVector<ApiTraceCall*> ApiTrace::calls() const
103 int ApiTrace::numCalls() const
105 return m_calls.count();
108 QList<ApiTraceFrame*> ApiTrace::frames() const
113 ApiTraceFrame * ApiTrace::frameAt(int idx) const
115 return m_frames.value(idx);
118 int ApiTrace::numFrames() const
120 return m_frames.count();
123 int ApiTrace::numCallsInFrame(int idx) const
125 const ApiTraceFrame *frame = frameAt(idx);
127 return frame->numChildren();
132 void ApiTrace::setFileName(const QString &name)
134 if (m_fileName != name) {
140 m_editedCalls.clear();
141 m_needsSaving = false;
144 // m_loader->loadTrace(m_fileName);
145 emit loadTrace(m_fileName);
149 void ApiTrace::setFrameMarker(FrameMarker marker)
151 if (m_frameMarker != marker) {
152 emit framesInvalidated();
154 qDeleteAll(m_frames);
160 void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
162 QVector<ApiTraceCall*> calls;
163 int currentFrames = m_frames.count();
164 int numNewFrames = frames.count();
166 emit beginAddingFrames(currentFrames, numNewFrames);
170 int currentCalls = m_calls.count();
172 foreach(ApiTraceFrame *frame, frames) {
173 frame->setParentTrace(this);
174 numNewCalls += frame->numChildren();
175 calls += frame->calls();
177 m_calls.reserve(m_calls.count() + calls.count() + 1);
180 emit endAddingFrames();
181 emit callsAdded(currentCalls, numNewCalls);
184 void ApiTrace::detectFrames()
186 if (m_calls.isEmpty())
189 emit beginAddingFrames(0, m_frames.count());
191 ApiTraceFrame *currentFrame = 0;
192 foreach(ApiTraceCall *apiCall, m_calls) {
194 currentFrame = new ApiTraceFrame(this);
195 currentFrame->number = m_frames.count();
196 currentFrame->setLoaded(true);
198 apiCall->setParentFrame(currentFrame);
199 currentFrame->addCall(apiCall);
200 if (ApiTrace::isCallAFrameMarker(apiCall,
202 m_frames.append(currentFrame);
206 //last frames won't have markers
207 // it's just a bunch of Delete calls for every object
208 // after the last SwapBuffers
210 m_frames.append(currentFrame);
213 emit endAddingFrames();
216 ApiTraceCall * ApiTrace::callWithIndex(int idx) const
218 for (int i = 0; i < m_calls.count(); ++i) {
219 ApiTraceCall *call = m_calls[i];
220 if (call->index() == idx)
226 ApiTraceState ApiTrace::defaultState() const
228 ApiTraceFrame *frame = frameAt(0);
229 if (!frame || !frame->hasState())
230 return ApiTraceState();
232 return *frame->state();
235 void ApiTrace::callEdited(ApiTraceCall *call)
237 if (!m_editedCalls.contains(call)) {
238 //lets generate a temp filename
239 QString tempPath = QDir::tempPath();
240 m_tempFileName = QString::fromLatin1("%1/%2.edited")
244 m_editedCalls.insert(call);
245 m_needsSaving = true;
250 void ApiTrace::callReverted(ApiTraceCall *call)
252 m_editedCalls.remove(call);
254 if (m_editedCalls.isEmpty()) {
255 m_needsSaving = false;
260 bool ApiTrace::edited() const
262 return !m_editedCalls.isEmpty();
265 bool ApiTrace::needsSaving() const
267 return m_needsSaving;
270 void ApiTrace::save()
272 QFileInfo fi(m_tempFileName);
274 emit startedSaving();
275 dir.mkpath(fi.absolutePath());
276 m_saver->saveFile(m_tempFileName, m_calls);
279 void ApiTrace::slotSaved()
281 m_needsSaving = false;
284 bool ApiTrace::isSaving() const
286 return m_saver->isRunning();
289 void ApiTrace::callError(ApiTraceCall *call)
293 if (call->hasError())
294 m_errors.insert(call);
296 m_errors.remove(call);
301 bool ApiTrace::hasErrors() const
303 return !m_errors.isEmpty();
306 void ApiTrace::loadFrame(ApiTraceFrame *frame)
308 Q_ASSERT(!frame->loaded());
309 emit beginLoadingFrame(frame, frame->numChildrenToLoad());
310 emit requestFrame(frame);
313 void ApiTrace::finishedParsing()
315 ApiTraceFrame *firstFrame = m_frames[0];
316 if (firstFrame && !firstFrame->loaded()) {
317 loadFrame(firstFrame);
321 void ApiTrace::frameLoadFinished(ApiTraceFrame *frame)
323 emit endLoadingFrame(frame);
326 #include "apitrace.moc"