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