From 4c4896f8490aca7f32956e402ffdf413d04c36dd Mon Sep 17 00:00:00 2001 From: James Benton Date: Wed, 22 Aug 2012 12:11:37 +0100 Subject: [PATCH] Improve internal format of profile results. --- common/trace_profiler.cpp | 62 +++++++++++----------- common/trace_profiler.hpp | 23 ++++----- gui/profiledialog.cpp | 2 +- gui/profiletablemodel.cpp | 15 +++--- gui/profiletablemodel.h | 8 +-- gui/timelinewidget.cpp | 106 +++++++++++++++++++++++++------------- gui/timelinewidget.h | 4 +- 7 files changed, 129 insertions(+), 91 deletions(-) diff --git a/common/trace_profiler.cpp b/common/trace_profiler.cpp index 642ba6e..402cdac 100644 --- a/common/trace_profiler.cpp +++ b/common/trace_profiler.cpp @@ -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); } } diff --git a/common/trace_profiler.hpp b/common/trace_profiler.hpp index 42fd032..8463c61 100644 --- a/common/trace_profiler.hpp +++ b/common/trace_profiler.hpp @@ -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 drawCalls; + + /* Indices to profile->calls array */ + std::vector calls; }; + std::vector calls; std::vector frames; std::vector programs; - std::vector cpuCalls; }; class Profiler diff --git a/gui/profiledialog.cpp b/gui/profiledialog.cpp index d0a55a3..5568b54 100644 --- a/gui/profiledialog.cpp +++ b/gui/profiledialog.cpp @@ -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); diff --git a/gui/profiletablemodel.cpp b/gui/profiletablemodel.cpp index 649dae0..a305709 100644 --- a/gui/profiletablemodel.cpp +++ b/gui/profiletablemodel.cpp @@ -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::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::const_iterator jtr = program.drawCalls.begin(); jtr != program.drawCalls.end(); ++jtr) { - const DrawCall& call = *jtr; + for (std::vector::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()) { diff --git a/gui/profiletablemodel.h b/gui/profiletablemodel.h index 6cca74d..dc08ba0 100644 --- a/gui/profiletablemodel.h +++ b/gui/profiletablemodel.h @@ -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; diff --git a/gui/timelinewidget.cpp b/gui/timelinewidget.cpp index d9f1b58..b6a52f8 100644 --- a/gui/timelinewidget.cpp +++ b/gui/timelinewidget.cpp @@ -9,10 +9,9 @@ #include #include +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::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::const_iterator binarySearchTimespanIndexed( + const std::vector& calls, + std::vector::const_iterator begin, + std::vector::const_iterator end, + int64_t time) +{ + int lower = 0; + int upper = end - begin; + int pos = (lower + upper) / 2; + std::vector::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::const_iterator res - = binarySearchTimespan( - m_profile->cpuCalls.begin(), - m_profile->cpuCalls.end(), + std::vector::const_iterator res + = binarySearchTimespan( + 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& drawCalls = m_profile->programs[program].drawCalls; - - std::vector::const_iterator res - = binarySearchTimespan( - drawCalls.begin(), - drawCalls.end(), + std::vector::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::const_iterator itr = program.drawCalls.begin(); itr != program.drawCalls.end(); ++itr) { - const DrawCall& call = *itr; + for (std::vector::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::const_iterator itr = m_profile->cpuCalls.begin(); itr != m_profile->cpuCalls.end(); ++itr) { - const CpuCall& call = *itr; + for (std::vector::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) { diff --git a/gui/timelinewidget.h b/gui/timelinewidget.h index 472ffa1..9d5d8a5 100644 --- a/gui/timelinewidget.h +++ b/gui/timelinewidget.h @@ -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 */ -- 2.43.0