1 #ifndef CALLDURATIONGRAPH_H
2 #define CALLDURATIONGRAPH_H
4 #include "graphing/graphwidget.h"
5 #include "trace_profiler.hpp"
9 * Wrapper for call duration graphs.
11 * This implements the transformSelectionIn and transformSelectionOut to
12 * allow sharing the selection between the graphs and the heatmap as they
13 * are using different scales. The duration graphs have call.no on the X-axis
14 * whereas the heatmap has time on the X axis.
16 class CallDurationGraph : public GraphWidget {
18 CallDurationGraph(QWidget* parent = 0) :
24 void setProfile(const trace::Profile* profile)
30 /* Transform from time-based horizontal selection to call no based. */
31 virtual SelectionState transformSelectionIn(SelectionState state)
33 if (!m_profile || state.type != SelectionState::Horizontal) {
37 qint64 timeStart = state.start;
38 qint64 timeEnd = state.end;
40 std::vector<trace::Profile::Call>::const_iterator itr;
43 Profiling::binarySearchTimespan<
45 &trace::Profile::Call::cpuStart,
46 &trace::Profile::Call::cpuDuration>
47 (m_profile->calls.begin(), m_profile->calls.end(), timeStart, true);
49 state.start = itr - m_profile->calls.begin();
52 Profiling::binarySearchTimespan<
54 &trace::Profile::Call::cpuStart,
55 &trace::Profile::Call::cpuDuration>
56 (m_profile->calls.begin(), m_profile->calls.end(), timeEnd, true);
58 state.end = itr - m_profile->calls.begin();
63 virtual SelectionState transformSelectionOut(SelectionState state)
65 if (!m_profile || state.type != SelectionState::Horizontal) {
69 qint64 start = qMax<qint64>(0, state.start);
70 qint64 end = qMin<qint64>(state.end, m_profile->calls.size());
72 /* Call based -> time based */
73 state.start = m_profile->calls[start].cpuStart;
74 state.end = m_profile->calls[end].cpuStart + m_profile->calls[end].cpuDuration;
80 const trace::Profile* m_profile;
83 /* Data provider for call duration graphs */
84 class CallDurationDataProvider : public GraphDataProvider {
86 CallDurationDataProvider(const trace::Profile* profile, bool gpu) :
89 m_selectionState(NULL)
93 virtual qint64 size() const
95 return m_profile ? m_profile->calls.size() : 0;
98 virtual bool selected(qint64 index) const
100 if (m_selectionState) {
101 if (m_selectionState->type == SelectionState::Horizontal) {
102 if (m_selectionState->start <= index && index < m_selectionState->end) {
105 } else if (m_selectionState->type == SelectionState::Vertical) {
106 return m_profile->calls[index].program == m_selectionState->start;
113 virtual void setSelectionState(SelectionState* state)
115 m_selectionState = state;
118 virtual qint64 value(qint64 index) const
121 return m_profile->calls[index].gpuDuration;
123 return m_profile->calls[index].cpuDuration;
127 virtual void itemDoubleClicked(qint64 index) const
133 if (index < 0 || index >= m_profile->calls.size()) {
137 const trace::Profile::Call& call = m_profile->calls[index];
138 Profiling::jumpToCall(call.no);
141 virtual QString itemTooltip(qint64 index) const
147 if (index < 0 || index >= m_profile->calls.size()) {
151 const trace::Profile::Call& call = m_profile->calls[index];
154 text = QString::fromStdString(call.name);
155 text += QString("\nCall: %1").arg(call.no);
156 text += QString("\nCPU Duration: %1").arg(Profiling::getTimeString(call.cpuDuration));
158 if (call.pixels >= 0) {
159 text += QString("\nGPU Duration: %1").arg(Profiling::getTimeString(call.gpuDuration));
160 text += QString("\nPixels Drawn: %1").arg(QLocale::system().toString((qlonglong)call.pixels));
161 text += QString("\nProgram: %1").arg(call.program);
169 const trace::Profile* m_profile;
170 SelectionState* m_selectionState;