blob: 0f5f4bb9f7046a5d6f7cfd9a2328105aa721f429 [file] [log] [blame]
Zack Rusin91065372011-03-26 01:54:10 -04001#include "apitracecall.h"
2
Zack Rusin661842d2011-04-17 01:59:16 -04003#include "apitrace.h"
Zack Rusinebf971e2011-09-06 17:44:43 -04004#include "traceloader.h"
Zack Rusin91065372011-03-26 01:54:10 -04005#include "trace_model.hpp"
6
7#include <QDebug>
Zack Rusin9e292fc2011-04-26 23:03:42 -04008#include <QLocale>
Zack Rusin35451522011-04-02 23:44:53 -04009#include <QObject>
Zack Rusin5e277b02011-04-16 21:52:26 -040010#define QT_USE_FAST_OPERATOR_PLUS
11#include <QStringBuilder>
José Fonsecae8a1aa92011-04-21 09:13:23 +010012#include <QTextDocument>
Zack Rusin91065372011-03-26 01:54:10 -040013
Zack Rusinb53b1612011-04-19 01:33:58 -040014const char * const styleSheet =
15 ".call {\n"
16 " font-weight:bold;\n"
17 // text shadow looks great but doesn't work well in qtwebkit 4.7
18 " /*text-shadow: 0px 2px 3px #555;*/\n"
Zack Rusin5a74d3c2011-11-16 23:52:15 -050019 " font-size: 1.1em;\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040020 "}\n"
21 ".arg-name {\n"
22 " border: 1px solid rgb(238,206,0);\n"
23 " border-radius: 4px;\n"
24 " background: yellow;\n"
25 " padding: 2px;\n"
26 " box-shadow: 0px 1px 3px dimgrey;\n"
27 " -webkit-transition: background 1s linear;\n"
28 "}\n"
29 ".arg-name:hover {\n"
30 " background: white;\n"
31 "}\n"
32 ".arg-value {\n"
33 " color: #0000ff;\n"
34 "}\n"
Vladimir Vukicevica9c42472013-11-30 13:40:31 -050035 ".thread-id {\n"
36 " color: #aaaaaa;\n"
37 " min-width: 3em;\n"
38 "}\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040039 ".error {\n"
Zack Rusincc0b4912011-04-19 01:59:20 -040040 " border: 1px solid rgb(255,0,0);\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040041 " margin: 10px;\n"
Zack Rusincc0b4912011-04-19 01:59:20 -040042 " padding: 1;\n"
43 " border-radius: 4px;\n"
44 // also looks great but qtwebkit doesn't support it
45 //" background: #6fb2e5;\n"
46 //" box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
47 //" -o-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
48 //" -webkit-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
49 //" -moz-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040050 "}\n";
51
Zack Rusin91065372011-03-26 01:54:10 -040052
José Fonsecae8a1aa92011-04-21 09:13:23 +010053// Qt::convertFromPlainText doesn't do precisely what we want
54static QString
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -050055plainTextToHTML(const QString & plain, bool multiLine, bool forceNoQuote = false)
José Fonsecae8a1aa92011-04-21 09:13:23 +010056{
57 int col = 0;
58 bool quote = false;
59 QString rich;
Jose Fonseca010f9962016-03-05 14:45:41 +000060 for (auto & ch : plain) {
61 if (ch == QLatin1Char('\n')){
José Fonsecae8a1aa92011-04-21 09:13:23 +010062 if (multiLine) {
63 rich += QLatin1String("<br>\n");
64 } else {
65 rich += QLatin1String("\\n");
66 }
67 col = 0;
68 quote = true;
69 } else {
Jose Fonseca010f9962016-03-05 14:45:41 +000070 if (ch == QLatin1Char('\t')){
José Fonsecae8a1aa92011-04-21 09:13:23 +010071 if (multiLine) {
72 rich += QChar(0x00a0U);
73 ++col;
74 while (col % 8) {
75 rich += QChar(0x00a0U);
76 ++col;
77 }
78 } else {
79 rich += QLatin1String("\\t");
80 }
81 quote = true;
Jose Fonseca010f9962016-03-05 14:45:41 +000082 } else if (ch.isSpace()) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010083 rich += QChar(0x00a0U);
84 quote = true;
Jose Fonseca010f9962016-03-05 14:45:41 +000085 } else if (ch == QLatin1Char('<')) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010086 rich += QLatin1String("&lt;");
Jose Fonseca010f9962016-03-05 14:45:41 +000087 } else if (ch == QLatin1Char('>')) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010088 rich += QLatin1String("&gt;");
Jose Fonseca010f9962016-03-05 14:45:41 +000089 } else if (ch == QLatin1Char('&')) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010090 rich += QLatin1String("&amp;");
91 } else {
Jose Fonseca010f9962016-03-05 14:45:41 +000092 rich += ch;
José Fonsecae8a1aa92011-04-21 09:13:23 +010093 }
94 ++col;
95 }
96 }
97
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -050098 if (quote && !forceNoQuote) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010099 return QLatin1Literal("\"") + rich + QLatin1Literal("\"");
100 }
101
102 return rich;
103}
104
Zack Rusina1a3ad52011-08-27 19:19:18 -0400105QString
106apiVariantToString(const QVariant &variant, bool multiLine)
Zack Rusin91065372011-03-26 01:54:10 -0400107{
José Fonseca1fa61832011-11-05 08:50:25 +0000108 if (variant.isNull()) {
109 return QLatin1String("?");
110 }
111
José Fonsecaea4b99f2011-11-25 13:37:37 +0000112 if (variant.userType() == QMetaType::Float) {
Zack Rusin91065372011-03-26 01:54:10 -0400113 return QString::number(variant.toFloat());
114 }
José Fonsecaea4b99f2011-11-25 13:37:37 +0000115 if (variant.userType() == QVariant::Double) {
116 return QString::number(variant.toDouble());
117 }
Zack Rusin35451522011-04-02 23:44:53 -0400118 if (variant.userType() == QVariant::ByteArray) {
Zack Rusin8e7a4ff2011-04-07 01:15:48 -0400119 if (variant.toByteArray().size() < 1024) {
120 int bytes = variant.toByteArray().size();
121 return QObject::tr("[binary data, size = %1 bytes]").arg(bytes);
122 } else {
123 float kb = variant.toByteArray().size()/1024.;
124 return QObject::tr("[binary data, size = %1 kb]").arg(kb);
125 }
Zack Rusin35451522011-04-02 23:44:53 -0400126 }
Zack Rusin91065372011-03-26 01:54:10 -0400127
José Fonsecae8a1aa92011-04-21 09:13:23 +0100128 if (variant.userType() == QVariant::String) {
129 return plainTextToHTML(variant.toString(), multiLine);
130 }
131
Zack Rusin91065372011-03-26 01:54:10 -0400132 if (variant.userType() < QVariant::UserType) {
133 return variant.toString();
134 }
135
136 if (variant.canConvert<ApiPointer>()) {
137 return variant.value<ApiPointer>().toString();
138 }
139 if (variant.canConvert<ApiBitmask>()) {
140 return variant.value<ApiBitmask>().toString();
141 }
142 if (variant.canConvert<ApiStruct>()) {
José Fonsecaa596a9e2011-09-27 10:19:28 +0100143 return variant.value<ApiStruct>().toString(multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400144 }
145 if (variant.canConvert<ApiArray>()) {
José Fonsecaa596a9e2011-09-27 10:19:28 +0100146 return variant.value<ApiArray>().toString(multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400147 }
Zack Rusind54055e2011-04-17 18:27:28 -0400148 if (variant.canConvert<ApiEnum>()) {
149 return variant.value<ApiEnum>().toString();
150 }
Zack Rusin91065372011-03-26 01:54:10 -0400151
152 return QString();
153}
154
Zack Rusina1a3ad52011-08-27 19:19:18 -0400155
José Fonsecab4a3d142011-10-27 07:43:19 +0100156void VariantVisitor::visit(trace::Null *)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400157{
158 m_variant = QVariant::fromValue(ApiPointer(0));
159}
160
José Fonsecab4a3d142011-10-27 07:43:19 +0100161void VariantVisitor::visit(trace::Bool *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400162{
163 m_variant = QVariant(node->value);
164}
165
José Fonsecab4a3d142011-10-27 07:43:19 +0100166void VariantVisitor::visit(trace::SInt *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400167{
168 m_variant = QVariant(node->value);
169}
170
José Fonsecab4a3d142011-10-27 07:43:19 +0100171void VariantVisitor::visit(trace::UInt *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400172{
173 m_variant = QVariant(node->value);
174}
175
José Fonsecab4a3d142011-10-27 07:43:19 +0100176void VariantVisitor::visit(trace::Float *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400177{
178 m_variant = QVariant(node->value);
179}
180
Carl Worthe935ee12011-11-17 14:04:16 -0800181void VariantVisitor::visit(trace::Double *node)
182{
183 m_variant = QVariant(node->value);
184}
185
José Fonsecab4a3d142011-10-27 07:43:19 +0100186void VariantVisitor::visit(trace::String *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400187{
José Fonseca26e84ee2014-06-18 17:42:08 +0100188 m_variant = QVariant(QString::fromLatin1(node->value));
Zack Rusina1a3ad52011-08-27 19:19:18 -0400189}
190
José Fonsecad5cda7c2014-09-25 15:19:09 +0100191void VariantVisitor::visit(trace::WString *node)
192{
193 m_variant = QVariant(QString::fromWCharArray(node->value));
194}
195
José Fonsecab4a3d142011-10-27 07:43:19 +0100196void VariantVisitor::visit(trace::Enum *e)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400197{
José Fonseca446ca502014-12-19 16:22:39 +0000198 m_variant = QVariant::fromValue(ApiEnum(e->sig, e->value));
Zack Rusina1a3ad52011-08-27 19:19:18 -0400199}
200
José Fonsecab4a3d142011-10-27 07:43:19 +0100201void VariantVisitor::visit(trace::Bitmask *bitmask)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400202{
203 m_variant = QVariant::fromValue(ApiBitmask(bitmask));
204}
205
José Fonsecab4a3d142011-10-27 07:43:19 +0100206void VariantVisitor::visit(trace::Struct *str)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400207{
208 m_variant = QVariant::fromValue(ApiStruct(str));
209}
210
José Fonsecab4a3d142011-10-27 07:43:19 +0100211void VariantVisitor::visit(trace::Array *array)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400212{
213 m_variant = QVariant::fromValue(ApiArray(array));
214}
215
José Fonsecab4a3d142011-10-27 07:43:19 +0100216void VariantVisitor::visit(trace::Blob *blob)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400217{
Zack Rusin95237682011-09-27 12:04:10 -0400218 QByteArray barray = QByteArray(blob->buf, blob->size);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400219 m_variant = QVariant(barray);
220}
221
José Fonsecab4a3d142011-10-27 07:43:19 +0100222void VariantVisitor::visit(trace::Pointer *ptr)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400223{
224 m_variant = QVariant::fromValue(ApiPointer(ptr->value));
225}
226
José Fonseca112a1322012-04-27 17:15:32 +0100227void VariantVisitor::visit(trace::Repr *repr)
228{
229 /* TODO: Preserve both the human and machine value */
230 repr->humanValue->visit(*this);
231}
232
José Fonseca446ca502014-12-19 16:22:39 +0000233ApiEnum::ApiEnum(const trace::EnumSig *sig, signed long long value)
José Fonsecaeb644512011-12-11 10:33:55 +0000234 : m_sig(sig), m_value(value)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400235{
José Fonseca446ca502014-12-19 16:22:39 +0000236 Q_ASSERT(m_sig);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400237}
238
239QString ApiEnum::toString() const
240{
José Fonseca446ca502014-12-19 16:22:39 +0000241 Q_ASSERT(m_sig);
242
243 for (const trace::EnumValue *it = m_sig->values;
244 it != m_sig->values + m_sig->num_values; ++it) {
245 if (m_value == it->value) {
246 return QString::fromLatin1(it->name);
247 }
Zack Rusin35c27932011-08-28 21:16:22 -0400248 }
José Fonseca446ca502014-12-19 16:22:39 +0000249
250 return QString::fromLatin1("%1").arg(m_value);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400251}
252
253QVariant ApiEnum::value() const
254{
Zack Rusin35c27932011-08-28 21:16:22 -0400255 if (m_sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000256 return QVariant::fromValue(m_value);
Zack Rusin35c27932011-08-28 21:16:22 -0400257 }
258 Q_ASSERT(!"should never happen");
259 return QVariant();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400260}
261
Zack Rusina1a3ad52011-08-27 19:19:18 -0400262unsigned long long ApiBitmask::value() const
263{
264 return m_value;
265}
266
267ApiBitmask::Signature ApiBitmask::signature() const
268{
269 return m_sig;
270}
271
272ApiStruct::Signature ApiStruct::signature() const
273{
274 return m_sig;
275}
276
277QList<QVariant> ApiStruct::values() const
278{
279 return m_members;
280}
281
282ApiPointer::ApiPointer(unsigned long long val)
283 : m_value(val)
284{
285}
286
287
288unsigned long long ApiPointer::value() const
289{
290 return m_value;
291}
292
293QString ApiPointer::toString() const
294{
295 if (m_value)
296 return QString("0x%1").arg(m_value, 0, 16);
297 else
298 return QLatin1String("NULL");
299}
300
José Fonsecab4a3d142011-10-27 07:43:19 +0100301ApiBitmask::ApiBitmask(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400302 : m_value(0)
303{
304 init(bitmask);
305}
306
José Fonsecab4a3d142011-10-27 07:43:19 +0100307void ApiBitmask::init(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400308{
309 if (!bitmask)
310 return;
311
312 m_value = bitmask->value;
José Fonsecab4a3d142011-10-27 07:43:19 +0100313 for (const trace::BitmaskFlag *it = bitmask->sig->flags;
José Fonsecafcfbf172011-05-28 13:20:01 +0100314 it != bitmask->sig->flags + bitmask->sig->num_flags; ++it) {
Zack Rusin91065372011-03-26 01:54:10 -0400315 QPair<QString, unsigned long long> pair;
316
José Fonseca26e84ee2014-06-18 17:42:08 +0100317 pair.first = QString::fromLatin1(it->name);
José Fonseca31b183a2011-05-28 12:21:15 +0100318 pair.second = it->value;
Zack Rusin91065372011-03-26 01:54:10 -0400319
320 m_sig.append(pair);
321 }
322}
323
324QString ApiBitmask::toString() const
325{
326 QString str;
327 unsigned long long value = m_value;
328 bool first = true;
José Fonsecafc9939f2012-04-23 10:13:48 +0100329 for (Signature::const_iterator it = m_sig.begin(); it != m_sig.end(); ++it) {
330 Q_ASSERT(it->second || first);
331 if ((it->second && (value & it->second) == it->second) ||
332 (!it->second && value == 0)) {
Zack Rusin91065372011-03-26 01:54:10 -0400333 if (!first) {
334 str += QLatin1String(" | ");
335 }
336 str += it->first;
337 value &= ~it->second;
338 first = false;
339 }
José Fonsecafc9939f2012-04-23 10:13:48 +0100340 if (value == 0) {
341 break;
342 }
Zack Rusin91065372011-03-26 01:54:10 -0400343 }
344 if (value || first) {
345 if (!first) {
346 str += QLatin1String(" | ");
347 }
348 str += QString::fromLatin1("0x%1").arg(value, 0, 16);
349 }
350 return str;
351}
352
José Fonsecab4a3d142011-10-27 07:43:19 +0100353ApiStruct::ApiStruct(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400354{
355 init(s);
356}
357
José Fonsecaa596a9e2011-09-27 10:19:28 +0100358QString ApiStruct::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400359{
360 QString str;
361
362 str += QLatin1String("{");
363 for (unsigned i = 0; i < m_members.count(); ++i) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400364 str += m_sig.memberNames[i] %
365 QLatin1Literal(" = ") %
José Fonsecaa596a9e2011-09-27 10:19:28 +0100366 apiVariantToString(m_members[i], multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400367 if (i < m_members.count() - 1)
368 str += QLatin1String(", ");
369 }
370 str += QLatin1String("}");
371
372 return str;
373}
374
José Fonsecab4a3d142011-10-27 07:43:19 +0100375void ApiStruct::init(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400376{
377 if (!s)
378 return;
379
José Fonseca26e84ee2014-06-18 17:42:08 +0100380 m_sig.name = QString::fromLatin1(s->sig->name);
José Fonseca1b23ed22011-05-28 13:01:16 +0100381 for (unsigned i = 0; i < s->sig->num_members; ++i) {
José Fonseca446ca502014-12-19 16:22:39 +0000382 VariantVisitor vis;
Zack Rusin91065372011-03-26 01:54:10 -0400383 m_sig.memberNames.append(
José Fonseca26e84ee2014-06-18 17:42:08 +0100384 QString::fromLatin1(s->sig->member_names[i]));
Zack Rusin91065372011-03-26 01:54:10 -0400385 s->members[i]->visit(vis);
386 m_members.append(vis.variant());
387 }
388}
389
José Fonsecab4a3d142011-10-27 07:43:19 +0100390ApiArray::ApiArray(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400391{
392 init(arr);
393}
394
Zack Rusin77ff98a2011-08-28 22:30:35 -0400395ApiArray::ApiArray(const QVector<QVariant> &vals)
Zack Rusinabb3fde2011-04-16 02:16:49 -0400396 : m_array(vals)
397{
398}
399
Zack Rusin77ff98a2011-08-28 22:30:35 -0400400QVector<QVariant> ApiArray::values() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400401{
402 return m_array;
403}
404
José Fonsecaa596a9e2011-09-27 10:19:28 +0100405QString ApiArray::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400406{
407 QString str;
408 str += QLatin1String("[");
409 for(int i = 0; i < m_array.count(); ++i) {
410 const QVariant &var = m_array[i];
José Fonsecaa596a9e2011-09-27 10:19:28 +0100411 str += apiVariantToString(var, multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400412 if (i < m_array.count() - 1)
413 str += QLatin1String(", ");
414 }
415 str += QLatin1String("]");
416
417 return str;
418}
419
José Fonsecab4a3d142011-10-27 07:43:19 +0100420void ApiArray::init(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400421{
422 if (!arr)
423 return;
424
Zack Rusin3c70dbf2011-08-28 03:10:01 -0400425 m_array.reserve(arr->values.size());
Jose Fonseca010f9962016-03-05 14:45:41 +0000426 for (auto & value : arr->values) {
José Fonseca446ca502014-12-19 16:22:39 +0000427 VariantVisitor vis;
Jose Fonseca010f9962016-03-05 14:45:41 +0000428 value->visit(vis);
Zack Rusin91065372011-03-26 01:54:10 -0400429
430 m_array.append(vis.variant());
431 }
Zack Rusin77ff98a2011-08-28 22:30:35 -0400432 m_array.squeeze();
Zack Rusin91065372011-03-26 01:54:10 -0400433}
Zack Rusin18eade52011-03-26 14:23:35 -0400434
Zack Rusina1a3ad52011-08-27 19:19:18 -0400435ApiTraceState::ApiTraceState()
436{
437}
438
Martin Schulze638ec442015-10-11 12:37:42 +0200439static ApiTexture getTextureFrom(QVariantMap const &image, QString label)
440{
441 QSize size(image[QLatin1String("__width__")].toInt(),
442 image[QLatin1String("__height__")].toInt());
443 QString cls = image[QLatin1String("__class__")].toString();
444 int depth =
445 image[QLatin1String("__depth__")].toInt();
446 QString formatName =
447 image[QLatin1String("__format__")].toString();
448
449 QByteArray dataArray =
450 image[QLatin1String("__data__")].toByteArray();
451
452 QString userLabel =
453 image[QLatin1String("__label__")].toString();
454 if (!userLabel.isEmpty()) {
455 label += QString(", \"%1\"").arg(userLabel);
456 }
457
458 ApiTexture tex;
459 tex.setSize(size);
460 tex.setDepth(depth);
461 tex.setFormatName(formatName);
462 tex.setLabel(label);
463 tex.setData(dataArray);
464 return tex;
465}
466
Zack Rusina1a3ad52011-08-27 19:19:18 -0400467ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
468{
469 m_parameters = parsedJson[QLatin1String("parameters")].toMap();
470 QVariantMap attachedShaders =
471 parsedJson[QLatin1String("shaders")].toMap();
472 QVariantMap::const_iterator itr;
473
474
475 for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd();
476 ++itr) {
477 QString type = itr.key();
478 QString source = itr.value().toString();
479 m_shaderSources[type] = source;
480 }
481
482 m_uniforms = parsedJson[QLatin1String("uniforms")].toMap();
483
José Fonsecad1d1ecf2014-10-22 23:55:16 +0100484 m_buffers = parsedJson[QLatin1String("buffers")].toMap();
485
Martin Schulze638ec442015-10-11 12:37:42 +0200486 {
487 QVariantMap textures =
488 parsedJson[QLatin1String("textures")].toMap();
489 for (itr = textures.constBegin(); itr != textures.constEnd(); ++itr) {
490 m_textures.append(getTextureFrom(itr.value().toMap(), itr.key()));
José Fonseca42ec5632015-02-06 22:43:05 +0000491 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400492 }
493
494 QVariantMap fbos =
495 parsedJson[QLatin1String("framebuffer")].toMap();
496 for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) {
497 QVariantMap buffer = itr.value().toMap();
498 QSize size(buffer[QLatin1String("__width__")].toInt(),
499 buffer[QLatin1String("__height__")].toInt());
500 QString cls = buffer[QLatin1String("__class__")].toString();
Zack Rusinb25c4b92011-11-16 22:43:34 -0500501 int depth = buffer[QLatin1String("__depth__")].toInt();
Zack Rusine181b992011-11-17 16:00:41 -0500502 QString formatName = buffer[QLatin1String("__format__")].toString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400503
Zack Rusina1a3ad52011-08-27 19:19:18 -0400504 QByteArray dataArray =
505 buffer[QLatin1String("__data__")].toByteArray();
506
José Fonseca42ec5632015-02-06 22:43:05 +0000507 QString label = itr.key();
508 QString userLabel =
509 buffer[QLatin1String("__label__")].toString();
510 if (!userLabel.isEmpty()) {
511 label += QString(", \"%1\"").arg(userLabel);
512 }
513
Zack Rusina1a3ad52011-08-27 19:19:18 -0400514 ApiFramebuffer fbo;
515 fbo.setSize(size);
Zack Rusinb25c4b92011-11-16 22:43:34 -0500516 fbo.setDepth(depth);
Zack Rusine181b992011-11-17 16:00:41 -0500517 fbo.setFormatName(formatName);
José Fonseca42ec5632015-02-06 22:43:05 +0000518 fbo.setType(label);
Jose Fonseca93a7c0c2015-05-27 20:52:51 +0100519 fbo.setData(dataArray);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400520 m_framebuffers.append(fbo);
521 }
522}
523
524const QVariantMap & ApiTraceState::parameters() const
525{
526 return m_parameters;
527}
528
529const QMap<QString, QString> & ApiTraceState::shaderSources() const
530{
531 return m_shaderSources;
532}
533
534const QVariantMap & ApiTraceState::uniforms() const
535{
536 return m_uniforms;
537}
538
José Fonsecad1d1ecf2014-10-22 23:55:16 +0100539const QVariantMap & ApiTraceState::buffers() const
540{
541 return m_buffers;
542}
543
Zack Rusina1a3ad52011-08-27 19:19:18 -0400544bool ApiTraceState::isEmpty() const
545{
José Fonseca4e0bfee2012-11-28 10:45:08 +0000546 return m_parameters.isEmpty() &&
547 m_shaderSources.isEmpty() &&
548 m_textures.isEmpty() &&
549 m_framebuffers.isEmpty();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400550}
551
552const QList<ApiTexture> & ApiTraceState::textures() const
553{
554 return m_textures;
555}
556
557const QList<ApiFramebuffer> & ApiTraceState::framebuffers() const
558{
559 return m_framebuffers;
560}
561
Zack Rusin353f0532011-09-15 20:23:27 -0400562ApiFramebuffer ApiTraceState::colorBuffer() const
563{
564 foreach (ApiFramebuffer fbo, m_framebuffers) {
565 if (fbo.type() == QLatin1String("GL_BACK")) {
566 return fbo;
567 }
568 }
569 foreach (ApiFramebuffer fbo, m_framebuffers) {
570 if (fbo.type() == QLatin1String("GL_FRONT")) {
571 return fbo;
572 }
573 }
574 return ApiFramebuffer();
575}
576
577
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400578ApiTraceCallSignature::ApiTraceCallSignature(const QString &name,
579 const QStringList &argNames)
580 : m_name(name),
581 m_argNames(argNames)
582{
583}
584
585ApiTraceCallSignature::~ApiTraceCallSignature()
586{
587}
588
589QUrl ApiTraceCallSignature::helpUrl() const
590{
591 return m_helpUrl;
592}
593
594void ApiTraceCallSignature::setHelpUrl(const QUrl &url)
595{
596 m_helpUrl = url;
597}
598
Zack Rusina1a3ad52011-08-27 19:19:18 -0400599ApiTraceEvent::ApiTraceEvent()
600 : m_type(ApiTraceEvent::None),
José Fonsecafb5df2a2014-12-19 16:45:32 +0000601 m_binaryDataIndex(-1),
Zack Rusined40bc62011-08-28 17:11:02 -0400602 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400603 m_staticText(0)
604{
605}
606
607ApiTraceEvent::ApiTraceEvent(Type t)
608 : m_type(t),
José Fonsecafb5df2a2014-12-19 16:45:32 +0000609 m_binaryDataIndex(-1),
Zack Rusined40bc62011-08-28 17:11:02 -0400610 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400611 m_staticText(0)
612{
José Fonsecafb5df2a2014-12-19 16:45:32 +0000613 Q_ASSERT(m_type == t);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400614}
615
616ApiTraceEvent::~ApiTraceEvent()
617{
Zack Rusined40bc62011-08-28 17:11:02 -0400618 delete m_state;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400619 delete m_staticText;
620}
621
Zack Rusined40bc62011-08-28 17:11:02 -0400622ApiTraceState *ApiTraceEvent::state() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400623{
624 return m_state;
625}
626
Zack Rusined40bc62011-08-28 17:11:02 -0400627void ApiTraceEvent::setState(ApiTraceState *state)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400628{
629 m_state = state;
630}
631
Dan McCabeb6b6d7c2012-06-01 13:40:02 -0700632void ApiTraceEvent::setThumbnail(const QImage & thumbnail)
633{
634 m_thumbnail = thumbnail;
635}
636
637const QImage & ApiTraceEvent::thumbnail() const
638{
639 return m_thumbnail;
640}
641
Zack Rusinebf971e2011-09-06 17:44:43 -0400642ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame,
643 TraceLoader *loader,
José Fonsecab4a3d142011-10-27 07:43:19 +0100644 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400645 : ApiTraceEvent(ApiTraceEvent::Call),
Zack Rusind9d9d222013-10-11 18:02:26 -0400646 m_parentFrame(parentFrame),
647 m_parentCall(0)
648{
649 loadData(loader, call);
650}
651
652ApiTraceCall::ApiTraceCall(ApiTraceCall *parentCall,
653 TraceLoader *loader,
654 const trace::Call *call)
655 : ApiTraceEvent(ApiTraceEvent::Call),
656 m_parentFrame(parentCall->parentFrame()),
657 m_parentCall(parentCall)
658{
659 loadData(loader, call);
660}
661
662
663ApiTraceCall::~ApiTraceCall()
664{
665}
666
667
668void
669ApiTraceCall::loadData(TraceLoader *loader,
670 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400671{
Zack Rusina1a3ad52011-08-27 19:19:18 -0400672 m_index = call->no;
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500673 m_thread = call->thread_id;
Zack Rusinebf971e2011-09-06 17:44:43 -0400674 m_signature = loader->signature(call->sig->id);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400675
676 if (!m_signature) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100677 QString name = QString::fromLatin1(call->sig->name);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400678 QStringList argNames;
Zack Rusinf22d7992011-08-28 02:23:47 -0400679 argNames.reserve(call->sig->num_args);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400680 for (int i = 0; i < call->sig->num_args; ++i) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100681 argNames += QString::fromLatin1(call->sig->arg_names[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400682 }
683 m_signature = new ApiTraceCallSignature(name, argNames);
Zack Rusinebf971e2011-09-06 17:44:43 -0400684 loader->addSignature(call->sig->id, m_signature);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400685 }
686 if (call->ret) {
José Fonseca446ca502014-12-19 16:22:39 +0000687 VariantVisitor retVisitor;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400688 call->ret->visit(retVisitor);
689 m_returnValue = retVisitor.variant();
690 }
Zack Rusinf22d7992011-08-28 02:23:47 -0400691 m_argValues.reserve(call->args.size());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400692 for (int i = 0; i < call->args.size(); ++i) {
Carl Wortha5b476e2011-11-16 17:22:40 -0800693 if (call->args[i].value) {
José Fonseca446ca502014-12-19 16:22:39 +0000694 VariantVisitor argVisitor;
Carl Wortha5b476e2011-11-16 17:22:40 -0800695 call->args[i].value->visit(argVisitor);
José Fonseca1fa61832011-11-05 08:50:25 +0000696 m_argValues.append(argVisitor.variant());
697 if (m_argValues[i].type() == QVariant::ByteArray) {
José Fonseca1fa61832011-11-05 08:50:25 +0000698 m_binaryDataIndex = i;
699 }
700 } else {
701 m_argValues.append(QVariant());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400702 }
703 }
Zack Rusinf736a622011-08-28 22:19:46 -0400704 m_argValues.squeeze();
José Fonseca340f5692011-11-30 07:04:44 +0000705 m_flags = call->flags;
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400706 if (call->backtrace != NULL) {
707 QString qbacktrace;
Jose Fonseca010f9962016-03-05 14:45:41 +0000708 for (auto frame : *call->backtrace) {
José Fonseca9c25e062013-05-06 07:25:40 +0100709 if (frame->module != NULL) {
710 qbacktrace += QString("%1 ").arg(frame->module);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400711 }
José Fonseca9c25e062013-05-06 07:25:40 +0100712 if (frame->function != NULL) {
713 qbacktrace += QString("at %1() ").arg(frame->function);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400714 }
José Fonseca9c25e062013-05-06 07:25:40 +0100715 if (frame->filename != NULL) {
716 qbacktrace += QString("at %1").arg(frame->filename);
717 if (frame->linenumber >= 0) {
718 qbacktrace += QString(":%1 ").arg(frame->linenumber);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400719 }
720 }
721 else {
José Fonseca9c25e062013-05-06 07:25:40 +0100722 if (frame->offset >= 0) {
723 qbacktrace += QString("[0x%1]").arg(frame->offset, 0, 16);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400724 }
725 }
726 qbacktrace += "\n";
727 }
728 this->setBacktrace(qbacktrace);
729 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400730}
731
Zack Rusind9d9d222013-10-11 18:02:26 -0400732ApiTraceCall *
733ApiTraceCall::parentCall() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400734{
Zack Rusind9d9d222013-10-11 18:02:26 -0400735 return m_parentCall;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400736}
737
738
Zack Rusind9d9d222013-10-11 18:02:26 -0400739ApiTraceEvent *
740ApiTraceCall::parentEvent() const
741{
742 if (m_parentCall)
743 return m_parentCall;
744 else
745 return m_parentFrame;
746}
747
748QVector<ApiTraceCall*>
749ApiTraceCall::children() const
750{
751 return m_children;
752}
753
754void
755ApiTraceCall::addChild(ApiTraceCall *call)
756{
757 m_children.append(call);
758}
759
760
761int
762ApiTraceCall::callIndex(ApiTraceCall *call) const
763{
764 return m_children.indexOf(call);
765}
766
767void
768ApiTraceCall::finishedAddingChildren()
769{
770 m_children.squeeze();
771}
772
Zack Rusina1a3ad52011-08-27 19:19:18 -0400773bool ApiTraceCall::hasError() const
774{
775 return !m_error.isEmpty();
776}
777
778QString ApiTraceCall::error() const
779{
780 return m_error;
781}
782
783void ApiTraceCall::setError(const QString &msg)
784{
785 if (m_error != msg) {
Zack Rusina1a3ad52011-08-27 19:19:18 -0400786 m_error = msg;
787 m_richText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400788 }
789}
790
791ApiTrace * ApiTraceCall::parentTrace() const
792{
793 if (m_parentFrame)
794 return m_parentFrame->parentTrace();
795 return NULL;
796}
797
Zack Rusinf736a622011-08-28 22:19:46 -0400798QVector<QVariant> ApiTraceCall::originalValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400799{
800 return m_argValues;
801}
802
Zack Rusinf736a622011-08-28 22:19:46 -0400803void ApiTraceCall::setEditedValues(const QVector<QVariant> &lst)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400804{
805 ApiTrace *trace = parentTrace();
806
807 m_editedValues = lst;
808 //lets regenerate data
809 m_richText = QString();
Zack Rusindc792082011-08-27 23:29:19 -0400810 m_searchText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400811 delete m_staticText;
812 m_staticText = 0;
813
814 if (trace) {
815 if (!lst.isEmpty()) {
816 trace->callEdited(this);
817 } else {
818 trace->callReverted(this);
819 }
820 }
821}
822
Zack Rusinf736a622011-08-28 22:19:46 -0400823QVector<QVariant> ApiTraceCall::editedValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400824{
825 return m_editedValues;
826}
827
828bool ApiTraceCall::edited() const
829{
830 return !m_editedValues.isEmpty();
831}
832
833void ApiTraceCall::revert()
834{
Zack Rusinf736a622011-08-28 22:19:46 -0400835 setEditedValues(QVector<QVariant>());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400836}
837
838void ApiTraceCall::setHelpUrl(const QUrl &url)
839{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400840 m_signature->setHelpUrl(url);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400841}
842
843void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
844{
845 m_parentFrame = frame;
846}
847
848ApiTraceFrame * ApiTraceCall::parentFrame()const
849{
850 return m_parentFrame;
851}
852
853int ApiTraceCall::index() const
854{
855 return m_index;
856}
857
858QString ApiTraceCall::name() const
859{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400860 return m_signature->name();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400861}
862
863QStringList ApiTraceCall::argNames() const
864{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400865 return m_signature->argNames();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400866}
867
Zack Rusinf736a622011-08-28 22:19:46 -0400868QVector<QVariant> ApiTraceCall::arguments() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400869{
870 if (m_editedValues.isEmpty())
871 return m_argValues;
872 else
873 return m_editedValues;
874}
875
Zack Rusind9d9d222013-10-11 18:02:26 -0400876ApiTraceEvent *
877ApiTraceCall::eventAtRow(int row) const
878{
879 if (row < m_children.count())
880 return m_children.value(row);
881 else
882 return NULL;
883}
884
Zack Rusina1a3ad52011-08-27 19:19:18 -0400885QVariant ApiTraceCall::returnValue() const
886{
887 return m_returnValue;
888}
889
José Fonseca340f5692011-11-30 07:04:44 +0000890trace::CallFlags ApiTraceCall::flags() const
891{
892 return m_flags;
893}
894
Zack Rusina1a3ad52011-08-27 19:19:18 -0400895QUrl ApiTraceCall::helpUrl() const
896{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400897 return m_signature->helpUrl();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400898}
899
900bool ApiTraceCall::hasBinaryData() const
901{
José Fonsecafb5df2a2014-12-19 16:45:32 +0000902 return m_binaryDataIndex >= 0;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400903}
904
905int ApiTraceCall::binaryDataIndex() const
906{
José Fonsecafb5df2a2014-12-19 16:45:32 +0000907 Q_ASSERT(hasBinaryData());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400908 return m_binaryDataIndex;
909}
910
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400911QString ApiTraceCall::backtrace() const
912{
913 return m_backtrace;
914}
915
916void ApiTraceCall::setBacktrace(QString backtrace)
917{
918 m_backtrace = backtrace;
919}
920
Zack Rusin18eade52011-03-26 14:23:35 -0400921QStaticText ApiTraceCall::staticText() const
922{
Zack Rusin53484b22011-04-16 11:56:19 -0400923 if (m_staticText && !m_staticText->text().isEmpty())
924 return *m_staticText;
Zack Rusin18eade52011-03-26 14:23:35 -0400925
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500926 QStringList argNames = m_signature->argNames();
Zack Rusinf736a622011-08-28 22:19:46 -0400927 QVector<QVariant> argValues = arguments();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400928
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500929 QString richText;
930
José Fonseca2258a6d2014-05-22 21:14:21 +0100931 // TODO: Toggle this via a menu option.
932 if (0) {
933 richText += QString::fromLatin1("<span style=\"color: #aaaaaa; min-width: 3em;\">@%1</span> ")
934 .arg(m_thread);
935 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500936
José Fonseca991723d2014-05-22 21:32:37 +0100937 if (m_flags & trace::CALL_FLAG_MARKER &&
938 argNames.count() &&
939 argValues.last().userType() == QVariant::String)
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500940 {
941 // special handling for string markers
José Fonseca991723d2014-05-22 21:32:37 +0100942 QString msgText = plainTextToHTML(argValues.last().toString(), false, true);
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500943 richText += QString::fromLatin1(
944 "<span style=\"font-weight:bold;color:green;\">%1</span>")
945 .arg(msgText);
946 } else {
947 richText += QString::fromLatin1(
948 "<span style=\"font-weight:bold\">%1</span>(").arg(
949 m_signature->name());
950 for (int i = 0; i < argNames.count(); ++i) {
951 richText += QLatin1String("<span style=\"color:#0000ff\">");
952 QString argText = apiVariantToString(argValues[i]);
953
954 //if arguments are really long (e.g. shader text), cut them
955 // and elide it
956 if (argText.length() > 40) {
957 QString shortened = argText.mid(0, 40);
958 shortened[argText.length() - 5] = '.';
959 shortened[argText.length() - 4] = '.';
960 shortened[argText.length() - 3] = '.';
961 shortened[argText.length() - 2] = argText.at(argText.length() - 2);
962 shortened[argText.length() - 1] = argText.at(argText.length() - 1);
963 richText += shortened;
964 } else {
965 richText += argText;
966 }
967 richText += QLatin1String("</span>");
968 if (i < argNames.count() - 1)
969 richText += QLatin1String(", ");
Zack Rusindd7f2302011-03-31 22:55:57 -0400970 }
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500971 richText += QLatin1String(")");
972 if (m_returnValue.isValid()) {
973 richText +=
974 QLatin1Literal(" = ") %
975 QLatin1Literal("<span style=\"color:#0000ff\">") %
976 apiVariantToString(m_returnValue) %
977 QLatin1Literal("</span>");
978 }
José Fonseca908f38d2011-03-31 10:09:14 +0100979 }
Zack Rusin27cb2c42011-03-27 23:53:36 -0400980
Zack Rusin53484b22011-04-16 11:56:19 -0400981 if (!m_staticText)
982 m_staticText = new QStaticText(richText);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400983 else
984 m_staticText->setText(richText);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400985 QTextOption opt;
986 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -0400987 m_staticText->setTextOption(opt);
988 m_staticText->prepare();
Zack Rusin27cb2c42011-03-27 23:53:36 -0400989
Zack Rusin53484b22011-04-16 11:56:19 -0400990 return *m_staticText;
Zack Rusin27cb2c42011-03-27 23:53:36 -0400991}
992
993QString ApiTraceCall::toHtml() const
994{
995 if (!m_richText.isEmpty())
996 return m_richText;
997
Zack Rusin5a74d3c2011-11-16 23:52:15 -0500998 m_richText += QLatin1String("<div class=\"call\">");
Zack Rusinb53b1612011-04-19 01:33:58 -0400999
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001000
1001 m_richText +=
José Fonseca2258a6d2014-05-22 21:14:21 +01001002 QString::fromLatin1("%1 ")
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001003 .arg(m_index);
1004 QString parentTip;
1005 if (m_parentFrame) {
1006 parentTip =
1007 QString::fromLatin1("Frame %1")
1008 .arg(m_parentFrame->number);
1009 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001010
José Fonseca2258a6d2014-05-22 21:14:21 +01001011 m_richText += QString::fromLatin1("<span class=\"thread-id\">@%1</span> ")
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001012 .arg(m_thread);
1013
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001014 QUrl helpUrl = m_signature->helpUrl();
1015 if (helpUrl.isEmpty()) {
Zack Rusinb53b1612011-04-19 01:33:58 -04001016 m_richText += QString::fromLatin1(
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001017 "<span class=\"callName\" title=\"%1\">%2</span>(")
1018 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001019 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001020 } else {
Zack Rusinb53b1612011-04-19 01:33:58 -04001021 m_richText += QString::fromLatin1(
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001022 "<span class=\"callName\" title=\"%1\"><a href=\"%2\">%3</a></span>(")
1023 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001024 .arg(helpUrl.toString())
1025 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001026 }
1027
Zack Rusinf736a622011-08-28 22:19:46 -04001028 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001029 QStringList argNames = m_signature->argNames();
1030 for (int i = 0; i < argNames.count(); ++i) {
Zack Rusinb53b1612011-04-19 01:33:58 -04001031 m_richText +=
1032 QLatin1String("<span class=\"arg-name\">") +
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001033 argNames[i] +
Zack Rusinb53b1612011-04-19 01:33:58 -04001034 QLatin1String("</span>") +
1035 QLatin1Literal(" = ") +
1036 QLatin1Literal("<span class=\"arg-value\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001037 apiVariantToString(argValues[i], true) +
Zack Rusinb53b1612011-04-19 01:33:58 -04001038 QLatin1Literal("</span>");
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001039 if (i < argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -04001040 m_richText += QLatin1String(", ");
Zack Rusin18eade52011-03-26 14:23:35 -04001041 }
1042 m_richText += QLatin1String(")");
1043
Zack Rusinead6aad2011-04-15 22:16:18 -04001044 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -04001045 m_richText +=
1046 QLatin1String(" = ") +
1047 QLatin1String("<span style=\"color:#0000ff\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001048 apiVariantToString(m_returnValue, true) +
Zack Rusin5e277b02011-04-16 21:52:26 -04001049 QLatin1String("</span>");
Zack Rusin18eade52011-03-26 14:23:35 -04001050 }
Zack Rusinb53b1612011-04-19 01:33:58 -04001051 m_richText += QLatin1String("</div>");
1052
Zack Rusincc0b4912011-04-19 01:59:20 -04001053 if (hasError()) {
1054 QString errorStr =
1055 QString::fromLatin1(
1056 "<div class=\"error\">%1</div>")
1057 .arg(m_error);
1058 m_richText += errorStr;
1059 }
1060
Zack Rusinb53b1612011-04-19 01:33:58 -04001061 m_richText =
1062 QString::fromLatin1(
1063 "<html><head><style type=\"text/css\" media=\"all\">"
1064 "%1</style></head><body>%2</body></html>")
1065 .arg(styleSheet)
1066 .arg(m_richText);
Zack Rusin5e277b02011-04-16 21:52:26 -04001067 m_richText.squeeze();
Zack Rusinb53b1612011-04-19 01:33:58 -04001068
1069 //qDebug()<<m_richText;
Zack Rusin18eade52011-03-26 14:23:35 -04001070 return m_richText;
1071}
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001072
Zack Rusindc792082011-08-27 23:29:19 -04001073QString ApiTraceCall::searchText() const
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001074{
Zack Rusindc792082011-08-27 23:29:19 -04001075 if (!m_searchText.isEmpty())
1076 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001077
Zack Rusinf736a622011-08-28 22:19:46 -04001078 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001079 m_searchText = m_signature->name() + QLatin1Literal("(");
1080 QStringList argNames = m_signature->argNames();
1081 for (int i = 0; i < argNames.count(); ++i) {
1082 m_searchText += argNames[i] +
Zack Rusin5e277b02011-04-16 21:52:26 -04001083 QLatin1Literal(" = ") +
Zack Rusin9af5bff2011-04-18 01:05:50 -04001084 apiVariantToString(argValues[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001085 if (i < argNames.count() - 1)
Zack Rusindc792082011-08-27 23:29:19 -04001086 m_searchText += QLatin1String(", ");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001087 }
Zack Rusindc792082011-08-27 23:29:19 -04001088 m_searchText += QLatin1String(")");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001089
Zack Rusinead6aad2011-04-15 22:16:18 -04001090 if (m_returnValue.isValid()) {
Zack Rusindc792082011-08-27 23:29:19 -04001091 m_searchText += QLatin1Literal(" = ") +
Zack Rusin5e277b02011-04-16 21:52:26 -04001092 apiVariantToString(m_returnValue);
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001093 }
Zack Rusindc792082011-08-27 23:29:19 -04001094 m_searchText.squeeze();
1095 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001096}
Zack Rusinf6667d12011-03-30 11:03:37 -04001097
Zack Rusina1a3ad52011-08-27 19:19:18 -04001098int ApiTraceCall::numChildren() const
1099{
Zack Rusind9d9d222013-10-11 18:02:26 -04001100 return m_children.count();
Zack Rusina1a3ad52011-08-27 19:19:18 -04001101}
1102
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001103bool ApiTraceCall::contains(const QString &str,
1104 Qt::CaseSensitivity sensitivity) const
1105{
1106 QString txt = searchText();
1107 return txt.contains(str, sensitivity);
1108}
1109
Dan McCabed1395322012-06-01 13:40:03 -07001110void ApiTraceCall::missingThumbnail()
1111{
1112 m_parentFrame->parentTrace()->missingThumbnail(this);
1113}
1114
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001115
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001116ApiTraceFrame::ApiTraceFrame(ApiTrace *parentTrace)
Zack Rusina1a3ad52011-08-27 19:19:18 -04001117 : ApiTraceEvent(ApiTraceEvent::Frame),
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001118 m_parentTrace(parentTrace),
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001119 m_binaryDataSize(0),
1120 m_loaded(false),
Zack Rusin851d0b02011-09-14 22:04:07 -04001121 m_callsToLoad(0),
1122 m_lastCallIndex(0)
Zack Rusina1a3ad52011-08-27 19:19:18 -04001123{
1124}
1125
Zack Rusinc1743432011-09-13 17:58:58 -04001126ApiTraceFrame::~ApiTraceFrame()
1127{
1128 qDeleteAll(m_calls);
1129}
1130
Zack Rusinf6667d12011-03-30 11:03:37 -04001131QStaticText ApiTraceFrame::staticText() const
1132{
Zack Rusin53484b22011-04-16 11:56:19 -04001133 if (m_staticText && !m_staticText->text().isEmpty())
1134 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -04001135
Zack Rusin45e094f2011-09-14 17:36:53 -04001136 QString richText = QObject::tr(
1137 "<span style=\"font-weight:bold\">Frame %1</span>"
1138 "&nbsp;&nbsp;&nbsp;"
1139 "<span style=\"font-style:italic;font-size:small;font-weight:lighter;\"> "
1140 "(%2 calls)</span>")
1141 .arg(number)
1142 .arg(m_loaded ? m_calls.count() : m_callsToLoad);
Zack Rusin9e292fc2011-04-26 23:03:42 -04001143
1144 //mark the frame if it uploads more than a meg a frame
1145 if (m_binaryDataSize > (1024*1024)) {
1146 richText =
1147 QObject::tr(
Zack Rusin45e094f2011-09-14 17:36:53 -04001148 "%1"
Zack Rusin9e292fc2011-04-26 23:03:42 -04001149 "<span style=\"font-style:italic;\">"
1150 "&nbsp;&nbsp;&nbsp;&nbsp;(%2MB)</span>")
Zack Rusin45e094f2011-09-14 17:36:53 -04001151 .arg(richText)
Zack Rusin9e292fc2011-04-26 23:03:42 -04001152 .arg(double(m_binaryDataSize / (1024.*1024.)), 0, 'g', 2);
Zack Rusin9e292fc2011-04-26 23:03:42 -04001153 }
Zack Rusinf6667d12011-03-30 11:03:37 -04001154
Zack Rusin53484b22011-04-16 11:56:19 -04001155 if (!m_staticText)
1156 m_staticText = new QStaticText(richText);
1157
Zack Rusinf6667d12011-03-30 11:03:37 -04001158 QTextOption opt;
1159 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -04001160 m_staticText->setTextOption(opt);
1161 m_staticText->prepare();
Zack Rusinf6667d12011-03-30 11:03:37 -04001162
Zack Rusin53484b22011-04-16 11:56:19 -04001163 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -04001164}
1165
Zack Rusinf6667d12011-03-30 11:03:37 -04001166int ApiTraceFrame::numChildren() const
1167{
Zack Rusind9d9d222013-10-11 18:02:26 -04001168 return m_children.count();
1169}
1170
1171int ApiTraceFrame::numTotalCalls() const
1172{
Zack Rusin3176ebe2011-09-06 21:11:36 -04001173 return m_calls.count();
Zack Rusinf6667d12011-03-30 11:03:37 -04001174}
1175
Zack Rusin7c1793e2011-04-16 23:14:25 -04001176ApiTrace * ApiTraceFrame::parentTrace() const
1177{
1178 return m_parentTrace;
1179}
1180
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001181QVector<ApiTraceCall*> ApiTraceFrame::calls() const
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001182{
1183 return m_calls;
1184}
1185
Zack Rusind9d9d222013-10-11 18:02:26 -04001186ApiTraceEvent * ApiTraceFrame::eventAtRow(int row) const
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001187{
Zack Rusind9d9d222013-10-11 18:02:26 -04001188 if (row < m_children.count())
1189 return m_children.value(row);
1190 else
1191 return NULL;
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001192}
1193
Zack Rusinda7579b2011-09-13 17:33:05 -04001194
1195ApiTraceCall * ApiTraceFrame::callWithIndex(int index) const
1196{
1197 QVector<ApiTraceCall*>::const_iterator itr;
1198 for (itr = m_calls.constBegin(); itr != m_calls.constEnd(); ++itr) {
1199 if ((*itr)->index() == index) {
1200 return *itr;
1201 }
1202 }
1203 return 0;
1204}
1205
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001206int ApiTraceFrame::callIndex(ApiTraceCall *call) const
1207{
Zack Rusind9d9d222013-10-11 18:02:26 -04001208 return m_children.indexOf(call);
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001209}
1210
1211bool ApiTraceFrame::isEmpty() const
1212{
Zack Rusin3176ebe2011-09-06 21:11:36 -04001213 if (m_loaded) {
1214 return m_calls.isEmpty();
1215 } else {
1216 return m_callsToLoad == 0;
1217 }
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001218}
1219
Zack Rusin9e292fc2011-04-26 23:03:42 -04001220int ApiTraceFrame::binaryDataSize() const
1221{
1222 return m_binaryDataSize;
1223}
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001224
Zack Rusind9d9d222013-10-11 18:02:26 -04001225void ApiTraceFrame::setCalls(const QVector<ApiTraceCall*> &children,
1226 const QVector<ApiTraceCall*> &calls,
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001227 quint64 binaryDataSize)
1228{
Zack Rusind9d9d222013-10-11 18:02:26 -04001229 m_children = children;
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001230 m_calls = calls;
1231 m_binaryDataSize = binaryDataSize;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001232 m_loaded = true;
Zack Rusin45e094f2011-09-14 17:36:53 -04001233 delete m_staticText;
1234 m_staticText = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001235}
1236
Zack Rusin1a9f7af2011-09-18 19:40:47 -04001237bool ApiTraceFrame::isLoaded() const
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001238{
1239 return m_loaded;
1240}
1241
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001242void ApiTraceFrame::setNumChildren(int num)
1243{
1244 m_callsToLoad = num;
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001245}
Zack Rusinebf971e2011-09-06 17:44:43 -04001246
1247void ApiTraceFrame::setParentTrace(ApiTrace *parent)
1248{
1249 m_parentTrace = parent;
1250}
Zack Rusin3176ebe2011-09-06 21:11:36 -04001251
1252int ApiTraceFrame::numChildrenToLoad() const
1253{
1254 return m_callsToLoad;
1255}
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001256
1257ApiTraceCall *
1258ApiTraceFrame::findNextCall(ApiTraceCall *from,
1259 const QString &str,
1260 Qt::CaseSensitivity sensitivity) const
1261{
1262 Q_ASSERT(m_loaded);
1263
1264 int callIndex = 0;
1265
1266 if (from) {
1267 callIndex = m_calls.indexOf(from) + 1;
1268 }
1269
1270 for (int i = callIndex; i < m_calls.count(); ++i) {
1271 ApiTraceCall *call = m_calls[i];
1272 if (call->contains(str, sensitivity)) {
1273 return call;
1274 }
1275 }
1276 return 0;
1277}
1278
1279ApiTraceCall *
1280ApiTraceFrame::findPrevCall(ApiTraceCall *from,
1281 const QString &str,
1282 Qt::CaseSensitivity sensitivity) const
1283{
1284 Q_ASSERT(m_loaded);
1285
1286 int callIndex = m_calls.count() - 1;
1287
1288 if (from) {
1289 callIndex = m_calls.indexOf(from) - 1;
1290 }
1291
1292 for (int i = callIndex; i >= 0; --i) {
1293 ApiTraceCall *call = m_calls[i];
1294 if (call->contains(str, sensitivity)) {
1295 return call;
1296 }
1297 }
1298 return 0;
1299}
Zack Rusin851d0b02011-09-14 22:04:07 -04001300
1301void ApiTraceFrame::setLastCallIndex(unsigned index)
1302{
1303 m_lastCallIndex = index;
1304}
1305
1306unsigned ApiTraceFrame::lastCallIndex() const
1307{
1308 if (m_loaded && !m_calls.isEmpty()) {
1309 return m_calls.last()->index();
1310 } else {
1311 return m_lastCallIndex;
1312 }
1313}
Dan McCabed1395322012-06-01 13:40:03 -07001314
1315void ApiTraceFrame::missingThumbnail()
1316{
1317 m_parentTrace->missingThumbnail(this);
1318}