[PATCH 2/2] Display captured snapshots as thumbnails.

Dan McCabe zen3d.linux at gmail.com
Mon Mar 5 17:20:40 PST 2012


Once snapshots are captured after being generated by glretrace, they are
then displayed in the GUI app, qapitrace.

The retracer passes a list of thumbnails to the main window. The main
window in turn binds those thumbnails to the ApiTraceFrames for later
display.

When the ApiTrace events are displayed, if a frame is being display, its
thumbnail is queried. That thumbnail is then displayed at the
front of the line for a frame.
---
 gui/apicalldelegate.cpp |   13 ++++++++++++-
 gui/apitrace.cpp        |   17 +++++++++++++++++
 gui/apitrace.h          |    3 ++-
 gui/apitracecall.cpp    |   10 ++++++++++
 gui/apitracecall.h      |    5 +++++
 gui/apitracemodel.cpp   |   21 +++++++++++++++++++--
 gui/apitracemodel.h     |    2 ++
 gui/mainwindow.cpp      |   17 +++++++++++------
 gui/mainwindow.h        |    2 +-
 9 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/gui/apicalldelegate.cpp b/gui/apicalldelegate.cpp
index 11ed3a5..221462e 100644
--- a/gui/apicalldelegate.cpp
+++ b/gui/apicalldelegate.cpp
@@ -27,12 +27,23 @@ void ApiCallDelegate::paint(QPainter *painter,
     Q_ASSERT(index.column() == 0);
 
     if (event) {
-        QPoint offset;
+        QPoint offset = QPoint(0, 0);
         QStaticText text = event->staticText();
         //text.setTextWidth(option.rect.width());
         //QStyledItemDelegate::paint(painter, option, index);
         QStyle *style = QApplication::style();
         style->drawControl(QStyle::CE_ItemViewItem, &option, painter, 0);
+
+        // draw thumbnail of frame
+        if(event->type() == ApiTraceEvent::Frame) {
+            ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
+            QImage thumbnail = frame->thumbnail();
+            if (!thumbnail.isNull()) {
+                painter->drawImage(option.rect.topLeft() + offset, thumbnail);
+                offset += QPoint(option.rect.height() + 16, 0);
+            }
+        }
+
         if (event->hasState()) {
             QPixmap px = m_stateEmblem.pixmap(option.rect.height(),
                                               option.rect.height());
diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp
index 5758b07..5db54d8 100644
--- a/gui/apitrace.cpp
+++ b/gui/apitrace.cpp
@@ -496,4 +496,21 @@ bool ApiTrace::isFrameLoading(ApiTraceFrame *frame) const
     return m_loadingFrames.contains(frame);
 }
 
+void ApiTrace::bindThumbnailsToFrames(const QList<QImage> &thumbnails)
+{
+    QList<ApiTraceFrame *> frames = m_frames;
+
+    QList<QImage>::const_iterator thumbnail = thumbnails.begin();
+
+    foreach (ApiTraceFrame *frame, frames) {
+        if (thumbnail != thumbnails.end()) {
+            frame->setThumbnail(*thumbnail);
+
+            ++thumbnail;
+
+            emit changed(frame);
+        }
+    }
+}
+
 #include "apitrace.moc"
diff --git a/gui/apitrace.h b/gui/apitrace.h
index 2833f60..ed137ed 100644
--- a/gui/apitrace.h
+++ b/gui/apitrace.h
@@ -100,6 +100,7 @@ public slots:
     void findCallIndex(int index);
     void setCallError(const ApiTraceError &error);
 
+    void bindThumbnailsToFrames(const QList<QImage> &thumbnails);
 
 signals:
     void loadTrace(const QString &name);
@@ -109,7 +110,7 @@ signals:
     void finishedLoadingTrace();
     void invalidated();
     void framesInvalidated();
-    void changed(ApiTraceCall *call);
+    void changed(ApiTraceEvent *event);
     void startedSaving();
     void saved();
     void findResult(const ApiTrace::SearchRequest &request,
diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp
index 267dc09..4d91001 100644
--- a/gui/apitracecall.cpp
+++ b/gui/apitracecall.cpp
@@ -1197,3 +1197,13 @@ unsigned ApiTraceFrame::lastCallIndex() const
         return m_lastCallIndex;
     }
 }
+
+void ApiTraceFrame::setThumbnail(QImage thumbnail)
+{
+    m_thumbnail = thumbnail;
+}
+
+QImage ApiTraceFrame::thumbnail() const
+{
+    return m_thumbnail;
+}
diff --git a/gui/apitracecall.h b/gui/apitracecall.h
index 3a9faaf..8d0e6db 100644
--- a/gui/apitracecall.h
+++ b/gui/apitracecall.h
@@ -335,6 +335,10 @@ public:
 
     void setLastCallIndex(unsigned index);
     unsigned lastCallIndex() const;
+
+    void setThumbnail(QImage thumbnail);
+    QImage thumbnail() const;
+
 private:
     ApiTrace *m_parentTrace;
     quint64 m_binaryDataSize;
@@ -342,6 +346,7 @@ private:
     bool m_loaded;
     unsigned m_callsToLoad;
     unsigned m_lastCallIndex;
+    QImage m_thumbnail;
 };
 Q_DECLARE_METATYPE(ApiTraceFrame*);
 
diff --git a/gui/apitracemodel.cpp b/gui/apitracemodel.cpp
index 7303ae1..9103da5 100644
--- a/gui/apitracemodel.cpp
+++ b/gui/apitracemodel.cpp
@@ -248,8 +248,8 @@ void ApiTraceModel::setApiTrace(ApiTrace *trace)
             this, SLOT(beginAddingFrames(int, int)));
     connect(m_trace, SIGNAL(endAddingFrames()),
             this, SLOT(endAddingFrames()));
-    connect(m_trace, SIGNAL(changed(ApiTraceCall*)),
-            this, SLOT(callChanged(ApiTraceCall*)));
+    connect(m_trace, SIGNAL(changed(ApiTraceEvent*)),
+            this, SLOT(changed(ApiTraceEvent*)));
     connect(m_trace, SIGNAL(beginLoadingFrame(ApiTraceFrame*,int)),
             this, SLOT(beginLoadingFrame(ApiTraceFrame*,int)));
     connect(m_trace, SIGNAL(endLoadingFrame(ApiTraceFrame*)),
@@ -318,6 +318,15 @@ QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const
     return createIndex(row, 0, call);
 }
 
+void ApiTraceModel::changed(ApiTraceEvent *event)
+{
+    if (event->type() == ApiTraceEvent::Call) {
+        callChanged(static_cast<ApiTraceCall*>(event));
+    } else if (event->type() == ApiTraceEvent::Frame) {
+        frameChanged(static_cast<ApiTraceFrame*>(event));
+    }
+}
+
 void ApiTraceModel::callChanged(ApiTraceCall *call)
 {
     ApiTrace *trace = call->parentFrame()->parentTrace();
@@ -339,6 +348,14 @@ void ApiTraceModel::callChanged(ApiTraceCall *call)
     emit dataChanged(index, index);
 }
 
+void ApiTraceModel::frameChanged(ApiTraceFrame *frame)
+{
+    const QList<ApiTraceFrame*> frames = m_trace->frames();
+    int row = frames.indexOf(frame);
+    QModelIndex index = createIndex(row, 0, frame);
+    emit dataChanged(index, index);
+}
+
 void ApiTraceModel::endAddingFrames()
 {
     endInsertRows();
diff --git a/gui/apitracemodel.h b/gui/apitracemodel.h
index fe6b5ce..e7354aa 100644
--- a/gui/apitracemodel.h
+++ b/gui/apitracemodel.h
@@ -54,7 +54,9 @@ private slots:
     void invalidateFrames();
     void beginAddingFrames(int oldCount, int numAdded);
     void endAddingFrames();
+    void changed(ApiTraceEvent *event);
     void callChanged(ApiTraceCall *call);
+    void frameChanged(ApiTraceFrame *frame);
     void beginLoadingFrame(ApiTraceFrame *frame, int numAdded);
     void endLoadingFrame(ApiTraceFrame *frame);
 
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index d1a143d..7130b55 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -731,8 +731,8 @@ void MainWindow::initConnections()
             this, SLOT(slotStartedSaving()));
     connect(m_trace, SIGNAL(saved()),
             this, SLOT(slotSaved()));
-    connect(m_trace, SIGNAL(changed(ApiTraceCall*)),
-            this, SLOT(slotTraceChanged(ApiTraceCall*)));
+    connect(m_trace, SIGNAL(changed(ApiTraceEvent*)),
+            this, SLOT(slotTraceChanged(ApiTraceEvent*)));
     connect(m_trace, SIGNAL(findResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)),
             this, SLOT(slotSearchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)));
     connect(m_trace, SIGNAL(foundFrameStart(ApiTraceFrame*)),
@@ -848,6 +848,8 @@ void MainWindow::replayStateFound(ApiTraceState *state)
 void MainWindow::replayThumbnailsFound(const QList<QImage> &thumbnails)
 {
     m_thumbnails = thumbnails;
+
+    m_trace->bindThumbnailsToFrames(thumbnails);
 }
 
 void MainWindow::slotGoTo()
@@ -1025,11 +1027,14 @@ ApiTraceFrame * MainWindow::selectedFrame() const
     return NULL;
 }
 
-void MainWindow::slotTraceChanged(ApiTraceCall *call)
+void MainWindow::slotTraceChanged(ApiTraceEvent *event)
 {
-    Q_ASSERT(call);
-    if (call == m_selectedEvent) {
-        m_ui.detailsWebView->setHtml(call->toHtml());
+    Q_ASSERT(event);
+    if (event == m_selectedEvent) {
+        if (event->type() == ApiTraceEvent::Call) {
+            ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
+            m_ui.detailsWebView->setHtml(call->toHtml());
+        }
     }
 }
 
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index 568f692..3bd9edb 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -74,7 +74,7 @@ private slots:
     void slotSaved();
     void slotGoFrameStart();
     void slotGoFrameEnd();
-    void slotTraceChanged(ApiTraceCall *call);
+    void slotTraceChanged(ApiTraceEvent *event);
     void slotRetraceErrors(const QList<ApiTraceError> &errors);
     void slotErrorSelected(QTreeWidgetItem *current);
     void slotSearchResult(const ApiTrace::SearchRequest &request,
-- 
1.7.5.4



More information about the apitrace mailing list