3 #include "traceloader.h"
4 #include "saverthread.h"
11 : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
14 m_loader = new TraceLoader();
15 connect(this, SIGNAL(loadTrace(QString)),
16 m_loader, SLOT(loadTrace(QString)));
17 connect(this, SIGNAL(requestFrame(ApiTraceFrame*)),
18 m_loader, SLOT(loadFrame(ApiTraceFrame*)));
19 connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
20 this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
21 connect(m_loader, SIGNAL(frameLoaded(ApiTraceFrame*)),
22 this, SIGNAL(frameLoaded(ApiTraceFrame*)));
24 connect(m_loader, SIGNAL(startedParsing()),
25 this, SIGNAL(startedLoadingTrace()));
26 connect(m_loader, SIGNAL(parsed(int)),
27 this, SIGNAL(loaded(int)));
28 connect(m_loader, SIGNAL(finishedParsing()),
29 this, SIGNAL(finishedLoadingTrace()));
32 m_saver = new SaverThread(this);
33 connect(m_saver, SIGNAL(traceSaved()),
34 this, SLOT(slotSaved()));
35 connect(m_saver, SIGNAL(traceSaved()),
36 this, SIGNAL(saved()));
38 m_loaderThread = new QThread();
39 m_loader->moveToThread(m_loaderThread);
40 m_loaderThread->start();
45 m_loaderThread->quit();
46 m_loaderThread->deleteLater();
53 bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
54 ApiTrace::FrameMarker marker)
60 case FrameMarker_SwapBuffers:
61 return call->name().contains(QLatin1String("SwapBuffers")) ||
62 call->name() == QLatin1String("CGLFlushDrawable") ||
63 call->name() == QLatin1String("glFrameTerminatorGREMEDY");
64 case FrameMarker_Flush:
65 return call->name() == QLatin1String("glFlush");
66 case FrameMarker_Finish:
67 return call->name() == QLatin1String("glFinish");
68 case FrameMarker_Clear:
69 return call->name() == QLatin1String("glClear");
72 Q_ASSERT(!"unknown frame marker");
77 bool ApiTrace::isEmpty() const
79 return m_calls.isEmpty();
82 QString ApiTrace::fileName() const
85 return m_tempFileName;
90 ApiTrace::FrameMarker ApiTrace::frameMarker() const
95 QVector<ApiTraceCall*> ApiTrace::calls() const
100 int ApiTrace::numCalls() const
102 return m_calls.count();
105 QList<ApiTraceFrame*> ApiTrace::frames() const
110 ApiTraceFrame * ApiTrace::frameAt(int idx) const
112 return m_frames.value(idx);
115 int ApiTrace::numFrames() const
117 return m_frames.count();
120 int ApiTrace::numCallsInFrame(int idx) const
122 const ApiTraceFrame *frame = frameAt(idx);
124 return frame->numChildren();
129 void ApiTrace::setFileName(const QString &name)
131 if (m_fileName != name) {
137 m_editedCalls.clear();
138 m_needsSaving = false;
141 // m_loader->loadTrace(m_fileName);
142 emit loadTrace(m_fileName);
146 void ApiTrace::setFrameMarker(FrameMarker marker)
148 if (m_frameMarker != marker) {
149 emit framesInvalidated();
151 qDeleteAll(m_frames);
157 void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
159 QVector<ApiTraceCall*> calls;
160 int currentFrames = m_frames.count();
161 int numNewFrames = frames.count();
163 emit beginAddingFrames(currentFrames, numNewFrames);
167 int currentCalls = m_calls.count();
169 foreach(ApiTraceFrame *frame, frames) {
170 frame->setParentTrace(this);
171 numNewCalls += frame->numChildren();
172 calls += frame->calls();
174 m_calls.reserve(m_calls.count() + calls.count() + 1);
177 emit endAddingFrames();
178 emit callsAdded(currentCalls, numNewCalls);
181 void ApiTrace::detectFrames()
183 if (m_calls.isEmpty())
186 emit beginAddingFrames(0, m_frames.count());
188 ApiTraceFrame *currentFrame = 0;
189 foreach(ApiTraceCall *apiCall, m_calls) {
191 currentFrame = new ApiTraceFrame(this);
192 currentFrame->number = m_frames.count();
193 currentFrame->setLoaded(true);
195 apiCall->setParentFrame(currentFrame);
196 currentFrame->addCall(apiCall);
197 if (ApiTrace::isCallAFrameMarker(apiCall,
199 m_frames.append(currentFrame);
203 //last frames won't have markers
204 // it's just a bunch of Delete calls for every object
205 // after the last SwapBuffers
207 m_frames.append(currentFrame);
210 emit endAddingFrames();
213 ApiTraceCall * ApiTrace::callWithIndex(int idx) const
215 for (int i = 0; i < m_calls.count(); ++i) {
216 ApiTraceCall *call = m_calls[i];
217 if (call->index() == idx)
223 ApiTraceState ApiTrace::defaultState() const
225 ApiTraceFrame *frame = frameAt(0);
226 if (!frame || !frame->hasState())
227 return ApiTraceState();
229 return *frame->state();
232 void ApiTrace::callEdited(ApiTraceCall *call)
234 if (!m_editedCalls.contains(call)) {
235 //lets generate a temp filename
236 QString tempPath = QDir::tempPath();
237 m_tempFileName = QString::fromLatin1("%1/%2.edited")
241 m_editedCalls.insert(call);
242 m_needsSaving = true;
247 void ApiTrace::callReverted(ApiTraceCall *call)
249 m_editedCalls.remove(call);
251 if (m_editedCalls.isEmpty()) {
252 m_needsSaving = false;
257 bool ApiTrace::edited() const
259 return !m_editedCalls.isEmpty();
262 bool ApiTrace::needsSaving() const
264 return m_needsSaving;
267 void ApiTrace::save()
269 QFileInfo fi(m_tempFileName);
271 emit startedSaving();
272 dir.mkpath(fi.absolutePath());
273 m_saver->saveFile(m_tempFileName, m_calls);
276 void ApiTrace::slotSaved()
278 m_needsSaving = false;
281 bool ApiTrace::isSaving() const
283 return m_saver->isRunning();
286 void ApiTrace::callError(ApiTraceCall *call)
290 if (call->hasError())
291 m_errors.insert(call);
293 m_errors.remove(call);
298 bool ApiTrace::hasErrors() const
300 return !m_errors.isEmpty();
303 void ApiTrace::loadFrame(ApiTraceFrame *frame)
305 Q_ASSERT(!frame->loaded());
306 emit requestFrame(frame);
309 #include "apitrace.moc"