blob: cbe2eea94189eaeb6125843c9b8d47838a101435 [file] [log] [blame]
James Bentonfc4f55a2012-08-08 17:09:07 +01001#include "profiletablemodel.h"
James Benton902626c2012-08-22 12:18:09 +01002#include "profiledialog.h"
3
4#include <QLocale>
James Bentonfc4f55a2012-08-08 17:09:07 +01005
James Benton4c4896f2012-08-22 12:11:37 +01006typedef trace::Profile::Call Call;
James Bentonfc4f55a2012-08-08 17:09:07 +01007typedef trace::Profile::Frame Frame;
James Benton56ad11c2012-08-16 13:44:19 +01008typedef trace::Profile::Program Program;
James Bentonfc4f55a2012-08-08 17:09:07 +01009
10enum {
11 COLUMN_PROGRAM,
12 COLUMN_USAGES,
13 COLUMN_GPU_TIME,
14 COLUMN_CPU_TIME,
15 COLUMN_PIXELS_DRAWN,
16 COLUMN_GPU_AVERAGE,
17 COLUMN_CPU_AVERAGE,
18 COLUMN_PIXELS_AVERAGE,
19 MAX_COLUMN
20};
21
22static QString columnNames[] = {
23 QString("Program"),
24 QString("Calls"),
25 QString("Total GPU Time"),
26 QString("Total CPU Time"),
27 QString("Total Pixels Drawn"),
28 QString("Avg GPU Time"),
29 QString("Avg CPU Time"),
30 QString("Avg Pixels Drawn")
31};
32
33ProfileTableModel::ProfileTableModel(QObject *parent)
34 : QAbstractTableModel(parent),
35 m_profile(0),
36 m_sortColumn(COLUMN_GPU_TIME),
37 m_sortOrder(Qt::DescendingOrder)
38{
39}
40
41
42void ProfileTableModel::setProfile(trace::Profile* profile)
43{
44 m_profile = profile;
James Benton56ad11c2012-08-16 13:44:19 +010045 m_timeMin = m_profile->frames.front().cpuStart;
46 m_timeMax = m_profile->frames.back().cpuStart + m_profile->frames.back().cpuDuration;
James Bentonfc4f55a2012-08-08 17:09:07 +010047 updateModel();
48}
49
50
James Bentonb70a86a2012-08-28 18:41:43 +010051/**
52 * Set selection to nothing
53 */
54void ProfileTableModel::selectNone()
55{
56 m_timeMin = m_timeMax = 0;
57 updateModel();
58 sort(m_sortColumn, m_sortOrder);
59}
60
61
62/**
63 * Set selection to program
64 */
65void ProfileTableModel::selectProgram(unsigned /*program*/)
66{
67 /* We have no program based selection for table */
68 selectNone();
69}
70
71
72/**
73 * Set selection to a period of time
74 */
75void ProfileTableModel::selectTime(int64_t start, int64_t end)
James Bentonfc4f55a2012-08-08 17:09:07 +010076{
77 m_timeMin = start;
78 m_timeMax = end;
James Bentonb70a86a2012-08-28 18:41:43 +010079
James Bentonfc4f55a2012-08-08 17:09:07 +010080 updateModel();
81 sort(m_sortColumn, m_sortOrder);
82}
83
84
85/**
86 * Creates the row data from trace profile
87 */
88void ProfileTableModel::updateModel()
89{
90 if (m_timeMin == m_timeMax) {
James Benton56ad11c2012-08-16 13:44:19 +010091 m_timeMin = m_profile->frames.front().cpuStart;
92 m_timeMax = m_profile->frames.back().cpuStart + m_profile->frames.back().cpuDuration;
James Bentonfc4f55a2012-08-08 17:09:07 +010093 }
94
95 for (QList<ProfileTableRow>::iterator itr = m_rowData.begin(); itr != m_rowData.end(); ++itr) {
96 ProfileTableRow& row = *itr;
97
98 row.uses = 0;
99 row.pixels = 0;
100 row.gpuTime = 0;
101 row.cpuTime = 0;
102 row.longestCpu = NULL;
103 row.longestGpu = NULL;
104 row.longestPixel = NULL;
105 }
106
James Benton56ad11c2012-08-16 13:44:19 +0100107 for (std::vector<Program>::const_iterator itr = m_profile->programs.begin(); itr != m_profile->programs.end(); ++itr) {
James Benton4c4896f2012-08-22 12:11:37 +0100108 ProfileTableRow* row = NULL;
James Benton56ad11c2012-08-16 13:44:19 +0100109 const Program& program = *itr;
James Bentonfc4f55a2012-08-08 17:09:07 +0100110
James Benton4c4896f2012-08-22 12:11:37 +0100111 for (std::vector<unsigned>::const_iterator jtr = program.calls.begin(); jtr != program.calls.end(); ++jtr) {
112 const Call& call = m_profile->calls[*jtr];
James Bentonfc4f55a2012-08-08 17:09:07 +0100113
James Benton56ad11c2012-08-16 13:44:19 +0100114 if (call.cpuStart > m_timeMax) {
James Bentonfc4f55a2012-08-08 17:09:07 +0100115 break;
116 }
117
James Benton56ad11c2012-08-16 13:44:19 +0100118 if (call.cpuStart + call.cpuDuration < m_timeMin) {
James Bentonfc4f55a2012-08-08 17:09:07 +0100119 continue;
120 }
121
James Benton4c4896f2012-08-22 12:11:37 +0100122 if (!row) {
123 row = getRow(itr - m_profile->programs.begin());
124 }
125
James Bentonfc4f55a2012-08-08 17:09:07 +0100126 row->uses++;
James Benton56ad11c2012-08-16 13:44:19 +0100127 row->pixels += call.pixels;
James Bentonfc4f55a2012-08-08 17:09:07 +0100128 row->gpuTime += call.gpuDuration;
129 row->cpuTime += call.cpuDuration;
James Bentonfc4f55a2012-08-08 17:09:07 +0100130
131 if (!row->longestGpu || row->longestGpu->gpuDuration < call.gpuDuration) {
132 row->longestGpu = &call;
133 }
134
135 if (!row->longestCpu || row->longestCpu->cpuDuration < call.cpuDuration) {
136 row->longestCpu = &call;
137 }
138
139 if (!row->longestPixel || row->longestPixel->pixels < call.pixels) {
140 row->longestPixel = &call;
141 }
142 }
143 }
144}
145
146
147/**
148 * Get the appropriate call associated with an item in the table
149 */
James Benton4c4896f2012-08-22 12:11:37 +0100150const trace::Profile::Call *ProfileTableModel::getJumpCall(const QModelIndex & index) const {
James Bentonfc4f55a2012-08-08 17:09:07 +0100151 const ProfileTableRow& row = m_rowData[index.row()];
152
153 switch(index.column()) {
154 case COLUMN_GPU_TIME:
155 case COLUMN_GPU_AVERAGE:
156 return row.longestGpu;
157 case COLUMN_CPU_TIME:
158 case COLUMN_CPU_AVERAGE:
159 return row.longestCpu;
160 case COLUMN_PIXELS_DRAWN:
161 case COLUMN_PIXELS_AVERAGE:
162 return row.longestPixel;
163 }
164
165 return NULL;
166}
167
168
James Bentonb70a86a2012-08-28 18:41:43 +0100169/**
170 * Get the shader program associated with an item in the table
171 */
172unsigned ProfileTableModel::getProgram(const QModelIndex & index) const
173{
174 const ProfileTableRow& row = m_rowData[index.row()];
175 return row.program;
176}
177
178
179/**
180 * Get the row index for a shader program
181 */
182int ProfileTableModel::getRowIndex(unsigned program) const
183{
184 for (int i = 0; i < m_rowData.size(); ++i) {
185 if (m_rowData[i].program == program)
186 return i;
187 }
188
189 return -1;
190}
191
192
193/**
194 * Get the row data for a shader program
195 */
James Bentonfc4f55a2012-08-08 17:09:07 +0100196ProfileTableRow* ProfileTableModel::getRow(unsigned program) {
197 for (QList<ProfileTableRow>::iterator itr = m_rowData.begin(); itr != m_rowData.end(); ++itr) {
198 if (itr->program == program)
199 return &*itr;
200 }
201
James Benton56ad11c2012-08-16 13:44:19 +0100202 m_rowData.append(ProfileTableRow(program));
203 return &m_rowData.back();
James Bentonfc4f55a2012-08-08 17:09:07 +0100204}
205
206
207int ProfileTableModel::rowCount(const QModelIndex & parent) const
208{
209 if (!parent.isValid()) {
210 return m_rowData.size();
211 } else {
212 return 0;
213 }
214}
215
216
217int ProfileTableModel::columnCount(const QModelIndex & /*parent*/) const
218{
219 return MAX_COLUMN;
220}
221
222
223QVariant ProfileTableModel::data(const QModelIndex &index, int role) const
224{
225 if (!index.isValid()) {
226 return QVariant();
227 }
228
229 if (role == Qt::DisplayRole) {
230 const ProfileTableRow& row = m_rowData[index.row()];
231
232 switch(index.column()) {
233 case COLUMN_PROGRAM:
234 return row.program;
235 case COLUMN_USAGES:
James Benton902626c2012-08-22 12:18:09 +0100236 return QLocale::system().toString(row.uses);
James Bentonfc4f55a2012-08-08 17:09:07 +0100237 case COLUMN_GPU_TIME:
James Benton902626c2012-08-22 12:18:09 +0100238 return getTimeString(row.gpuTime);
James Bentonfc4f55a2012-08-08 17:09:07 +0100239 case COLUMN_CPU_TIME:
James Benton902626c2012-08-22 12:18:09 +0100240 return getTimeString(row.cpuTime);
James Bentonfc4f55a2012-08-08 17:09:07 +0100241 case COLUMN_PIXELS_DRAWN:
James Benton902626c2012-08-22 12:18:09 +0100242 return QLocale::system().toString((qlonglong)row.pixels);
James Bentonfc4f55a2012-08-08 17:09:07 +0100243 case COLUMN_GPU_AVERAGE:
James Benton902626c2012-08-22 12:18:09 +0100244 return getTimeString((row.uses <= 0) ? 0 : (row.gpuTime / row.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100245 case COLUMN_CPU_AVERAGE:
James Benton902626c2012-08-22 12:18:09 +0100246 return getTimeString((row.uses <= 0) ? 0 : (row.cpuTime / row.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100247 case COLUMN_PIXELS_AVERAGE:
James Benton902626c2012-08-22 12:18:09 +0100248 return QLocale::system().toString((row.uses <= 0) ? 0 : (row.pixels / row.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100249 }
250 } else if (role == Qt::TextAlignmentRole) {
251 return Qt::AlignRight;
252 }
253
254 return QVariant();
255}
256
257
258QVariant ProfileTableModel::headerData(int section, Qt::Orientation orientation, int role) const
259{
260 if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
261 if (section >= 0 && section < MAX_COLUMN) {
262 return columnNames[section];
263 }
264 }
265
266 return QVariant();
267}
268
269
270class ProgramSorter {
271public:
272 ProgramSorter(int column, Qt::SortOrder order)
273 : mSortColumn(column),
274 mSortOrder(order)
275 {
276 }
277
278 bool operator()(const ProfileTableRow &p1, const ProfileTableRow &p2) const
279 {
280 bool result = true;
281
282 switch(mSortColumn) {
283 case COLUMN_PROGRAM:
284 result = p1.program < p2.program;
285 break;
286 case COLUMN_USAGES:
287 result = p1.uses < p2.uses;
288 break;
289 case COLUMN_GPU_TIME:
290 result = p1.gpuTime < p2.gpuTime;
291 break;
292 case COLUMN_CPU_TIME:
293 result = p1.cpuTime < p2.cpuTime;
294 break;
295 case COLUMN_PIXELS_DRAWN:
296 result = p1.pixels < p2.pixels;
297 break;
298 case COLUMN_GPU_AVERAGE:
James Benton08717052012-08-08 17:43:52 +0100299 result = ((p1.uses <= 0) ? 0 : (p1.gpuTime / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.gpuTime / p2.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100300 break;
301 case COLUMN_CPU_AVERAGE:
James Benton08717052012-08-08 17:43:52 +0100302 result = ((p1.uses <= 0) ? 0 : (p1.cpuTime / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.cpuTime / p2.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100303 break;
304 case COLUMN_PIXELS_AVERAGE:
James Benton08717052012-08-08 17:43:52 +0100305 result = ((p1.uses <= 0) ? 0 : (p1.pixels / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.pixels / p2.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100306 break;
307 }
308
309 if (mSortOrder == Qt::DescendingOrder) {
310 return !result;
311 } else {
312 return result;
313 }
314 }
315
316private:
317 int mSortColumn;
318 Qt::SortOrder mSortOrder;
319};
320
321
322void ProfileTableModel::sort(int column, Qt::SortOrder order) {
323 m_sortColumn = column;
324 m_sortOrder = order;
325 qSort(m_rowData.begin(), m_rowData.end(), ProgramSorter(column, order));
326 emit dataChanged(createIndex(0, 0), createIndex(m_rowData.size(), MAX_COLUMN));
327}
328
329
330#include "profiletablemodel.moc"