3 #include "loaderthread.h"
4 #include "saverthread.h"
9 : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
12 m_loader = new LoaderThread(this);
13 connect(m_loader, SIGNAL(parsedFrames(const QList<ApiTraceFrame*>)),
14 this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
15 connect(m_loader, SIGNAL(started()),
16 this, SIGNAL(startedLoadingTrace()));
17 connect(m_loader, SIGNAL(finished()),
18 this, SIGNAL(finishedLoadingTrace()));
20 m_saver = new SaverThread(this);
21 connect(m_saver, SIGNAL(traceSaved()),
22 this, SLOT(slotSaved()));
23 connect(m_saver, SIGNAL(traceSaved()),
24 this, SIGNAL(saved()));
35 bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
36 ApiTrace::FrameMarker marker)
42 case FrameMarker_SwapBuffers:
43 return call->name().contains(QLatin1String("SwapBuffers")) ||
44 call->name() == QLatin1String("CGLFlushDrawable") ||
45 call->name() == QLatin1String("glFrameTerminatorGREMEDY");
46 case FrameMarker_Flush:
47 return call->name() == QLatin1String("glFlush");
48 case FrameMarker_Finish:
49 return call->name() == QLatin1String("glFinish");
50 case FrameMarker_Clear:
51 return call->name() == QLatin1String("glClear");
54 Q_ASSERT(!"unknown frame marker");
59 bool ApiTrace::isEmpty() const
61 return m_calls.isEmpty();
64 QString ApiTrace::fileName() const
67 return m_tempFileName;
72 ApiTrace::FrameMarker ApiTrace::frameMarker() const
77 QVector<ApiTraceCall*> ApiTrace::calls() const
82 ApiTraceCall * ApiTrace::callAt(int idx) const
84 return m_calls.value(idx);
87 int ApiTrace::numCalls() const
89 return m_calls.count();
92 QList<ApiTraceFrame*> ApiTrace::frames() const
97 ApiTraceFrame * ApiTrace::frameAt(int idx) const
99 return m_frames.value(idx);
102 int ApiTrace::numFrames() const
104 return m_frames.count();
107 int ApiTrace::numCallsInFrame(int idx) const
109 const ApiTraceFrame *frame = frameAt(idx);
111 return frame->numChildren();
116 void ApiTrace::setFileName(const QString &name)
118 if (m_fileName != name) {
121 if (m_loader->isRunning()) {
122 m_loader->terminate();
128 m_editedCalls.clear();
129 m_needsSaving = false;
132 m_loader->loadFile(m_fileName);
136 void ApiTrace::setFrameMarker(FrameMarker marker)
138 if (m_frameMarker != marker) {
139 emit framesInvalidated();
141 qDeleteAll(m_frames);
147 void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
149 QVector<ApiTraceCall*> calls;
150 int currentFrames = m_frames.count();
151 int numNewFrames = frames.count();
153 emit beginAddingFrames(currentFrames, numNewFrames);
157 int currentCalls = m_calls.count();
159 foreach(ApiTraceFrame *frame, frames) {
160 Q_ASSERT(this == frame->parentTrace());
161 numNewCalls += frame->numChildren();
162 calls += frame->calls();
164 m_calls.reserve(m_calls.count() + calls.count() + 1);
167 emit endAddingFrames();
168 emit callsAdded(currentCalls, numNewCalls);
171 void ApiTrace::detectFrames()
173 if (m_calls.isEmpty())
176 emit beginAddingFrames(0, m_frames.count());
178 ApiTraceFrame *currentFrame = 0;
179 foreach(ApiTraceCall *apiCall, m_calls) {
181 currentFrame = new ApiTraceFrame(this);
182 currentFrame->number = m_frames.count();
183 currentFrame->setLoaded(true);
185 apiCall->setParentFrame(currentFrame);
186 currentFrame->addCall(apiCall);
187 if (ApiTrace::isCallAFrameMarker(apiCall,
189 m_frames.append(currentFrame);
193 //last frames won't have markers
194 // it's just a bunch of Delete calls for every object
195 // after the last SwapBuffers
197 m_frames.append(currentFrame);
200 emit endAddingFrames();
203 ApiTraceCall * ApiTrace::callWithIndex(int idx) const
205 for (int i = 0; i < m_calls.count(); ++i) {
206 ApiTraceCall *call = m_calls[i];
207 if (call->index() == idx)
213 ApiTraceState ApiTrace::defaultState() const
215 ApiTraceFrame *frame = frameAt(0);
216 if (!frame || !frame->hasState())
217 return ApiTraceState();
219 return *frame->state();
222 void ApiTrace::callEdited(ApiTraceCall *call)
224 if (!m_editedCalls.contains(call)) {
225 //lets generate a temp filename
226 QString tempPath = QDir::tempPath();
227 m_tempFileName = QString::fromLatin1("%1/%2.edited")
231 m_editedCalls.insert(call);
232 m_needsSaving = true;
237 void ApiTrace::callReverted(ApiTraceCall *call)
239 m_editedCalls.remove(call);
241 if (m_editedCalls.isEmpty()) {
242 m_needsSaving = false;
247 bool ApiTrace::edited() const
249 return !m_editedCalls.isEmpty();
252 bool ApiTrace::needsSaving() const
254 return m_needsSaving;
257 void ApiTrace::save()
259 QFileInfo fi(m_tempFileName);
261 emit startedSaving();
262 dir.mkpath(fi.absolutePath());
263 m_saver->saveFile(m_tempFileName, m_calls);
266 void ApiTrace::slotSaved()
268 m_needsSaving = false;
271 bool ApiTrace::isSaving() const
273 return m_saver->isRunning();
276 void ApiTrace::callError(ApiTraceCall *call)
280 if (call->hasError())
281 m_errors.insert(call);
283 m_errors.remove(call);
288 bool ApiTrace::hasErrors() const
290 return !m_errors.isEmpty();
293 ApiTraceCallSignature * ApiTrace::signature(unsigned id)
295 if (id >= m_signatures.count()) {
296 m_signatures.resize(id + 1);
299 return m_signatures[id];
303 void ApiTrace::addSignature(unsigned id, ApiTraceCallSignature *signature)
305 m_signatures[id] = signature;
308 ApiTraceEnumSignature * ApiTrace::enumSignature(unsigned id)
310 if (id >= m_enumSignatures.count()) {
311 m_enumSignatures.resize(id + 1);
314 return m_enumSignatures[id];
318 void ApiTrace::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature)
320 m_enumSignatures[id] = signature;
323 #include "apitrace.moc"