[PATCH 2/6] Detect and accumulate missing thumbnails

Dan McCabe zen3d.linux at gmail.com
Fri Jun 1 13:40:03 PDT 2012


Previously, ALL frame thumbnails were loaded when the user wanted to see
thumbnails. This patch sets the foundations for loading only those
thumbnails that are visible in the current (and all previously displayed)
window(s).

In ApiCallDelegate::paint(), it is noted that a thumbnail may not be valid
and therefore is missing. If this is the case, the frame or call is
notified that the client of the thumbnail cares that the thumbnail is
missing.

The frame or call in turn notifies the trace that a thumbnail is missing
and is desired. The trace then accumulates the missing thumbnails in a set.

Note that the act of querying the thumbnail itself is not sufficient to
detect that a thumbnail is missing. This is because
ApiCallDelegate::sizeHint() also queries the thumbnail to determine its
size. It turns out that these size queries occur even for calls and frames
that are not immediately visible. Using just the query for the thumbnail
to detect that it is missing results in many more thumbnail capture
activities than are otherwise needed.
---
 gui/apicalldelegate.cpp |    4 ++++
 gui/apitrace.cpp        |   29 +++++++++++++++++++++++++++++
 gui/apitrace.h          |   10 ++++++++++
 gui/apitracecall.cpp    |   10 ++++++++++
 gui/apitracecall.h      |    5 +++++
 5 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/gui/apicalldelegate.cpp b/gui/apicalldelegate.cpp
index 0e583bc..82b9721 100644
--- a/gui/apicalldelegate.cpp
+++ b/gui/apicalldelegate.cpp
@@ -43,6 +43,8 @@ void ApiCallDelegate::paint(QPainter *painter,
             if (!thumbnail.isNull()) {
                 painter->drawImage(offset, thumbnail);
                 offset += QPoint(textSize.height() + thumbnail.width(), option.rect.height()/2 - textSize.height()/2);
+            } else {
+            	frame->missingThumbnail();
             }
         }
 
@@ -58,6 +60,8 @@ void ApiCallDelegate::paint(QPainter *painter,
             if (!thumbnail.isNull()) {
                 painter->drawImage(offset, thumbnail);
                 offset += QPoint(textSize.height() + thumbnail.width(), option.rect.height()/2 - textSize.height()/2);
+            } else {
+            	call->missingThumbnail();
             }
             if (call->hasError()) {
                 QPixmap px = m_errorEmblem.pixmap(textSize.height(),
diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp
index b11c17c..2de4563 100644
--- a/gui/apitrace.cpp
+++ b/gui/apitrace.cpp
@@ -498,4 +498,33 @@ void ApiTrace::bindThumbnailsToFrames(const QList<QImage> &thumbnails)
     }
 }
 
+void ApiTrace::missingThumbnail(ApiTraceFrame *frame)
+{
+    missingThumbnail(frame->lastCallIndex());
+}
+
+void ApiTrace::missingThumbnail(ApiTraceCall *call)
+{
+    missingThumbnail(call->index());
+}
+
+void ApiTrace::missingThumbnail(int callIdx)
+{
+    // technically, the contain() test is redundant, since this is a set;
+    // however, it enables debugging techniques to confirm correct behavior
+    if (!m_missingThumbnails.contains(callIdx)) {
+        //qDebug() << QLatin1String("debug: new missing thumbnail: ") << callIdx;
+        m_missingThumbnails.insert(callIdx);
+    }
+}
+
+bool ApiTrace::isMissingThumbnails() const
+{
+	return !m_missingThumbnails.isEmpty();
+}
+void ApiTrace::resetMissingThumbnails()
+{
+    m_missingThumbnails.clear();
+}
+
 #include "apitrace.moc"
diff --git a/gui/apitrace.h b/gui/apitrace.h
index 04e295c..a6cfa1c 100644
--- a/gui/apitrace.h
+++ b/gui/apitrace.h
@@ -77,6 +77,12 @@ public:
 
     trace::API api() const;
 
+    void missingThumbnail(ApiTraceFrame* frame);
+    void missingThumbnail(ApiTraceCall* call);
+
+    bool isMissingThumbnails() const;
+    void resetMissingThumbnails();
+
 public slots:
     void setFileName(const QString &name);
     void save();
@@ -140,6 +146,8 @@ private slots:
 private:
     int callInFrame(int callIdx) const;
     bool isFrameLoading(ApiTraceFrame *frame) const;
+
+    void missingThumbnail(int callIdx);
 private:
     QString m_fileName;
     QString m_tempFileName;
@@ -158,6 +166,8 @@ private:
     QSet<ApiTraceCall*> m_errors;
     QList< QPair<ApiTraceFrame*, ApiTraceError> > m_queuedErrors;
     QSet<ApiTraceFrame*> m_loadingFrames;
+
+    QSet<int> m_missingThumbnails;
 };
 
 #endif
diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp
index eca6945..2450747 100644
--- a/gui/apitracecall.cpp
+++ b/gui/apitracecall.cpp
@@ -1011,6 +1011,11 @@ bool ApiTraceCall::contains(const QString &str,
     return txt.contains(str, sensitivity);
 }
 
+void ApiTraceCall::missingThumbnail()
+{
+    m_parentFrame->parentTrace()->missingThumbnail(this);
+}
+
 
 ApiTraceFrame::ApiTraceFrame(ApiTrace *parentTrace)
     : ApiTraceEvent(ApiTraceEvent::Frame),
@@ -1215,3 +1220,8 @@ unsigned ApiTraceFrame::lastCallIndex() const
         return m_lastCallIndex;
     }
 }
+
+void ApiTraceFrame::missingThumbnail()
+{
+    m_parentTrace->missingThumbnail(this);
+}
diff --git a/gui/apitracecall.h b/gui/apitracecall.h
index 86db3e9..345bba5 100644
--- a/gui/apitracecall.h
+++ b/gui/apitracecall.h
@@ -232,6 +232,8 @@ public:
     void setThumbnail(const QImage & thumbnail);
     const QImage & thumbnail() const;
 
+    virtual void missingThumbnail() = 0;
+
 protected:
     int m_type : 4;
     mutable bool m_hasBinaryData;
@@ -284,6 +286,8 @@ public:
     int numChildren() const;
     bool hasBinaryData() const;
     int binaryDataIndex() const;
+
+    void missingThumbnail();
 private:
     int m_index;
     ApiTraceCallSignature *m_signature;
@@ -342,6 +346,7 @@ public:
     void setLastCallIndex(unsigned index);
     unsigned lastCallIndex() const;
 
+    void missingThumbnail();
 private:
     ApiTrace *m_parentTrace;
     quint64 m_binaryDataSize;
-- 
1.7.9.1



More information about the apitrace mailing list