#include "apitrace.h"
#include "loaderthread.h"
+#include "saverthread.h"
+
+#include <QDir>
ApiTrace::ApiTrace()
- : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers)
+ : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
+ m_needsSaving(false)
{
m_loader = new LoaderThread(this);
connect(m_loader, SIGNAL(parsedFrames(const QList<ApiTraceFrame*>)),
this, SIGNAL(startedLoadingTrace()));
connect(m_loader, SIGNAL(finished()),
this, SIGNAL(finishedLoadingTrace()));
+
+ m_saver = new SaverThread(this);
+ connect(m_saver, SIGNAL(traceSaved()),
+ this, SLOT(slotSaved()));
+ connect(m_saver, SIGNAL(traceSaved()),
+ this, SIGNAL(saved()));
}
ApiTrace::~ApiTrace()
qDeleteAll(m_calls);
qDeleteAll(m_frames);
delete m_loader;
+ delete m_saver;
}
bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
switch (marker) {
case FrameMarker_SwapBuffers:
- return call->name.contains(QLatin1String("SwapBuffers"));
+ return call->name().contains(QLatin1String("SwapBuffers")) ||
+ call->name() == QLatin1String("CGLFlushDrawable") ||
+ call->name() == QLatin1String("glFrameTerminatorGREMEDY");
case FrameMarker_Flush:
- return call->name == QLatin1String("glFlush");
+ return call->name() == QLatin1String("glFlush");
case FrameMarker_Finish:
- return call->name == QLatin1String("glFinish");
+ return call->name() == QLatin1String("glFinish");
case FrameMarker_Clear:
- return call->name == QLatin1String("glClear");
+ return call->name() == QLatin1String("glClear");
}
Q_ASSERT(!"unknown frame marker");
QString ApiTrace::fileName() const
{
+ if (edited())
+ return m_tempFileName;
+
return m_fileName;
}
{
const ApiTraceFrame *frame = frameAt(idx);
if (frame)
- return frame->calls.count();
+ return frame->numChildren();
else
return 0;
}
}
m_frames.clear();
m_calls.clear();
+ m_errors.clear();
+ m_editedCalls.clear();
+ m_needsSaving = false;
emit invalidated();
m_loader->loadFile(m_fileName);
void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
{
+ QList<ApiTraceCall*> calls;
int currentFrames = m_frames.count();
int numNewFrames = frames.count();
+
+ emit beginAddingFrames(currentFrames, numNewFrames);
+
m_frames += frames;
int currentCalls = m_calls.count();
int numNewCalls = 0;
foreach(ApiTraceFrame *frame, frames) {
- numNewCalls += frame->calls.count();
- m_calls += frame->calls;
+ Q_ASSERT(this == frame->parentTrace());
+ numNewCalls += frame->numChildren();
+ calls += frame->calls();
}
+ m_calls.reserve(m_calls.count() + calls.count());
+ m_calls += calls;
- emit framesAdded(currentFrames, numNewFrames);
+ emit endAddingFrames();
emit callsAdded(currentCalls, numNewCalls);
}
if (m_calls.isEmpty())
return;
+ emit beginAddingFrames(0, m_frames.count());
+
ApiTraceFrame *currentFrame = 0;
foreach(ApiTraceCall *apiCall, m_calls) {
if (!currentFrame) {
- currentFrame = new ApiTraceFrame();
+ currentFrame = new ApiTraceFrame(this);
currentFrame->number = m_frames.count();
}
- apiCall->parentFrame = currentFrame;
- currentFrame->calls.append(apiCall);
+ apiCall->setParentFrame(currentFrame);
+ currentFrame->addCall(apiCall);
if (ApiTrace::isCallAFrameMarker(apiCall,
m_frameMarker)) {
m_frames.append(currentFrame);
m_frames.append(currentFrame);
currentFrame = 0;
}
- emit framesAdded(0, m_frames.count());
+ emit endAddingFrames();
+}
+
+ApiTraceCall * ApiTrace::callWithIndex(int idx) const
+{
+ for (int i = 0; i < m_calls.count(); ++i) {
+ ApiTraceCall *call = m_calls[i];
+ if (call->index() == idx)
+ return call;
+ }
+ return NULL;
+}
+
+ApiTraceState ApiTrace::defaultState() const
+{
+ ApiTraceFrame *frame = frameAt(0);
+ if (!frame || !frame->hasState())
+ return ApiTraceState();
+
+ return *frame->state();
+}
+
+void ApiTrace::callEdited(ApiTraceCall *call)
+{
+ if (!m_editedCalls.contains(call)) {
+ //lets generate a temp filename
+ QString tempPath = QDir::tempPath();
+ m_tempFileName = QString::fromLatin1("%1/%2.edited")
+ .arg(tempPath)
+ .arg(m_fileName);
+ }
+ m_editedCalls.insert(call);
+ m_needsSaving = true;
+
+ emit changed(call);
+}
+
+void ApiTrace::callReverted(ApiTraceCall *call)
+{
+ m_editedCalls.remove(call);
+
+ if (m_editedCalls.isEmpty()) {
+ m_needsSaving = false;
+ }
+ emit changed(call);
+}
+
+bool ApiTrace::edited() const
+{
+ return !m_editedCalls.isEmpty();
+}
+
+bool ApiTrace::needsSaving() const
+{
+ return m_needsSaving;
+}
+
+void ApiTrace::save()
+{
+ QFileInfo fi(m_tempFileName);
+ QDir dir;
+ emit startedSaving();
+ dir.mkpath(fi.absolutePath());
+ m_saver->saveFile(m_tempFileName, m_calls);
+}
+
+void ApiTrace::slotSaved()
+{
+ m_needsSaving = false;
+}
+
+bool ApiTrace::isSaving() const
+{
+ return m_saver->isRunning();
+}
+
+void ApiTrace::callError(ApiTraceCall *call)
+{
+ Q_ASSERT(call);
+
+ if (call->hasError())
+ m_errors.insert(call);
+ else
+ m_errors.remove(call);
+
+ emit changed(call);
+}
+
+bool ApiTrace::hasErrors() const
+{
+ return !m_errors.isEmpty();
+}
+
+ApiTraceCallSignature * ApiTrace::signature(unsigned id)
+{
+ if (id >= m_signatures.count()) {
+ m_signatures.resize(id + 1);
+ return NULL;
+ } else {
+ return m_signatures[id];
+ }
+}
+
+void ApiTrace::addSignature(unsigned id, ApiTraceCallSignature *signature)
+{
+ m_signatures[id] = signature;
}
#include "apitrace.moc"