blob: 5b9d48473319a46fdac867184c68bfc51a3fbc64 [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
51void ProfileTableModel::setTimeSelection(int64_t start, int64_t end)
52{
53 m_timeMin = start;
54 m_timeMax = end;
55 updateModel();
56 sort(m_sortColumn, m_sortOrder);
57}
58
59
60/**
61 * Creates the row data from trace profile
62 */
63void ProfileTableModel::updateModel()
64{
65 if (m_timeMin == m_timeMax) {
James Benton56ad11c2012-08-16 13:44:19 +010066 m_timeMin = m_profile->frames.front().cpuStart;
67 m_timeMax = m_profile->frames.back().cpuStart + m_profile->frames.back().cpuDuration;
James Bentonfc4f55a2012-08-08 17:09:07 +010068 }
69
70 for (QList<ProfileTableRow>::iterator itr = m_rowData.begin(); itr != m_rowData.end(); ++itr) {
71 ProfileTableRow& row = *itr;
72
73 row.uses = 0;
74 row.pixels = 0;
75 row.gpuTime = 0;
76 row.cpuTime = 0;
77 row.longestCpu = NULL;
78 row.longestGpu = NULL;
79 row.longestPixel = NULL;
80 }
81
James Benton56ad11c2012-08-16 13:44:19 +010082 for (std::vector<Program>::const_iterator itr = m_profile->programs.begin(); itr != m_profile->programs.end(); ++itr) {
James Benton4c4896f2012-08-22 12:11:37 +010083 ProfileTableRow* row = NULL;
James Benton56ad11c2012-08-16 13:44:19 +010084 const Program& program = *itr;
James Bentonfc4f55a2012-08-08 17:09:07 +010085
James Benton4c4896f2012-08-22 12:11:37 +010086 for (std::vector<unsigned>::const_iterator jtr = program.calls.begin(); jtr != program.calls.end(); ++jtr) {
87 const Call& call = m_profile->calls[*jtr];
James Bentonfc4f55a2012-08-08 17:09:07 +010088
James Benton56ad11c2012-08-16 13:44:19 +010089 if (call.cpuStart > m_timeMax) {
James Bentonfc4f55a2012-08-08 17:09:07 +010090 break;
91 }
92
James Benton56ad11c2012-08-16 13:44:19 +010093 if (call.cpuStart + call.cpuDuration < m_timeMin) {
James Bentonfc4f55a2012-08-08 17:09:07 +010094 continue;
95 }
96
James Benton4c4896f2012-08-22 12:11:37 +010097 if (!row) {
98 row = getRow(itr - m_profile->programs.begin());
99 }
100
James Bentonfc4f55a2012-08-08 17:09:07 +0100101 row->uses++;
James Benton56ad11c2012-08-16 13:44:19 +0100102 row->pixels += call.pixels;
James Bentonfc4f55a2012-08-08 17:09:07 +0100103 row->gpuTime += call.gpuDuration;
104 row->cpuTime += call.cpuDuration;
James Bentonfc4f55a2012-08-08 17:09:07 +0100105
106 if (!row->longestGpu || row->longestGpu->gpuDuration < call.gpuDuration) {
107 row->longestGpu = &call;
108 }
109
110 if (!row->longestCpu || row->longestCpu->cpuDuration < call.cpuDuration) {
111 row->longestCpu = &call;
112 }
113
114 if (!row->longestPixel || row->longestPixel->pixels < call.pixels) {
115 row->longestPixel = &call;
116 }
117 }
118 }
119}
120
121
122/**
123 * Get the appropriate call associated with an item in the table
124 */
James Benton4c4896f2012-08-22 12:11:37 +0100125const trace::Profile::Call *ProfileTableModel::getJumpCall(const QModelIndex & index) const {
James Bentonfc4f55a2012-08-08 17:09:07 +0100126 const ProfileTableRow& row = m_rowData[index.row()];
127
128 switch(index.column()) {
129 case COLUMN_GPU_TIME:
130 case COLUMN_GPU_AVERAGE:
131 return row.longestGpu;
132 case COLUMN_CPU_TIME:
133 case COLUMN_CPU_AVERAGE:
134 return row.longestCpu;
135 case COLUMN_PIXELS_DRAWN:
136 case COLUMN_PIXELS_AVERAGE:
137 return row.longestPixel;
138 }
139
140 return NULL;
141}
142
143
144ProfileTableRow* ProfileTableModel::getRow(unsigned program) {
145 for (QList<ProfileTableRow>::iterator itr = m_rowData.begin(); itr != m_rowData.end(); ++itr) {
146 if (itr->program == program)
147 return &*itr;
148 }
149
James Benton56ad11c2012-08-16 13:44:19 +0100150 m_rowData.append(ProfileTableRow(program));
151 return &m_rowData.back();
James Bentonfc4f55a2012-08-08 17:09:07 +0100152}
153
154
155int ProfileTableModel::rowCount(const QModelIndex & parent) const
156{
157 if (!parent.isValid()) {
158 return m_rowData.size();
159 } else {
160 return 0;
161 }
162}
163
164
165int ProfileTableModel::columnCount(const QModelIndex & /*parent*/) const
166{
167 return MAX_COLUMN;
168}
169
170
171QVariant ProfileTableModel::data(const QModelIndex &index, int role) const
172{
173 if (!index.isValid()) {
174 return QVariant();
175 }
176
177 if (role == Qt::DisplayRole) {
178 const ProfileTableRow& row = m_rowData[index.row()];
179
180 switch(index.column()) {
181 case COLUMN_PROGRAM:
182 return row.program;
183 case COLUMN_USAGES:
James Benton902626c2012-08-22 12:18:09 +0100184 return QLocale::system().toString(row.uses);
James Bentonfc4f55a2012-08-08 17:09:07 +0100185 case COLUMN_GPU_TIME:
James Benton902626c2012-08-22 12:18:09 +0100186 return getTimeString(row.gpuTime);
James Bentonfc4f55a2012-08-08 17:09:07 +0100187 case COLUMN_CPU_TIME:
James Benton902626c2012-08-22 12:18:09 +0100188 return getTimeString(row.cpuTime);
James Bentonfc4f55a2012-08-08 17:09:07 +0100189 case COLUMN_PIXELS_DRAWN:
James Benton902626c2012-08-22 12:18:09 +0100190 return QLocale::system().toString((qlonglong)row.pixels);
James Bentonfc4f55a2012-08-08 17:09:07 +0100191 case COLUMN_GPU_AVERAGE:
James Benton902626c2012-08-22 12:18:09 +0100192 return getTimeString((row.uses <= 0) ? 0 : (row.gpuTime / row.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100193 case COLUMN_CPU_AVERAGE:
James Benton902626c2012-08-22 12:18:09 +0100194 return getTimeString((row.uses <= 0) ? 0 : (row.cpuTime / row.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100195 case COLUMN_PIXELS_AVERAGE:
James Benton902626c2012-08-22 12:18:09 +0100196 return QLocale::system().toString((row.uses <= 0) ? 0 : (row.pixels / row.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100197 }
198 } else if (role == Qt::TextAlignmentRole) {
199 return Qt::AlignRight;
200 }
201
202 return QVariant();
203}
204
205
206QVariant ProfileTableModel::headerData(int section, Qt::Orientation orientation, int role) const
207{
208 if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
209 if (section >= 0 && section < MAX_COLUMN) {
210 return columnNames[section];
211 }
212 }
213
214 return QVariant();
215}
216
217
218class ProgramSorter {
219public:
220 ProgramSorter(int column, Qt::SortOrder order)
221 : mSortColumn(column),
222 mSortOrder(order)
223 {
224 }
225
226 bool operator()(const ProfileTableRow &p1, const ProfileTableRow &p2) const
227 {
228 bool result = true;
229
230 switch(mSortColumn) {
231 case COLUMN_PROGRAM:
232 result = p1.program < p2.program;
233 break;
234 case COLUMN_USAGES:
235 result = p1.uses < p2.uses;
236 break;
237 case COLUMN_GPU_TIME:
238 result = p1.gpuTime < p2.gpuTime;
239 break;
240 case COLUMN_CPU_TIME:
241 result = p1.cpuTime < p2.cpuTime;
242 break;
243 case COLUMN_PIXELS_DRAWN:
244 result = p1.pixels < p2.pixels;
245 break;
246 case COLUMN_GPU_AVERAGE:
James Benton08717052012-08-08 17:43:52 +0100247 result = ((p1.uses <= 0) ? 0 : (p1.gpuTime / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.gpuTime / p2.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100248 break;
249 case COLUMN_CPU_AVERAGE:
James Benton08717052012-08-08 17:43:52 +0100250 result = ((p1.uses <= 0) ? 0 : (p1.cpuTime / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.cpuTime / p2.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100251 break;
252 case COLUMN_PIXELS_AVERAGE:
James Benton08717052012-08-08 17:43:52 +0100253 result = ((p1.uses <= 0) ? 0 : (p1.pixels / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.pixels / p2.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100254 break;
255 }
256
257 if (mSortOrder == Qt::DescendingOrder) {
258 return !result;
259 } else {
260 return result;
261 }
262 }
263
264private:
265 int mSortColumn;
266 Qt::SortOrder mSortOrder;
267};
268
269
270void ProfileTableModel::sort(int column, Qt::SortOrder order) {
271 m_sortColumn = column;
272 m_sortOrder = order;
273 qSort(m_rowData.begin(), m_rowData.end(), ProgramSorter(column, order));
274 emit dataChanged(createIndex(0, 0), createIndex(m_rowData.size(), MAX_COLUMN));
275}
276
277
278#include "profiletablemodel.moc"