1 #include "profiledialog.h"
2 #include "profiletablemodel.h"
3 #include <QSortFilterProxyModel>
5 #include "graphing/histogramview.h"
6 #include "graphing/timeaxiswidget.h"
7 #include "graphing/frameaxiswidget.h"
8 #include "graphing/heatmapverticalaxiswidget.h"
9 #include "profileheatmap.h"
11 /* Handy function to allow selection of a call in main window */
12 ProfileDialog* g_profileDialog = 0;
14 void Profiling::jumpToCall(int index)
16 if (g_profileDialog) {
17 g_profileDialog->showCall(index);
21 /* Provides frame numbers based off call index */
22 class FrameCallDataProvider : public FrameDataProvider {
24 FrameCallDataProvider(const trace::Profile* profile)
29 unsigned size() const {
30 return m_profile->frames.size();
33 qint64 frameStart(unsigned index) const {
34 return m_profile->frames[index].calls.begin;
37 qint64 frameEnd(unsigned index) const {
38 return m_profile->frames[index].calls.end;
42 const trace::Profile* m_profile;
45 /* Provides frame numbers based off time */
46 class FrameTimeDataProvider : public FrameDataProvider {
48 FrameTimeDataProvider(const trace::Profile* profile)
53 unsigned size() const {
54 return m_profile->frames.size();
57 qint64 frameStart(unsigned index) const {
58 return m_profile->frames[index].cpuStart;
61 qint64 frameEnd(unsigned index) const {
62 return m_profile->frames[index].cpuStart + m_profile->frames[index].cpuDuration;
66 const trace::Profile* m_profile;
69 ProfileDialog::ProfileDialog(QWidget *parent)
74 g_profileDialog = this;
76 /* Gradients for call duration histograms */
77 QLinearGradient cpuGradient;
78 cpuGradient.setColorAt(0.9, QColor(0, 0, 210));
79 cpuGradient.setColorAt(0.0, QColor(130, 130, 255));
81 QLinearGradient gpuGradient;
82 gpuGradient.setColorAt(0.9, QColor(210, 0, 0));
83 gpuGradient.setColorAt(0.0, QColor(255, 130, 130));
86 /* Setup heatmap timeline */
87 m_timeline->setLabel(new GraphLabelWidget("Frames ", m_timeline));
88 m_timeline->label()->setFlags(Qt::AlignVCenter | Qt::AlignRight);
90 m_timeline->setView(new HeatmapView(m_timeline));
92 m_timeline->setAxis(GraphWidget::AxisTop, new FrameAxisWidget(m_timeline));
93 m_timeline->setAxis(GraphWidget::AxisLeft, new HeatmapVerticalAxisWidget(m_timeline));
94 m_timeline->axis(GraphWidget::AxisLeft)->resize(80, 0);
96 m_timeline->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
97 m_timeline->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
100 /* Setup Cpu call duration histogram */
101 m_cpuGraph->setLabel(new GraphLabelWidget("CPU", m_cpuGraph));
103 m_cpuGraph->setAxis(GraphWidget::AxisTop, new FrameAxisWidget(m_cpuGraph));
104 m_cpuGraph->setAxis(GraphWidget::AxisLeft, new TimeAxisWidget(m_cpuGraph));
105 m_cpuGraph->axis(GraphWidget::AxisLeft)->resize(80, 0);
107 HistogramView* cpuView = new HistogramView(m_cpuGraph);
108 cpuView->setSelectedGradient(cpuGradient);
109 m_cpuGraph->setView(cpuView);
112 /* Setup Gpu call duration histogram */
113 m_gpuGraph->setLabel(new GraphLabelWidget("GPU", m_gpuGraph));
115 m_gpuGraph->setAxis(GraphWidget::AxisTop, new FrameAxisWidget(m_gpuGraph));
116 m_gpuGraph->setAxis(GraphWidget::AxisLeft, new TimeAxisWidget(m_gpuGraph));
117 m_gpuGraph->axis(GraphWidget::AxisLeft)->resize(80, 0);
119 HistogramView* gpuView = new HistogramView(m_gpuGraph);
120 gpuView->setSelectedGradient(gpuGradient);
121 m_gpuGraph->setView(gpuView);
124 /* Synchronise selections */
125 connect(m_timeline, SIGNAL(selectionChanged(SelectionState)), m_cpuGraph, SLOT(setSelection(SelectionState)));
126 connect(m_timeline, SIGNAL(selectionChanged(SelectionState)), m_gpuGraph, SLOT(setSelection(SelectionState)));
128 connect(m_cpuGraph, SIGNAL(selectionChanged(SelectionState)), m_timeline, SLOT(setSelection(SelectionState)));
129 connect(m_cpuGraph, SIGNAL(selectionChanged(SelectionState)), m_gpuGraph, SLOT(setSelection(SelectionState)));
131 connect(m_gpuGraph, SIGNAL(selectionChanged(SelectionState)), m_timeline, SLOT(setSelection(SelectionState)));
132 connect(m_gpuGraph, SIGNAL(selectionChanged(SelectionState)), m_cpuGraph, SLOT(setSelection(SelectionState)));
134 connect(m_timeline, SIGNAL(selectionChanged(SelectionState)), this, SLOT(graphSelectionChanged(SelectionState)));
135 connect(m_cpuGraph, SIGNAL(selectionChanged(SelectionState)), this, SLOT(graphSelectionChanged(SelectionState)));
136 connect(m_gpuGraph, SIGNAL(selectionChanged(SelectionState)), this, SLOT(graphSelectionChanged(SelectionState)));
139 /* Synchronise views between cpuGraph and gpuGraph */
140 connect(m_cpuGraph, SIGNAL(horizontalViewChanged(qint64,qint64)), m_gpuGraph, SLOT(setHorizontalView(qint64,qint64)));
141 connect(m_gpuGraph, SIGNAL(horizontalViewChanged(qint64,qint64)), m_cpuGraph, SLOT(setHorizontalView(qint64,qint64)));
145 ProfileDialog::~ProfileDialog()
151 void ProfileDialog::showCall(int call)
153 emit jumpToCall(call);
157 void ProfileDialog::tableDoubleClicked(const QModelIndex& index)
159 ProfileTableModel* model = (ProfileTableModel*)m_table->model();
165 const trace::Profile::Call* call = model->getJumpCall(index);
168 emit jumpToCall(call->no);
170 unsigned program = model->getProgram(index);
172 SelectionState state;
173 state.type = SelectionState::Vertical;
174 state.end = state.start = program;
176 m_timeline->setSelection(state);
177 m_cpuGraph->setSelection(state);
178 m_gpuGraph->setSelection(state);
183 void ProfileDialog::setProfile(trace::Profile* profile)
186 if (profile && profile->frames.size()) {
187 HeatmapVerticalAxisWidget* programAxis;
188 FrameAxisWidget* frameAxis;
189 HistogramView* histogram;
190 HeatmapView* heatmap;
193 /* Setup data providers for Cpu graph */
194 m_cpuGraph->setProfile(profile);
195 histogram = (HistogramView*)m_cpuGraph->view();
196 frameAxis = (FrameAxisWidget*)m_cpuGraph->axis(GraphWidget::AxisTop);
198 histogram->setDataProvider(new CallDurationDataProvider(profile, false));
199 frameAxis->setDataProvider(new FrameCallDataProvider(profile));
201 /* Setup data provider for Gpu graph */
202 m_gpuGraph->setProfile(profile);
203 histogram = (HistogramView*)m_gpuGraph->view();
204 frameAxis = (FrameAxisWidget*)m_gpuGraph->axis(GraphWidget::AxisTop);
206 histogram->setDataProvider(new CallDurationDataProvider(profile, true));
207 frameAxis->setDataProvider(new FrameCallDataProvider(profile));
209 /* Setup data provider for heatmap timeline */
210 heatmap = (HeatmapView*)m_timeline->view();
211 frameAxis = (FrameAxisWidget*)m_timeline->axis(GraphWidget::AxisTop);
212 programAxis = (HeatmapVerticalAxisWidget*)m_timeline->axis(GraphWidget::AxisLeft);
214 heatmap->setDataProvider(new ProfileHeatmapDataProvider(profile));
215 frameAxis->setDataProvider(new FrameTimeDataProvider(profile));
216 programAxis->setDataProvider(new ProfileHeatmapDataProvider(profile));
218 /* Setup data model for table view */
219 ProfileTableModel* model = new ProfileTableModel(m_table);
220 model->setProfile(profile);
222 delete m_table->model();
223 m_table->setModel(model);
224 m_table->update(QModelIndex());
225 m_table->sortByColumn(2, Qt::DescendingOrder);
226 m_table->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
227 m_table->resizeColumnsToContents();
229 /* Reset selection */
230 SelectionState emptySelection;
231 emptySelection.type = SelectionState::None;
232 m_cpuGraph->setSelection(emptySelection);
233 m_gpuGraph->setSelection(emptySelection);
234 m_timeline->setSelection(emptySelection);
242 void ProfileDialog::graphSelectionChanged(SelectionState state)
244 ProfileTableModel* model = (ProfileTableModel*)m_table->model();
250 if (state.type == SelectionState::None) {
252 } else if (state.type == SelectionState::Horizontal) {
253 model->selectTime(state.start, state.end);
254 } else if (state.type == SelectionState::Vertical) {
255 model->selectProgram(state.start);
260 if (state.type == SelectionState::Vertical) {
261 m_table->selectRow(model->getRowIndex(state.start));
265 #include "profiledialog.moc"