blob: a305709fa9c9c1cf9903894e574b8c9ea317654e [file] [log] [blame]
James Bentonfc4f55a2012-08-08 17:09:07 +01001#include "profiletablemodel.h"
2
James Benton4c4896f2012-08-22 12:11:37 +01003typedef trace::Profile::Call Call;
James Bentonfc4f55a2012-08-08 17:09:07 +01004typedef trace::Profile::Frame Frame;
James Benton56ad11c2012-08-16 13:44:19 +01005typedef trace::Profile::Program Program;
James Bentonfc4f55a2012-08-08 17:09:07 +01006
7enum {
8 COLUMN_PROGRAM,
9 COLUMN_USAGES,
10 COLUMN_GPU_TIME,
11 COLUMN_CPU_TIME,
12 COLUMN_PIXELS_DRAWN,
13 COLUMN_GPU_AVERAGE,
14 COLUMN_CPU_AVERAGE,
15 COLUMN_PIXELS_AVERAGE,
16 MAX_COLUMN
17};
18
19static QString columnNames[] = {
20 QString("Program"),
21 QString("Calls"),
22 QString("Total GPU Time"),
23 QString("Total CPU Time"),
24 QString("Total Pixels Drawn"),
25 QString("Avg GPU Time"),
26 QString("Avg CPU Time"),
27 QString("Avg Pixels Drawn")
28};
29
30ProfileTableModel::ProfileTableModel(QObject *parent)
31 : QAbstractTableModel(parent),
32 m_profile(0),
33 m_sortColumn(COLUMN_GPU_TIME),
34 m_sortOrder(Qt::DescendingOrder)
35{
36}
37
38
39void ProfileTableModel::setProfile(trace::Profile* profile)
40{
41 m_profile = profile;
James Benton56ad11c2012-08-16 13:44:19 +010042 m_timeMin = m_profile->frames.front().cpuStart;
43 m_timeMax = m_profile->frames.back().cpuStart + m_profile->frames.back().cpuDuration;
James Bentonfc4f55a2012-08-08 17:09:07 +010044 updateModel();
45}
46
47
48void ProfileTableModel::setTimeSelection(int64_t start, int64_t end)
49{
50 m_timeMin = start;
51 m_timeMax = end;
52 updateModel();
53 sort(m_sortColumn, m_sortOrder);
54}
55
56
57/**
58 * Creates the row data from trace profile
59 */
60void ProfileTableModel::updateModel()
61{
62 if (m_timeMin == m_timeMax) {
James Benton56ad11c2012-08-16 13:44:19 +010063 m_timeMin = m_profile->frames.front().cpuStart;
64 m_timeMax = m_profile->frames.back().cpuStart + m_profile->frames.back().cpuDuration;
James Bentonfc4f55a2012-08-08 17:09:07 +010065 }
66
67 for (QList<ProfileTableRow>::iterator itr = m_rowData.begin(); itr != m_rowData.end(); ++itr) {
68 ProfileTableRow& row = *itr;
69
70 row.uses = 0;
71 row.pixels = 0;
72 row.gpuTime = 0;
73 row.cpuTime = 0;
74 row.longestCpu = NULL;
75 row.longestGpu = NULL;
76 row.longestPixel = NULL;
77 }
78
James Benton56ad11c2012-08-16 13:44:19 +010079 for (std::vector<Program>::const_iterator itr = m_profile->programs.begin(); itr != m_profile->programs.end(); ++itr) {
James Benton4c4896f2012-08-22 12:11:37 +010080 ProfileTableRow* row = NULL;
James Benton56ad11c2012-08-16 13:44:19 +010081 const Program& program = *itr;
James Bentonfc4f55a2012-08-08 17:09:07 +010082
James Benton4c4896f2012-08-22 12:11:37 +010083 for (std::vector<unsigned>::const_iterator jtr = program.calls.begin(); jtr != program.calls.end(); ++jtr) {
84 const Call& call = m_profile->calls[*jtr];
James Bentonfc4f55a2012-08-08 17:09:07 +010085
James Benton56ad11c2012-08-16 13:44:19 +010086 if (call.cpuStart > m_timeMax) {
James Bentonfc4f55a2012-08-08 17:09:07 +010087 break;
88 }
89
James Benton56ad11c2012-08-16 13:44:19 +010090 if (call.cpuStart + call.cpuDuration < m_timeMin) {
James Bentonfc4f55a2012-08-08 17:09:07 +010091 continue;
92 }
93
James Benton4c4896f2012-08-22 12:11:37 +010094 if (!row) {
95 row = getRow(itr - m_profile->programs.begin());
96 }
97
James Bentonfc4f55a2012-08-08 17:09:07 +010098 row->uses++;
James Benton56ad11c2012-08-16 13:44:19 +010099 row->pixels += call.pixels;
James Bentonfc4f55a2012-08-08 17:09:07 +0100100 row->gpuTime += call.gpuDuration;
101 row->cpuTime += call.cpuDuration;
James Bentonfc4f55a2012-08-08 17:09:07 +0100102
103 if (!row->longestGpu || row->longestGpu->gpuDuration < call.gpuDuration) {
104 row->longestGpu = &call;
105 }
106
107 if (!row->longestCpu || row->longestCpu->cpuDuration < call.cpuDuration) {
108 row->longestCpu = &call;
109 }
110
111 if (!row->longestPixel || row->longestPixel->pixels < call.pixels) {
112 row->longestPixel = &call;
113 }
114 }
115 }
116}
117
118
119/**
120 * Get the appropriate call associated with an item in the table
121 */
James Benton4c4896f2012-08-22 12:11:37 +0100122const trace::Profile::Call *ProfileTableModel::getJumpCall(const QModelIndex & index) const {
James Bentonfc4f55a2012-08-08 17:09:07 +0100123 const ProfileTableRow& row = m_rowData[index.row()];
124
125 switch(index.column()) {
126 case COLUMN_GPU_TIME:
127 case COLUMN_GPU_AVERAGE:
128 return row.longestGpu;
129 case COLUMN_CPU_TIME:
130 case COLUMN_CPU_AVERAGE:
131 return row.longestCpu;
132 case COLUMN_PIXELS_DRAWN:
133 case COLUMN_PIXELS_AVERAGE:
134 return row.longestPixel;
135 }
136
137 return NULL;
138}
139
140
141ProfileTableRow* ProfileTableModel::getRow(unsigned program) {
142 for (QList<ProfileTableRow>::iterator itr = m_rowData.begin(); itr != m_rowData.end(); ++itr) {
143 if (itr->program == program)
144 return &*itr;
145 }
146
James Benton56ad11c2012-08-16 13:44:19 +0100147 m_rowData.append(ProfileTableRow(program));
148 return &m_rowData.back();
James Bentonfc4f55a2012-08-08 17:09:07 +0100149}
150
151
152int ProfileTableModel::rowCount(const QModelIndex & parent) const
153{
154 if (!parent.isValid()) {
155 return m_rowData.size();
156 } else {
157 return 0;
158 }
159}
160
161
162int ProfileTableModel::columnCount(const QModelIndex & /*parent*/) const
163{
164 return MAX_COLUMN;
165}
166
167
168QVariant ProfileTableModel::data(const QModelIndex &index, int role) const
169{
170 if (!index.isValid()) {
171 return QVariant();
172 }
173
174 if (role == Qt::DisplayRole) {
175 const ProfileTableRow& row = m_rowData[index.row()];
176
177 switch(index.column()) {
178 case COLUMN_PROGRAM:
179 return row.program;
180 case COLUMN_USAGES:
181 return row.uses;
182 case COLUMN_GPU_TIME:
183 return row.gpuTime;
184 case COLUMN_CPU_TIME:
185 return row.cpuTime;
186 case COLUMN_PIXELS_DRAWN:
187 return row.pixels;
188 case COLUMN_GPU_AVERAGE:
189 return (row.uses <= 0) ? 0 : (row.gpuTime / row.uses);
190 case COLUMN_CPU_AVERAGE:
191 return (row.uses <= 0) ? 0 : (row.cpuTime / row.uses);
192 case COLUMN_PIXELS_AVERAGE:
193 return (row.uses <= 0) ? 0 : (row.pixels / row.uses);
194 }
195 } else if (role == Qt::TextAlignmentRole) {
196 return Qt::AlignRight;
197 }
198
199 return QVariant();
200}
201
202
203QVariant ProfileTableModel::headerData(int section, Qt::Orientation orientation, int role) const
204{
205 if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
206 if (section >= 0 && section < MAX_COLUMN) {
207 return columnNames[section];
208 }
209 }
210
211 return QVariant();
212}
213
214
215class ProgramSorter {
216public:
217 ProgramSorter(int column, Qt::SortOrder order)
218 : mSortColumn(column),
219 mSortOrder(order)
220 {
221 }
222
223 bool operator()(const ProfileTableRow &p1, const ProfileTableRow &p2) const
224 {
225 bool result = true;
226
227 switch(mSortColumn) {
228 case COLUMN_PROGRAM:
229 result = p1.program < p2.program;
230 break;
231 case COLUMN_USAGES:
232 result = p1.uses < p2.uses;
233 break;
234 case COLUMN_GPU_TIME:
235 result = p1.gpuTime < p2.gpuTime;
236 break;
237 case COLUMN_CPU_TIME:
238 result = p1.cpuTime < p2.cpuTime;
239 break;
240 case COLUMN_PIXELS_DRAWN:
241 result = p1.pixels < p2.pixels;
242 break;
243 case COLUMN_GPU_AVERAGE:
James Benton08717052012-08-08 17:43:52 +0100244 result = ((p1.uses <= 0) ? 0 : (p1.gpuTime / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.gpuTime / p2.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100245 break;
246 case COLUMN_CPU_AVERAGE:
James Benton08717052012-08-08 17:43:52 +0100247 result = ((p1.uses <= 0) ? 0 : (p1.cpuTime / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.cpuTime / p2.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100248 break;
249 case COLUMN_PIXELS_AVERAGE:
James Benton08717052012-08-08 17:43:52 +0100250 result = ((p1.uses <= 0) ? 0 : (p1.pixels / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.pixels / p2.uses));
James Bentonfc4f55a2012-08-08 17:09:07 +0100251 break;
252 }
253
254 if (mSortOrder == Qt::DescendingOrder) {
255 return !result;
256 } else {
257 return result;
258 }
259 }
260
261private:
262 int mSortColumn;
263 Qt::SortOrder mSortOrder;
264};
265
266
267void ProfileTableModel::sort(int column, Qt::SortOrder order) {
268 m_sortColumn = column;
269 m_sortOrder = order;
270 qSort(m_rowData.begin(), m_rowData.end(), ProgramSorter(column, order));
271 emit dataChanged(createIndex(0, 0), createIndex(m_rowData.size(), MAX_COLUMN));
272}
273
274
275#include "profiletablemodel.moc"