]> git.cworth.org Git - apitrace/commitdiff
Improve internal format of profile results.
authorJames Benton <jbenton@vmware.com>
Wed, 22 Aug 2012 11:11:37 +0000 (12:11 +0100)
committerJames Benton <jbenton@vmware.com>
Wed, 22 Aug 2012 12:12:29 +0000 (13:12 +0100)
common/trace_profiler.cpp
common/trace_profiler.hpp
gui/profiledialog.cpp
gui/profiletablemodel.cpp
gui/profiletablemodel.h
gui/timelinewidget.cpp
gui/timelinewidget.h

index 642ba6e88325560e235dd1d9cab0bc2aa6e023d2..402cdacc025954115f3ca9d964c272a3f1904fac 100644 (file)
@@ -136,7 +136,7 @@ void Profiler::parseLine(const char* in, Profile* profile)
     if (in[0] == '#' || strlen(in) < 4)
         return;
 
-    if (profile->programs.size() == 0 && profile->cpuCalls.size() == 0 && profile->frames.size() == 0) {
+    if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) {
         lastGpuTime = 0;
         lastCpuTime = 0;
     }
@@ -144,43 +144,39 @@ void Profiler::parseLine(const char* in, Profile* profile)
     line >> type;
 
     if (type.compare("call") == 0) {
-        Profile::DrawCall draw;
-        unsigned program;
-
-        line >> draw.no
-             >> draw.gpuStart
-             >> draw.gpuDuration
-             >> draw.cpuStart
-             >> draw.cpuDuration
-             >> draw.pixels
-             >> program
-             >> draw.name;
-
-        if (lastGpuTime < draw.gpuStart + draw.gpuDuration) {
-            lastGpuTime = draw.gpuStart + draw.gpuDuration;
+        Profile::Call call;
+        unsigned programNo;
+
+        line >> call.no
+             >> call.gpuStart
+             >> call.gpuDuration
+             >> call.cpuStart
+             >> call.cpuDuration
+             >> call.pixels
+             >> programNo
+             >> call.name;
+
+        if (lastGpuTime < call.gpuStart + call.gpuDuration) {
+            lastGpuTime = call.gpuStart + call.gpuDuration;
         }
 
-        if (lastCpuTime < draw.cpuStart + draw.cpuDuration) {
-            lastCpuTime = draw.cpuStart + draw.cpuDuration;
+        if (lastCpuTime < call.cpuStart + call.cpuDuration) {
+            lastCpuTime = call.cpuStart + call.cpuDuration;
         }
 
-        if (draw.pixels >= 0) {
-            if (profile->programs.size() <= program) {
-                profile->programs.resize(program + 1);
+        profile->calls.push_back(call);
+
+        if (call.pixels >= 0) {
+            if (profile->programs.size() <= programNo) {
+                profile->programs.resize(programNo + 1);
             }
 
-            profile->programs[program].cpuTotal += draw.cpuDuration;
-            profile->programs[program].gpuTotal += draw.gpuDuration;
-            profile->programs[program].pixelTotal += draw.pixels;
-            profile->programs[program].drawCalls.push_back(draw);
+            Profile::Program& program = profile->programs[programNo];
+            program.cpuTotal += call.cpuDuration;
+            program.gpuTotal += call.gpuDuration;
+            program.pixelTotal += call.pixels;
+            program.calls.push_back(profile->calls.size() - 1);
         }
-
-        Profile::CpuCall call;
-        call.no          = draw.no;
-        call.name        = draw.name;
-        call.cpuStart    = draw.cpuStart;
-        call.cpuDuration = draw.cpuDuration;
-        profile->cpuCalls.push_back(call);
     } else if (type.compare("frame_end") == 0) {
         Profile::Frame frame;
         frame.no = profile->frames.size();
@@ -188,13 +184,17 @@ void Profiler::parseLine(const char* in, Profile* profile)
         if (frame.no == 0) {
             frame.gpuStart = 0;
             frame.cpuStart = 0;
+            frame.calls.begin = 0;
         } else {
             frame.gpuStart = profile->frames.back().gpuStart + profile->frames.back().gpuDuration;
             frame.cpuStart = profile->frames.back().cpuStart + profile->frames.back().cpuDuration;
+            frame.calls.begin = profile->frames.back().calls.end + 1;
         }
 
         frame.gpuDuration = lastGpuTime - frame.gpuStart;
         frame.cpuDuration = lastCpuTime - frame.cpuStart;
+        frame.calls.end = profile->calls.size() - 1;
+
         profile->frames.push_back(frame);
     }
 }
index 42fd032008ca668b4fe3767947b092005996f426..8463c61f4ff5d06230b7b3217cf3bb723389276b 100644 (file)
@@ -34,16 +34,7 @@ namespace trace
 {
 
 struct Profile {
-    struct CpuCall {
-        unsigned no;
-
-        int64_t cpuStart;
-        int64_t cpuDuration;
-
-        std::string name;
-    };
-
-    struct DrawCall {
+    struct Call {
         unsigned no;
 
         int64_t gpuStart;
@@ -65,6 +56,12 @@ struct Profile {
 
         int64_t cpuStart;
         int64_t cpuDuration;
+
+        /* Indices to profile->calls array */
+        struct {
+            unsigned begin;
+            unsigned end;
+        } calls;
     };
 
     struct Program {
@@ -73,12 +70,14 @@ struct Profile {
         uint64_t gpuTotal;
         uint64_t cpuTotal;
         uint64_t pixelTotal;
-        std::vector<DrawCall> drawCalls;
+
+        /* Indices to profile->calls array */
+        std::vector<unsigned> calls;
     };
 
+    std::vector<Call> calls;
     std::vector<Frame> frames;
     std::vector<Program> programs;
-    std::vector<CpuCall> cpuCalls;
 };
 
 class Profiler
index d0a55a3400d46423fd5d9413b3d2f706de7697cc..5568b54120a905518f97dc50af6e8658722adf47 100644 (file)
@@ -22,7 +22,7 @@ ProfileDialog::~ProfileDialog()
 void ProfileDialog::tableDoubleClicked(const QModelIndex& index)
 {
     ProfileTableModel* model = (ProfileTableModel*)m_table->model();
-    const trace::Profile::DrawCall* call = model->getJumpCall(index);
+    const trace::Profile::Call* call = model->getJumpCall(index);
 
     if (call) {
         emit jumpToCall(call->no);
index 649dae08e3fa9d72e23382a865c8ede52bd9552b..a305709fa9c9c1cf9903894e574b8c9ea317654e 100644 (file)
@@ -1,9 +1,8 @@
 #include "profiletablemodel.h"
 
+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;
 
 enum {
     COLUMN_PROGRAM,
@@ -78,11 +77,11 @@ void ProfileTableModel::updateModel()
     }
 
     for (std::vector<Program>::const_iterator itr = m_profile->programs.begin(); itr != m_profile->programs.end(); ++itr) {
-        ProfileTableRow* row = getRow(itr - m_profile->programs.begin());
+        ProfileTableRow* row = NULL;
         const Program& program = *itr;
 
-        for (std::vector<DrawCall>::const_iterator jtr = program.drawCalls.begin(); jtr != program.drawCalls.end(); ++jtr) {
-            const DrawCall& call = *jtr;
+        for (std::vector<unsigned>::const_iterator jtr = program.calls.begin(); jtr != program.calls.end(); ++jtr) {
+            const Call& call = m_profile->calls[*jtr];
 
             if (call.cpuStart > m_timeMax) {
                 break;
@@ -92,6 +91,10 @@ void ProfileTableModel::updateModel()
                 continue;
             }
 
+            if (!row) {
+                row = getRow(itr - m_profile->programs.begin());
+            }
+
             row->uses++;
             row->pixels  += call.pixels;
             row->gpuTime += call.gpuDuration;
@@ -116,7 +119,7 @@ void ProfileTableModel::updateModel()
 /**
  * Get the appropriate call associated with an item in the table
  */
-const DrawCall* ProfileTableModel::getJumpCall(const QModelIndex & index) const {
+const trace::Profile::Call *ProfileTableModel::getJumpCall(const QModelIndex & index) const {
     const ProfileTableRow& row = m_rowData[index.row()];
 
     switch(index.column()) {
index 6cca74d9324958fd8c3a5f336c4b1fa4d1b94e3b..dc08ba0ec2b390850b302c207582f9596e6d55a5 100644 (file)
@@ -24,9 +24,9 @@ struct ProfileTableRow
     qulonglong cpuTime;
     qulonglong pixels;
 
-    const trace::Profile::DrawCall* longestGpu;
-    const trace::Profile::DrawCall* longestCpu;
-    const trace::Profile::DrawCall* longestPixel;
+    const trace::Profile::Call* longestGpu;
+    const trace::Profile::Call* longestCpu;
+    const trace::Profile::Call* longestPixel;
 };
 
 class ProfileTableModel : public QAbstractTableModel
@@ -39,7 +39,7 @@ public:
     void setProfile(trace::Profile* profile);
     void setTimeSelection(int64_t start, int64_t end);
 
-    const trace::Profile::DrawCall* getJumpCall(const QModelIndex & index) const;
+    const trace::Profile::Call* getJumpCall(const QModelIndex & index) const;
 
     virtual int rowCount(const QModelIndex & parent) const;
     virtual int columnCount(const QModelIndex & parent) const;
index d9f1b5809ebf63246dba4c4c7f7cb2aeb53c9bca..b6a52f875980322c8306ef8ead5341b8f4583057 100644 (file)
@@ -9,10 +9,9 @@
 #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 +138,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 +201,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 +211,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 +234,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,7 +396,7 @@ 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;
@@ -374,8 +412,7 @@ 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;
@@ -489,7 +526,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 +534,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 +633,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 +700,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) {
index 472ffa113f6ff6571f2ab1111ce869367cc02ece..9d5d8a51082d2d5b88970ab31275cdef3c99cd53 100644 (file)
@@ -60,8 +60,8 @@ private:
     void calculateRows();
 
     const trace::Profile::Frame* frameAtTime(int64_t time);
-    const trace::Profile::CpuCall* cpuCallAtTime(int64_t time);
-    const trace::Profile::DrawCall* drawCallAtTime(int program, int64_t time);
+    const trace::Profile::Call* cpuCallAtTime(int64_t time);
+    const trace::Profile::Call* drawCallAtTime(int64_t time, int program);
 
 private:
     /* Data */