3 #include "traceloader.h"
4 #include "saverthread.h"
10 : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
13 m_loader = new TraceLoader();
14 connect(this, SIGNAL(loadTrace(QString)),
15 m_loader, SLOT(loadTrace(QString)));
16 connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
17 this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
18 connect(m_loader, SIGNAL(frameLoaded(int,QVector<ApiTraceCall*>,quint64)),
19 this, SLOT(fillFrame(int,QVector<ApiTraceCall*>,quint64)));
21 connect(m_loader, SIGNAL(startedParsing()),
22 this, SIGNAL(startedLoadingTrace()));
23 connect(m_loader, SIGNAL(parsed(int)),
24 this, SIGNAL(loaded(int)));
25 connect(m_loader, SIGNAL(finishedParsing()),
26 this, SIGNAL(finishedLoadingTrace()));
29 m_saver = new SaverThread(this);
30 connect(m_saver, SIGNAL(traceSaved()),
31 this, SLOT(slotSaved()));
32 connect(m_saver, SIGNAL(traceSaved()),
33 this, SIGNAL(saved()));
35 m_loaderThread = new QThread();
36 m_loader->moveToThread(m_loaderThread);
37 m_loaderThread->start();
42 m_loaderThread->quit();
43 m_loaderThread->deleteLater();
50 bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
51 ApiTrace::FrameMarker marker)
57 case FrameMarker_SwapBuffers:
58 return call->name().contains(QLatin1String("SwapBuffers")) ||
59 call->name() == QLatin1String("CGLFlushDrawable") ||
60 call->name() == QLatin1String("glFrameTerminatorGREMEDY");
61 case FrameMarker_Flush:
62 return call->name() == QLatin1String("glFlush");
63 case FrameMarker_Finish:
64 return call->name() == QLatin1String("glFinish");
65 case FrameMarker_Clear:
66 return call->name() == QLatin1String("glClear");
69 Q_ASSERT(!"unknown frame marker");
74 bool ApiTrace::isEmpty() const
76 return m_calls.isEmpty();
79 QString ApiTrace::fileName() const
82 return m_tempFileName;
87 ApiTrace::FrameMarker ApiTrace::frameMarker() const
92 QVector<ApiTraceCall*> ApiTrace::calls() const
97 ApiTraceCall * ApiTrace::callAt(int idx) const
99 return m_calls.value(idx);
102 int ApiTrace::numCalls() const
104 return m_calls.count();
107 QList<ApiTraceFrame*> ApiTrace::frames() const
112 ApiTraceFrame * ApiTrace::frameAt(int idx) const
114 return m_frames.value(idx);
117 int ApiTrace::numFrames() const
119 return m_frames.count();
122 int ApiTrace::numCallsInFrame(int idx) const
124 const ApiTraceFrame *frame = frameAt(idx);
126 return frame->numChildren();
131 void ApiTrace::setFileName(const QString &name)
133 if (m_fileName != name) {
139 m_editedCalls.clear();
140 m_needsSaving = false;
143 // m_loader->loadTrace(m_fileName);
144 emit loadTrace(m_fileName);
148 void ApiTrace::setFrameMarker(FrameMarker marker)
150 if (m_frameMarker != marker) {
151 emit framesInvalidated();
153 qDeleteAll(m_frames);
159 void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
161 QVector<ApiTraceCall*> calls;
162 int currentFrames = m_frames.count();
163 int numNewFrames = frames.count();
165 emit beginAddingFrames(currentFrames, numNewFrames);
169 int currentCalls = m_calls.count();
171 foreach(ApiTraceFrame *frame, frames) {
172 frame->setParentTrace(this);
173 numNewCalls += frame->numChildren();
174 calls += frame->calls();
176 m_calls.reserve(m_calls.count() + calls.count() + 1);
179 emit endAddingFrames();
180 emit callsAdded(currentCalls, numNewCalls);
183 void ApiTrace::detectFrames()
185 if (m_calls.isEmpty())
188 emit beginAddingFrames(0, m_frames.count());
190 ApiTraceFrame *currentFrame = 0;
191 foreach(ApiTraceCall *apiCall, m_calls) {
193 currentFrame = new ApiTraceFrame(this);
194 currentFrame->number = m_frames.count();
195 currentFrame->setLoaded(true);
197 apiCall->setParentFrame(currentFrame);
198 currentFrame->addCall(apiCall);
199 if (ApiTrace::isCallAFrameMarker(apiCall,
201 m_frames.append(currentFrame);
205 //last frames won't have markers
206 // it's just a bunch of Delete calls for every object
207 // after the last SwapBuffers
209 m_frames.append(currentFrame);
212 emit endAddingFrames();
215 ApiTraceCall * ApiTrace::callWithIndex(int idx) const
217 for (int i = 0; i < m_calls.count(); ++i) {
218 ApiTraceCall *call = m_calls[i];
219 if (call->index() == idx)
225 ApiTraceState ApiTrace::defaultState() const
227 ApiTraceFrame *frame = frameAt(0);
228 if (!frame || !frame->hasState())
229 return ApiTraceState();
231 return *frame->state();
234 void ApiTrace::callEdited(ApiTraceCall *call)
236 if (!m_editedCalls.contains(call)) {
237 //lets generate a temp filename
238 QString tempPath = QDir::tempPath();
239 m_tempFileName = QString::fromLatin1("%1/%2.edited")
243 m_editedCalls.insert(call);
244 m_needsSaving = true;
249 void ApiTrace::callReverted(ApiTraceCall *call)
251 m_editedCalls.remove(call);
253 if (m_editedCalls.isEmpty()) {
254 m_needsSaving = false;
259 bool ApiTrace::edited() const
261 return !m_editedCalls.isEmpty();
264 bool ApiTrace::needsSaving() const
266 return m_needsSaving;
269 void ApiTrace::save()
271 QFileInfo fi(m_tempFileName);
273 emit startedSaving();
274 dir.mkpath(fi.absolutePath());
275 m_saver->saveFile(m_tempFileName, m_calls);
278 void ApiTrace::slotSaved()
280 m_needsSaving = false;
283 bool ApiTrace::isSaving() const
285 return m_saver->isRunning();
288 void ApiTrace::callError(ApiTraceCall *call)
292 if (call->hasError())
293 m_errors.insert(call);
295 m_errors.remove(call);
300 bool ApiTrace::hasErrors() const
302 return !m_errors.isEmpty();
305 void ApiTrace::fillFrame(int frameIdx, const QVector<ApiTraceCall *> &calls,
306 quint64 binaryDataSize)
310 #include "apitrace.moc"