]> git.cworth.org Git - apitrace/blobdiff - gui/apitrace.cpp
Reduce the size of ApiTraceCall, ApiTraceEvent and ApiTraceFrame
[apitrace] / gui / apitrace.cpp
index 03ff02e1ab0655c48bcbf4ddccc93cc8f4bed3e5..2985d9dd44a977eca8053ab03244cc794a967b57 100644 (file)
@@ -1,9 +1,13 @@
 #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*>)),
@@ -12,6 +16,12 @@ ApiTrace::ApiTrace()
             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()
@@ -19,6 +29,7 @@ ApiTrace::~ApiTrace()
     qDeleteAll(m_calls);
     qDeleteAll(m_frames);
     delete m_loader;
+    delete m_saver;
 }
 
 bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
@@ -29,13 +40,15 @@ 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");
@@ -50,6 +63,9 @@ bool ApiTrace::isEmpty() const
 
 QString ApiTrace::fileName() const
 {
+    if (edited())
+        return m_tempFileName;
+
     return m_fileName;
 }
 
@@ -92,7 +108,7 @@ int ApiTrace::numCallsInFrame(int idx) const
 {
     const ApiTraceFrame *frame = frameAt(idx);
     if (frame)
-        return frame->calls.count();
+        return frame->numChildren();
     else
         return 0;
 }
@@ -108,6 +124,9 @@ void ApiTrace::setFileName(const QString &name)
         }
         m_frames.clear();
         m_calls.clear();
+        m_errors.clear();
+        m_editedCalls.clear();
+        m_needsSaving = false;
         emit invalidated();
 
         m_loader->loadFile(m_fileName);
@@ -127,18 +146,25 @@ void ApiTrace::setFrameMarker(FrameMarker marker)
 
 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);
 }
 
@@ -147,14 +173,16 @@ void ApiTrace::detectFrames()
     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);
@@ -168,17 +196,107 @@ void ApiTrace::detectFrames()
         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)
+        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(const QString &callName)
+{
+    return m_signatures[callName];
+}
+
+void ApiTrace::addSignature(ApiTraceCallSignature *signature)
+{
+    m_signatures.insert(signature->name(), signature);
+}
+
 #include "apitrace.moc"