]> git.cworth.org Git - apitrace/blobdiff - gui/timelinewidget.cpp
Add call duration graphs to profile dialog.
[apitrace] / gui / timelinewidget.cpp
index d9f1b5809ebf63246dba4c4c7f7cb2aeb53c9bca..0375831871570930eb9d5256aaaecf2e844a4671 100644 (file)
@@ -1,18 +1,19 @@
 #include "timelinewidget.h"
+#include "profiledialog.h"
 #include "trace_profiler.hpp"
 
 #include <math.h>
 #include <QColor>
+#include <QLocale>
 #include <QPainter>
 #include <QToolTip>
 #include <QMouseEvent>
 #include <QWheelEvent>
 #include <QApplication>
 
+typedef trace::Profile::Call Call;
 typedef trace::Profile::Frame Frame;
 typedef trace::Profile::Program Program;
-typedef trace::Profile::CpuCall CpuCall;
-typedef trace::Profile::DrawCall DrawCall;
 
 TimelineWidget::TimelineWidget(QWidget *parent)
     : QWidget(parent),
@@ -139,17 +140,58 @@ typename std::vector<val_ty>::const_iterator binarySearchTimespan(
         itr = begin + pos;
     }
 
-    if (lower <= upper)
+    if (lower <= upper) {
         return itr;
-    else
+    } else {
+        return end;
+    }
+}
+
+
+/**
+ * Binary Search for a time in start+durations on an array of indices
+ */
+std::vector<unsigned>::const_iterator binarySearchTimespanIndexed(
+        const std::vector<Call>& calls,
+        std::vector<unsigned>::const_iterator begin,
+        std::vector<unsigned>::const_iterator end,
+        int64_t time)
+{
+    int lower = 0;
+    int upper = end - begin;
+    int pos = (lower + upper) / 2;
+    std::vector<unsigned>::const_iterator itr = begin + pos;
+
+    while (lower <= upper) {
+        const Call& call = calls[*itr];
+
+        if (call.gpuStart <= time && call.gpuStart + call.gpuDuration > time) {
+            break;
+        }
+
+        if (call.gpuStart > time) {
+            upper = pos - 1;
+        } else {
+            lower = pos + 1;
+        }
+
+        pos = (lower + upper) / 2;
+        itr = begin + pos;
+    }
+
+    if (lower <= upper) {
+        return itr;
+    } else {
         return end;
+    }
 }
 
 
 /**
  * Find the frame at time
  */
-const Frame* TimelineWidget::frameAtTime(int64_t time) {
+const Frame* TimelineWidget::frameAtTime(int64_t time)
+{
     if (!m_profile) {
         return NULL;
     }
@@ -161,8 +203,7 @@ const Frame* TimelineWidget::frameAtTime(int64_t time) {
                 time);
 
     if (res != m_profile->frames.end()) {
-        const Frame& frame = *res;
-        return &frame;
+        return &*res;
     }
 
     return NULL;
@@ -172,20 +213,20 @@ const Frame* TimelineWidget::frameAtTime(int64_t time) {
 /**
  * Find the CPU call at time
  */
-const CpuCall* TimelineWidget::cpuCallAtTime(int64_t time) {
+const Call* TimelineWidget::cpuCallAtTime(int64_t time)
+{
     if (!m_profile) {
         return NULL;
     }
 
-    std::vector<CpuCall>::const_iterator res
-            = binarySearchTimespan<CpuCall, &CpuCall::cpuStart, &CpuCall::cpuDuration>(
-                m_profile->cpuCalls.begin(),
-                m_profile->cpuCalls.end(),
+    std::vector<Call>::const_iterator res
+            = binarySearchTimespan<Call, &Call::cpuStart, &Call::cpuDuration>(
+                m_profile->calls.begin(),
+                m_profile->calls.end(),
                 time);
 
-    if (res != m_profile->cpuCalls.end()) {
-        const CpuCall& call = *res;
-        return &call;
+    if (res != m_profile->calls.end()) {
+        return &*res;
     }
 
     return NULL;
@@ -195,22 +236,21 @@ const CpuCall* TimelineWidget::cpuCallAtTime(int64_t time) {
 /**
  * Find the draw call at time
  */
-const DrawCall* TimelineWidget::drawCallAtTime(int program, int64_t time) {
+const Call* TimelineWidget::drawCallAtTime(int64_t time, int program)
+{
     if (!m_profile) {
         return NULL;
     }
 
-    std::vector<DrawCall>& drawCalls = m_profile->programs[program].drawCalls;
-
-    std::vector<DrawCall>::const_iterator res
-            = binarySearchTimespan<DrawCall, &DrawCall::gpuStart, &DrawCall::gpuDuration>(
-                drawCalls.begin(),
-                drawCalls.end(),
+    std::vector<unsigned>::const_iterator res
+            = binarySearchTimespanIndexed(
+                m_profile->calls,
+                m_profile->programs[program].calls.begin(),
+                m_profile->programs[program].calls.end(),
                 time);
 
-    if (res != drawCalls.end()) {
-        const DrawCall& call = *res;
-        return &call;
+    if (res != m_profile->programs[program].calls.end()) {
+        return &m_profile->calls[*res];
     }
 
     return NULL;
@@ -358,14 +398,14 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *e)
             int y = m_mousePosition.y() - m_axisHeight;
 
             if (y < m_rowHeight) {
-                const CpuCall* call = cpuCallAtTime(time);
+                const Call* call = cpuCallAtTime(time);
 
                 if (call) {
                     QString text;
                     text  = QString::fromStdString(call->name);
                     text += QString("\nCall: %1").arg(call->no);
-                    text += QString("\nCPU Start: %1").arg(call->cpuStart);
-                    text += QString("\nCPU Duration: %1").arg(call->cpuDuration);
+                    text += QString("\nCPU Start: %1").arg(getTimeString(call->cpuStart));
+                    text += QString("\nCPU Duration: %1").arg(getTimeString(call->cpuDuration));
 
                     QToolTip::showText(e->globalPos(), text);
                     tooltip = true;
@@ -374,18 +414,17 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *e)
                 int row = (y - m_rowHeight + m_scrollY) / m_rowHeight;
 
                 if (row < m_rowPrograms.size()) {
-                    int program = m_rowPrograms[row];
-                    const DrawCall* call = drawCallAtTime(program, time);
+                    const Call* call = drawCallAtTime(time, m_rowPrograms[row]);
 
                     if (call) {
                         QString text;
                         text  = QString::fromStdString(call->name);
                         text += QString("\nCall: %1").arg(call->no);
-                        text += QString("\nGPU Start: %1").arg(call->gpuStart);
-                        text += QString("\nCPU Start: %1").arg(call->cpuStart);
-                        text += QString("\nGPU Duration: %1").arg(call->gpuDuration);
-                        text += QString("\nCPU Duration: %1").arg(call->cpuDuration);
-                        text += QString("\nPixels Drawn: %1").arg(call->pixels);
+                        text += QString("\nCPU Start: %1").arg(getTimeString(call->cpuStart));
+                        text += QString("\nGPU Start: %1").arg(getTimeString(call->gpuStart));
+                        text += QString("\nCPU Duration: %1").arg(getTimeString(call->cpuDuration));
+                        text += QString("\nGPU Duration: %1").arg(getTimeString(call->gpuDuration));
+                        text += QString("\nPixels Drawn: %1").arg(QLocale::system().toString((qlonglong)call->pixels));
 
                         QToolTip::showText(e->globalPos(), text);
                         tooltip = true;
@@ -489,7 +528,7 @@ void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *e)
             }
         } else if (row == 0) {
             /* CPU Calls */
-            const CpuCall* call = cpuCallAtTime(time);
+            const Call* call = cpuCallAtTime(time);
 
             if (call) {
                 emit jumpToCall(call->no);
@@ -497,8 +536,7 @@ void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *e)
             }
         } else if (row > 0) {
             /* Draw Calls */
-            int program = m_rowPrograms[row - 1 + m_row];
-            const DrawCall* call = drawCallAtTime(program, time);
+            const Call* call = drawCallAtTime(time, 0);
 
             if (call) {
                 emit jumpToCall(call->no);
@@ -597,8 +635,8 @@ void TimelineWidget::paintEvent(QPaintEvent *e)
         lastX = 0;
         heat = 0;
 
-        for (std::vector<DrawCall>::const_iterator itr = program.drawCalls.begin(); itr != program.drawCalls.end(); ++itr) {
-            const DrawCall& call = *itr;
+        for (std::vector<unsigned>::const_iterator itr = program.calls.begin(); itr != program.calls.end(); ++itr) {
+            const Call& call = m_profile->calls[*itr];
             int64_t gpuEnd = call.gpuStart + call.gpuDuration;
 
             if (call.gpuStart > timeEnd) {
@@ -664,8 +702,8 @@ void TimelineWidget::paintEvent(QPaintEvent *e)
     painter.translate(m_axisWidth, m_axisHeight);
     painter.fillRect(0, 0, m_viewWidth, m_rowHeight, Qt::white);
 
-    for (std::vector<CpuCall>::const_iterator itr = m_profile->cpuCalls.begin(); itr != m_profile->cpuCalls.end(); ++itr) {
-        const CpuCall& call = *itr;
+    for (std::vector<Call>::const_iterator itr = m_profile->calls.begin(); itr != m_profile->calls.end(); ++itr) {
+        const Call& call = *itr;
         int64_t cpuEnd = call.cpuStart + call.cpuDuration;
 
         if (call.cpuStart > timeEnd) {