]> git.cworth.org Git - apitrace/commitdiff
Merge remote-tracking branch 'origin/master' into on-demand-loading
authorZack Rusin <zack@kde.org>
Thu, 1 Sep 2011 04:01:02 +0000 (00:01 -0400)
committerZack Rusin <zack@kde.org>
Thu, 1 Sep 2011 04:01:02 +0000 (00:01 -0400)
20 files changed:
glretrace.py
gui/apicalldelegate.cpp
gui/apitrace.cpp
gui/apitrace.h
gui/apitracecall.cpp
gui/apitracecall.h
gui/apitracemodel.cpp
gui/argumentseditor.cpp
gui/argumentseditor.h
gui/loaderthread.cpp
gui/loaderthread.h
gui/mainwindow.cpp
gui/mainwindow.h
gui/retracer.cpp
gui/retracer.h
gui/saverthread.cpp
gui/saverthread.h
trace_model.cpp
trace_model.hpp
trace_snappyfile.cpp

index b775609aa0eb79ca6f4daf538ed258febfcc54f6..6a5103e0db2523894d8ff60f7632191af4cc3f19 100644 (file)
@@ -302,7 +302,7 @@ class GlRetracer(Retracer):
 
     def extract_arg(self, function, arg, arg_type, lvalue, rvalue):
         if function.name in self.array_pointer_function_names and arg.name == 'pointer':
-            print '    %s = static_cast<%s>(%s.toPointer());' % (lvalue, arg_type, rvalue)
+            print '    %s = static_cast<%s>(%s.toPointer(true));' % (lvalue, arg_type, rvalue)
             return
 
         if function.name in self.draw_elements_function_names and arg.name == 'indices':
index dc9dc94a45248a50caf0a9941085a20d6367418a..11ed3a5ca03d5c59c96b8c7bc05c67e2e5583bf8 100644 (file)
@@ -33,7 +33,7 @@ void ApiCallDelegate::paint(QPainter *painter,
         //QStyledItemDelegate::paint(painter, option, index);
         QStyle *style = QApplication::style();
         style->drawControl(QStyle::CE_ItemViewItem, &option, painter, 0);
-        if (!event->state().isEmpty()) {
+        if (event->hasState()) {
             QPixmap px = m_stateEmblem.pixmap(option.rect.height(),
                                               option.rect.height());
             painter->drawPixmap(option.rect.topLeft(), px);
index d9a248dbaddc180b121d146a50777aaf55486953..51c4755b28194a70b635ac16d3230ef5c03623b1 100644 (file)
@@ -74,7 +74,7 @@ ApiTrace::FrameMarker ApiTrace::frameMarker() const
     return m_frameMarker;
 }
 
-QList<ApiTraceCall*> ApiTrace::calls() const
+QVector<ApiTraceCall*> ApiTrace::calls() const
 {
     return m_calls;
 }
@@ -146,6 +146,7 @@ void ApiTrace::setFrameMarker(FrameMarker marker)
 
 void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
 {
+    QVector<ApiTraceCall*> calls;
     int currentFrames = m_frames.count();
     int numNewFrames = frames.count();
 
@@ -156,10 +157,12 @@ void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
     int currentCalls = m_calls.count();
     int numNewCalls = 0;
     foreach(ApiTraceFrame *frame, frames) {
-        frame->setParentTrace(this);
+        Q_ASSERT(this == frame->parentTrace());
         numNewCalls += frame->numChildren();
-        m_calls += frame->calls();
+        calls += frame->calls();
     }
+    m_calls.reserve(m_calls.count() + calls.count() + 1);
+    m_calls += calls;
 
     emit endAddingFrames();
     emit callsAdded(currentCalls, numNewCalls);
@@ -175,8 +178,7 @@ void ApiTrace::detectFrames()
     ApiTraceFrame *currentFrame = 0;
     foreach(ApiTraceCall *apiCall, m_calls) {
         if (!currentFrame) {
-            currentFrame = new ApiTraceFrame();
-            currentFrame->setParentTrace(this);
+            currentFrame = new ApiTraceFrame(this);
             currentFrame->number = m_frames.count();
         }
         apiCall->setParentFrame(currentFrame);
@@ -210,10 +212,10 @@ ApiTraceCall * ApiTrace::callWithIndex(int idx) const
 ApiTraceState ApiTrace::defaultState() const
 {
     ApiTraceFrame *frame = frameAt(0);
-    if (!frame)
+    if (!frame || !frame->hasState())
         return ApiTraceState();
 
-    return frame->state();
+    return *frame->state();
 }
 
 void ApiTrace::callEdited(ApiTraceCall *call)
@@ -287,4 +289,34 @@ 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;
+}
+
+ApiTraceEnumSignature * ApiTrace::enumSignature(unsigned id)
+{
+    if (id >= m_enumSignatures.count()) {
+        m_enumSignatures.resize(id + 1);
+        return NULL;
+    } else {
+        return m_enumSignatures[id];
+    }
+}
+
+void ApiTrace::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature)
+{
+    m_enumSignatures[id] = signature;
+}
+
 #include "apitrace.moc"
index d52c669928aeac70654bf3c9a48be89fbaa04698..036a84cdd0b14f150560570c6104b8c543772169 100644 (file)
@@ -33,7 +33,14 @@ public:
 
     ApiTraceState defaultState() const;
 
-    QList<ApiTraceCall*> calls() const;
+    ApiTraceCallSignature *signature(unsigned id);
+    void addSignature(unsigned id, ApiTraceCallSignature *signature);
+
+    ApiTraceEnumSignature *enumSignature(unsigned id);
+    void addEnumSignature(unsigned id, ApiTraceEnumSignature *signature);
+
+
+    QVector<ApiTraceCall*> calls() const;
     ApiTraceCall *callAt(int idx) const;
     ApiTraceCall *callWithIndex(int idx) const;
     int numCalls() const;
@@ -82,7 +89,7 @@ private:
     QString m_tempFileName;
 
     QList<ApiTraceFrame*> m_frames;
-    QList<ApiTraceCall*> m_calls;
+    QVector<ApiTraceCall*> m_calls;
 
     FrameMarker m_frameMarker;
 
@@ -94,6 +101,8 @@ private:
     bool m_needsSaving;
 
     QSet<ApiTraceCall*> m_errors;
+    QVector<ApiTraceCallSignature*> m_signatures;
+    QVector<ApiTraceEnumSignature*> m_enumSignatures;
 };
 
 #endif
index c3f883147fe9f743a8135e08421229e3d93ef301..bd30aaaa89aff9a333ea84f13dc534e2b62d4a42 100644 (file)
@@ -44,18 +44,6 @@ const char * const styleSheet =
     //"    -moz-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
     "}\n";
 
-ApiPointer::ApiPointer(unsigned long long val)
-    : m_value(val)
-{
-}
-
-QString ApiPointer::toString() const
-{
-    if (m_value)
-        return QString("0x%1").arg(m_value, 0, 16);
-    else
-        return QLatin1String("NULL");
-}
 
 // Qt::convertFromPlainText doesn't do precisely what we want
 static QString
@@ -109,7 +97,8 @@ plainTextToHTML(const QString & plain, bool multiLine)
     return rich;
 }
 
-QString apiVariantToString(const QVariant &variant, bool multiLine)
+QString
+apiVariantToString(const QVariant &variant, bool multiLine)
 {
     if (variant.userType() == QVariant::Double) {
         return QString::number(variant.toFloat());
@@ -151,13 +140,169 @@ QString apiVariantToString(const QVariant &variant, bool multiLine)
     return QString();
 }
 
+
+void VariantVisitor::visit(Trace::Null *)
+{
+    m_variant = QVariant::fromValue(ApiPointer(0));
+}
+
+void VariantVisitor::visit(Trace::Bool *node)
+{
+    m_variant = QVariant(node->value);
+}
+
+void VariantVisitor::visit(Trace::SInt *node)
+{
+    m_variant = QVariant(node->value);
+}
+
+void VariantVisitor::visit(Trace::UInt *node)
+{
+    m_variant = QVariant(node->value);
+}
+
+void VariantVisitor::visit(Trace::Float *node)
+{
+    m_variant = QVariant(node->value);
+}
+
+void VariantVisitor::visit(Trace::String *node)
+{
+    m_variant = QVariant(QString::fromStdString(node->value));
+}
+
+void VariantVisitor::visit(Trace::Enum *e)
+{
+    ApiTraceEnumSignature *sig = 0;
+
+    if (m_trace) {
+        sig = m_trace->enumSignature(e->sig->id);
+    }
+    if (!sig) {
+        sig = new ApiTraceEnumSignature(
+            QString::fromStdString(e->sig->name),
+            QVariant(e->sig->value));
+        if (m_trace) {
+            m_trace->addEnumSignature(e->sig->id, sig);
+        }
+    }
+
+    m_variant = QVariant::fromValue(ApiEnum(sig));
+}
+
+void VariantVisitor::visit(Trace::Bitmask *bitmask)
+{
+    m_variant = QVariant::fromValue(ApiBitmask(bitmask));
+}
+
+void VariantVisitor::visit(Trace::Struct *str)
+{
+    m_variant = QVariant::fromValue(ApiStruct(str));
+}
+
+void VariantVisitor::visit(Trace::Array *array)
+{
+    m_variant = QVariant::fromValue(ApiArray(array));
+}
+
+void VariantVisitor::visit(Trace::Blob *blob)
+{
+    //XXX
+    //FIXME: this is a nasty hack. Trace::Blob's can't
+    //   delete the contents in the destructor because
+    //   the data is being used by other calls. We piggy back
+    //   on that assumption and don't deep copy the data. If
+    //   Blob's will start deleting the data we will need to
+    //   start deep copying it or switch to using something like
+    //   Boost's shared_ptr or Qt's QSharedPointer to handle it
+    blob->toPointer(true);
+    QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size);
+    m_variant = QVariant(barray);
+}
+
+void VariantVisitor::visit(Trace::Pointer *ptr)
+{
+    m_variant = QVariant::fromValue(ApiPointer(ptr->value));
+}
+
+
+ApiEnum::ApiEnum(ApiTraceEnumSignature *sig)
+    : m_sig(sig)
+{
+}
+
+QString ApiEnum::toString() const
+{
+    if (m_sig) {
+        return m_sig->name();
+    }
+    Q_ASSERT(!"should never happen");
+    return QString();
+}
+
+QVariant ApiEnum::value() const
+{
+    if (m_sig) {
+        return m_sig->value();
+    }
+    Q_ASSERT(!"should never happen");
+    return QVariant();
+}
+
+QString ApiEnum::name() const
+{
+    if (m_sig) {
+        return m_sig->name();
+    }
+    Q_ASSERT(!"should never happen");
+    return QString();
+}
+
+unsigned long long ApiBitmask::value() const
+{
+    return m_value;
+}
+
+ApiBitmask::Signature ApiBitmask::signature() const
+{
+    return m_sig;
+}
+
+ApiStruct::Signature ApiStruct::signature() const
+{
+    return m_sig;
+}
+
+QList<QVariant> ApiStruct::values() const
+{
+    return m_members;
+}
+
+ApiPointer::ApiPointer(unsigned long long val)
+    : m_value(val)
+{
+}
+
+
+unsigned long long ApiPointer::value() const
+{
+    return m_value;
+}
+
+QString ApiPointer::toString() const
+{
+    if (m_value)
+        return QString("0x%1").arg(m_value, 0, 16);
+    else
+        return QLatin1String("NULL");
+}
+
 ApiBitmask::ApiBitmask(const Trace::Bitmask *bitmask)
     : m_value(0)
 {
     init(bitmask);
 }
 
-
 void ApiBitmask::init(const Trace::Bitmask *bitmask)
 {
     if (!bitmask)
@@ -231,7 +376,7 @@ void ApiStruct::init(const Trace::Struct *s)
 
     m_sig.name = QString::fromStdString(s->sig->name);
     for (unsigned i = 0; i < s->sig->num_members; ++i) {
-        VariantVisitor vis;
+        VariantVisitor vis(0);
         m_sig.memberNames.append(
             QString::fromStdString(s->sig->member_names[i]));
         s->members[i]->visit(vis);
@@ -239,88 +384,21 @@ void ApiStruct::init(const Trace::Struct *s)
     }
 }
 
-void VariantVisitor::visit(Trace::Null *)
-{
-    m_variant = QVariant::fromValue(ApiPointer(0));
-}
-
-void VariantVisitor::visit(Trace::Bool *node)
-{
-    m_variant = QVariant(node->value);
-}
-
-void VariantVisitor::visit(Trace::SInt *node)
-{
-    m_variant = QVariant(node->value);
-}
-
-void VariantVisitor::visit(Trace::UInt *node)
-{
-    m_variant = QVariant(node->value);
-}
-
-void VariantVisitor::visit(Trace::Float *node)
-{
-    m_variant = QVariant(node->value);
-}
-
-void VariantVisitor::visit(Trace::String *node)
-{
-    m_variant = QVariant(QString::fromStdString(node->value));
-}
-
-void VariantVisitor::visit(Trace::Enum *e)
-{
-    QVariant val = QVariant(e->sig->value);
-
-    m_variant = QVariant::fromValue(
-        ApiEnum(QString::fromStdString(e->sig->name), val));
-}
-
-void VariantVisitor::visit(Trace::Bitmask *bitmask)
-{
-    m_variant = QVariant::fromValue(ApiBitmask(bitmask));
-}
-
-void VariantVisitor::visit(Trace::Struct *str)
-{
-    m_variant = QVariant::fromValue(ApiStruct(str));
-}
-
-void VariantVisitor::visit(Trace::Array *array)
-{
-    m_variant = QVariant::fromValue(ApiArray(array));
-}
-
-void VariantVisitor::visit(Trace::Blob *blob)
-{
-    //XXX
-    //FIXME: this is a nasty hack. Trace::Blob's can't
-    //   delete the contents in the destructor because
-    //   the data is being used by other calls. We piggy back
-    //   on that assumption and don't deep copy the data. If
-    //   Blob's will start deleting the data we will need to
-    //   start deep copying it or switch to using something like
-    //   Boost's shared_ptr or Qt's QSharedPointer to handle it
-    QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size);
-    m_variant = QVariant(barray);
-}
-
-void VariantVisitor::visit(Trace::Pointer *ptr)
-{
-    m_variant = QVariant::fromValue(ApiPointer(ptr->value));
-}
-
 ApiArray::ApiArray(const Trace::Array *arr)
 {
     init(arr);
 }
 
-ApiArray::ApiArray(const QList<QVariant> &vals)
+ApiArray::ApiArray(const QVector<QVariant> &vals)
     : m_array(vals)
 {
 }
 
+QVector<QVariant> ApiArray::values() const
+{
+    return m_array;
+}
+
 QString ApiArray::toString() const
 {
     QString str;
@@ -341,270 +419,33 @@ void ApiArray::init(const Trace::Array *arr)
     if (!arr)
         return;
 
+    m_array.reserve(arr->values.size());
     for (int i = 0; i < arr->values.size(); ++i) {
-        VariantVisitor vis;
+        VariantVisitor vis(0);
         arr->values[i]->visit(vis);
 
         m_array.append(vis.variant());
     }
+    m_array.squeeze();
 }
 
-QStaticText ApiTraceCall::staticText() const
+ApiTraceState::ApiTraceState()
 {
-    if (m_staticText && !m_staticText->text().isEmpty())
-        return *m_staticText;
+}
 
-    QVariantList argValues = arguments();
+ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
+{
+    m_parameters = parsedJson[QLatin1String("parameters")].toMap();
+    QVariantMap attachedShaders =
+        parsedJson[QLatin1String("shaders")].toMap();
+    QVariantMap::const_iterator itr;
 
-    QString richText = QString::fromLatin1(
-        "<span style=\"font-weight:bold\">%1</span>(").arg(m_name);
-    for (int i = 0; i < m_argNames.count(); ++i) {
-        richText += QLatin1String("<span style=\"color:#0000ff\">");
-        QString argText = apiVariantToString(argValues[i]);
 
-        //if arguments are really long (e.g. shader text), cut them
-        // and elide it
-        if (argText.length() > 40) {
-            QString shortened = argText.mid(0, 40);
-            shortened[argText.length() - 5] = '.';
-            shortened[argText.length() - 4] = '.';
-            shortened[argText.length() - 3] = '.';
-            shortened[argText.length() - 2] = argText[argText.length() - 2];
-            shortened[argText.length() - 1] = argText[argText.length() - 1];
-            richText += shortened;
-        } else {
-            richText += argText;
-        }
-        richText += QLatin1String("</span>");
-        if (i < m_argNames.count() - 1)
-            richText += QLatin1String(", ");
-    }
-    richText += QLatin1String(")");
-    if (m_returnValue.isValid()) {
-        richText +=
-            QLatin1Literal(" = ") %
-            QLatin1Literal("<span style=\"color:#0000ff\">") %
-            apiVariantToString(m_returnValue) %
-            QLatin1Literal("</span>");
-    }
-
-    if (!m_staticText)
-        m_staticText = new QStaticText(richText);
-    else
-        m_staticText->setText(richText);
-    QTextOption opt;
-    opt.setWrapMode(QTextOption::NoWrap);
-    m_staticText->setTextOption(opt);
-    m_staticText->prepare();
-
-    return *m_staticText;
-}
-
-QString ApiTraceCall::toHtml() const
-{
-    if (!m_richText.isEmpty())
-        return m_richText;
-
-    m_richText = QLatin1String("<div class=\"call\">");
-
-    if (m_helpUrl.isEmpty()) {
-        m_richText += QString::fromLatin1(
-            "%1) <span class=\"callName\">%2</span>(")
-                      .arg(m_index)
-                      .arg(m_name);
-    } else {
-        m_richText += QString::fromLatin1(
-            "%1) <span class=\"callName\"><a href=\"%2\">%3</a></span>(")
-                      .arg(m_index)
-                      .arg(m_helpUrl.toString())
-                      .arg(m_name);
-    }
-
-    QVariantList argValues = arguments();
-    for (int i = 0; i < m_argNames.count(); ++i) {
-        m_richText +=
-            QLatin1String("<span class=\"arg-name\">") +
-            m_argNames[i] +
-            QLatin1String("</span>") +
-            QLatin1Literal(" = ") +
-            QLatin1Literal("<span class=\"arg-value\">") +
-            apiVariantToString(argValues[i], true) +
-            QLatin1Literal("</span>");
-        if (i < m_argNames.count() - 1)
-            m_richText += QLatin1String(", ");
-    }
-    m_richText += QLatin1String(")");
-
-    if (m_returnValue.isValid()) {
-        m_richText +=
-            QLatin1String(" = ") +
-            QLatin1String("<span style=\"color:#0000ff\">") +
-            apiVariantToString(m_returnValue, true) +
-            QLatin1String("</span>");
-    }
-    m_richText += QLatin1String("</div>");
-
-    if (hasError()) {
-        QString errorStr =
-            QString::fromLatin1(
-                "<div class=\"error\">%1</div>")
-            .arg(m_error);
-        m_richText += errorStr;
-    }
-
-    m_richText =
-        QString::fromLatin1(
-            "<html><head><style type=\"text/css\" media=\"all\">"
-            "%1</style></head><body>%2</body></html>")
-        .arg(styleSheet)
-        .arg(m_richText);
-    m_richText.squeeze();
-
-    //qDebug()<<m_richText;
-    return m_richText;
-}
-
-QString ApiTraceCall::filterText() const
-{
-    if (!m_filterText.isEmpty())
-        return m_filterText;
-
-    QVariantList argValues = arguments();
-    m_filterText = m_name + QLatin1Literal("(");
-    for (int i = 0; i < m_argNames.count(); ++i) {
-        m_filterText += m_argNames[i] +
-                        QLatin1Literal(" = ") +
-                        apiVariantToString(argValues[i]);
-        if (i < m_argNames.count() - 1)
-            m_filterText += QLatin1String(", ");
-    }
-    m_filterText += QLatin1String(")");
-
-    if (m_returnValue.isValid()) {
-        m_filterText += QLatin1Literal(" = ") +
-                        apiVariantToString(m_returnValue);
-    }
-    m_filterText.squeeze();
-    return m_filterText;
-}
-
-QStaticText ApiTraceFrame::staticText() const
-{
-    if (m_staticText && !m_staticText->text().isEmpty())
-        return *m_staticText;
-
-    QString richText;
-
-    //mark the frame if it uploads more than a meg a frame
-    if (m_binaryDataSize > (1024*1024)) {
-        richText =
-            QObject::tr(
-                "<span style=\"font-weight:bold;\">"
-                "Frame&nbsp;%1</span>"
-                "<span style=\"font-style:italic;\">"
-                "&nbsp;&nbsp;&nbsp;&nbsp;(%2MB)</span>")
-            .arg(number)
-            .arg(double(m_binaryDataSize / (1024.*1024.)), 0, 'g', 2);
-    } else {
-        richText =
-            QObject::tr(
-                "<span style=\"font-weight:bold\">Frame %1</span>")
-            .arg(number);
-    }
-
-    if (!m_staticText)
-        m_staticText = new QStaticText(richText);
-
-    QTextOption opt;
-    opt.setWrapMode(QTextOption::NoWrap);
-    m_staticText->setTextOption(opt);
-    m_staticText->prepare();
-
-    return *m_staticText;
-}
-
-int ApiTraceCall::numChildren() const
-{
-    return 0;
-}
-
-int ApiTraceFrame::numChildren() const
-{
-    return m_calls.count();
-}
-
-ApiTraceFrame::ApiTraceFrame()
-    : ApiTraceEvent(ApiTraceEvent::Frame),
-      m_parentTrace(0),
-      m_binaryDataSize(0)
-{
-}
-
-ApiTraceCall::ApiTraceCall()
-    : ApiTraceEvent(ApiTraceEvent::Call),
-      m_hasBinaryData(false),
-      m_binaryDataIndex(0)
-{
-}
-
-ApiTraceEvent::ApiTraceEvent()
-    : m_type(ApiTraceEvent::None),
-      m_staticText(0)
-{
-}
-
-ApiTraceEvent::ApiTraceEvent(Type t)
-    : m_type(t),
-      m_staticText(0)
-{
-}
-
-ApiTraceCall::~ApiTraceCall()
-{
-}
-
-QVariantMap ApiTraceEvent::stateParameters() const
-{
-    return m_state.parameters();
-}
-
-ApiTraceState ApiTraceEvent::state() const
-{
-    return m_state;
-}
-
-void ApiTraceEvent::setState(const ApiTraceState &state)
-{
-    m_state = state;
-}
-
-bool ApiTraceCall::hasBinaryData() const
-{
-    return m_hasBinaryData;
-}
-
-int ApiTraceCall::binaryDataIndex() const
-{
-    return m_binaryDataIndex;
-}
-
-ApiTraceState::ApiTraceState()
-{
-}
-
-ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
-{
-    m_parameters = parsedJson[QLatin1String("parameters")].toMap();
-    QVariantMap attachedShaders =
-        parsedJson[QLatin1String("shaders")].toMap();
-    QVariantMap::const_iterator itr;
-
-
-    for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd();
-         ++itr) {
-        QString type = itr.key();
-        QString source = itr.value().toString();
-        m_shaderSources[type] = source;
+    for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd();
+         ++itr) {
+        QString type = itr.key();
+        QString source = itr.value().toString();
+        m_shaderSources[type] = source;
     }
 
     m_uniforms = parsedJson[QLatin1String("uniforms")].toMap();
@@ -624,6 +465,7 @@ ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
 
         Q_ASSERT(type == QLatin1String("uint8"));
         Q_ASSERT(normalized == true);
+        Q_UNUSED(normalized);
 
         QByteArray dataArray =
             image[QLatin1String("__data__")].toByteArray();
@@ -650,6 +492,7 @@ ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
 
         Q_ASSERT(type == QLatin1String("uint8"));
         Q_ASSERT(normalized == true);
+        Q_UNUSED(normalized);
 
         QByteArray dataArray =
             buffer[QLatin1String("__data__")].toByteArray();
@@ -693,121 +536,156 @@ const QList<ApiFramebuffer> & ApiTraceState::framebuffers() const
     return m_framebuffers;
 }
 
-QList<QVariant> ApiArray::values() const
+ApiTraceCallSignature::ApiTraceCallSignature(const QString &name,
+                                             const QStringList &argNames)
+    : m_name(name),
+      m_argNames(argNames)
 {
-    return m_array;
 }
 
-int ApiTraceCall::index() const
+ApiTraceCallSignature::~ApiTraceCallSignature()
 {
-    return m_index;
 }
 
-QString ApiTraceCall::name() const
+QUrl ApiTraceCallSignature::helpUrl() const
 {
-    return m_name;
+    return m_helpUrl;
 }
 
-QStringList ApiTraceCall::argNames() const
+void ApiTraceCallSignature::setHelpUrl(const QUrl &url)
 {
-    return m_argNames;
+    m_helpUrl = url;
 }
 
-QVariantList ApiTraceCall::arguments() const
+ApiTraceEvent::ApiTraceEvent()
+    : m_type(ApiTraceEvent::None),
+      m_hasBinaryData(false),
+      m_binaryDataIndex(0),
+      m_state(0),
+      m_staticText(0)
 {
-    if (m_editedValues.isEmpty())
-        return m_argValues;
-    else
-        return m_editedValues;
 }
 
-QVariant ApiTraceCall::returnValue() const
+ApiTraceEvent::ApiTraceEvent(Type t)
+    : m_type(t),
+      m_hasBinaryData(false),
+      m_binaryDataIndex(0),
+      m_state(0),
+      m_staticText(0)
 {
-    return m_returnValue;
 }
 
-QUrl ApiTraceCall::helpUrl() const
+ApiTraceEvent::~ApiTraceEvent()
 {
-    return m_helpUrl;
+    delete m_state;
+    delete m_staticText;
+}
+
+QVariantMap ApiTraceEvent::stateParameters() const
+{
+    if (m_state) {
+        return m_state->parameters();
+    } else {
+        return QVariantMap();
+    }
+}
+
+ApiTraceState *ApiTraceEvent::state() const
+{
+    return m_state;
+}
+
+void ApiTraceEvent::setState(ApiTraceState *state)
+{
+    m_state = state;
 }
 
-ApiTraceCall::ApiTraceCall(const Trace::Call *call)
+ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame, const Trace::Call *call)
     : ApiTraceEvent(ApiTraceEvent::Call),
-      m_hasBinaryData(false),
-      m_binaryDataIndex(0)
+      m_parentFrame(parentFrame)
 {
-    m_name = QString::fromStdString(call->sig->name);
+    ApiTrace *trace = parentTrace();
+
+    Q_ASSERT(trace);
+
     m_index = call->no;
 
-    QString argumentsText;
-    for (int i = 0; i < call->sig->num_args; ++i) {
-        m_argNames +=
-            QString::fromStdString(call->sig->arg_names[i]);
+    m_signature = trace->signature(call->sig->id);
+
+    if (!m_signature) {
+        QString name = QString::fromStdString(call->sig->name);
+        QStringList argNames;
+        argNames.reserve(call->sig->num_args);
+        for (int i = 0; i < call->sig->num_args; ++i) {
+            argNames += QString::fromStdString(call->sig->arg_names[i]);
+        }
+        m_signature = new ApiTraceCallSignature(name, argNames);
+        trace->addSignature(call->sig->id, m_signature);
     }
     if (call->ret) {
-        VariantVisitor retVisitor;
+        VariantVisitor retVisitor(trace);
         call->ret->visit(retVisitor);
         m_returnValue = retVisitor.variant();
     }
+    m_argValues.reserve(call->args.size());
     for (int i = 0; i < call->args.size(); ++i) {
-        VariantVisitor argVisitor;
+        VariantVisitor argVisitor(trace);
         call->args[i]->visit(argVisitor);
-        m_argValues += argVisitor.variant();
+        m_argValues.append(argVisitor.variant());
         if (m_argValues[i].type() == QVariant::ByteArray) {
             m_hasBinaryData = true;
             m_binaryDataIndex = i;
         }
     }
+    m_argValues.squeeze();
 }
 
-void ApiTraceCall::setHelpUrl(const QUrl &url)
-{
-    m_helpUrl = url;
-}
-
-void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
+ApiTraceCall::~ApiTraceCall()
 {
-    m_parentFrame = frame;
 }
 
-ApiTraceFrame * ApiTraceCall::parentFrame()const
-{
-    return m_parentFrame;
-}
 
-ApiTraceEvent::~ApiTraceEvent()
+bool ApiTraceCall::hasError() const
 {
-    delete m_staticText;
+    return !m_error.isEmpty();
 }
 
-void ApiTraceCall::revert()
+QString ApiTraceCall::error() const
 {
-    setEditedValues(QVariantList());
+    return m_error;
 }
 
-ApiTrace * ApiTraceFrame::parentTrace() const
+void ApiTraceCall::setError(const QString &msg)
 {
-    return m_parentTrace;
+    if (m_error != msg) {
+        ApiTrace *trace = parentTrace();
+        m_error = msg;
+        m_richText = QString();
+        if (trace)
+            trace->callError(this);
+    }
 }
 
-void ApiTraceFrame::setParentTrace(ApiTrace *trace)
+ApiTrace * ApiTraceCall::parentTrace() const
 {
-    m_parentTrace = trace;
+    if (m_parentFrame)
+        return m_parentFrame->parentTrace();
+    return NULL;
 }
 
-QVariantList ApiTraceCall::originalValues() const
+QVector<QVariant> ApiTraceCall::originalValues() const
 {
     return m_argValues;
 }
 
-void ApiTraceCall::setEditedValues(const QVariantList &lst)
+void ApiTraceCall::setEditedValues(const QVector<QVariant> &lst)
 {
     ApiTrace *trace = parentTrace();
 
     m_editedValues = lst;
     //lets regenerate data
     m_richText = QString();
-    m_filterText = QString();
+    m_searchText = QString();
     delete m_staticText;
     m_staticText = 0;
 
@@ -820,7 +698,7 @@ void ApiTraceCall::setEditedValues(const QVariantList &lst)
     }
 }
 
-QVariantList ApiTraceCall::editedValues() const
+QVector<QVariant> ApiTraceCall::editedValues() const
 {
     return m_editedValues;
 }
@@ -830,78 +708,268 @@ bool ApiTraceCall::edited() const
     return !m_editedValues.isEmpty();
 }
 
-ApiEnum::ApiEnum(const QString &name, const QVariant &val)
-    : m_name(name),
-      m_value(val)
+void ApiTraceCall::revert()
 {
+    setEditedValues(QVector<QVariant>());
 }
 
-QString ApiEnum::toString() const
+void ApiTraceCall::setHelpUrl(const QUrl &url)
 {
-    return m_name;
+    m_signature->setHelpUrl(url);
 }
 
-QVariant ApiEnum::value() const
+void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
 {
-    return m_value;
+    m_parentFrame = frame;
 }
 
-QString ApiEnum::name() const
+ApiTraceFrame * ApiTraceCall::parentFrame()const
 {
-    return m_name;
+    return m_parentFrame;
 }
 
-unsigned long long ApiBitmask::value() const
+int ApiTraceCall::index() const
 {
-    return m_value;
+    return m_index;
 }
 
-ApiBitmask::Signature ApiBitmask::signature() const
+QString ApiTraceCall::name() const
 {
-    return m_sig;
+    return m_signature->name();
 }
 
-ApiStruct::Signature ApiStruct::signature() const
+QStringList ApiTraceCall::argNames() const
 {
-    return m_sig;
+    return m_signature->argNames();
 }
 
-QList<QVariant> ApiStruct::values() const
+QVector<QVariant> ApiTraceCall::arguments() const
 {
-    return m_members;
+    if (m_editedValues.isEmpty())
+        return m_argValues;
+    else
+        return m_editedValues;
 }
 
-unsigned long long ApiPointer::value() const
+QVariant ApiTraceCall::returnValue() const
 {
-    return m_value;
+    return m_returnValue;
 }
 
-bool ApiTraceCall::hasError() const
+QUrl ApiTraceCall::helpUrl() const
 {
-    return !m_error.isEmpty();
+    return m_signature->helpUrl();
 }
 
-QString ApiTraceCall::error() const
+bool ApiTraceCall::hasBinaryData() const
 {
-    return m_error;
+    return m_hasBinaryData;
 }
 
-void ApiTraceCall::setError(const QString &msg)
+int ApiTraceCall::binaryDataIndex() const
 {
-    if (m_error != msg) {
-        ApiTrace *trace = parentTrace();
-        m_error = msg;
-        m_richText = QString();
-        if (trace)
-            trace->callError(this);
+    return m_binaryDataIndex;
+}
+
+QStaticText ApiTraceCall::staticText() const
+{
+    if (m_staticText && !m_staticText->text().isEmpty())
+        return *m_staticText;
+
+    QVector<QVariant> argValues = arguments();
+
+    QString richText = QString::fromLatin1(
+        "<span style=\"font-weight:bold\">%1</span>(").arg(
+            m_signature->name());
+    QStringList argNames = m_signature->argNames();
+    for (int i = 0; i < argNames.count(); ++i) {
+        richText += QLatin1String("<span style=\"color:#0000ff\">");
+        QString argText = apiVariantToString(argValues[i]);
+
+        //if arguments are really long (e.g. shader text), cut them
+        // and elide it
+        if (argText.length() > 40) {
+            QString shortened = argText.mid(0, 40);
+            shortened[argText.length() - 5] = '.';
+            shortened[argText.length() - 4] = '.';
+            shortened[argText.length() - 3] = '.';
+            shortened[argText.length() - 2] = argText.at(argText.length() - 2);
+            shortened[argText.length() - 1] = argText.at(argText.length() - 1);
+            richText += shortened;
+        } else {
+            richText += argText;
+        }
+        richText += QLatin1String("</span>");
+        if (i < argNames.count() - 1)
+            richText += QLatin1String(", ");
+    }
+    richText += QLatin1String(")");
+    if (m_returnValue.isValid()) {
+        richText +=
+            QLatin1Literal(" = ") %
+            QLatin1Literal("<span style=\"color:#0000ff\">") %
+            apiVariantToString(m_returnValue) %
+            QLatin1Literal("</span>");
     }
+
+    if (!m_staticText)
+        m_staticText = new QStaticText(richText);
+    else
+        m_staticText->setText(richText);
+    QTextOption opt;
+    opt.setWrapMode(QTextOption::NoWrap);
+    m_staticText->setTextOption(opt);
+    m_staticText->prepare();
+
+    return *m_staticText;
 }
 
-ApiTrace * ApiTraceCall::parentTrace() const
+QString ApiTraceCall::toHtml() const
+{
+    if (!m_richText.isEmpty())
+        return m_richText;
+
+    m_richText = QLatin1String("<div class=\"call\">");
+
+    QUrl helpUrl = m_signature->helpUrl();
+    if (helpUrl.isEmpty()) {
+        m_richText += QString::fromLatin1(
+            "%1) <span class=\"callName\">%2</span>(")
+                      .arg(m_index)
+                      .arg(m_signature->name());
+    } else {
+        m_richText += QString::fromLatin1(
+            "%1) <span class=\"callName\"><a href=\"%2\">%3</a></span>(")
+                      .arg(m_index)
+                      .arg(helpUrl.toString())
+                      .arg(m_signature->name());
+    }
+
+    QVector<QVariant> argValues = arguments();
+    QStringList argNames = m_signature->argNames();
+    for (int i = 0; i < argNames.count(); ++i) {
+        m_richText +=
+            QLatin1String("<span class=\"arg-name\">") +
+            argNames[i] +
+            QLatin1String("</span>") +
+            QLatin1Literal(" = ") +
+            QLatin1Literal("<span class=\"arg-value\">") +
+            apiVariantToString(argValues[i], true) +
+            QLatin1Literal("</span>");
+        if (i < argNames.count() - 1)
+            m_richText += QLatin1String(", ");
+    }
+    m_richText += QLatin1String(")");
+
+    if (m_returnValue.isValid()) {
+        m_richText +=
+            QLatin1String(" = ") +
+            QLatin1String("<span style=\"color:#0000ff\">") +
+            apiVariantToString(m_returnValue, true) +
+            QLatin1String("</span>");
+    }
+    m_richText += QLatin1String("</div>");
+
+    if (hasError()) {
+        QString errorStr =
+            QString::fromLatin1(
+                "<div class=\"error\">%1</div>")
+            .arg(m_error);
+        m_richText += errorStr;
+    }
+
+    m_richText =
+        QString::fromLatin1(
+            "<html><head><style type=\"text/css\" media=\"all\">"
+            "%1</style></head><body>%2</body></html>")
+        .arg(styleSheet)
+        .arg(m_richText);
+    m_richText.squeeze();
+
+    //qDebug()<<m_richText;
+    return m_richText;
+}
+
+QString ApiTraceCall::searchText() const
+{
+    if (!m_searchText.isEmpty())
+        return m_searchText;
+
+    QVector<QVariant> argValues = arguments();
+    m_searchText = m_signature->name() + QLatin1Literal("(");
+    QStringList argNames = m_signature->argNames();
+    for (int i = 0; i < argNames.count(); ++i) {
+        m_searchText += argNames[i] +
+                        QLatin1Literal(" = ") +
+                        apiVariantToString(argValues[i]);
+        if (i < argNames.count() - 1)
+            m_searchText += QLatin1String(", ");
+    }
+    m_searchText += QLatin1String(")");
+
+    if (m_returnValue.isValid()) {
+        m_searchText += QLatin1Literal(" = ") +
+                        apiVariantToString(m_returnValue);
+    }
+    m_searchText.squeeze();
+    return m_searchText;
+}
+
+int ApiTraceCall::numChildren() const
+{
+    return 0;
+}
+
+ApiTraceFrame::ApiTraceFrame(ApiTrace *parentTrace)
+    : ApiTraceEvent(ApiTraceEvent::Frame),
+      m_parentTrace(parentTrace),
+      m_binaryDataSize(0)
 {
-    if (m_parentFrame)
-        return m_parentFrame->parentTrace();
-    return NULL;
+}
+
+QStaticText ApiTraceFrame::staticText() const
+{
+    if (m_staticText && !m_staticText->text().isEmpty())
+        return *m_staticText;
+
+    QString richText;
+
+    //mark the frame if it uploads more than a meg a frame
+    if (m_binaryDataSize > (1024*1024)) {
+        richText =
+            QObject::tr(
+                "<span style=\"font-weight:bold;\">"
+                "Frame&nbsp;%1</span>"
+                "<span style=\"font-style:italic;\">"
+                "&nbsp;&nbsp;&nbsp;&nbsp;(%2MB)</span>")
+            .arg(number)
+            .arg(double(m_binaryDataSize / (1024.*1024.)), 0, 'g', 2);
+    } else {
+        richText =
+            QObject::tr(
+                "<span style=\"font-weight:bold\">Frame %1</span>")
+            .arg(number);
+    }
+
+    if (!m_staticText)
+        m_staticText = new QStaticText(richText);
+
+    QTextOption opt;
+    opt.setWrapMode(QTextOption::NoWrap);
+    m_staticText->setTextOption(opt);
+    m_staticText->prepare();
+
+    return *m_staticText;
+}
+
+int ApiTraceFrame::numChildren() const
+{
+    return m_calls.count();
+}
+
+ApiTrace * ApiTraceFrame::parentTrace() const
+{
+    return m_parentTrace;
 }
 
 void ApiTraceFrame::addCall(ApiTraceCall *call)
@@ -914,7 +982,7 @@ void ApiTraceFrame::addCall(ApiTraceCall *call)
     }
 }
 
-QList<ApiTraceCall*> ApiTraceFrame::calls() const
+QVector<ApiTraceCall*> ApiTraceFrame::calls() const
 {
     return m_calls;
 }
@@ -939,3 +1007,9 @@ int ApiTraceFrame::binaryDataSize() const
     return m_binaryDataSize;
 }
 
+void ApiTraceFrame::setCalls(const QVector<ApiTraceCall*> &calls,
+                             quint64 binaryDataSize)
+{
+    m_calls = calls;
+    m_binaryDataSize = binaryDataSize;
+}
index 7eae245cd3965997ba13c18d99040716205496bc..33648f2f28b054803d15e8f38b0ab1cd2b05e011 100644 (file)
@@ -16,6 +16,9 @@ class ApiTrace;
 class VariantVisitor : public Trace::Visitor
 {
 public:
+    VariantVisitor(ApiTrace *trace)
+        : m_trace(trace)
+    {}
     virtual void visit(Trace::Null *);
     virtual void visit(Trace::Bool *node);
     virtual void visit(Trace::SInt *node);
@@ -34,21 +37,37 @@ public:
         return m_variant;
     }
 private:
+    ApiTrace *m_trace;
     QVariant m_variant;
 };
 
+class ApiTraceEnumSignature
+{
+public:
+    ApiTraceEnumSignature(const QString &name = QString(),
+                          const QVariant &val=QVariant())\
+        : m_name(name),
+          m_value(val)
+    {}
+
+    QVariant value() const { return m_value; }
+    QString name() const { return m_name; }
+private:
+    QString m_name;
+    QVariant m_value;
+};
+
 class ApiEnum
 {
 public:
-    ApiEnum(const QString &name = QString(), const QVariant &val=QVariant());
+    ApiEnum(ApiTraceEnumSignature *sig=0);
 
     QString toString() const;
 
     QVariant value() const;
     QString name() const;
 private:
-    QString m_name;
-    QVariant m_value;
+    ApiTraceEnumSignature *m_sig;
 };
 Q_DECLARE_METATYPE(ApiEnum);
 
@@ -112,15 +131,15 @@ class ApiArray
 {
 public:
     ApiArray(const Trace::Array *arr = 0);
-    ApiArray(const QList<QVariant> &vals);
+    ApiArray(const QVector<QVariant> &vals);
 
     QString toString() const;
 
-    QList<QVariant> values() const;
+    QVector<QVariant> values() const;
 private:
     void init(const Trace::Array *arr);
 private:
-    QList<QVariant> m_array;
+    QVector<QVariant> m_array;
 };
 Q_DECLARE_METATYPE(ApiArray);
 
@@ -150,31 +169,62 @@ private:
 };
 Q_DECLARE_METATYPE(ApiTraceState);
 
+class ApiTraceCallSignature
+{
+public:
+    ApiTraceCallSignature(const QString &name,
+                          const QStringList &argNames);
+    ~ApiTraceCallSignature();
+
+    QString name() const
+    {
+        return m_name;
+    }
+    QStringList argNames() const
+    {
+        return m_argNames;
+    }
+
+    QUrl helpUrl() const;
+    void setHelpUrl(const QUrl &url);
+
+private:
+    QString m_name;
+    QStringList m_argNames;
+    QUrl m_helpUrl;
+};
+
 class ApiTraceEvent
 {
 public:
     enum Type {
-        None,
-        Call,
-        Frame
+        None  = 0,
+        Call  = 1 << 0,
+        Frame = 1 << 1
     };
 public:
     ApiTraceEvent();
     ApiTraceEvent(Type t);
     virtual ~ApiTraceEvent();
 
-    Type type() const { return m_type; }
+    Type type() const { return (Type)m_type; }
 
     virtual QStaticText staticText() const = 0;
     virtual int numChildren() const = 0;
 
     QVariantMap stateParameters() const;
-    ApiTraceState state() const;
-    void setState(const ApiTraceState &state);
+    ApiTraceState *state() const;
+    void setState(ApiTraceState *state);
+    bool hasState() const
+    {
+        return m_state && !m_state->isEmpty();
+    }
 
 protected:
-    Type m_type;
-    ApiTraceState m_state;
+    int m_type : 4;
+    mutable bool m_hasBinaryData;
+    mutable int m_binaryDataIndex:8;
+    ApiTraceState *m_state;
 
     mutable QStaticText *m_staticText;
 };
@@ -183,14 +233,13 @@ Q_DECLARE_METATYPE(ApiTraceEvent*);
 class ApiTraceCall : public ApiTraceEvent
 {
 public:
-    ApiTraceCall();
-    ApiTraceCall(const Trace::Call *tcall);
+    ApiTraceCall(ApiTraceFrame *parentFrame, const Trace::Call *tcall);
     ~ApiTraceCall();
 
     int index() const;
     QString name() const;
     QStringList argNames() const;
-    QVariantList arguments() const;
+    QVector<QVariant> arguments() const;
     QVariant returnValue() const;
     QUrl helpUrl() const;
     void setHelpUrl(const QUrl &url);
@@ -201,51 +250,46 @@ public:
     QString error() const;
     void setError(const QString &msg);
 
-    QVariantList originalValues() const;
+    QVector<QVariant> originalValues() const;
 
     bool edited() const;
-    void setEditedValues(const QVariantList &lst);
-    QVariantList editedValues() const;
+    void setEditedValues(const QVector<QVariant> &lst);
+    QVector<QVariant> editedValues() const;
     void revert();
 
     ApiTrace *parentTrace() const;
 
     QString toHtml() const;
-    QString filterText() const;
+    QString searchText() const;
     QStaticText staticText() const;
     int numChildren() const;
     bool hasBinaryData() const;
     int binaryDataIndex() const;
 private:
     int m_index;
-    QString m_name;
-    QStringList m_argNames;
-    QVariantList m_argValues;
+    ApiTraceCallSignature *m_signature;
+    QVector<QVariant> m_argValues;
     QVariant m_returnValue;
     ApiTraceFrame *m_parentFrame;
-    QUrl m_helpUrl;
 
-    QVariantList m_editedValues;
+    QVector<QVariant> m_editedValues;
 
     QString m_error;
 
     mutable QString m_richText;
-    mutable QString m_filterText;
-    mutable bool m_hasBinaryData;
-    mutable int m_binaryDataIndex;
+    mutable QString m_searchText;
 };
 Q_DECLARE_METATYPE(ApiTraceCall*);
 
 class ApiTraceFrame : public ApiTraceEvent
 {
 public:
-    ApiTraceFrame();
+    ApiTraceFrame(ApiTrace *parent);
     int number;
 
     bool isEmpty() const;
 
     ApiTrace *parentTrace() const;
-    void setParentTrace(ApiTrace *trace);
 
     int numChildren() const;
     QStaticText staticText() const;
@@ -253,13 +297,15 @@ public:
     int callIndex(ApiTraceCall *call) const;
     ApiTraceCall *call(int idx) const;
     void addCall(ApiTraceCall *call);
-    QList<ApiTraceCall*> calls() const;
+    QVector<ApiTraceCall*> calls() const;
+    void setCalls(const QVector<ApiTraceCall*> &calls,
+                  quint64 binaryDataSize);
 
     int binaryDataSize() const;
 private:
     ApiTrace *m_parentTrace;
     quint64 m_binaryDataSize;
-    QList<ApiTraceCall*> m_calls;
+    QVector<ApiTraceCall*> m_calls;
 };
 Q_DECLARE_METATYPE(ApiTraceFrame*);
 
index e60b176f02311387ab62d35fa25544833293e99c..5860cf9530e4d66310d6497db52454b7f9f085fc 100644 (file)
@@ -42,7 +42,7 @@ QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
         const QString stateText = tr("State info available.");
         if (itm->type() == ApiTraceEvent::Call) {
             ApiTraceCall *call = static_cast<ApiTraceCall*>(itm);
-            if (call->state().isEmpty())
+            if (!call->hasState())
                 return QString::fromLatin1("%1)&nbsp;<b>%2</b>")
                     .arg(call->index())
                     .arg(call->name());
@@ -56,7 +56,7 @@ QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
             QString text = QObject::tr("%1)&nbsp;Frame&nbsp;")
                            .arg(frame->number);
             int binaryDataSize = frame->binaryDataSize() / 1024;
-            if (frame->state().isEmpty())
+            if (!frame->hasState())
                 return QObject::tr(
                     "<b>%1&nbsp;</b>(binary&nbsp;data&nbsp;size&nbsp;=&nbsp;%2kB)")
                     .arg(text)
index 8848122b60089479c3343eb69a6c7010ca060483..1ee519ea444d672598d414f7dc12f559c4914862 100644 (file)
@@ -16,7 +16,7 @@ isVariantEditable(const QVariant &var)
 {
     if (var.canConvert<ApiArray>()) {
         ApiArray array = var.value<ApiArray>();
-        QList<QVariant> vals = array.values();
+        QVector<QVariant> vals = array.values();
         if (vals.isEmpty())
             return false;
         else
@@ -42,7 +42,7 @@ isVariantStringArray(const QVariant &var)
         return false;
 
     ApiArray array = var.value<ApiArray>();
-    QList<QVariant> origValues = array.values();
+    QVector<QVariant> origValues = array.values();
     if (origValues.isEmpty() ||
         origValues.first().userType() != QVariant::String)
         return false;
@@ -210,7 +210,7 @@ void ArgumentsEditor::setupCall()
 
         if (val.canConvert<ApiArray>()) {
             ApiArray array = val.value<ApiArray>();
-            QList<QVariant> vals = array.values();
+            QVector<QVariant> vals = array.values();
 
             QVariant firstVal = vals.value(0);
             if (firstVal.userType() == QVariant::String) {
@@ -304,7 +304,7 @@ void ArgumentsEditor::setupCall()
     }
 }
 
-void ArgumentsEditor::setupShaderEditor(const QList<QVariant> &sources)
+void ArgumentsEditor::setupShaderEditor(const QVector<QVariant> &sources)
 {
     m_ui.selectStringCB->clear();
     m_ui.glslEdit->clear();
@@ -339,8 +339,8 @@ void ArgumentsEditor::sourceChanged()
 void ArgumentsEditor::accept()
 {
     QStringList argNames = m_call->argNames();
-    QList<QVariant> originalValues = m_call->arguments();
-    QList<QVariant> newValues;
+    QVector<QVariant> originalValues = m_call->arguments();
+    QVector<QVariant> newValues;
     bool changed = false;
     for (int i = 0; i < argNames.count(); ++i) {
         bool valChanged = false;
@@ -405,14 +405,14 @@ QVariant ArgumentsEditor::arrayFromIndex(const QModelIndex &parentIndex,
                                          const ApiArray &origArray,
                                          bool *changed) const
 {
-    QList<QVariant> origValues = origArray.values();
+    QVector<QVariant> origValues = origArray.values();
 
     *changed = false;
 
     if (origValues.isEmpty())
         return QVariant::fromValue(ApiArray());
 
-    QList<QVariant> lst;
+    QVector<QVariant> lst;
     for (int i = 0; i < origValues.count(); ++i) {
         QModelIndex valIdx = m_model->index(i, 1, parentIndex);
         QVariant var = valIdx.data();
@@ -428,8 +428,8 @@ QVariant ArgumentsEditor::arrayFromIndex(const QModelIndex &parentIndex,
 QVariant ArgumentsEditor::arrayFromEditor(const ApiArray &origArray,
                                           bool *changed) const
 {
-    QList<QVariant> vals;
-    QList<QVariant> origValues = origArray.values();
+    QVector<QVariant> vals;
+    QVector<QVariant> origValues = origArray.values();
 
     Q_ASSERT(isVariantStringArray(QVariant::fromValue(origArray)));
     *changed = false;
index e6b3d8fd65f01043ad5072787d0a622a18a90d44..7671d71bcd0264f720e2fbeac506bf8b71293328 100644 (file)
@@ -49,7 +49,7 @@ private slots:
 private:
     void init();
     void setupCall();
-    void setupShaderEditor(const QList<QVariant> &sources);
+    void setupShaderEditor(const QVector<QVariant> &sources);
     QVariant valueForName(const QString &name,
                           const QVariant &orignalValue,
                           bool *changed) const;
index de5e3f85ec4d40a3e4144a71b58222a7c9da05c8..f311fe0d3e33f52e19bfcc1c471d8666a809d953 100644 (file)
 
 static ApiTraceCall *
 apiCallFromTraceCall(const Trace::Call *call,
-                     const QHash<QString, QUrl> &helpHash)
+                     const QHash<QString, QUrl> &helpHash,
+                     ApiTraceFrame *frame)
 {
-    ApiTraceCall *apiCall = new ApiTraceCall(call);
+    ApiTraceCall *apiCall = new ApiTraceCall(frame, call);
 
     apiCall->setHelpUrl(helpHash.value(apiCall->name()));
 
     return apiCall;
 }
 
-LoaderThread::LoaderThread(QObject *parent)
+LoaderThread::LoaderThread(ApiTrace *parent)
     : QThread(parent),
-      m_frameMarker(ApiTrace::FrameMarker_SwapBuffers)
+      m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
+      m_trace(parent)
 {
 }
 
@@ -53,23 +55,33 @@ void LoaderThread::run()
     file.close();
 
     Trace::Parser p;
+    QVector<ApiTraceCall*> calls;
+    quint64 binaryDataSize = 0;
     if (p.open(m_fileName.toLatin1().constData())) {
         Trace::Call *call = p.parse_call();
         while (call) {
             //std::cout << *call;
             if (!currentFrame) {
-                currentFrame = new ApiTraceFrame();
+                currentFrame = new ApiTraceFrame(m_trace);
                 currentFrame->number = frameCount;
                 ++frameCount;
             }
             ApiTraceCall *apiCall =
-                apiCallFromTraceCall(call, helpHash);
-            apiCall->setParentFrame(currentFrame);
-            currentFrame->addCall(apiCall);
+                apiCallFromTraceCall(call, helpHash, currentFrame);
+            calls.append(apiCall);
+            if (apiCall->hasBinaryData()) {
+                QByteArray data =
+                    apiCall->arguments()[apiCall->binaryDataIndex()].toByteArray();
+                binaryDataSize += data.size();
+            }
             if (ApiTrace::isCallAFrameMarker(apiCall,
                                              m_frameMarker)) {
+                calls.squeeze();
+                currentFrame->setCalls(calls, binaryDataSize);
+                calls.clear();
                 frames.append(currentFrame);
                 currentFrame = 0;
+                binaryDataSize = 0;
                 if (frames.count() >= FRAMES_TO_CACHE) {
                     emit parsedFrames(frames);
                     frames.clear();
index 5073e14fff7e5e2c6802da20a358aca29bb607ac..c847c7315d8ef87781b9642243b92a9a659e78c7 100644 (file)
@@ -12,7 +12,7 @@ class LoaderThread : public QThread
 {
     Q_OBJECT
 public:
-    LoaderThread(QObject *parent=0);
+    LoaderThread(ApiTrace *parent);
 
     ApiTrace::FrameMarker frameMarker() const;
     void setFrameMarker(ApiTrace::FrameMarker marker);
@@ -28,6 +28,7 @@ protected:
 private:
     QString m_fileName;
     ApiTrace::FrameMarker m_frameMarker;
+    ApiTrace *m_trace;
 };
 
 #endif
index 465dd8b0e0b767843a47e2e9d5815738adfd4369..591c557e55567eda81a93c1341eadf7cc727aa7a 100644 (file)
@@ -104,7 +104,7 @@ void MainWindow::callItemSelected(const QModelIndex &index)
             QByteArray data =
                 call->arguments()[call->binaryDataIndex()].toByteArray();
             m_vdataInterpreter->setData(data);
-            QVariantList args = call->arguments();
+            QVector<QVariant> args = call->arguments();
 
             for (int i = 0; i < call->argNames().count(); ++i) {
                 QString name = call->argNames()[i];
@@ -132,7 +132,7 @@ void MainWindow::callItemSelected(const QModelIndex &index)
         m_ui.detailsDock->hide();
         m_ui.vertexDataDock->hide();
     }
-    if (m_selectedEvent && !m_selectedEvent->state().isEmpty()) {
+    if (m_selectedEvent && m_selectedEvent->hasState()) {
         fillStateForFrame();
     } else
         m_ui.stateDock->hide();
@@ -320,7 +320,7 @@ static void
 variantToString(const QVariant &var, QString &str)
 {
     if (var.type() == QVariant::List) {
-        QVariantList lst = var.toList();
+        QVector<QVariant> lst = var.toList().toVector();
         str += QLatin1String("[");
         for (int i = 0; i < lst.count(); ++i) {
             QVariant val = lst[i];
@@ -358,7 +358,8 @@ variantMapToItems(const QVariantMap &map, const QVariantMap &defaultMap, QList<Q
 }
 
 static void
-variantListToItems(const QVariantList &lst, const QVariantList &defaultLst, QList<QTreeWidgetItem *> &items)
+variantListToItems(const QVector<QVariant> &lst, const QVector<QVariant> &defaultLst,
+                   QList<QTreeWidgetItem *> &items)
 {
     for (int i = 0; i < lst.count(); ++i) {
         QString key = QString::number(i);
@@ -380,7 +381,7 @@ static bool
 isVariantDeep(const QVariant &var)
 {
     if (var.type() == QVariant::List) {
-        QVariantList lst = var.toList();
+        QVector<QVariant> lst = var.toList().toVector();
         for (int i = 0; i < lst.count(); ++i) {
             if (isVariantDeep(lst[i])) {
                 return true;
@@ -426,8 +427,8 @@ variantToItem(const QString &key, const QVariant &var, const QVariant &defaultVa
             variantMapToItems(map, defaultMap, children);
         }
         if (var.type() == QVariant::List) {
-            QVariantList lst = var.toList();
-            QVariantList defaultLst = defaultVar.toList();
+            QVector<QVariant> lst = var.toList().toVector();
+            QVector<QVariant> defaultLst = defaultVar.toList().toVector();
             variantListToItems(lst, defaultLst, children);
         }
         item->addChildren(children);
@@ -464,7 +465,7 @@ static void addSurfaceItem(const ApiSurface &surface,
 
 void MainWindow::fillStateForFrame()
 {
-    if (!m_selectedEvent || m_selectedEvent->state().isEmpty())
+    if (!m_selectedEvent || !m_selectedEvent->hasState())
         return;
 
     if (m_nonDefaultsLookupEvent) {
@@ -480,7 +481,7 @@ void MainWindow::fillStateForFrame()
         defaultParams = defaultState.parameters();
     }
 
-    const ApiTraceState &state = m_selectedEvent->state();
+    const ApiTraceState &state = *m_selectedEvent->state();
     m_ui.stateTreeWidget->clear();
     QList<QTreeWidgetItem *> items;
     variantMapToItems(state.parameters(), defaultParams, items);
@@ -694,8 +695,8 @@ void MainWindow::initConnections()
             this, SLOT(replayFinished(const QString&)));
     connect(m_retracer, SIGNAL(error(const QString&)),
             this, SLOT(replayError(const QString&)));
-    connect(m_retracer, SIGNAL(foundState(const ApiTraceState&)),
-            this, SLOT(replayStateFound(const ApiTraceState&)));
+    connect(m_retracer, SIGNAL(foundState(ApiTraceState*)),
+            this, SLOT(replayStateFound(ApiTraceState*)));
     connect(m_retracer, SIGNAL(retraceErrors(const QList<RetraceError>&)),
             this, SLOT(slotRetraceErrors(const QList<RetraceError>&)));
 
@@ -778,7 +779,7 @@ void MainWindow::initConnections()
             this, SLOT(slotErrorSelected(QTreeWidgetItem*)));
 }
 
-void MainWindow::replayStateFound(const ApiTraceState &state)
+void MainWindow::replayStateFound(ApiTraceState *state)
 {
     m_stateEvent->setState(state);
     m_model->stateSetOnEvent(m_stateEvent);
@@ -856,7 +857,7 @@ void MainWindow::slotSearchNext(const QString &str,
         m_searchWidget->setFound(false);
         return;
     }
-    const QList<ApiTraceCall*> &calls = m_trace->calls();
+    const QVector<ApiTraceCall*> &calls = m_trace->calls();
     int callNum = calls.indexOf(call);
 
     for (int i = callNum + 1; i < calls.count(); ++i) {
@@ -865,7 +866,7 @@ void MainWindow::slotSearchNext(const QString &str,
         /* if it's not valid it means that the proxy model has already
          * filtered it out */
         if (index.isValid()) {
-            QString txt = testCall->filterText();
+            QString txt = testCall->searchText();
             if (txt.contains(str, sensitivity)) {
                 m_ui.callView->setCurrentIndex(index);
                 m_searchWidget->setFound(true);
@@ -907,7 +908,7 @@ void MainWindow::slotSearchPrev(const QString &str,
         m_searchWidget->setFound(false);
         return;
     }
-    const QList<ApiTraceCall*> &calls = m_trace->calls();
+    const QVector<ApiTraceCall*> &calls = m_trace->calls();
     int callNum = calls.indexOf(call);
 
     for (int i = callNum - 1; i >= 0; --i) {
@@ -916,7 +917,7 @@ void MainWindow::slotSearchPrev(const QString &str,
         /* if it's not valid it means that the proxy model has already
          * filtered it out */
         if (index.isValid()) {
-            QString txt = testCall->filterText();
+            QString txt = testCall->searchText();
             if (txt.contains(str, sensitivity)) {
                 m_ui.callView->setCurrentIndex(index);
                 m_searchWidget->setFound(true);
@@ -1002,8 +1003,8 @@ void MainWindow::slotGoFrameStart()
         return;
     }
 
-    QList<ApiTraceCall*>::const_iterator itr;
-    QList<ApiTraceCall*> calls = frame->calls();
+    QVector<ApiTraceCall*>::const_iterator itr;
+    QVector<ApiTraceCall*> calls = frame->calls();
 
     itr = calls.constBegin();
     while (itr != calls.constEnd()) {
@@ -1023,8 +1024,8 @@ void MainWindow::slotGoFrameEnd()
     if (!frame || frame->isEmpty()) {
         return;
     }
-    QList<ApiTraceCall*>::const_iterator itr;
-    QList<ApiTraceCall*> calls = frame->calls();
+    QVector<ApiTraceCall*>::const_iterator itr;
+    QVector<ApiTraceCall*> calls = frame->calls();
 
     itr = calls.constEnd();
     do {
index 5cb2e767eacaa0342a1d21d3307e96d6ac7cdf4c..f3e31811717f4a218f60860df2f5e203534125cd 100644 (file)
@@ -43,7 +43,7 @@ private slots:
     void replayStart();
     void replayStop();
     void replayFinished(const QString &output);
-    void replayStateFound(const ApiTraceState &state);
+    void replayStateFound(ApiTraceState *state);
     void replayError(const QString &msg);
     void startedLoadingTrace();
     void finishedLoadingTrace();
index 98a4db220e7d203d320774ec790fce87ff8a8de2..500d859aa3f6d73011acc0bbaabd38a58ed19287 100644 (file)
@@ -98,8 +98,8 @@ void Retracer::run()
             this, SIGNAL(finished(const QString&)));
     connect(retrace, SIGNAL(error(const QString&)),
             this, SIGNAL(error(const QString&)));
-    connect(retrace, SIGNAL(foundState(const ApiTraceState&)),
-            this, SIGNAL(foundState(const ApiTraceState&)));
+    connect(retrace, SIGNAL(foundState(ApiTraceState*)),
+            this, SIGNAL(foundState(ApiTraceState*)));
     connect(retrace, SIGNAL(retraceErrors(const QList<RetraceError>&)),
             this, SIGNAL(retraceErrors(const QList<RetraceError>&)));
 
@@ -155,7 +155,7 @@ void RetraceProcess::replayFinished()
     if (m_captureState) {
         bool ok = false;
         QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap();
-        ApiTraceState state(parsedJson);
+        ApiTraceState *state = new ApiTraceState(parsedJson);
         emit foundState(state);
         msg = tr("State fetched.");
     } else {
index 1b5a4bd04313ed0ed3406eb42588397583bdc60f..70170f5ce4605949789083d555ab76307976df7e 100644 (file)
@@ -48,7 +48,7 @@ public slots:
 signals:
     void finished(const QString &output);
     void error(const QString &msg);
-    void foundState(const ApiTraceState &state);
+    void foundState(ApiTraceState *state);
     void retraceErrors(const QList<RetraceError> &errors);
 
 private slots:
@@ -89,7 +89,7 @@ public:
 
 signals:
     void finished(const QString &output);
-    void foundState(const ApiTraceState &state);
+    void foundState(ApiTraceState *state);
     void error(const QString &msg);
     void retraceErrors(const QList<RetraceError> &errors);
 
index d7f6906c7e136b7653d18084d487522ebf764b86..5837c9961d92703ade8b0eea4a2bcd423488210d 100644 (file)
@@ -162,7 +162,7 @@ writeValue(Trace::Writer &writer, const QVariant &var, unsigned &id)
     default:
         if (type == arrayType) {
             ApiArray array = var.value<ApiArray>();
-            QList<QVariant> vals = array.values();
+            QVector<QVariant> vals = array.values();
             writer.beginArray(vals.count());
             foreach(QVariant el, vals) {
                 writer.beginElement();
@@ -210,7 +210,7 @@ SaverThread::SaverThread(QObject *parent)
 }
 
 void SaverThread::saveFile(const QString &fileName,
-                           const QList<ApiTraceCall*> &calls)
+                           const QVector<ApiTraceCall*> &calls)
 {
     m_fileName = fileName;
     m_calls = calls;
@@ -229,7 +229,7 @@ void SaverThread::run()
         unsigned callNo = writer.beginEnter(funcSig);
         {
             //args
-            QVariantList vars = call->arguments();
+            QVector<QVariant> vars = call->arguments();
             int index = 0;
             foreach(QVariant var, vars) {
                 writer.beginArg(index++);
index 5bea5b7581fc8d07a3857da494ddeaa74e7dea08..3da502ce98df509b190893cd7b7df39d9f2fab7c 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "apitrace.h"
 #include <QThread>
-#include <QList>
+#include <QVector>
 
 class ApiTraceCall;
 class ApiTraceFrame;
@@ -17,7 +17,7 @@ public:
 
 public slots:
     void saveFile(const QString &fileName,
-                  const QList<ApiTraceCall*> &calls);
+                  const QVector<ApiTraceCall*> &calls);
 
 signals:
     void traceSaved();
@@ -27,7 +27,7 @@ protected:
 
 private:
     QString m_fileName;
-    QList<ApiTraceCall*> m_calls;
+    QVector<ApiTraceCall*> m_calls;
 };
 
 
index 79bb7575801b4842c2bb23be04deacc9986a5c9d..25dc4bb487138a2e38a33f277940c733bab5ce7e 100644 (file)
@@ -56,9 +56,16 @@ Array::~Array() {
 }
 
 Blob::~Blob() {
-    // TODO: Don't leak blobs.  Blobs are often bound and accessed during many
-    // calls, so we can't delete them here.
-    //delete [] buf;
+    // Blobs are often bound and referred during many calls, so we can't delete
+    // them here in that case.
+    //
+    // Once bound there is no way to know when they were unbound, which
+    // effectively means we have to leak them.  A better solution would be to
+    // keep a list of bound pointers, and defer the destruction to when the
+    // trace in question has been fully processed.
+    if (!bound) {
+        delete [] buf;
+    }
 }
 
 
@@ -122,6 +129,11 @@ void * Null   ::toPointer(void) const { return NULL; }
 void * Blob   ::toPointer(void) const { return buf; }
 void * Pointer::toPointer(void) const { return (void *)value; }
 
+void * Value  ::toPointer(bool bind) { assert(0); return NULL; }
+void * Null   ::toPointer(bool bind) { return NULL; }
+void * Blob   ::toPointer(bool bind) { if (bind) bound = true; return buf; }
+void * Pointer::toPointer(bool bind) { return (void *)value; }
+
 
 // pointer cast
 unsigned long long Value  ::toUIntPtr(void) const { assert(0); return 0; }
index 5c51bba7d06c345a541b8dca59cebe1291d546f6..a2847547421f8972666681d0784882192e2fb628 100644 (file)
@@ -96,6 +96,7 @@ public:
     virtual double toDouble(void) const;
 
     virtual void *toPointer(void) const;
+    virtual void *toPointer(bool bind);
     virtual unsigned long long toUIntPtr(void) const;
     virtual const char *toString(void) const;
 
@@ -114,6 +115,7 @@ public:
     virtual float toFloat(void) const;
     virtual double toDouble(void) const;
     void *toPointer(void) const;
+    void *toPointer(bool bind);
     unsigned long long toUIntPtr(void) const;
     const char *toString(void) const;
     void visit(Visitor &visitor);
@@ -257,16 +259,19 @@ public:
     Blob(size_t _size) {
         size = _size;
         buf = new char[_size];
+        bound = false;
     }
 
     ~Blob();
 
     bool toBool(void) const;
     void *toPointer(void) const;
+    void *toPointer(bool bind);
     void visit(Visitor &visitor);
 
     size_t size;
     char *buf;
+    bool bound;
 };
 
 
@@ -277,6 +282,7 @@ public:
 
     bool toBool(void) const;
     void *toPointer(void) const;
+    void *toPointer(bool bind);
     unsigned long long toUIntPtr(void) const;
     void visit(Visitor &visitor);
 };
index c13a97940d04c0e0372d42124f8ba2fddafc0723..07a62f6bcc187edb38875a43122abfee2c3ddc7d 100644 (file)
@@ -68,7 +68,9 @@ SnappyFile::SnappyFile(const std::string &filename,
       m_cachePtr(0),
       m_cacheSize(0)
 {
-    m_compressedCache = new char[SNAPPY_CHUNK_SIZE];
+    size_t maxCompressedLength =
+        snappy::MaxCompressedLength(SNAPPY_CHUNK_SIZE);
+    m_compressedCache = new char[maxCompressedLength];
 }
 
 SnappyFile::~SnappyFile()