blob: 59cc7e6030b85d61bd5adc8247044a53bd109950 [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;
60 for (int i = 0; i < plain.length(); ++i) {
61 if (plain[i] == QLatin1Char('\n')){
62 if (multiLine) {
63 rich += QLatin1String("<br>\n");
64 } else {
65 rich += QLatin1String("\\n");
66 }
67 col = 0;
68 quote = true;
69 } else {
70 if (plain[i] == QLatin1Char('\t')){
71 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;
82 } else if (plain[i].isSpace()) {
83 rich += QChar(0x00a0U);
84 quote = true;
85 } else if (plain[i] == QLatin1Char('<')) {
86 rich += QLatin1String("&lt;");
87 } else if (plain[i] == QLatin1Char('>')) {
88 rich += QLatin1String("&gt;");
89 } else if (plain[i] == QLatin1Char('&')) {
90 rich += QLatin1String("&amp;");
91 } else {
92 rich += plain[i];
93 }
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é Fonsecab4a3d142011-10-27 07:43:19 +0100191void VariantVisitor::visit(trace::Enum *e)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400192{
Zack Rusin35c27932011-08-28 21:16:22 -0400193 ApiTraceEnumSignature *sig = 0;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400194
Zack Rusinebf971e2011-09-06 17:44:43 -0400195 if (m_loader) {
196 sig = m_loader->enumSignature(e->sig->id);
Zack Rusin35c27932011-08-28 21:16:22 -0400197 }
198 if (!sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000199 sig = new ApiTraceEnumSignature(e->sig);
Zack Rusinebf971e2011-09-06 17:44:43 -0400200 if (m_loader) {
201 m_loader->addEnumSignature(e->sig->id, sig);
Zack Rusin35c27932011-08-28 21:16:22 -0400202 }
203 }
204
José Fonsecaeb644512011-12-11 10:33:55 +0000205 m_variant = QVariant::fromValue(ApiEnum(sig, e->value));
Zack Rusina1a3ad52011-08-27 19:19:18 -0400206}
207
José Fonsecab4a3d142011-10-27 07:43:19 +0100208void VariantVisitor::visit(trace::Bitmask *bitmask)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400209{
210 m_variant = QVariant::fromValue(ApiBitmask(bitmask));
211}
212
José Fonsecab4a3d142011-10-27 07:43:19 +0100213void VariantVisitor::visit(trace::Struct *str)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400214{
215 m_variant = QVariant::fromValue(ApiStruct(str));
216}
217
José Fonsecab4a3d142011-10-27 07:43:19 +0100218void VariantVisitor::visit(trace::Array *array)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400219{
220 m_variant = QVariant::fromValue(ApiArray(array));
221}
222
José Fonsecab4a3d142011-10-27 07:43:19 +0100223void VariantVisitor::visit(trace::Blob *blob)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400224{
Zack Rusin95237682011-09-27 12:04:10 -0400225 QByteArray barray = QByteArray(blob->buf, blob->size);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400226 m_variant = QVariant(barray);
227}
228
José Fonsecab4a3d142011-10-27 07:43:19 +0100229void VariantVisitor::visit(trace::Pointer *ptr)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400230{
231 m_variant = QVariant::fromValue(ApiPointer(ptr->value));
232}
233
José Fonseca112a1322012-04-27 17:15:32 +0100234void VariantVisitor::visit(trace::Repr *repr)
235{
236 /* TODO: Preserve both the human and machine value */
237 repr->humanValue->visit(*this);
238}
239
José Fonsecaeb644512011-12-11 10:33:55 +0000240ApiTraceEnumSignature::ApiTraceEnumSignature(const trace::EnumSig *sig)
241{
242 for (const trace::EnumValue *it = sig->values;
243 it != sig->values + sig->num_values; ++it) {
244 QPair<QString, signed long long> pair;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400245
José Fonseca26e84ee2014-06-18 17:42:08 +0100246 pair.first = QString::fromLatin1(it->name);
José Fonsecaeb644512011-12-11 10:33:55 +0000247 pair.second = it->value;
248
249 m_names.append(pair);
250 }
251}
252
253QString ApiTraceEnumSignature::name(signed long long value) const
254{
255 for (ValueList::const_iterator it = m_names.begin();
256 it != m_names.end(); ++it) {
257 if (value == it->second) {
258 return it->first;
259 }
260 }
261 return QString::fromLatin1("%1").arg(value);
262}
263
264ApiEnum::ApiEnum(ApiTraceEnumSignature *sig, signed long long value)
265 : m_sig(sig), m_value(value)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400266{
267}
268
269QString ApiEnum::toString() const
270{
Zack Rusin35c27932011-08-28 21:16:22 -0400271 if (m_sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000272 return m_sig->name(m_value);
Zack Rusin35c27932011-08-28 21:16:22 -0400273 }
274 Q_ASSERT(!"should never happen");
275 return QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400276}
277
278QVariant ApiEnum::value() const
279{
Zack Rusin35c27932011-08-28 21:16:22 -0400280 if (m_sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000281 return QVariant::fromValue(m_value);
Zack Rusin35c27932011-08-28 21:16:22 -0400282 }
283 Q_ASSERT(!"should never happen");
284 return QVariant();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400285}
286
287QString ApiEnum::name() const
288{
Zack Rusin35c27932011-08-28 21:16:22 -0400289 if (m_sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000290 return m_sig->name(m_value);
Zack Rusin35c27932011-08-28 21:16:22 -0400291 }
292 Q_ASSERT(!"should never happen");
293 return QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400294}
295
296unsigned long long ApiBitmask::value() const
297{
298 return m_value;
299}
300
301ApiBitmask::Signature ApiBitmask::signature() const
302{
303 return m_sig;
304}
305
306ApiStruct::Signature ApiStruct::signature() const
307{
308 return m_sig;
309}
310
311QList<QVariant> ApiStruct::values() const
312{
313 return m_members;
314}
315
316ApiPointer::ApiPointer(unsigned long long val)
317 : m_value(val)
318{
319}
320
321
322unsigned long long ApiPointer::value() const
323{
324 return m_value;
325}
326
327QString ApiPointer::toString() const
328{
329 if (m_value)
330 return QString("0x%1").arg(m_value, 0, 16);
331 else
332 return QLatin1String("NULL");
333}
334
José Fonsecab4a3d142011-10-27 07:43:19 +0100335ApiBitmask::ApiBitmask(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400336 : m_value(0)
337{
338 init(bitmask);
339}
340
José Fonsecab4a3d142011-10-27 07:43:19 +0100341void ApiBitmask::init(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400342{
343 if (!bitmask)
344 return;
345
346 m_value = bitmask->value;
José Fonsecab4a3d142011-10-27 07:43:19 +0100347 for (const trace::BitmaskFlag *it = bitmask->sig->flags;
José Fonsecafcfbf172011-05-28 13:20:01 +0100348 it != bitmask->sig->flags + bitmask->sig->num_flags; ++it) {
Zack Rusin91065372011-03-26 01:54:10 -0400349 QPair<QString, unsigned long long> pair;
350
José Fonseca26e84ee2014-06-18 17:42:08 +0100351 pair.first = QString::fromLatin1(it->name);
José Fonseca31b183a2011-05-28 12:21:15 +0100352 pair.second = it->value;
Zack Rusin91065372011-03-26 01:54:10 -0400353
354 m_sig.append(pair);
355 }
356}
357
358QString ApiBitmask::toString() const
359{
360 QString str;
361 unsigned long long value = m_value;
362 bool first = true;
José Fonsecafc9939f2012-04-23 10:13:48 +0100363 for (Signature::const_iterator it = m_sig.begin(); it != m_sig.end(); ++it) {
364 Q_ASSERT(it->second || first);
365 if ((it->second && (value & it->second) == it->second) ||
366 (!it->second && value == 0)) {
Zack Rusin91065372011-03-26 01:54:10 -0400367 if (!first) {
368 str += QLatin1String(" | ");
369 }
370 str += it->first;
371 value &= ~it->second;
372 first = false;
373 }
José Fonsecafc9939f2012-04-23 10:13:48 +0100374 if (value == 0) {
375 break;
376 }
Zack Rusin91065372011-03-26 01:54:10 -0400377 }
378 if (value || first) {
379 if (!first) {
380 str += QLatin1String(" | ");
381 }
382 str += QString::fromLatin1("0x%1").arg(value, 0, 16);
383 }
384 return str;
385}
386
José Fonsecab4a3d142011-10-27 07:43:19 +0100387ApiStruct::ApiStruct(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400388{
389 init(s);
390}
391
José Fonsecaa596a9e2011-09-27 10:19:28 +0100392QString ApiStruct::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400393{
394 QString str;
395
396 str += QLatin1String("{");
397 for (unsigned i = 0; i < m_members.count(); ++i) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400398 str += m_sig.memberNames[i] %
399 QLatin1Literal(" = ") %
José Fonsecaa596a9e2011-09-27 10:19:28 +0100400 apiVariantToString(m_members[i], multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400401 if (i < m_members.count() - 1)
402 str += QLatin1String(", ");
403 }
404 str += QLatin1String("}");
405
406 return str;
407}
408
José Fonsecab4a3d142011-10-27 07:43:19 +0100409void ApiStruct::init(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400410{
411 if (!s)
412 return;
413
José Fonseca26e84ee2014-06-18 17:42:08 +0100414 m_sig.name = QString::fromLatin1(s->sig->name);
José Fonseca1b23ed22011-05-28 13:01:16 +0100415 for (unsigned i = 0; i < s->sig->num_members; ++i) {
Zack Rusin35c27932011-08-28 21:16:22 -0400416 VariantVisitor vis(0);
Zack Rusin91065372011-03-26 01:54:10 -0400417 m_sig.memberNames.append(
José Fonseca26e84ee2014-06-18 17:42:08 +0100418 QString::fromLatin1(s->sig->member_names[i]));
Zack Rusin91065372011-03-26 01:54:10 -0400419 s->members[i]->visit(vis);
420 m_members.append(vis.variant());
421 }
422}
423
José Fonsecab4a3d142011-10-27 07:43:19 +0100424ApiArray::ApiArray(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400425{
426 init(arr);
427}
428
Zack Rusin77ff98a2011-08-28 22:30:35 -0400429ApiArray::ApiArray(const QVector<QVariant> &vals)
Zack Rusinabb3fde2011-04-16 02:16:49 -0400430 : m_array(vals)
431{
432}
433
Zack Rusin77ff98a2011-08-28 22:30:35 -0400434QVector<QVariant> ApiArray::values() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400435{
436 return m_array;
437}
438
José Fonsecaa596a9e2011-09-27 10:19:28 +0100439QString ApiArray::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400440{
441 QString str;
442 str += QLatin1String("[");
443 for(int i = 0; i < m_array.count(); ++i) {
444 const QVariant &var = m_array[i];
José Fonsecaa596a9e2011-09-27 10:19:28 +0100445 str += apiVariantToString(var, multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400446 if (i < m_array.count() - 1)
447 str += QLatin1String(", ");
448 }
449 str += QLatin1String("]");
450
451 return str;
452}
453
José Fonsecab4a3d142011-10-27 07:43:19 +0100454void ApiArray::init(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400455{
456 if (!arr)
457 return;
458
Zack Rusin3c70dbf2011-08-28 03:10:01 -0400459 m_array.reserve(arr->values.size());
Zack Rusin91065372011-03-26 01:54:10 -0400460 for (int i = 0; i < arr->values.size(); ++i) {
Zack Rusin35c27932011-08-28 21:16:22 -0400461 VariantVisitor vis(0);
Zack Rusin91065372011-03-26 01:54:10 -0400462 arr->values[i]->visit(vis);
463
464 m_array.append(vis.variant());
465 }
Zack Rusin77ff98a2011-08-28 22:30:35 -0400466 m_array.squeeze();
Zack Rusin91065372011-03-26 01:54:10 -0400467}
Zack Rusin18eade52011-03-26 14:23:35 -0400468
Zack Rusina1a3ad52011-08-27 19:19:18 -0400469ApiTraceState::ApiTraceState()
470{
471}
472
473ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
474{
475 m_parameters = parsedJson[QLatin1String("parameters")].toMap();
476 QVariantMap attachedShaders =
477 parsedJson[QLatin1String("shaders")].toMap();
478 QVariantMap::const_iterator itr;
479
480
481 for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd();
482 ++itr) {
483 QString type = itr.key();
484 QString source = itr.value().toString();
485 m_shaderSources[type] = source;
486 }
487
488 m_uniforms = parsedJson[QLatin1String("uniforms")].toMap();
489
490 QVariantMap textures =
491 parsedJson[QLatin1String("textures")].toMap();
492 for (itr = textures.constBegin(); itr != textures.constEnd(); ++itr) {
493 QVariantMap image = itr.value().toMap();
494 QSize size(image[QLatin1String("__width__")].toInt(),
495 image[QLatin1String("__height__")].toInt());
496 QString cls = image[QLatin1String("__class__")].toString();
Zack Rusinb25c4b92011-11-16 22:43:34 -0500497 int depth =
498 image[QLatin1String("__depth__")].toInt();
Zack Rusine181b992011-11-17 16:00:41 -0500499 QString formatName =
500 image[QLatin1String("__format__")].toString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400501
Zack Rusina1a3ad52011-08-27 19:19:18 -0400502 QByteArray dataArray =
503 image[QLatin1String("__data__")].toByteArray();
504
505 ApiTexture tex;
506 tex.setSize(size);
Zack Rusinb25c4b92011-11-16 22:43:34 -0500507 tex.setDepth(depth);
Zack Rusine181b992011-11-17 16:00:41 -0500508 tex.setFormatName(formatName);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400509 tex.setLabel(itr.key());
510 tex.contentsFromBase64(dataArray);
511
512 m_textures.append(tex);
513 }
514
515 QVariantMap fbos =
516 parsedJson[QLatin1String("framebuffer")].toMap();
517 for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) {
518 QVariantMap buffer = itr.value().toMap();
519 QSize size(buffer[QLatin1String("__width__")].toInt(),
520 buffer[QLatin1String("__height__")].toInt());
521 QString cls = buffer[QLatin1String("__class__")].toString();
Zack Rusinb25c4b92011-11-16 22:43:34 -0500522 int depth = buffer[QLatin1String("__depth__")].toInt();
Zack Rusine181b992011-11-17 16:00:41 -0500523 QString formatName = buffer[QLatin1String("__format__")].toString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400524
Zack Rusina1a3ad52011-08-27 19:19:18 -0400525 QByteArray dataArray =
526 buffer[QLatin1String("__data__")].toByteArray();
527
528 ApiFramebuffer fbo;
529 fbo.setSize(size);
Zack Rusinb25c4b92011-11-16 22:43:34 -0500530 fbo.setDepth(depth);
Zack Rusine181b992011-11-17 16:00:41 -0500531 fbo.setFormatName(formatName);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400532 fbo.setType(itr.key());
533 fbo.contentsFromBase64(dataArray);
534 m_framebuffers.append(fbo);
535 }
536}
537
538const QVariantMap & ApiTraceState::parameters() const
539{
540 return m_parameters;
541}
542
543const QMap<QString, QString> & ApiTraceState::shaderSources() const
544{
545 return m_shaderSources;
546}
547
548const QVariantMap & ApiTraceState::uniforms() const
549{
550 return m_uniforms;
551}
552
553bool ApiTraceState::isEmpty() const
554{
José Fonseca4e0bfee2012-11-28 10:45:08 +0000555 return m_parameters.isEmpty() &&
556 m_shaderSources.isEmpty() &&
557 m_textures.isEmpty() &&
558 m_framebuffers.isEmpty();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400559}
560
561const QList<ApiTexture> & ApiTraceState::textures() const
562{
563 return m_textures;
564}
565
566const QList<ApiFramebuffer> & ApiTraceState::framebuffers() const
567{
568 return m_framebuffers;
569}
570
Zack Rusin353f0532011-09-15 20:23:27 -0400571ApiFramebuffer ApiTraceState::colorBuffer() const
572{
573 foreach (ApiFramebuffer fbo, m_framebuffers) {
574 if (fbo.type() == QLatin1String("GL_BACK")) {
575 return fbo;
576 }
577 }
578 foreach (ApiFramebuffer fbo, m_framebuffers) {
579 if (fbo.type() == QLatin1String("GL_FRONT")) {
580 return fbo;
581 }
582 }
583 return ApiFramebuffer();
584}
585
586
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400587ApiTraceCallSignature::ApiTraceCallSignature(const QString &name,
588 const QStringList &argNames)
589 : m_name(name),
590 m_argNames(argNames)
591{
592}
593
594ApiTraceCallSignature::~ApiTraceCallSignature()
595{
596}
597
598QUrl ApiTraceCallSignature::helpUrl() const
599{
600 return m_helpUrl;
601}
602
603void ApiTraceCallSignature::setHelpUrl(const QUrl &url)
604{
605 m_helpUrl = url;
606}
607
Zack Rusina1a3ad52011-08-27 19:19:18 -0400608ApiTraceEvent::ApiTraceEvent()
609 : m_type(ApiTraceEvent::None),
Zack Rusined40bc62011-08-28 17:11:02 -0400610 m_hasBinaryData(false),
611 m_binaryDataIndex(0),
612 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400613 m_staticText(0)
614{
615}
616
617ApiTraceEvent::ApiTraceEvent(Type t)
618 : m_type(t),
Zack Rusined40bc62011-08-28 17:11:02 -0400619 m_hasBinaryData(false),
620 m_binaryDataIndex(0),
621 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400622 m_staticText(0)
623{
624}
625
626ApiTraceEvent::~ApiTraceEvent()
627{
Zack Rusined40bc62011-08-28 17:11:02 -0400628 delete m_state;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400629 delete m_staticText;
630}
631
632QVariantMap ApiTraceEvent::stateParameters() const
633{
Zack Rusined40bc62011-08-28 17:11:02 -0400634 if (m_state) {
635 return m_state->parameters();
636 } else {
637 return QVariantMap();
638 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400639}
640
Zack Rusined40bc62011-08-28 17:11:02 -0400641ApiTraceState *ApiTraceEvent::state() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400642{
643 return m_state;
644}
645
Zack Rusined40bc62011-08-28 17:11:02 -0400646void ApiTraceEvent::setState(ApiTraceState *state)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400647{
648 m_state = state;
649}
650
Zack Rusinebf971e2011-09-06 17:44:43 -0400651ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame,
652 TraceLoader *loader,
José Fonsecab4a3d142011-10-27 07:43:19 +0100653 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400654 : ApiTraceEvent(ApiTraceEvent::Call),
Zack Rusind9d9d222013-10-11 18:02:26 -0400655 m_parentFrame(parentFrame),
656 m_parentCall(0)
657{
658 loadData(loader, call);
659}
660
661ApiTraceCall::ApiTraceCall(ApiTraceCall *parentCall,
662 TraceLoader *loader,
663 const trace::Call *call)
664 : ApiTraceEvent(ApiTraceEvent::Call),
665 m_parentFrame(parentCall->parentFrame()),
666 m_parentCall(parentCall)
667{
668 loadData(loader, call);
669}
670
671
672ApiTraceCall::~ApiTraceCall()
673{
674}
675
676
677void
678ApiTraceCall::loadData(TraceLoader *loader,
679 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400680{
Zack Rusina1a3ad52011-08-27 19:19:18 -0400681 m_index = call->no;
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500682 m_thread = call->thread_id;
Zack Rusinebf971e2011-09-06 17:44:43 -0400683 m_signature = loader->signature(call->sig->id);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400684
685 if (!m_signature) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100686 QString name = QString::fromLatin1(call->sig->name);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400687 QStringList argNames;
Zack Rusinf22d7992011-08-28 02:23:47 -0400688 argNames.reserve(call->sig->num_args);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400689 for (int i = 0; i < call->sig->num_args; ++i) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100690 argNames += QString::fromLatin1(call->sig->arg_names[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400691 }
692 m_signature = new ApiTraceCallSignature(name, argNames);
Zack Rusinebf971e2011-09-06 17:44:43 -0400693 loader->addSignature(call->sig->id, m_signature);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400694 }
695 if (call->ret) {
Zack Rusinebf971e2011-09-06 17:44:43 -0400696 VariantVisitor retVisitor(loader);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400697 call->ret->visit(retVisitor);
698 m_returnValue = retVisitor.variant();
699 }
Zack Rusinf22d7992011-08-28 02:23:47 -0400700 m_argValues.reserve(call->args.size());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400701 for (int i = 0; i < call->args.size(); ++i) {
Carl Wortha5b476e2011-11-16 17:22:40 -0800702 if (call->args[i].value) {
José Fonseca1fa61832011-11-05 08:50:25 +0000703 VariantVisitor argVisitor(loader);
Carl Wortha5b476e2011-11-16 17:22:40 -0800704 call->args[i].value->visit(argVisitor);
José Fonseca1fa61832011-11-05 08:50:25 +0000705 m_argValues.append(argVisitor.variant());
706 if (m_argValues[i].type() == QVariant::ByteArray) {
707 m_hasBinaryData = true;
708 m_binaryDataIndex = i;
709 }
710 } else {
711 m_argValues.append(QVariant());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400712 }
713 }
Zack Rusinf736a622011-08-28 22:19:46 -0400714 m_argValues.squeeze();
José Fonseca340f5692011-11-30 07:04:44 +0000715 m_flags = call->flags;
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400716 if (call->backtrace != NULL) {
717 QString qbacktrace;
José Fonsecaac55ba82013-05-05 08:11:23 +0100718 for (int i = 0; i < call->backtrace->size(); i++) {
José Fonseca9c25e062013-05-06 07:25:40 +0100719 const trace::StackFrame * frame = (*call->backtrace)[i];
720 if (frame->module != NULL) {
721 qbacktrace += QString("%1 ").arg(frame->module);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400722 }
José Fonseca9c25e062013-05-06 07:25:40 +0100723 if (frame->function != NULL) {
724 qbacktrace += QString("at %1() ").arg(frame->function);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400725 }
José Fonseca9c25e062013-05-06 07:25:40 +0100726 if (frame->filename != NULL) {
727 qbacktrace += QString("at %1").arg(frame->filename);
728 if (frame->linenumber >= 0) {
729 qbacktrace += QString(":%1 ").arg(frame->linenumber);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400730 }
731 }
732 else {
José Fonseca9c25e062013-05-06 07:25:40 +0100733 if (frame->offset >= 0) {
734 qbacktrace += QString("[0x%1]").arg(frame->offset, 0, 16);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400735 }
736 }
737 qbacktrace += "\n";
738 }
739 this->setBacktrace(qbacktrace);
740 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400741}
742
Zack Rusind9d9d222013-10-11 18:02:26 -0400743ApiTraceCall *
744ApiTraceCall::parentCall() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400745{
Zack Rusind9d9d222013-10-11 18:02:26 -0400746 return m_parentCall;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400747}
748
749
Zack Rusind9d9d222013-10-11 18:02:26 -0400750ApiTraceEvent *
751ApiTraceCall::parentEvent() const
752{
753 if (m_parentCall)
754 return m_parentCall;
755 else
756 return m_parentFrame;
757}
758
759QVector<ApiTraceCall*>
760ApiTraceCall::children() const
761{
762 return m_children;
763}
764
765void
766ApiTraceCall::addChild(ApiTraceCall *call)
767{
768 m_children.append(call);
769}
770
771
772int
773ApiTraceCall::callIndex(ApiTraceCall *call) const
774{
775 return m_children.indexOf(call);
776}
777
778void
779ApiTraceCall::finishedAddingChildren()
780{
781 m_children.squeeze();
782}
783
Zack Rusina1a3ad52011-08-27 19:19:18 -0400784bool ApiTraceCall::hasError() const
785{
786 return !m_error.isEmpty();
787}
788
789QString ApiTraceCall::error() const
790{
791 return m_error;
792}
793
794void ApiTraceCall::setError(const QString &msg)
795{
796 if (m_error != msg) {
Zack Rusina1a3ad52011-08-27 19:19:18 -0400797 m_error = msg;
798 m_richText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400799 }
800}
801
802ApiTrace * ApiTraceCall::parentTrace() const
803{
804 if (m_parentFrame)
805 return m_parentFrame->parentTrace();
806 return NULL;
807}
808
Zack Rusinf736a622011-08-28 22:19:46 -0400809QVector<QVariant> ApiTraceCall::originalValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400810{
811 return m_argValues;
812}
813
Zack Rusinf736a622011-08-28 22:19:46 -0400814void ApiTraceCall::setEditedValues(const QVector<QVariant> &lst)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400815{
816 ApiTrace *trace = parentTrace();
817
818 m_editedValues = lst;
819 //lets regenerate data
820 m_richText = QString();
Zack Rusindc792082011-08-27 23:29:19 -0400821 m_searchText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400822 delete m_staticText;
823 m_staticText = 0;
824
825 if (trace) {
826 if (!lst.isEmpty()) {
827 trace->callEdited(this);
828 } else {
829 trace->callReverted(this);
830 }
831 }
832}
833
Zack Rusinf736a622011-08-28 22:19:46 -0400834QVector<QVariant> ApiTraceCall::editedValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400835{
836 return m_editedValues;
837}
838
839bool ApiTraceCall::edited() const
840{
841 return !m_editedValues.isEmpty();
842}
843
844void ApiTraceCall::revert()
845{
Zack Rusinf736a622011-08-28 22:19:46 -0400846 setEditedValues(QVector<QVariant>());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400847}
848
849void ApiTraceCall::setHelpUrl(const QUrl &url)
850{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400851 m_signature->setHelpUrl(url);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400852}
853
854void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
855{
856 m_parentFrame = frame;
857}
858
859ApiTraceFrame * ApiTraceCall::parentFrame()const
860{
861 return m_parentFrame;
862}
863
864int ApiTraceCall::index() const
865{
866 return m_index;
867}
868
869QString ApiTraceCall::name() const
870{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400871 return m_signature->name();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400872}
873
874QStringList ApiTraceCall::argNames() const
875{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400876 return m_signature->argNames();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400877}
878
Zack Rusinf736a622011-08-28 22:19:46 -0400879QVector<QVariant> ApiTraceCall::arguments() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400880{
881 if (m_editedValues.isEmpty())
882 return m_argValues;
883 else
884 return m_editedValues;
885}
886
Zack Rusind9d9d222013-10-11 18:02:26 -0400887ApiTraceEvent *
888ApiTraceCall::eventAtRow(int row) const
889{
890 if (row < m_children.count())
891 return m_children.value(row);
892 else
893 return NULL;
894}
895
Zack Rusina1a3ad52011-08-27 19:19:18 -0400896QVariant ApiTraceCall::returnValue() const
897{
898 return m_returnValue;
899}
900
José Fonseca340f5692011-11-30 07:04:44 +0000901trace::CallFlags ApiTraceCall::flags() const
902{
903 return m_flags;
904}
905
Zack Rusina1a3ad52011-08-27 19:19:18 -0400906QUrl ApiTraceCall::helpUrl() const
907{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400908 return m_signature->helpUrl();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400909}
910
911bool ApiTraceCall::hasBinaryData() const
912{
913 return m_hasBinaryData;
914}
915
916int ApiTraceCall::binaryDataIndex() const
917{
918 return m_binaryDataIndex;
919}
920
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400921QString ApiTraceCall::backtrace() const
922{
923 return m_backtrace;
924}
925
926void ApiTraceCall::setBacktrace(QString backtrace)
927{
928 m_backtrace = backtrace;
929}
930
Zack Rusin18eade52011-03-26 14:23:35 -0400931QStaticText ApiTraceCall::staticText() const
932{
Zack Rusin53484b22011-04-16 11:56:19 -0400933 if (m_staticText && !m_staticText->text().isEmpty())
934 return *m_staticText;
Zack Rusin18eade52011-03-26 14:23:35 -0400935
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500936 QStringList argNames = m_signature->argNames();
Zack Rusinf736a622011-08-28 22:19:46 -0400937 QVector<QVariant> argValues = arguments();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400938
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500939 QString richText;
940
José Fonseca2258a6d2014-05-22 21:14:21 +0100941 // TODO: Toggle this via a menu option.
942 if (0) {
943 richText += QString::fromLatin1("<span style=\"color: #aaaaaa; min-width: 3em;\">@%1</span> ")
944 .arg(m_thread);
945 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500946
José Fonseca991723d2014-05-22 21:32:37 +0100947 if (m_flags & trace::CALL_FLAG_MARKER &&
948 argNames.count() &&
949 argValues.last().userType() == QVariant::String)
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500950 {
951 // special handling for string markers
José Fonseca991723d2014-05-22 21:32:37 +0100952 QString msgText = plainTextToHTML(argValues.last().toString(), false, true);
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500953 richText += QString::fromLatin1(
954 "<span style=\"font-weight:bold;color:green;\">%1</span>")
955 .arg(msgText);
956 } else {
957 richText += QString::fromLatin1(
958 "<span style=\"font-weight:bold\">%1</span>(").arg(
959 m_signature->name());
960 for (int i = 0; i < argNames.count(); ++i) {
961 richText += QLatin1String("<span style=\"color:#0000ff\">");
962 QString argText = apiVariantToString(argValues[i]);
963
964 //if arguments are really long (e.g. shader text), cut them
965 // and elide it
966 if (argText.length() > 40) {
967 QString shortened = argText.mid(0, 40);
968 shortened[argText.length() - 5] = '.';
969 shortened[argText.length() - 4] = '.';
970 shortened[argText.length() - 3] = '.';
971 shortened[argText.length() - 2] = argText.at(argText.length() - 2);
972 shortened[argText.length() - 1] = argText.at(argText.length() - 1);
973 richText += shortened;
974 } else {
975 richText += argText;
976 }
977 richText += QLatin1String("</span>");
978 if (i < argNames.count() - 1)
979 richText += QLatin1String(", ");
Zack Rusindd7f2302011-03-31 22:55:57 -0400980 }
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500981 richText += QLatin1String(")");
982 if (m_returnValue.isValid()) {
983 richText +=
984 QLatin1Literal(" = ") %
985 QLatin1Literal("<span style=\"color:#0000ff\">") %
986 apiVariantToString(m_returnValue) %
987 QLatin1Literal("</span>");
988 }
José Fonseca908f38d2011-03-31 10:09:14 +0100989 }
Zack Rusin27cb2c42011-03-27 23:53:36 -0400990
Zack Rusin53484b22011-04-16 11:56:19 -0400991 if (!m_staticText)
992 m_staticText = new QStaticText(richText);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400993 else
994 m_staticText->setText(richText);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400995 QTextOption opt;
996 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -0400997 m_staticText->setTextOption(opt);
998 m_staticText->prepare();
Zack Rusin27cb2c42011-03-27 23:53:36 -0400999
Zack Rusin53484b22011-04-16 11:56:19 -04001000 return *m_staticText;
Zack Rusin27cb2c42011-03-27 23:53:36 -04001001}
1002
1003QString ApiTraceCall::toHtml() const
1004{
1005 if (!m_richText.isEmpty())
1006 return m_richText;
1007
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001008 m_richText += QLatin1String("<div class=\"call\">");
Zack Rusinb53b1612011-04-19 01:33:58 -04001009
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001010
1011 m_richText +=
José Fonseca2258a6d2014-05-22 21:14:21 +01001012 QString::fromLatin1("%1 ")
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001013 .arg(m_index);
1014 QString parentTip;
1015 if (m_parentFrame) {
1016 parentTip =
1017 QString::fromLatin1("Frame %1")
1018 .arg(m_parentFrame->number);
1019 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001020
José Fonseca2258a6d2014-05-22 21:14:21 +01001021 m_richText += QString::fromLatin1("<span class=\"thread-id\">@%1</span> ")
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001022 .arg(m_thread);
1023
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001024 QUrl helpUrl = m_signature->helpUrl();
1025 if (helpUrl.isEmpty()) {
Zack Rusinb53b1612011-04-19 01:33:58 -04001026 m_richText += QString::fromLatin1(
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001027 "<span class=\"callName\" title=\"%1\">%2</span>(")
1028 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001029 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001030 } else {
Zack Rusinb53b1612011-04-19 01:33:58 -04001031 m_richText += QString::fromLatin1(
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001032 "<span class=\"callName\" title=\"%1\"><a href=\"%2\">%3</a></span>(")
1033 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001034 .arg(helpUrl.toString())
1035 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001036 }
1037
Zack Rusinf736a622011-08-28 22:19:46 -04001038 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001039 QStringList argNames = m_signature->argNames();
1040 for (int i = 0; i < argNames.count(); ++i) {
Zack Rusinb53b1612011-04-19 01:33:58 -04001041 m_richText +=
1042 QLatin1String("<span class=\"arg-name\">") +
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001043 argNames[i] +
Zack Rusinb53b1612011-04-19 01:33:58 -04001044 QLatin1String("</span>") +
1045 QLatin1Literal(" = ") +
1046 QLatin1Literal("<span class=\"arg-value\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001047 apiVariantToString(argValues[i], true) +
Zack Rusinb53b1612011-04-19 01:33:58 -04001048 QLatin1Literal("</span>");
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001049 if (i < argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -04001050 m_richText += QLatin1String(", ");
Zack Rusin18eade52011-03-26 14:23:35 -04001051 }
1052 m_richText += QLatin1String(")");
1053
Zack Rusinead6aad2011-04-15 22:16:18 -04001054 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -04001055 m_richText +=
1056 QLatin1String(" = ") +
1057 QLatin1String("<span style=\"color:#0000ff\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001058 apiVariantToString(m_returnValue, true) +
Zack Rusin5e277b02011-04-16 21:52:26 -04001059 QLatin1String("</span>");
Zack Rusin18eade52011-03-26 14:23:35 -04001060 }
Zack Rusinb53b1612011-04-19 01:33:58 -04001061 m_richText += QLatin1String("</div>");
1062
Zack Rusincc0b4912011-04-19 01:59:20 -04001063 if (hasError()) {
1064 QString errorStr =
1065 QString::fromLatin1(
1066 "<div class=\"error\">%1</div>")
1067 .arg(m_error);
1068 m_richText += errorStr;
1069 }
1070
Zack Rusinb53b1612011-04-19 01:33:58 -04001071 m_richText =
1072 QString::fromLatin1(
1073 "<html><head><style type=\"text/css\" media=\"all\">"
1074 "%1</style></head><body>%2</body></html>")
1075 .arg(styleSheet)
1076 .arg(m_richText);
Zack Rusin5e277b02011-04-16 21:52:26 -04001077 m_richText.squeeze();
Zack Rusinb53b1612011-04-19 01:33:58 -04001078
1079 //qDebug()<<m_richText;
Zack Rusin18eade52011-03-26 14:23:35 -04001080 return m_richText;
1081}
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001082
Zack Rusindc792082011-08-27 23:29:19 -04001083QString ApiTraceCall::searchText() const
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001084{
Zack Rusindc792082011-08-27 23:29:19 -04001085 if (!m_searchText.isEmpty())
1086 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001087
Zack Rusinf736a622011-08-28 22:19:46 -04001088 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001089 m_searchText = m_signature->name() + QLatin1Literal("(");
1090 QStringList argNames = m_signature->argNames();
1091 for (int i = 0; i < argNames.count(); ++i) {
1092 m_searchText += argNames[i] +
Zack Rusin5e277b02011-04-16 21:52:26 -04001093 QLatin1Literal(" = ") +
Zack Rusin9af5bff2011-04-18 01:05:50 -04001094 apiVariantToString(argValues[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001095 if (i < argNames.count() - 1)
Zack Rusindc792082011-08-27 23:29:19 -04001096 m_searchText += QLatin1String(", ");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001097 }
Zack Rusindc792082011-08-27 23:29:19 -04001098 m_searchText += QLatin1String(")");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001099
Zack Rusinead6aad2011-04-15 22:16:18 -04001100 if (m_returnValue.isValid()) {
Zack Rusindc792082011-08-27 23:29:19 -04001101 m_searchText += QLatin1Literal(" = ") +
Zack Rusin5e277b02011-04-16 21:52:26 -04001102 apiVariantToString(m_returnValue);
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001103 }
Zack Rusindc792082011-08-27 23:29:19 -04001104 m_searchText.squeeze();
1105 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001106}
Zack Rusinf6667d12011-03-30 11:03:37 -04001107
Zack Rusina1a3ad52011-08-27 19:19:18 -04001108int ApiTraceCall::numChildren() const
1109{
Zack Rusind9d9d222013-10-11 18:02:26 -04001110 return m_children.count();
Zack Rusina1a3ad52011-08-27 19:19:18 -04001111}
1112
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001113bool ApiTraceCall::contains(const QString &str,
1114 Qt::CaseSensitivity sensitivity) const
1115{
1116 QString txt = searchText();
1117 return txt.contains(str, sensitivity);
1118}
1119
1120
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001121ApiTraceFrame::ApiTraceFrame(ApiTrace *parentTrace)
Zack Rusina1a3ad52011-08-27 19:19:18 -04001122 : ApiTraceEvent(ApiTraceEvent::Frame),
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001123 m_parentTrace(parentTrace),
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001124 m_binaryDataSize(0),
1125 m_loaded(false),
Zack Rusin851d0b02011-09-14 22:04:07 -04001126 m_callsToLoad(0),
1127 m_lastCallIndex(0)
Zack Rusina1a3ad52011-08-27 19:19:18 -04001128{
1129}
1130
Zack Rusinc1743432011-09-13 17:58:58 -04001131ApiTraceFrame::~ApiTraceFrame()
1132{
1133 qDeleteAll(m_calls);
1134}
1135
Zack Rusinf6667d12011-03-30 11:03:37 -04001136QStaticText ApiTraceFrame::staticText() const
1137{
Zack Rusin53484b22011-04-16 11:56:19 -04001138 if (m_staticText && !m_staticText->text().isEmpty())
1139 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -04001140
Zack Rusin45e094f2011-09-14 17:36:53 -04001141 QString richText = QObject::tr(
1142 "<span style=\"font-weight:bold\">Frame %1</span>"
1143 "&nbsp;&nbsp;&nbsp;"
1144 "<span style=\"font-style:italic;font-size:small;font-weight:lighter;\"> "
1145 "(%2 calls)</span>")
1146 .arg(number)
1147 .arg(m_loaded ? m_calls.count() : m_callsToLoad);
Zack Rusin9e292fc2011-04-26 23:03:42 -04001148
1149 //mark the frame if it uploads more than a meg a frame
1150 if (m_binaryDataSize > (1024*1024)) {
1151 richText =
1152 QObject::tr(
Zack Rusin45e094f2011-09-14 17:36:53 -04001153 "%1"
Zack Rusin9e292fc2011-04-26 23:03:42 -04001154 "<span style=\"font-style:italic;\">"
1155 "&nbsp;&nbsp;&nbsp;&nbsp;(%2MB)</span>")
Zack Rusin45e094f2011-09-14 17:36:53 -04001156 .arg(richText)
Zack Rusin9e292fc2011-04-26 23:03:42 -04001157 .arg(double(m_binaryDataSize / (1024.*1024.)), 0, 'g', 2);
Zack Rusin9e292fc2011-04-26 23:03:42 -04001158 }
Zack Rusinf6667d12011-03-30 11:03:37 -04001159
Zack Rusin53484b22011-04-16 11:56:19 -04001160 if (!m_staticText)
1161 m_staticText = new QStaticText(richText);
1162
Zack Rusinf6667d12011-03-30 11:03:37 -04001163 QTextOption opt;
1164 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -04001165 m_staticText->setTextOption(opt);
1166 m_staticText->prepare();
Zack Rusinf6667d12011-03-30 11:03:37 -04001167
Zack Rusin53484b22011-04-16 11:56:19 -04001168 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -04001169}
1170
Zack Rusinf6667d12011-03-30 11:03:37 -04001171int ApiTraceFrame::numChildren() const
1172{
Zack Rusind9d9d222013-10-11 18:02:26 -04001173 return m_children.count();
1174}
1175
1176int ApiTraceFrame::numTotalCalls() const
1177{
Zack Rusin3176ebe2011-09-06 21:11:36 -04001178 return m_calls.count();
Zack Rusinf6667d12011-03-30 11:03:37 -04001179}
1180
Zack Rusin7c1793e2011-04-16 23:14:25 -04001181ApiTrace * ApiTraceFrame::parentTrace() const
1182{
1183 return m_parentTrace;
1184}
1185
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001186QVector<ApiTraceCall*> ApiTraceFrame::calls() const
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001187{
1188 return m_calls;
1189}
1190
Zack Rusind9d9d222013-10-11 18:02:26 -04001191ApiTraceEvent * ApiTraceFrame::eventAtRow(int row) const
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001192{
Zack Rusind9d9d222013-10-11 18:02:26 -04001193 if (row < m_children.count())
1194 return m_children.value(row);
1195 else
1196 return NULL;
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001197}
1198
Zack Rusinda7579b2011-09-13 17:33:05 -04001199
1200ApiTraceCall * ApiTraceFrame::callWithIndex(int index) const
1201{
1202 QVector<ApiTraceCall*>::const_iterator itr;
1203 for (itr = m_calls.constBegin(); itr != m_calls.constEnd(); ++itr) {
1204 if ((*itr)->index() == index) {
1205 return *itr;
1206 }
1207 }
1208 return 0;
1209}
1210
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001211int ApiTraceFrame::callIndex(ApiTraceCall *call) const
1212{
Zack Rusind9d9d222013-10-11 18:02:26 -04001213 return m_children.indexOf(call);
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001214}
1215
1216bool ApiTraceFrame::isEmpty() const
1217{
Zack Rusin3176ebe2011-09-06 21:11:36 -04001218 if (m_loaded) {
1219 return m_calls.isEmpty();
1220 } else {
1221 return m_callsToLoad == 0;
1222 }
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001223}
1224
Zack Rusin9e292fc2011-04-26 23:03:42 -04001225int ApiTraceFrame::binaryDataSize() const
1226{
1227 return m_binaryDataSize;
1228}
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001229
Zack Rusind9d9d222013-10-11 18:02:26 -04001230void ApiTraceFrame::setCalls(const QVector<ApiTraceCall*> &children,
1231 const QVector<ApiTraceCall*> &calls,
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001232 quint64 binaryDataSize)
1233{
Zack Rusind9d9d222013-10-11 18:02:26 -04001234 m_children = children;
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001235 m_calls = calls;
1236 m_binaryDataSize = binaryDataSize;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001237 m_loaded = true;
Zack Rusin45e094f2011-09-14 17:36:53 -04001238 delete m_staticText;
1239 m_staticText = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001240}
1241
Zack Rusin1a9f7af2011-09-18 19:40:47 -04001242bool ApiTraceFrame::isLoaded() const
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001243{
1244 return m_loaded;
1245}
1246
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001247void ApiTraceFrame::setNumChildren(int num)
1248{
1249 m_callsToLoad = num;
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001250}
Zack Rusinebf971e2011-09-06 17:44:43 -04001251
1252void ApiTraceFrame::setParentTrace(ApiTrace *parent)
1253{
1254 m_parentTrace = parent;
1255}
Zack Rusin3176ebe2011-09-06 21:11:36 -04001256
1257int ApiTraceFrame::numChildrenToLoad() const
1258{
1259 return m_callsToLoad;
1260}
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001261
1262ApiTraceCall *
1263ApiTraceFrame::findNextCall(ApiTraceCall *from,
1264 const QString &str,
1265 Qt::CaseSensitivity sensitivity) const
1266{
1267 Q_ASSERT(m_loaded);
1268
1269 int callIndex = 0;
1270
1271 if (from) {
1272 callIndex = m_calls.indexOf(from) + 1;
1273 }
1274
1275 for (int i = callIndex; i < m_calls.count(); ++i) {
1276 ApiTraceCall *call = m_calls[i];
1277 if (call->contains(str, sensitivity)) {
1278 return call;
1279 }
1280 }
1281 return 0;
1282}
1283
1284ApiTraceCall *
1285ApiTraceFrame::findPrevCall(ApiTraceCall *from,
1286 const QString &str,
1287 Qt::CaseSensitivity sensitivity) const
1288{
1289 Q_ASSERT(m_loaded);
1290
1291 int callIndex = m_calls.count() - 1;
1292
1293 if (from) {
1294 callIndex = m_calls.indexOf(from) - 1;
1295 }
1296
1297 for (int i = callIndex; i >= 0; --i) {
1298 ApiTraceCall *call = m_calls[i];
1299 if (call->contains(str, sensitivity)) {
1300 return call;
1301 }
1302 }
1303 return 0;
1304}
Zack Rusin851d0b02011-09-14 22:04:07 -04001305
1306void ApiTraceFrame::setLastCallIndex(unsigned index)
1307{
1308 m_lastCallIndex = index;
1309}
1310
1311unsigned ApiTraceFrame::lastCallIndex() const
1312{
1313 if (m_loaded && !m_calls.isEmpty()) {
1314 return m_calls.last()->index();
1315 } else {
1316 return m_lastCallIndex;
1317 }
1318}
Dan McCabe10bd4242012-03-05 17:20:40 -08001319
José Fonseca8759ae02012-03-24 07:44:43 +00001320void ApiTraceFrame::setThumbnail(const QImage & thumbnail)
Dan McCabe10bd4242012-03-05 17:20:40 -08001321{
1322 m_thumbnail = thumbnail;
1323}
1324
José Fonseca8759ae02012-03-24 07:44:43 +00001325const QImage & ApiTraceFrame::thumbnail() const
Dan McCabe10bd4242012-03-05 17:20:40 -08001326{
1327 return m_thumbnail;
1328}