blob: fe30947bba48e964a3e853c790e7a4736bff0520 [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é 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{
Zack Rusin35c27932011-08-28 21:16:22 -0400198 ApiTraceEnumSignature *sig = 0;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400199
Zack Rusinebf971e2011-09-06 17:44:43 -0400200 if (m_loader) {
201 sig = m_loader->enumSignature(e->sig->id);
Zack Rusin35c27932011-08-28 21:16:22 -0400202 }
203 if (!sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000204 sig = new ApiTraceEnumSignature(e->sig);
Zack Rusinebf971e2011-09-06 17:44:43 -0400205 if (m_loader) {
206 m_loader->addEnumSignature(e->sig->id, sig);
Zack Rusin35c27932011-08-28 21:16:22 -0400207 }
208 }
209
José Fonsecaeb644512011-12-11 10:33:55 +0000210 m_variant = QVariant::fromValue(ApiEnum(sig, e->value));
Zack Rusina1a3ad52011-08-27 19:19:18 -0400211}
212
José Fonsecab4a3d142011-10-27 07:43:19 +0100213void VariantVisitor::visit(trace::Bitmask *bitmask)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400214{
215 m_variant = QVariant::fromValue(ApiBitmask(bitmask));
216}
217
José Fonsecab4a3d142011-10-27 07:43:19 +0100218void VariantVisitor::visit(trace::Struct *str)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400219{
220 m_variant = QVariant::fromValue(ApiStruct(str));
221}
222
José Fonsecab4a3d142011-10-27 07:43:19 +0100223void VariantVisitor::visit(trace::Array *array)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400224{
225 m_variant = QVariant::fromValue(ApiArray(array));
226}
227
José Fonsecab4a3d142011-10-27 07:43:19 +0100228void VariantVisitor::visit(trace::Blob *blob)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400229{
Zack Rusin95237682011-09-27 12:04:10 -0400230 QByteArray barray = QByteArray(blob->buf, blob->size);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400231 m_variant = QVariant(barray);
232}
233
José Fonsecab4a3d142011-10-27 07:43:19 +0100234void VariantVisitor::visit(trace::Pointer *ptr)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400235{
236 m_variant = QVariant::fromValue(ApiPointer(ptr->value));
237}
238
José Fonseca112a1322012-04-27 17:15:32 +0100239void VariantVisitor::visit(trace::Repr *repr)
240{
241 /* TODO: Preserve both the human and machine value */
242 repr->humanValue->visit(*this);
243}
244
José Fonsecaeb644512011-12-11 10:33:55 +0000245ApiTraceEnumSignature::ApiTraceEnumSignature(const trace::EnumSig *sig)
246{
247 for (const trace::EnumValue *it = sig->values;
248 it != sig->values + sig->num_values; ++it) {
249 QPair<QString, signed long long> pair;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400250
José Fonseca26e84ee2014-06-18 17:42:08 +0100251 pair.first = QString::fromLatin1(it->name);
José Fonsecaeb644512011-12-11 10:33:55 +0000252 pair.second = it->value;
253
254 m_names.append(pair);
255 }
256}
257
258QString ApiTraceEnumSignature::name(signed long long value) const
259{
260 for (ValueList::const_iterator it = m_names.begin();
261 it != m_names.end(); ++it) {
262 if (value == it->second) {
263 return it->first;
264 }
265 }
266 return QString::fromLatin1("%1").arg(value);
267}
268
269ApiEnum::ApiEnum(ApiTraceEnumSignature *sig, signed long long value)
270 : m_sig(sig), m_value(value)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400271{
272}
273
274QString ApiEnum::toString() const
275{
Zack Rusin35c27932011-08-28 21:16:22 -0400276 if (m_sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000277 return m_sig->name(m_value);
Zack Rusin35c27932011-08-28 21:16:22 -0400278 }
279 Q_ASSERT(!"should never happen");
280 return QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400281}
282
283QVariant ApiEnum::value() const
284{
Zack Rusin35c27932011-08-28 21:16:22 -0400285 if (m_sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000286 return QVariant::fromValue(m_value);
Zack Rusin35c27932011-08-28 21:16:22 -0400287 }
288 Q_ASSERT(!"should never happen");
289 return QVariant();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400290}
291
292QString ApiEnum::name() const
293{
Zack Rusin35c27932011-08-28 21:16:22 -0400294 if (m_sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000295 return m_sig->name(m_value);
Zack Rusin35c27932011-08-28 21:16:22 -0400296 }
297 Q_ASSERT(!"should never happen");
298 return QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400299}
300
301unsigned long long ApiBitmask::value() const
302{
303 return m_value;
304}
305
306ApiBitmask::Signature ApiBitmask::signature() const
307{
308 return m_sig;
309}
310
311ApiStruct::Signature ApiStruct::signature() const
312{
313 return m_sig;
314}
315
316QList<QVariant> ApiStruct::values() const
317{
318 return m_members;
319}
320
321ApiPointer::ApiPointer(unsigned long long val)
322 : m_value(val)
323{
324}
325
326
327unsigned long long ApiPointer::value() const
328{
329 return m_value;
330}
331
332QString ApiPointer::toString() const
333{
334 if (m_value)
335 return QString("0x%1").arg(m_value, 0, 16);
336 else
337 return QLatin1String("NULL");
338}
339
José Fonsecab4a3d142011-10-27 07:43:19 +0100340ApiBitmask::ApiBitmask(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400341 : m_value(0)
342{
343 init(bitmask);
344}
345
José Fonsecab4a3d142011-10-27 07:43:19 +0100346void ApiBitmask::init(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400347{
348 if (!bitmask)
349 return;
350
351 m_value = bitmask->value;
José Fonsecab4a3d142011-10-27 07:43:19 +0100352 for (const trace::BitmaskFlag *it = bitmask->sig->flags;
José Fonsecafcfbf172011-05-28 13:20:01 +0100353 it != bitmask->sig->flags + bitmask->sig->num_flags; ++it) {
Zack Rusin91065372011-03-26 01:54:10 -0400354 QPair<QString, unsigned long long> pair;
355
José Fonseca26e84ee2014-06-18 17:42:08 +0100356 pair.first = QString::fromLatin1(it->name);
José Fonseca31b183a2011-05-28 12:21:15 +0100357 pair.second = it->value;
Zack Rusin91065372011-03-26 01:54:10 -0400358
359 m_sig.append(pair);
360 }
361}
362
363QString ApiBitmask::toString() const
364{
365 QString str;
366 unsigned long long value = m_value;
367 bool first = true;
José Fonsecafc9939f2012-04-23 10:13:48 +0100368 for (Signature::const_iterator it = m_sig.begin(); it != m_sig.end(); ++it) {
369 Q_ASSERT(it->second || first);
370 if ((it->second && (value & it->second) == it->second) ||
371 (!it->second && value == 0)) {
Zack Rusin91065372011-03-26 01:54:10 -0400372 if (!first) {
373 str += QLatin1String(" | ");
374 }
375 str += it->first;
376 value &= ~it->second;
377 first = false;
378 }
José Fonsecafc9939f2012-04-23 10:13:48 +0100379 if (value == 0) {
380 break;
381 }
Zack Rusin91065372011-03-26 01:54:10 -0400382 }
383 if (value || first) {
384 if (!first) {
385 str += QLatin1String(" | ");
386 }
387 str += QString::fromLatin1("0x%1").arg(value, 0, 16);
388 }
389 return str;
390}
391
José Fonsecab4a3d142011-10-27 07:43:19 +0100392ApiStruct::ApiStruct(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400393{
394 init(s);
395}
396
José Fonsecaa596a9e2011-09-27 10:19:28 +0100397QString ApiStruct::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400398{
399 QString str;
400
401 str += QLatin1String("{");
402 for (unsigned i = 0; i < m_members.count(); ++i) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400403 str += m_sig.memberNames[i] %
404 QLatin1Literal(" = ") %
José Fonsecaa596a9e2011-09-27 10:19:28 +0100405 apiVariantToString(m_members[i], multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400406 if (i < m_members.count() - 1)
407 str += QLatin1String(", ");
408 }
409 str += QLatin1String("}");
410
411 return str;
412}
413
José Fonsecab4a3d142011-10-27 07:43:19 +0100414void ApiStruct::init(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400415{
416 if (!s)
417 return;
418
José Fonseca26e84ee2014-06-18 17:42:08 +0100419 m_sig.name = QString::fromLatin1(s->sig->name);
José Fonseca1b23ed22011-05-28 13:01:16 +0100420 for (unsigned i = 0; i < s->sig->num_members; ++i) {
Zack Rusin35c27932011-08-28 21:16:22 -0400421 VariantVisitor vis(0);
Zack Rusin91065372011-03-26 01:54:10 -0400422 m_sig.memberNames.append(
José Fonseca26e84ee2014-06-18 17:42:08 +0100423 QString::fromLatin1(s->sig->member_names[i]));
Zack Rusin91065372011-03-26 01:54:10 -0400424 s->members[i]->visit(vis);
425 m_members.append(vis.variant());
426 }
427}
428
José Fonsecab4a3d142011-10-27 07:43:19 +0100429ApiArray::ApiArray(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400430{
431 init(arr);
432}
433
Zack Rusin77ff98a2011-08-28 22:30:35 -0400434ApiArray::ApiArray(const QVector<QVariant> &vals)
Zack Rusinabb3fde2011-04-16 02:16:49 -0400435 : m_array(vals)
436{
437}
438
Zack Rusin77ff98a2011-08-28 22:30:35 -0400439QVector<QVariant> ApiArray::values() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400440{
441 return m_array;
442}
443
José Fonsecaa596a9e2011-09-27 10:19:28 +0100444QString ApiArray::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400445{
446 QString str;
447 str += QLatin1String("[");
448 for(int i = 0; i < m_array.count(); ++i) {
449 const QVariant &var = m_array[i];
José Fonsecaa596a9e2011-09-27 10:19:28 +0100450 str += apiVariantToString(var, multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400451 if (i < m_array.count() - 1)
452 str += QLatin1String(", ");
453 }
454 str += QLatin1String("]");
455
456 return str;
457}
458
José Fonsecab4a3d142011-10-27 07:43:19 +0100459void ApiArray::init(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400460{
461 if (!arr)
462 return;
463
Zack Rusin3c70dbf2011-08-28 03:10:01 -0400464 m_array.reserve(arr->values.size());
Zack Rusin91065372011-03-26 01:54:10 -0400465 for (int i = 0; i < arr->values.size(); ++i) {
Zack Rusin35c27932011-08-28 21:16:22 -0400466 VariantVisitor vis(0);
Zack Rusin91065372011-03-26 01:54:10 -0400467 arr->values[i]->visit(vis);
468
469 m_array.append(vis.variant());
470 }
Zack Rusin77ff98a2011-08-28 22:30:35 -0400471 m_array.squeeze();
Zack Rusin91065372011-03-26 01:54:10 -0400472}
Zack Rusin18eade52011-03-26 14:23:35 -0400473
Zack Rusina1a3ad52011-08-27 19:19:18 -0400474ApiTraceState::ApiTraceState()
475{
476}
477
478ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
479{
480 m_parameters = parsedJson[QLatin1String("parameters")].toMap();
481 QVariantMap attachedShaders =
482 parsedJson[QLatin1String("shaders")].toMap();
483 QVariantMap::const_iterator itr;
484
485
486 for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd();
487 ++itr) {
488 QString type = itr.key();
489 QString source = itr.value().toString();
490 m_shaderSources[type] = source;
491 }
492
493 m_uniforms = parsedJson[QLatin1String("uniforms")].toMap();
494
495 QVariantMap textures =
496 parsedJson[QLatin1String("textures")].toMap();
497 for (itr = textures.constBegin(); itr != textures.constEnd(); ++itr) {
498 QVariantMap image = itr.value().toMap();
499 QSize size(image[QLatin1String("__width__")].toInt(),
500 image[QLatin1String("__height__")].toInt());
501 QString cls = image[QLatin1String("__class__")].toString();
Zack Rusinb25c4b92011-11-16 22:43:34 -0500502 int depth =
503 image[QLatin1String("__depth__")].toInt();
Zack Rusine181b992011-11-17 16:00:41 -0500504 QString formatName =
505 image[QLatin1String("__format__")].toString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400506
Zack Rusina1a3ad52011-08-27 19:19:18 -0400507 QByteArray dataArray =
508 image[QLatin1String("__data__")].toByteArray();
509
510 ApiTexture tex;
511 tex.setSize(size);
Zack Rusinb25c4b92011-11-16 22:43:34 -0500512 tex.setDepth(depth);
Zack Rusine181b992011-11-17 16:00:41 -0500513 tex.setFormatName(formatName);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400514 tex.setLabel(itr.key());
515 tex.contentsFromBase64(dataArray);
516
517 m_textures.append(tex);
518 }
519
520 QVariantMap fbos =
521 parsedJson[QLatin1String("framebuffer")].toMap();
522 for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) {
523 QVariantMap buffer = itr.value().toMap();
524 QSize size(buffer[QLatin1String("__width__")].toInt(),
525 buffer[QLatin1String("__height__")].toInt());
526 QString cls = buffer[QLatin1String("__class__")].toString();
Zack Rusinb25c4b92011-11-16 22:43:34 -0500527 int depth = buffer[QLatin1String("__depth__")].toInt();
Zack Rusine181b992011-11-17 16:00:41 -0500528 QString formatName = buffer[QLatin1String("__format__")].toString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400529
Zack Rusina1a3ad52011-08-27 19:19:18 -0400530 QByteArray dataArray =
531 buffer[QLatin1String("__data__")].toByteArray();
532
533 ApiFramebuffer fbo;
534 fbo.setSize(size);
Zack Rusinb25c4b92011-11-16 22:43:34 -0500535 fbo.setDepth(depth);
Zack Rusine181b992011-11-17 16:00:41 -0500536 fbo.setFormatName(formatName);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400537 fbo.setType(itr.key());
538 fbo.contentsFromBase64(dataArray);
539 m_framebuffers.append(fbo);
540 }
541}
542
543const QVariantMap & ApiTraceState::parameters() const
544{
545 return m_parameters;
546}
547
548const QMap<QString, QString> & ApiTraceState::shaderSources() const
549{
550 return m_shaderSources;
551}
552
553const QVariantMap & ApiTraceState::uniforms() const
554{
555 return m_uniforms;
556}
557
558bool ApiTraceState::isEmpty() const
559{
José Fonseca4e0bfee2012-11-28 10:45:08 +0000560 return m_parameters.isEmpty() &&
561 m_shaderSources.isEmpty() &&
562 m_textures.isEmpty() &&
563 m_framebuffers.isEmpty();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400564}
565
566const QList<ApiTexture> & ApiTraceState::textures() const
567{
568 return m_textures;
569}
570
571const QList<ApiFramebuffer> & ApiTraceState::framebuffers() const
572{
573 return m_framebuffers;
574}
575
Zack Rusin353f0532011-09-15 20:23:27 -0400576ApiFramebuffer ApiTraceState::colorBuffer() const
577{
578 foreach (ApiFramebuffer fbo, m_framebuffers) {
579 if (fbo.type() == QLatin1String("GL_BACK")) {
580 return fbo;
581 }
582 }
583 foreach (ApiFramebuffer fbo, m_framebuffers) {
584 if (fbo.type() == QLatin1String("GL_FRONT")) {
585 return fbo;
586 }
587 }
588 return ApiFramebuffer();
589}
590
591
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400592ApiTraceCallSignature::ApiTraceCallSignature(const QString &name,
593 const QStringList &argNames)
594 : m_name(name),
595 m_argNames(argNames)
596{
597}
598
599ApiTraceCallSignature::~ApiTraceCallSignature()
600{
601}
602
603QUrl ApiTraceCallSignature::helpUrl() const
604{
605 return m_helpUrl;
606}
607
608void ApiTraceCallSignature::setHelpUrl(const QUrl &url)
609{
610 m_helpUrl = url;
611}
612
Zack Rusina1a3ad52011-08-27 19:19:18 -0400613ApiTraceEvent::ApiTraceEvent()
614 : m_type(ApiTraceEvent::None),
Zack Rusined40bc62011-08-28 17:11:02 -0400615 m_hasBinaryData(false),
616 m_binaryDataIndex(0),
617 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400618 m_staticText(0)
619{
620}
621
622ApiTraceEvent::ApiTraceEvent(Type t)
623 : m_type(t),
Zack Rusined40bc62011-08-28 17:11:02 -0400624 m_hasBinaryData(false),
625 m_binaryDataIndex(0),
626 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400627 m_staticText(0)
628{
629}
630
631ApiTraceEvent::~ApiTraceEvent()
632{
Zack Rusined40bc62011-08-28 17:11:02 -0400633 delete m_state;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400634 delete m_staticText;
635}
636
637QVariantMap ApiTraceEvent::stateParameters() const
638{
Zack Rusined40bc62011-08-28 17:11:02 -0400639 if (m_state) {
640 return m_state->parameters();
641 } else {
642 return QVariantMap();
643 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400644}
645
Zack Rusined40bc62011-08-28 17:11:02 -0400646ApiTraceState *ApiTraceEvent::state() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400647{
648 return m_state;
649}
650
Zack Rusined40bc62011-08-28 17:11:02 -0400651void ApiTraceEvent::setState(ApiTraceState *state)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400652{
653 m_state = state;
654}
655
Zack Rusinebf971e2011-09-06 17:44:43 -0400656ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame,
657 TraceLoader *loader,
José Fonsecab4a3d142011-10-27 07:43:19 +0100658 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400659 : ApiTraceEvent(ApiTraceEvent::Call),
Zack Rusind9d9d222013-10-11 18:02:26 -0400660 m_parentFrame(parentFrame),
661 m_parentCall(0)
662{
663 loadData(loader, call);
664}
665
666ApiTraceCall::ApiTraceCall(ApiTraceCall *parentCall,
667 TraceLoader *loader,
668 const trace::Call *call)
669 : ApiTraceEvent(ApiTraceEvent::Call),
670 m_parentFrame(parentCall->parentFrame()),
671 m_parentCall(parentCall)
672{
673 loadData(loader, call);
674}
675
676
677ApiTraceCall::~ApiTraceCall()
678{
679}
680
681
682void
683ApiTraceCall::loadData(TraceLoader *loader,
684 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400685{
Zack Rusina1a3ad52011-08-27 19:19:18 -0400686 m_index = call->no;
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500687 m_thread = call->thread_id;
Zack Rusinebf971e2011-09-06 17:44:43 -0400688 m_signature = loader->signature(call->sig->id);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400689
690 if (!m_signature) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100691 QString name = QString::fromLatin1(call->sig->name);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400692 QStringList argNames;
Zack Rusinf22d7992011-08-28 02:23:47 -0400693 argNames.reserve(call->sig->num_args);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400694 for (int i = 0; i < call->sig->num_args; ++i) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100695 argNames += QString::fromLatin1(call->sig->arg_names[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400696 }
697 m_signature = new ApiTraceCallSignature(name, argNames);
Zack Rusinebf971e2011-09-06 17:44:43 -0400698 loader->addSignature(call->sig->id, m_signature);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400699 }
700 if (call->ret) {
Zack Rusinebf971e2011-09-06 17:44:43 -0400701 VariantVisitor retVisitor(loader);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400702 call->ret->visit(retVisitor);
703 m_returnValue = retVisitor.variant();
704 }
Zack Rusinf22d7992011-08-28 02:23:47 -0400705 m_argValues.reserve(call->args.size());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400706 for (int i = 0; i < call->args.size(); ++i) {
Carl Wortha5b476e2011-11-16 17:22:40 -0800707 if (call->args[i].value) {
José Fonseca1fa61832011-11-05 08:50:25 +0000708 VariantVisitor argVisitor(loader);
Carl Wortha5b476e2011-11-16 17:22:40 -0800709 call->args[i].value->visit(argVisitor);
José Fonseca1fa61832011-11-05 08:50:25 +0000710 m_argValues.append(argVisitor.variant());
711 if (m_argValues[i].type() == QVariant::ByteArray) {
712 m_hasBinaryData = true;
713 m_binaryDataIndex = i;
714 }
715 } else {
716 m_argValues.append(QVariant());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400717 }
718 }
Zack Rusinf736a622011-08-28 22:19:46 -0400719 m_argValues.squeeze();
José Fonseca340f5692011-11-30 07:04:44 +0000720 m_flags = call->flags;
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400721 if (call->backtrace != NULL) {
722 QString qbacktrace;
José Fonsecaac55ba82013-05-05 08:11:23 +0100723 for (int i = 0; i < call->backtrace->size(); i++) {
José Fonseca9c25e062013-05-06 07:25:40 +0100724 const trace::StackFrame * frame = (*call->backtrace)[i];
725 if (frame->module != NULL) {
726 qbacktrace += QString("%1 ").arg(frame->module);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400727 }
José Fonseca9c25e062013-05-06 07:25:40 +0100728 if (frame->function != NULL) {
729 qbacktrace += QString("at %1() ").arg(frame->function);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400730 }
José Fonseca9c25e062013-05-06 07:25:40 +0100731 if (frame->filename != NULL) {
732 qbacktrace += QString("at %1").arg(frame->filename);
733 if (frame->linenumber >= 0) {
734 qbacktrace += QString(":%1 ").arg(frame->linenumber);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400735 }
736 }
737 else {
José Fonseca9c25e062013-05-06 07:25:40 +0100738 if (frame->offset >= 0) {
739 qbacktrace += QString("[0x%1]").arg(frame->offset, 0, 16);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400740 }
741 }
742 qbacktrace += "\n";
743 }
744 this->setBacktrace(qbacktrace);
745 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400746}
747
Zack Rusind9d9d222013-10-11 18:02:26 -0400748ApiTraceCall *
749ApiTraceCall::parentCall() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400750{
Zack Rusind9d9d222013-10-11 18:02:26 -0400751 return m_parentCall;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400752}
753
754
Zack Rusind9d9d222013-10-11 18:02:26 -0400755ApiTraceEvent *
756ApiTraceCall::parentEvent() const
757{
758 if (m_parentCall)
759 return m_parentCall;
760 else
761 return m_parentFrame;
762}
763
764QVector<ApiTraceCall*>
765ApiTraceCall::children() const
766{
767 return m_children;
768}
769
770void
771ApiTraceCall::addChild(ApiTraceCall *call)
772{
773 m_children.append(call);
774}
775
776
777int
778ApiTraceCall::callIndex(ApiTraceCall *call) const
779{
780 return m_children.indexOf(call);
781}
782
783void
784ApiTraceCall::finishedAddingChildren()
785{
786 m_children.squeeze();
787}
788
Zack Rusina1a3ad52011-08-27 19:19:18 -0400789bool ApiTraceCall::hasError() const
790{
791 return !m_error.isEmpty();
792}
793
794QString ApiTraceCall::error() const
795{
796 return m_error;
797}
798
799void ApiTraceCall::setError(const QString &msg)
800{
801 if (m_error != msg) {
Zack Rusina1a3ad52011-08-27 19:19:18 -0400802 m_error = msg;
803 m_richText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400804 }
805}
806
807ApiTrace * ApiTraceCall::parentTrace() const
808{
809 if (m_parentFrame)
810 return m_parentFrame->parentTrace();
811 return NULL;
812}
813
Zack Rusinf736a622011-08-28 22:19:46 -0400814QVector<QVariant> ApiTraceCall::originalValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400815{
816 return m_argValues;
817}
818
Zack Rusinf736a622011-08-28 22:19:46 -0400819void ApiTraceCall::setEditedValues(const QVector<QVariant> &lst)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400820{
821 ApiTrace *trace = parentTrace();
822
823 m_editedValues = lst;
824 //lets regenerate data
825 m_richText = QString();
Zack Rusindc792082011-08-27 23:29:19 -0400826 m_searchText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400827 delete m_staticText;
828 m_staticText = 0;
829
830 if (trace) {
831 if (!lst.isEmpty()) {
832 trace->callEdited(this);
833 } else {
834 trace->callReverted(this);
835 }
836 }
837}
838
Zack Rusinf736a622011-08-28 22:19:46 -0400839QVector<QVariant> ApiTraceCall::editedValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400840{
841 return m_editedValues;
842}
843
844bool ApiTraceCall::edited() const
845{
846 return !m_editedValues.isEmpty();
847}
848
849void ApiTraceCall::revert()
850{
Zack Rusinf736a622011-08-28 22:19:46 -0400851 setEditedValues(QVector<QVariant>());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400852}
853
854void ApiTraceCall::setHelpUrl(const QUrl &url)
855{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400856 m_signature->setHelpUrl(url);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400857}
858
859void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
860{
861 m_parentFrame = frame;
862}
863
864ApiTraceFrame * ApiTraceCall::parentFrame()const
865{
866 return m_parentFrame;
867}
868
869int ApiTraceCall::index() const
870{
871 return m_index;
872}
873
874QString ApiTraceCall::name() const
875{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400876 return m_signature->name();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400877}
878
879QStringList ApiTraceCall::argNames() const
880{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400881 return m_signature->argNames();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400882}
883
Zack Rusinf736a622011-08-28 22:19:46 -0400884QVector<QVariant> ApiTraceCall::arguments() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400885{
886 if (m_editedValues.isEmpty())
887 return m_argValues;
888 else
889 return m_editedValues;
890}
891
Zack Rusind9d9d222013-10-11 18:02:26 -0400892ApiTraceEvent *
893ApiTraceCall::eventAtRow(int row) const
894{
895 if (row < m_children.count())
896 return m_children.value(row);
897 else
898 return NULL;
899}
900
Zack Rusina1a3ad52011-08-27 19:19:18 -0400901QVariant ApiTraceCall::returnValue() const
902{
903 return m_returnValue;
904}
905
José Fonseca340f5692011-11-30 07:04:44 +0000906trace::CallFlags ApiTraceCall::flags() const
907{
908 return m_flags;
909}
910
Zack Rusina1a3ad52011-08-27 19:19:18 -0400911QUrl ApiTraceCall::helpUrl() const
912{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400913 return m_signature->helpUrl();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400914}
915
916bool ApiTraceCall::hasBinaryData() const
917{
918 return m_hasBinaryData;
919}
920
921int ApiTraceCall::binaryDataIndex() const
922{
923 return m_binaryDataIndex;
924}
925
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400926QString ApiTraceCall::backtrace() const
927{
928 return m_backtrace;
929}
930
931void ApiTraceCall::setBacktrace(QString backtrace)
932{
933 m_backtrace = backtrace;
934}
935
Zack Rusin18eade52011-03-26 14:23:35 -0400936QStaticText ApiTraceCall::staticText() const
937{
Zack Rusin53484b22011-04-16 11:56:19 -0400938 if (m_staticText && !m_staticText->text().isEmpty())
939 return *m_staticText;
Zack Rusin18eade52011-03-26 14:23:35 -0400940
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500941 QStringList argNames = m_signature->argNames();
Zack Rusinf736a622011-08-28 22:19:46 -0400942 QVector<QVariant> argValues = arguments();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400943
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500944 QString richText;
945
José Fonseca2258a6d2014-05-22 21:14:21 +0100946 // TODO: Toggle this via a menu option.
947 if (0) {
948 richText += QString::fromLatin1("<span style=\"color: #aaaaaa; min-width: 3em;\">@%1</span> ")
949 .arg(m_thread);
950 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500951
José Fonseca991723d2014-05-22 21:32:37 +0100952 if (m_flags & trace::CALL_FLAG_MARKER &&
953 argNames.count() &&
954 argValues.last().userType() == QVariant::String)
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500955 {
956 // special handling for string markers
José Fonseca991723d2014-05-22 21:32:37 +0100957 QString msgText = plainTextToHTML(argValues.last().toString(), false, true);
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500958 richText += QString::fromLatin1(
959 "<span style=\"font-weight:bold;color:green;\">%1</span>")
960 .arg(msgText);
961 } else {
962 richText += QString::fromLatin1(
963 "<span style=\"font-weight:bold\">%1</span>(").arg(
964 m_signature->name());
965 for (int i = 0; i < argNames.count(); ++i) {
966 richText += QLatin1String("<span style=\"color:#0000ff\">");
967 QString argText = apiVariantToString(argValues[i]);
968
969 //if arguments are really long (e.g. shader text), cut them
970 // and elide it
971 if (argText.length() > 40) {
972 QString shortened = argText.mid(0, 40);
973 shortened[argText.length() - 5] = '.';
974 shortened[argText.length() - 4] = '.';
975 shortened[argText.length() - 3] = '.';
976 shortened[argText.length() - 2] = argText.at(argText.length() - 2);
977 shortened[argText.length() - 1] = argText.at(argText.length() - 1);
978 richText += shortened;
979 } else {
980 richText += argText;
981 }
982 richText += QLatin1String("</span>");
983 if (i < argNames.count() - 1)
984 richText += QLatin1String(", ");
Zack Rusindd7f2302011-03-31 22:55:57 -0400985 }
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500986 richText += QLatin1String(")");
987 if (m_returnValue.isValid()) {
988 richText +=
989 QLatin1Literal(" = ") %
990 QLatin1Literal("<span style=\"color:#0000ff\">") %
991 apiVariantToString(m_returnValue) %
992 QLatin1Literal("</span>");
993 }
José Fonseca908f38d2011-03-31 10:09:14 +0100994 }
Zack Rusin27cb2c42011-03-27 23:53:36 -0400995
Zack Rusin53484b22011-04-16 11:56:19 -0400996 if (!m_staticText)
997 m_staticText = new QStaticText(richText);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400998 else
999 m_staticText->setText(richText);
Zack Rusin27cb2c42011-03-27 23:53:36 -04001000 QTextOption opt;
1001 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -04001002 m_staticText->setTextOption(opt);
1003 m_staticText->prepare();
Zack Rusin27cb2c42011-03-27 23:53:36 -04001004
Zack Rusin53484b22011-04-16 11:56:19 -04001005 return *m_staticText;
Zack Rusin27cb2c42011-03-27 23:53:36 -04001006}
1007
1008QString ApiTraceCall::toHtml() const
1009{
1010 if (!m_richText.isEmpty())
1011 return m_richText;
1012
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001013 m_richText += QLatin1String("<div class=\"call\">");
Zack Rusinb53b1612011-04-19 01:33:58 -04001014
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001015
1016 m_richText +=
José Fonseca2258a6d2014-05-22 21:14:21 +01001017 QString::fromLatin1("%1 ")
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001018 .arg(m_index);
1019 QString parentTip;
1020 if (m_parentFrame) {
1021 parentTip =
1022 QString::fromLatin1("Frame %1")
1023 .arg(m_parentFrame->number);
1024 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001025
José Fonseca2258a6d2014-05-22 21:14:21 +01001026 m_richText += QString::fromLatin1("<span class=\"thread-id\">@%1</span> ")
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001027 .arg(m_thread);
1028
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001029 QUrl helpUrl = m_signature->helpUrl();
1030 if (helpUrl.isEmpty()) {
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\">%2</span>(")
1033 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001034 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001035 } else {
Zack Rusinb53b1612011-04-19 01:33:58 -04001036 m_richText += QString::fromLatin1(
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001037 "<span class=\"callName\" title=\"%1\"><a href=\"%2\">%3</a></span>(")
1038 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001039 .arg(helpUrl.toString())
1040 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001041 }
1042
Zack Rusinf736a622011-08-28 22:19:46 -04001043 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001044 QStringList argNames = m_signature->argNames();
1045 for (int i = 0; i < argNames.count(); ++i) {
Zack Rusinb53b1612011-04-19 01:33:58 -04001046 m_richText +=
1047 QLatin1String("<span class=\"arg-name\">") +
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001048 argNames[i] +
Zack Rusinb53b1612011-04-19 01:33:58 -04001049 QLatin1String("</span>") +
1050 QLatin1Literal(" = ") +
1051 QLatin1Literal("<span class=\"arg-value\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001052 apiVariantToString(argValues[i], true) +
Zack Rusinb53b1612011-04-19 01:33:58 -04001053 QLatin1Literal("</span>");
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001054 if (i < argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -04001055 m_richText += QLatin1String(", ");
Zack Rusin18eade52011-03-26 14:23:35 -04001056 }
1057 m_richText += QLatin1String(")");
1058
Zack Rusinead6aad2011-04-15 22:16:18 -04001059 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -04001060 m_richText +=
1061 QLatin1String(" = ") +
1062 QLatin1String("<span style=\"color:#0000ff\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001063 apiVariantToString(m_returnValue, true) +
Zack Rusin5e277b02011-04-16 21:52:26 -04001064 QLatin1String("</span>");
Zack Rusin18eade52011-03-26 14:23:35 -04001065 }
Zack Rusinb53b1612011-04-19 01:33:58 -04001066 m_richText += QLatin1String("</div>");
1067
Zack Rusincc0b4912011-04-19 01:59:20 -04001068 if (hasError()) {
1069 QString errorStr =
1070 QString::fromLatin1(
1071 "<div class=\"error\">%1</div>")
1072 .arg(m_error);
1073 m_richText += errorStr;
1074 }
1075
Zack Rusinb53b1612011-04-19 01:33:58 -04001076 m_richText =
1077 QString::fromLatin1(
1078 "<html><head><style type=\"text/css\" media=\"all\">"
1079 "%1</style></head><body>%2</body></html>")
1080 .arg(styleSheet)
1081 .arg(m_richText);
Zack Rusin5e277b02011-04-16 21:52:26 -04001082 m_richText.squeeze();
Zack Rusinb53b1612011-04-19 01:33:58 -04001083
1084 //qDebug()<<m_richText;
Zack Rusin18eade52011-03-26 14:23:35 -04001085 return m_richText;
1086}
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001087
Zack Rusindc792082011-08-27 23:29:19 -04001088QString ApiTraceCall::searchText() const
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001089{
Zack Rusindc792082011-08-27 23:29:19 -04001090 if (!m_searchText.isEmpty())
1091 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001092
Zack Rusinf736a622011-08-28 22:19:46 -04001093 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001094 m_searchText = m_signature->name() + QLatin1Literal("(");
1095 QStringList argNames = m_signature->argNames();
1096 for (int i = 0; i < argNames.count(); ++i) {
1097 m_searchText += argNames[i] +
Zack Rusin5e277b02011-04-16 21:52:26 -04001098 QLatin1Literal(" = ") +
Zack Rusin9af5bff2011-04-18 01:05:50 -04001099 apiVariantToString(argValues[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001100 if (i < argNames.count() - 1)
Zack Rusindc792082011-08-27 23:29:19 -04001101 m_searchText += QLatin1String(", ");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001102 }
Zack Rusindc792082011-08-27 23:29:19 -04001103 m_searchText += QLatin1String(")");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001104
Zack Rusinead6aad2011-04-15 22:16:18 -04001105 if (m_returnValue.isValid()) {
Zack Rusindc792082011-08-27 23:29:19 -04001106 m_searchText += QLatin1Literal(" = ") +
Zack Rusin5e277b02011-04-16 21:52:26 -04001107 apiVariantToString(m_returnValue);
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001108 }
Zack Rusindc792082011-08-27 23:29:19 -04001109 m_searchText.squeeze();
1110 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001111}
Zack Rusinf6667d12011-03-30 11:03:37 -04001112
Zack Rusina1a3ad52011-08-27 19:19:18 -04001113int ApiTraceCall::numChildren() const
1114{
Zack Rusind9d9d222013-10-11 18:02:26 -04001115 return m_children.count();
Zack Rusina1a3ad52011-08-27 19:19:18 -04001116}
1117
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001118bool ApiTraceCall::contains(const QString &str,
1119 Qt::CaseSensitivity sensitivity) const
1120{
1121 QString txt = searchText();
1122 return txt.contains(str, sensitivity);
1123}
1124
1125
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001126ApiTraceFrame::ApiTraceFrame(ApiTrace *parentTrace)
Zack Rusina1a3ad52011-08-27 19:19:18 -04001127 : ApiTraceEvent(ApiTraceEvent::Frame),
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001128 m_parentTrace(parentTrace),
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001129 m_binaryDataSize(0),
1130 m_loaded(false),
Zack Rusin851d0b02011-09-14 22:04:07 -04001131 m_callsToLoad(0),
1132 m_lastCallIndex(0)
Zack Rusina1a3ad52011-08-27 19:19:18 -04001133{
1134}
1135
Zack Rusinc1743432011-09-13 17:58:58 -04001136ApiTraceFrame::~ApiTraceFrame()
1137{
1138 qDeleteAll(m_calls);
1139}
1140
Zack Rusinf6667d12011-03-30 11:03:37 -04001141QStaticText ApiTraceFrame::staticText() const
1142{
Zack Rusin53484b22011-04-16 11:56:19 -04001143 if (m_staticText && !m_staticText->text().isEmpty())
1144 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -04001145
Zack Rusin45e094f2011-09-14 17:36:53 -04001146 QString richText = QObject::tr(
1147 "<span style=\"font-weight:bold\">Frame %1</span>"
1148 "&nbsp;&nbsp;&nbsp;"
1149 "<span style=\"font-style:italic;font-size:small;font-weight:lighter;\"> "
1150 "(%2 calls)</span>")
1151 .arg(number)
1152 .arg(m_loaded ? m_calls.count() : m_callsToLoad);
Zack Rusin9e292fc2011-04-26 23:03:42 -04001153
1154 //mark the frame if it uploads more than a meg a frame
1155 if (m_binaryDataSize > (1024*1024)) {
1156 richText =
1157 QObject::tr(
Zack Rusin45e094f2011-09-14 17:36:53 -04001158 "%1"
Zack Rusin9e292fc2011-04-26 23:03:42 -04001159 "<span style=\"font-style:italic;\">"
1160 "&nbsp;&nbsp;&nbsp;&nbsp;(%2MB)</span>")
Zack Rusin45e094f2011-09-14 17:36:53 -04001161 .arg(richText)
Zack Rusin9e292fc2011-04-26 23:03:42 -04001162 .arg(double(m_binaryDataSize / (1024.*1024.)), 0, 'g', 2);
Zack Rusin9e292fc2011-04-26 23:03:42 -04001163 }
Zack Rusinf6667d12011-03-30 11:03:37 -04001164
Zack Rusin53484b22011-04-16 11:56:19 -04001165 if (!m_staticText)
1166 m_staticText = new QStaticText(richText);
1167
Zack Rusinf6667d12011-03-30 11:03:37 -04001168 QTextOption opt;
1169 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -04001170 m_staticText->setTextOption(opt);
1171 m_staticText->prepare();
Zack Rusinf6667d12011-03-30 11:03:37 -04001172
Zack Rusin53484b22011-04-16 11:56:19 -04001173 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -04001174}
1175
Zack Rusinf6667d12011-03-30 11:03:37 -04001176int ApiTraceFrame::numChildren() const
1177{
Zack Rusind9d9d222013-10-11 18:02:26 -04001178 return m_children.count();
1179}
1180
1181int ApiTraceFrame::numTotalCalls() const
1182{
Zack Rusin3176ebe2011-09-06 21:11:36 -04001183 return m_calls.count();
Zack Rusinf6667d12011-03-30 11:03:37 -04001184}
1185
Zack Rusin7c1793e2011-04-16 23:14:25 -04001186ApiTrace * ApiTraceFrame::parentTrace() const
1187{
1188 return m_parentTrace;
1189}
1190
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001191QVector<ApiTraceCall*> ApiTraceFrame::calls() const
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001192{
1193 return m_calls;
1194}
1195
Zack Rusind9d9d222013-10-11 18:02:26 -04001196ApiTraceEvent * ApiTraceFrame::eventAtRow(int row) const
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001197{
Zack Rusind9d9d222013-10-11 18:02:26 -04001198 if (row < m_children.count())
1199 return m_children.value(row);
1200 else
1201 return NULL;
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001202}
1203
Zack Rusinda7579b2011-09-13 17:33:05 -04001204
1205ApiTraceCall * ApiTraceFrame::callWithIndex(int index) const
1206{
1207 QVector<ApiTraceCall*>::const_iterator itr;
1208 for (itr = m_calls.constBegin(); itr != m_calls.constEnd(); ++itr) {
1209 if ((*itr)->index() == index) {
1210 return *itr;
1211 }
1212 }
1213 return 0;
1214}
1215
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001216int ApiTraceFrame::callIndex(ApiTraceCall *call) const
1217{
Zack Rusind9d9d222013-10-11 18:02:26 -04001218 return m_children.indexOf(call);
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001219}
1220
1221bool ApiTraceFrame::isEmpty() const
1222{
Zack Rusin3176ebe2011-09-06 21:11:36 -04001223 if (m_loaded) {
1224 return m_calls.isEmpty();
1225 } else {
1226 return m_callsToLoad == 0;
1227 }
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001228}
1229
Zack Rusin9e292fc2011-04-26 23:03:42 -04001230int ApiTraceFrame::binaryDataSize() const
1231{
1232 return m_binaryDataSize;
1233}
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001234
Zack Rusind9d9d222013-10-11 18:02:26 -04001235void ApiTraceFrame::setCalls(const QVector<ApiTraceCall*> &children,
1236 const QVector<ApiTraceCall*> &calls,
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001237 quint64 binaryDataSize)
1238{
Zack Rusind9d9d222013-10-11 18:02:26 -04001239 m_children = children;
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001240 m_calls = calls;
1241 m_binaryDataSize = binaryDataSize;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001242 m_loaded = true;
Zack Rusin45e094f2011-09-14 17:36:53 -04001243 delete m_staticText;
1244 m_staticText = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001245}
1246
Zack Rusin1a9f7af2011-09-18 19:40:47 -04001247bool ApiTraceFrame::isLoaded() const
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001248{
1249 return m_loaded;
1250}
1251
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001252void ApiTraceFrame::setNumChildren(int num)
1253{
1254 m_callsToLoad = num;
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001255}
Zack Rusinebf971e2011-09-06 17:44:43 -04001256
1257void ApiTraceFrame::setParentTrace(ApiTrace *parent)
1258{
1259 m_parentTrace = parent;
1260}
Zack Rusin3176ebe2011-09-06 21:11:36 -04001261
1262int ApiTraceFrame::numChildrenToLoad() const
1263{
1264 return m_callsToLoad;
1265}
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001266
1267ApiTraceCall *
1268ApiTraceFrame::findNextCall(ApiTraceCall *from,
1269 const QString &str,
1270 Qt::CaseSensitivity sensitivity) const
1271{
1272 Q_ASSERT(m_loaded);
1273
1274 int callIndex = 0;
1275
1276 if (from) {
1277 callIndex = m_calls.indexOf(from) + 1;
1278 }
1279
1280 for (int i = callIndex; i < m_calls.count(); ++i) {
1281 ApiTraceCall *call = m_calls[i];
1282 if (call->contains(str, sensitivity)) {
1283 return call;
1284 }
1285 }
1286 return 0;
1287}
1288
1289ApiTraceCall *
1290ApiTraceFrame::findPrevCall(ApiTraceCall *from,
1291 const QString &str,
1292 Qt::CaseSensitivity sensitivity) const
1293{
1294 Q_ASSERT(m_loaded);
1295
1296 int callIndex = m_calls.count() - 1;
1297
1298 if (from) {
1299 callIndex = m_calls.indexOf(from) - 1;
1300 }
1301
1302 for (int i = callIndex; i >= 0; --i) {
1303 ApiTraceCall *call = m_calls[i];
1304 if (call->contains(str, sensitivity)) {
1305 return call;
1306 }
1307 }
1308 return 0;
1309}
Zack Rusin851d0b02011-09-14 22:04:07 -04001310
1311void ApiTraceFrame::setLastCallIndex(unsigned index)
1312{
1313 m_lastCallIndex = index;
1314}
1315
1316unsigned ApiTraceFrame::lastCallIndex() const
1317{
1318 if (m_loaded && !m_calls.isEmpty()) {
1319 return m_calls.last()->index();
1320 } else {
1321 return m_lastCallIndex;
1322 }
1323}
Dan McCabe10bd4242012-03-05 17:20:40 -08001324
José Fonseca8759ae02012-03-24 07:44:43 +00001325void ApiTraceFrame::setThumbnail(const QImage & thumbnail)
Dan McCabe10bd4242012-03-05 17:20:40 -08001326{
1327 m_thumbnail = thumbnail;
1328}
1329
José Fonseca8759ae02012-03-24 07:44:43 +00001330const QImage & ApiTraceFrame::thumbnail() const
Dan McCabe10bd4242012-03-05 17:20:40 -08001331{
1332 return m_thumbnail;
1333}