blob: a48b478218346c1372079438ebfc13d9c5544fa5 [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
José Fonsecad1d1ecf2014-10-22 23:55:16 +0100495 m_buffers = parsedJson[QLatin1String("buffers")].toMap();
496
Zack Rusina1a3ad52011-08-27 19:19:18 -0400497 QVariantMap textures =
498 parsedJson[QLatin1String("textures")].toMap();
499 for (itr = textures.constBegin(); itr != textures.constEnd(); ++itr) {
500 QVariantMap image = itr.value().toMap();
501 QSize size(image[QLatin1String("__width__")].toInt(),
502 image[QLatin1String("__height__")].toInt());
503 QString cls = image[QLatin1String("__class__")].toString();
Zack Rusinb25c4b92011-11-16 22:43:34 -0500504 int depth =
505 image[QLatin1String("__depth__")].toInt();
Zack Rusine181b992011-11-17 16:00:41 -0500506 QString formatName =
507 image[QLatin1String("__format__")].toString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400508
Zack Rusina1a3ad52011-08-27 19:19:18 -0400509 QByteArray dataArray =
510 image[QLatin1String("__data__")].toByteArray();
511
512 ApiTexture tex;
513 tex.setSize(size);
Zack Rusinb25c4b92011-11-16 22:43:34 -0500514 tex.setDepth(depth);
Zack Rusine181b992011-11-17 16:00:41 -0500515 tex.setFormatName(formatName);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400516 tex.setLabel(itr.key());
517 tex.contentsFromBase64(dataArray);
518
519 m_textures.append(tex);
520 }
521
522 QVariantMap fbos =
523 parsedJson[QLatin1String("framebuffer")].toMap();
524 for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) {
525 QVariantMap buffer = itr.value().toMap();
526 QSize size(buffer[QLatin1String("__width__")].toInt(),
527 buffer[QLatin1String("__height__")].toInt());
528 QString cls = buffer[QLatin1String("__class__")].toString();
Zack Rusinb25c4b92011-11-16 22:43:34 -0500529 int depth = buffer[QLatin1String("__depth__")].toInt();
Zack Rusine181b992011-11-17 16:00:41 -0500530 QString formatName = buffer[QLatin1String("__format__")].toString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400531
Zack Rusina1a3ad52011-08-27 19:19:18 -0400532 QByteArray dataArray =
533 buffer[QLatin1String("__data__")].toByteArray();
534
535 ApiFramebuffer fbo;
536 fbo.setSize(size);
Zack Rusinb25c4b92011-11-16 22:43:34 -0500537 fbo.setDepth(depth);
Zack Rusine181b992011-11-17 16:00:41 -0500538 fbo.setFormatName(formatName);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400539 fbo.setType(itr.key());
540 fbo.contentsFromBase64(dataArray);
541 m_framebuffers.append(fbo);
542 }
543}
544
545const QVariantMap & ApiTraceState::parameters() const
546{
547 return m_parameters;
548}
549
550const QMap<QString, QString> & ApiTraceState::shaderSources() const
551{
552 return m_shaderSources;
553}
554
555const QVariantMap & ApiTraceState::uniforms() const
556{
557 return m_uniforms;
558}
559
José Fonsecad1d1ecf2014-10-22 23:55:16 +0100560const QVariantMap & ApiTraceState::buffers() const
561{
562 return m_buffers;
563}
564
Zack Rusina1a3ad52011-08-27 19:19:18 -0400565bool ApiTraceState::isEmpty() const
566{
José Fonseca4e0bfee2012-11-28 10:45:08 +0000567 return m_parameters.isEmpty() &&
568 m_shaderSources.isEmpty() &&
569 m_textures.isEmpty() &&
570 m_framebuffers.isEmpty();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400571}
572
573const QList<ApiTexture> & ApiTraceState::textures() const
574{
575 return m_textures;
576}
577
578const QList<ApiFramebuffer> & ApiTraceState::framebuffers() const
579{
580 return m_framebuffers;
581}
582
Zack Rusin353f0532011-09-15 20:23:27 -0400583ApiFramebuffer ApiTraceState::colorBuffer() const
584{
585 foreach (ApiFramebuffer fbo, m_framebuffers) {
586 if (fbo.type() == QLatin1String("GL_BACK")) {
587 return fbo;
588 }
589 }
590 foreach (ApiFramebuffer fbo, m_framebuffers) {
591 if (fbo.type() == QLatin1String("GL_FRONT")) {
592 return fbo;
593 }
594 }
595 return ApiFramebuffer();
596}
597
598
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400599ApiTraceCallSignature::ApiTraceCallSignature(const QString &name,
600 const QStringList &argNames)
601 : m_name(name),
602 m_argNames(argNames)
603{
604}
605
606ApiTraceCallSignature::~ApiTraceCallSignature()
607{
608}
609
610QUrl ApiTraceCallSignature::helpUrl() const
611{
612 return m_helpUrl;
613}
614
615void ApiTraceCallSignature::setHelpUrl(const QUrl &url)
616{
617 m_helpUrl = url;
618}
619
Zack Rusina1a3ad52011-08-27 19:19:18 -0400620ApiTraceEvent::ApiTraceEvent()
621 : m_type(ApiTraceEvent::None),
Zack Rusined40bc62011-08-28 17:11:02 -0400622 m_hasBinaryData(false),
623 m_binaryDataIndex(0),
624 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400625 m_staticText(0)
626{
627}
628
629ApiTraceEvent::ApiTraceEvent(Type t)
630 : m_type(t),
Zack Rusined40bc62011-08-28 17:11:02 -0400631 m_hasBinaryData(false),
632 m_binaryDataIndex(0),
633 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400634 m_staticText(0)
635{
636}
637
638ApiTraceEvent::~ApiTraceEvent()
639{
Zack Rusined40bc62011-08-28 17:11:02 -0400640 delete m_state;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400641 delete m_staticText;
642}
643
644QVariantMap ApiTraceEvent::stateParameters() const
645{
Zack Rusined40bc62011-08-28 17:11:02 -0400646 if (m_state) {
647 return m_state->parameters();
648 } else {
649 return QVariantMap();
650 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400651}
652
Zack Rusined40bc62011-08-28 17:11:02 -0400653ApiTraceState *ApiTraceEvent::state() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400654{
655 return m_state;
656}
657
Zack Rusined40bc62011-08-28 17:11:02 -0400658void ApiTraceEvent::setState(ApiTraceState *state)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400659{
660 m_state = state;
661}
662
Zack Rusinebf971e2011-09-06 17:44:43 -0400663ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame,
664 TraceLoader *loader,
José Fonsecab4a3d142011-10-27 07:43:19 +0100665 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400666 : ApiTraceEvent(ApiTraceEvent::Call),
Zack Rusind9d9d222013-10-11 18:02:26 -0400667 m_parentFrame(parentFrame),
668 m_parentCall(0)
669{
670 loadData(loader, call);
671}
672
673ApiTraceCall::ApiTraceCall(ApiTraceCall *parentCall,
674 TraceLoader *loader,
675 const trace::Call *call)
676 : ApiTraceEvent(ApiTraceEvent::Call),
677 m_parentFrame(parentCall->parentFrame()),
678 m_parentCall(parentCall)
679{
680 loadData(loader, call);
681}
682
683
684ApiTraceCall::~ApiTraceCall()
685{
686}
687
688
689void
690ApiTraceCall::loadData(TraceLoader *loader,
691 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400692{
Zack Rusina1a3ad52011-08-27 19:19:18 -0400693 m_index = call->no;
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500694 m_thread = call->thread_id;
Zack Rusinebf971e2011-09-06 17:44:43 -0400695 m_signature = loader->signature(call->sig->id);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400696
697 if (!m_signature) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100698 QString name = QString::fromLatin1(call->sig->name);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400699 QStringList argNames;
Zack Rusinf22d7992011-08-28 02:23:47 -0400700 argNames.reserve(call->sig->num_args);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400701 for (int i = 0; i < call->sig->num_args; ++i) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100702 argNames += QString::fromLatin1(call->sig->arg_names[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400703 }
704 m_signature = new ApiTraceCallSignature(name, argNames);
Zack Rusinebf971e2011-09-06 17:44:43 -0400705 loader->addSignature(call->sig->id, m_signature);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400706 }
707 if (call->ret) {
Zack Rusinebf971e2011-09-06 17:44:43 -0400708 VariantVisitor retVisitor(loader);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400709 call->ret->visit(retVisitor);
710 m_returnValue = retVisitor.variant();
711 }
Zack Rusinf22d7992011-08-28 02:23:47 -0400712 m_argValues.reserve(call->args.size());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400713 for (int i = 0; i < call->args.size(); ++i) {
Carl Wortha5b476e2011-11-16 17:22:40 -0800714 if (call->args[i].value) {
José Fonseca1fa61832011-11-05 08:50:25 +0000715 VariantVisitor argVisitor(loader);
Carl Wortha5b476e2011-11-16 17:22:40 -0800716 call->args[i].value->visit(argVisitor);
José Fonseca1fa61832011-11-05 08:50:25 +0000717 m_argValues.append(argVisitor.variant());
718 if (m_argValues[i].type() == QVariant::ByteArray) {
719 m_hasBinaryData = true;
720 m_binaryDataIndex = i;
721 }
722 } else {
723 m_argValues.append(QVariant());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400724 }
725 }
Zack Rusinf736a622011-08-28 22:19:46 -0400726 m_argValues.squeeze();
José Fonseca340f5692011-11-30 07:04:44 +0000727 m_flags = call->flags;
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400728 if (call->backtrace != NULL) {
729 QString qbacktrace;
José Fonsecaac55ba82013-05-05 08:11:23 +0100730 for (int i = 0; i < call->backtrace->size(); i++) {
José Fonseca9c25e062013-05-06 07:25:40 +0100731 const trace::StackFrame * frame = (*call->backtrace)[i];
732 if (frame->module != NULL) {
733 qbacktrace += QString("%1 ").arg(frame->module);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400734 }
José Fonseca9c25e062013-05-06 07:25:40 +0100735 if (frame->function != NULL) {
736 qbacktrace += QString("at %1() ").arg(frame->function);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400737 }
José Fonseca9c25e062013-05-06 07:25:40 +0100738 if (frame->filename != NULL) {
739 qbacktrace += QString("at %1").arg(frame->filename);
740 if (frame->linenumber >= 0) {
741 qbacktrace += QString(":%1 ").arg(frame->linenumber);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400742 }
743 }
744 else {
José Fonseca9c25e062013-05-06 07:25:40 +0100745 if (frame->offset >= 0) {
746 qbacktrace += QString("[0x%1]").arg(frame->offset, 0, 16);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400747 }
748 }
749 qbacktrace += "\n";
750 }
751 this->setBacktrace(qbacktrace);
752 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400753}
754
Zack Rusind9d9d222013-10-11 18:02:26 -0400755ApiTraceCall *
756ApiTraceCall::parentCall() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400757{
Zack Rusind9d9d222013-10-11 18:02:26 -0400758 return m_parentCall;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400759}
760
761
Zack Rusind9d9d222013-10-11 18:02:26 -0400762ApiTraceEvent *
763ApiTraceCall::parentEvent() const
764{
765 if (m_parentCall)
766 return m_parentCall;
767 else
768 return m_parentFrame;
769}
770
771QVector<ApiTraceCall*>
772ApiTraceCall::children() const
773{
774 return m_children;
775}
776
777void
778ApiTraceCall::addChild(ApiTraceCall *call)
779{
780 m_children.append(call);
781}
782
783
784int
785ApiTraceCall::callIndex(ApiTraceCall *call) const
786{
787 return m_children.indexOf(call);
788}
789
790void
791ApiTraceCall::finishedAddingChildren()
792{
793 m_children.squeeze();
794}
795
Zack Rusina1a3ad52011-08-27 19:19:18 -0400796bool ApiTraceCall::hasError() const
797{
798 return !m_error.isEmpty();
799}
800
801QString ApiTraceCall::error() const
802{
803 return m_error;
804}
805
806void ApiTraceCall::setError(const QString &msg)
807{
808 if (m_error != msg) {
Zack Rusina1a3ad52011-08-27 19:19:18 -0400809 m_error = msg;
810 m_richText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400811 }
812}
813
814ApiTrace * ApiTraceCall::parentTrace() const
815{
816 if (m_parentFrame)
817 return m_parentFrame->parentTrace();
818 return NULL;
819}
820
Zack Rusinf736a622011-08-28 22:19:46 -0400821QVector<QVariant> ApiTraceCall::originalValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400822{
823 return m_argValues;
824}
825
Zack Rusinf736a622011-08-28 22:19:46 -0400826void ApiTraceCall::setEditedValues(const QVector<QVariant> &lst)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400827{
828 ApiTrace *trace = parentTrace();
829
830 m_editedValues = lst;
831 //lets regenerate data
832 m_richText = QString();
Zack Rusindc792082011-08-27 23:29:19 -0400833 m_searchText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400834 delete m_staticText;
835 m_staticText = 0;
836
837 if (trace) {
838 if (!lst.isEmpty()) {
839 trace->callEdited(this);
840 } else {
841 trace->callReverted(this);
842 }
843 }
844}
845
Zack Rusinf736a622011-08-28 22:19:46 -0400846QVector<QVariant> ApiTraceCall::editedValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400847{
848 return m_editedValues;
849}
850
851bool ApiTraceCall::edited() const
852{
853 return !m_editedValues.isEmpty();
854}
855
856void ApiTraceCall::revert()
857{
Zack Rusinf736a622011-08-28 22:19:46 -0400858 setEditedValues(QVector<QVariant>());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400859}
860
861void ApiTraceCall::setHelpUrl(const QUrl &url)
862{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400863 m_signature->setHelpUrl(url);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400864}
865
866void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
867{
868 m_parentFrame = frame;
869}
870
871ApiTraceFrame * ApiTraceCall::parentFrame()const
872{
873 return m_parentFrame;
874}
875
876int ApiTraceCall::index() const
877{
878 return m_index;
879}
880
881QString ApiTraceCall::name() const
882{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400883 return m_signature->name();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400884}
885
886QStringList ApiTraceCall::argNames() const
887{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400888 return m_signature->argNames();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400889}
890
Zack Rusinf736a622011-08-28 22:19:46 -0400891QVector<QVariant> ApiTraceCall::arguments() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400892{
893 if (m_editedValues.isEmpty())
894 return m_argValues;
895 else
896 return m_editedValues;
897}
898
Zack Rusind9d9d222013-10-11 18:02:26 -0400899ApiTraceEvent *
900ApiTraceCall::eventAtRow(int row) const
901{
902 if (row < m_children.count())
903 return m_children.value(row);
904 else
905 return NULL;
906}
907
Zack Rusina1a3ad52011-08-27 19:19:18 -0400908QVariant ApiTraceCall::returnValue() const
909{
910 return m_returnValue;
911}
912
José Fonseca340f5692011-11-30 07:04:44 +0000913trace::CallFlags ApiTraceCall::flags() const
914{
915 return m_flags;
916}
917
Zack Rusina1a3ad52011-08-27 19:19:18 -0400918QUrl ApiTraceCall::helpUrl() const
919{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400920 return m_signature->helpUrl();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400921}
922
923bool ApiTraceCall::hasBinaryData() const
924{
925 return m_hasBinaryData;
926}
927
928int ApiTraceCall::binaryDataIndex() const
929{
930 return m_binaryDataIndex;
931}
932
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400933QString ApiTraceCall::backtrace() const
934{
935 return m_backtrace;
936}
937
938void ApiTraceCall::setBacktrace(QString backtrace)
939{
940 m_backtrace = backtrace;
941}
942
Zack Rusin18eade52011-03-26 14:23:35 -0400943QStaticText ApiTraceCall::staticText() const
944{
Zack Rusin53484b22011-04-16 11:56:19 -0400945 if (m_staticText && !m_staticText->text().isEmpty())
946 return *m_staticText;
Zack Rusin18eade52011-03-26 14:23:35 -0400947
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500948 QStringList argNames = m_signature->argNames();
Zack Rusinf736a622011-08-28 22:19:46 -0400949 QVector<QVariant> argValues = arguments();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400950
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500951 QString richText;
952
José Fonseca2258a6d2014-05-22 21:14:21 +0100953 // TODO: Toggle this via a menu option.
954 if (0) {
955 richText += QString::fromLatin1("<span style=\"color: #aaaaaa; min-width: 3em;\">@%1</span> ")
956 .arg(m_thread);
957 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500958
José Fonseca991723d2014-05-22 21:32:37 +0100959 if (m_flags & trace::CALL_FLAG_MARKER &&
960 argNames.count() &&
961 argValues.last().userType() == QVariant::String)
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500962 {
963 // special handling for string markers
José Fonseca991723d2014-05-22 21:32:37 +0100964 QString msgText = plainTextToHTML(argValues.last().toString(), false, true);
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500965 richText += QString::fromLatin1(
966 "<span style=\"font-weight:bold;color:green;\">%1</span>")
967 .arg(msgText);
968 } else {
969 richText += QString::fromLatin1(
970 "<span style=\"font-weight:bold\">%1</span>(").arg(
971 m_signature->name());
972 for (int i = 0; i < argNames.count(); ++i) {
973 richText += QLatin1String("<span style=\"color:#0000ff\">");
974 QString argText = apiVariantToString(argValues[i]);
975
976 //if arguments are really long (e.g. shader text), cut them
977 // and elide it
978 if (argText.length() > 40) {
979 QString shortened = argText.mid(0, 40);
980 shortened[argText.length() - 5] = '.';
981 shortened[argText.length() - 4] = '.';
982 shortened[argText.length() - 3] = '.';
983 shortened[argText.length() - 2] = argText.at(argText.length() - 2);
984 shortened[argText.length() - 1] = argText.at(argText.length() - 1);
985 richText += shortened;
986 } else {
987 richText += argText;
988 }
989 richText += QLatin1String("</span>");
990 if (i < argNames.count() - 1)
991 richText += QLatin1String(", ");
Zack Rusindd7f2302011-03-31 22:55:57 -0400992 }
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500993 richText += QLatin1String(")");
994 if (m_returnValue.isValid()) {
995 richText +=
996 QLatin1Literal(" = ") %
997 QLatin1Literal("<span style=\"color:#0000ff\">") %
998 apiVariantToString(m_returnValue) %
999 QLatin1Literal("</span>");
1000 }
José Fonseca908f38d2011-03-31 10:09:14 +01001001 }
Zack Rusin27cb2c42011-03-27 23:53:36 -04001002
Zack Rusin53484b22011-04-16 11:56:19 -04001003 if (!m_staticText)
1004 m_staticText = new QStaticText(richText);
Zack Rusin9af5bff2011-04-18 01:05:50 -04001005 else
1006 m_staticText->setText(richText);
Zack Rusin27cb2c42011-03-27 23:53:36 -04001007 QTextOption opt;
1008 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -04001009 m_staticText->setTextOption(opt);
1010 m_staticText->prepare();
Zack Rusin27cb2c42011-03-27 23:53:36 -04001011
Zack Rusin53484b22011-04-16 11:56:19 -04001012 return *m_staticText;
Zack Rusin27cb2c42011-03-27 23:53:36 -04001013}
1014
1015QString ApiTraceCall::toHtml() const
1016{
1017 if (!m_richText.isEmpty())
1018 return m_richText;
1019
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001020 m_richText += QLatin1String("<div class=\"call\">");
Zack Rusinb53b1612011-04-19 01:33:58 -04001021
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001022
1023 m_richText +=
José Fonseca2258a6d2014-05-22 21:14:21 +01001024 QString::fromLatin1("%1 ")
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001025 .arg(m_index);
1026 QString parentTip;
1027 if (m_parentFrame) {
1028 parentTip =
1029 QString::fromLatin1("Frame %1")
1030 .arg(m_parentFrame->number);
1031 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001032
José Fonseca2258a6d2014-05-22 21:14:21 +01001033 m_richText += QString::fromLatin1("<span class=\"thread-id\">@%1</span> ")
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001034 .arg(m_thread);
1035
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001036 QUrl helpUrl = m_signature->helpUrl();
1037 if (helpUrl.isEmpty()) {
Zack Rusinb53b1612011-04-19 01:33:58 -04001038 m_richText += QString::fromLatin1(
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001039 "<span class=\"callName\" title=\"%1\">%2</span>(")
1040 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001041 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001042 } else {
Zack Rusinb53b1612011-04-19 01:33:58 -04001043 m_richText += QString::fromLatin1(
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001044 "<span class=\"callName\" title=\"%1\"><a href=\"%2\">%3</a></span>(")
1045 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001046 .arg(helpUrl.toString())
1047 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001048 }
1049
Zack Rusinf736a622011-08-28 22:19:46 -04001050 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001051 QStringList argNames = m_signature->argNames();
1052 for (int i = 0; i < argNames.count(); ++i) {
Zack Rusinb53b1612011-04-19 01:33:58 -04001053 m_richText +=
1054 QLatin1String("<span class=\"arg-name\">") +
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001055 argNames[i] +
Zack Rusinb53b1612011-04-19 01:33:58 -04001056 QLatin1String("</span>") +
1057 QLatin1Literal(" = ") +
1058 QLatin1Literal("<span class=\"arg-value\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001059 apiVariantToString(argValues[i], true) +
Zack Rusinb53b1612011-04-19 01:33:58 -04001060 QLatin1Literal("</span>");
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001061 if (i < argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -04001062 m_richText += QLatin1String(", ");
Zack Rusin18eade52011-03-26 14:23:35 -04001063 }
1064 m_richText += QLatin1String(")");
1065
Zack Rusinead6aad2011-04-15 22:16:18 -04001066 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -04001067 m_richText +=
1068 QLatin1String(" = ") +
1069 QLatin1String("<span style=\"color:#0000ff\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001070 apiVariantToString(m_returnValue, true) +
Zack Rusin5e277b02011-04-16 21:52:26 -04001071 QLatin1String("</span>");
Zack Rusin18eade52011-03-26 14:23:35 -04001072 }
Zack Rusinb53b1612011-04-19 01:33:58 -04001073 m_richText += QLatin1String("</div>");
1074
Zack Rusincc0b4912011-04-19 01:59:20 -04001075 if (hasError()) {
1076 QString errorStr =
1077 QString::fromLatin1(
1078 "<div class=\"error\">%1</div>")
1079 .arg(m_error);
1080 m_richText += errorStr;
1081 }
1082
Zack Rusinb53b1612011-04-19 01:33:58 -04001083 m_richText =
1084 QString::fromLatin1(
1085 "<html><head><style type=\"text/css\" media=\"all\">"
1086 "%1</style></head><body>%2</body></html>")
1087 .arg(styleSheet)
1088 .arg(m_richText);
Zack Rusin5e277b02011-04-16 21:52:26 -04001089 m_richText.squeeze();
Zack Rusinb53b1612011-04-19 01:33:58 -04001090
1091 //qDebug()<<m_richText;
Zack Rusin18eade52011-03-26 14:23:35 -04001092 return m_richText;
1093}
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001094
Zack Rusindc792082011-08-27 23:29:19 -04001095QString ApiTraceCall::searchText() const
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001096{
Zack Rusindc792082011-08-27 23:29:19 -04001097 if (!m_searchText.isEmpty())
1098 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001099
Zack Rusinf736a622011-08-28 22:19:46 -04001100 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001101 m_searchText = m_signature->name() + QLatin1Literal("(");
1102 QStringList argNames = m_signature->argNames();
1103 for (int i = 0; i < argNames.count(); ++i) {
1104 m_searchText += argNames[i] +
Zack Rusin5e277b02011-04-16 21:52:26 -04001105 QLatin1Literal(" = ") +
Zack Rusin9af5bff2011-04-18 01:05:50 -04001106 apiVariantToString(argValues[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001107 if (i < argNames.count() - 1)
Zack Rusindc792082011-08-27 23:29:19 -04001108 m_searchText += QLatin1String(", ");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001109 }
Zack Rusindc792082011-08-27 23:29:19 -04001110 m_searchText += QLatin1String(")");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001111
Zack Rusinead6aad2011-04-15 22:16:18 -04001112 if (m_returnValue.isValid()) {
Zack Rusindc792082011-08-27 23:29:19 -04001113 m_searchText += QLatin1Literal(" = ") +
Zack Rusin5e277b02011-04-16 21:52:26 -04001114 apiVariantToString(m_returnValue);
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001115 }
Zack Rusindc792082011-08-27 23:29:19 -04001116 m_searchText.squeeze();
1117 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001118}
Zack Rusinf6667d12011-03-30 11:03:37 -04001119
Zack Rusina1a3ad52011-08-27 19:19:18 -04001120int ApiTraceCall::numChildren() const
1121{
Zack Rusind9d9d222013-10-11 18:02:26 -04001122 return m_children.count();
Zack Rusina1a3ad52011-08-27 19:19:18 -04001123}
1124
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001125bool ApiTraceCall::contains(const QString &str,
1126 Qt::CaseSensitivity sensitivity) const
1127{
1128 QString txt = searchText();
1129 return txt.contains(str, sensitivity);
1130}
1131
1132
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001133ApiTraceFrame::ApiTraceFrame(ApiTrace *parentTrace)
Zack Rusina1a3ad52011-08-27 19:19:18 -04001134 : ApiTraceEvent(ApiTraceEvent::Frame),
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001135 m_parentTrace(parentTrace),
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001136 m_binaryDataSize(0),
1137 m_loaded(false),
Zack Rusin851d0b02011-09-14 22:04:07 -04001138 m_callsToLoad(0),
1139 m_lastCallIndex(0)
Zack Rusina1a3ad52011-08-27 19:19:18 -04001140{
1141}
1142
Zack Rusinc1743432011-09-13 17:58:58 -04001143ApiTraceFrame::~ApiTraceFrame()
1144{
1145 qDeleteAll(m_calls);
1146}
1147
Zack Rusinf6667d12011-03-30 11:03:37 -04001148QStaticText ApiTraceFrame::staticText() const
1149{
Zack Rusin53484b22011-04-16 11:56:19 -04001150 if (m_staticText && !m_staticText->text().isEmpty())
1151 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -04001152
Zack Rusin45e094f2011-09-14 17:36:53 -04001153 QString richText = QObject::tr(
1154 "<span style=\"font-weight:bold\">Frame %1</span>"
1155 "&nbsp;&nbsp;&nbsp;"
1156 "<span style=\"font-style:italic;font-size:small;font-weight:lighter;\"> "
1157 "(%2 calls)</span>")
1158 .arg(number)
1159 .arg(m_loaded ? m_calls.count() : m_callsToLoad);
Zack Rusin9e292fc2011-04-26 23:03:42 -04001160
1161 //mark the frame if it uploads more than a meg a frame
1162 if (m_binaryDataSize > (1024*1024)) {
1163 richText =
1164 QObject::tr(
Zack Rusin45e094f2011-09-14 17:36:53 -04001165 "%1"
Zack Rusin9e292fc2011-04-26 23:03:42 -04001166 "<span style=\"font-style:italic;\">"
1167 "&nbsp;&nbsp;&nbsp;&nbsp;(%2MB)</span>")
Zack Rusin45e094f2011-09-14 17:36:53 -04001168 .arg(richText)
Zack Rusin9e292fc2011-04-26 23:03:42 -04001169 .arg(double(m_binaryDataSize / (1024.*1024.)), 0, 'g', 2);
Zack Rusin9e292fc2011-04-26 23:03:42 -04001170 }
Zack Rusinf6667d12011-03-30 11:03:37 -04001171
Zack Rusin53484b22011-04-16 11:56:19 -04001172 if (!m_staticText)
1173 m_staticText = new QStaticText(richText);
1174
Zack Rusinf6667d12011-03-30 11:03:37 -04001175 QTextOption opt;
1176 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -04001177 m_staticText->setTextOption(opt);
1178 m_staticText->prepare();
Zack Rusinf6667d12011-03-30 11:03:37 -04001179
Zack Rusin53484b22011-04-16 11:56:19 -04001180 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -04001181}
1182
Zack Rusinf6667d12011-03-30 11:03:37 -04001183int ApiTraceFrame::numChildren() const
1184{
Zack Rusind9d9d222013-10-11 18:02:26 -04001185 return m_children.count();
1186}
1187
1188int ApiTraceFrame::numTotalCalls() const
1189{
Zack Rusin3176ebe2011-09-06 21:11:36 -04001190 return m_calls.count();
Zack Rusinf6667d12011-03-30 11:03:37 -04001191}
1192
Zack Rusin7c1793e2011-04-16 23:14:25 -04001193ApiTrace * ApiTraceFrame::parentTrace() const
1194{
1195 return m_parentTrace;
1196}
1197
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001198QVector<ApiTraceCall*> ApiTraceFrame::calls() const
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001199{
1200 return m_calls;
1201}
1202
Zack Rusind9d9d222013-10-11 18:02:26 -04001203ApiTraceEvent * ApiTraceFrame::eventAtRow(int row) const
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001204{
Zack Rusind9d9d222013-10-11 18:02:26 -04001205 if (row < m_children.count())
1206 return m_children.value(row);
1207 else
1208 return NULL;
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001209}
1210
Zack Rusinda7579b2011-09-13 17:33:05 -04001211
1212ApiTraceCall * ApiTraceFrame::callWithIndex(int index) const
1213{
1214 QVector<ApiTraceCall*>::const_iterator itr;
1215 for (itr = m_calls.constBegin(); itr != m_calls.constEnd(); ++itr) {
1216 if ((*itr)->index() == index) {
1217 return *itr;
1218 }
1219 }
1220 return 0;
1221}
1222
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001223int ApiTraceFrame::callIndex(ApiTraceCall *call) const
1224{
Zack Rusind9d9d222013-10-11 18:02:26 -04001225 return m_children.indexOf(call);
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001226}
1227
1228bool ApiTraceFrame::isEmpty() const
1229{
Zack Rusin3176ebe2011-09-06 21:11:36 -04001230 if (m_loaded) {
1231 return m_calls.isEmpty();
1232 } else {
1233 return m_callsToLoad == 0;
1234 }
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001235}
1236
Zack Rusin9e292fc2011-04-26 23:03:42 -04001237int ApiTraceFrame::binaryDataSize() const
1238{
1239 return m_binaryDataSize;
1240}
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001241
Zack Rusind9d9d222013-10-11 18:02:26 -04001242void ApiTraceFrame::setCalls(const QVector<ApiTraceCall*> &children,
1243 const QVector<ApiTraceCall*> &calls,
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001244 quint64 binaryDataSize)
1245{
Zack Rusind9d9d222013-10-11 18:02:26 -04001246 m_children = children;
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001247 m_calls = calls;
1248 m_binaryDataSize = binaryDataSize;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001249 m_loaded = true;
Zack Rusin45e094f2011-09-14 17:36:53 -04001250 delete m_staticText;
1251 m_staticText = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001252}
1253
Zack Rusin1a9f7af2011-09-18 19:40:47 -04001254bool ApiTraceFrame::isLoaded() const
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001255{
1256 return m_loaded;
1257}
1258
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001259void ApiTraceFrame::setNumChildren(int num)
1260{
1261 m_callsToLoad = num;
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001262}
Zack Rusinebf971e2011-09-06 17:44:43 -04001263
1264void ApiTraceFrame::setParentTrace(ApiTrace *parent)
1265{
1266 m_parentTrace = parent;
1267}
Zack Rusin3176ebe2011-09-06 21:11:36 -04001268
1269int ApiTraceFrame::numChildrenToLoad() const
1270{
1271 return m_callsToLoad;
1272}
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001273
1274ApiTraceCall *
1275ApiTraceFrame::findNextCall(ApiTraceCall *from,
1276 const QString &str,
1277 Qt::CaseSensitivity sensitivity) const
1278{
1279 Q_ASSERT(m_loaded);
1280
1281 int callIndex = 0;
1282
1283 if (from) {
1284 callIndex = m_calls.indexOf(from) + 1;
1285 }
1286
1287 for (int i = callIndex; i < m_calls.count(); ++i) {
1288 ApiTraceCall *call = m_calls[i];
1289 if (call->contains(str, sensitivity)) {
1290 return call;
1291 }
1292 }
1293 return 0;
1294}
1295
1296ApiTraceCall *
1297ApiTraceFrame::findPrevCall(ApiTraceCall *from,
1298 const QString &str,
1299 Qt::CaseSensitivity sensitivity) const
1300{
1301 Q_ASSERT(m_loaded);
1302
1303 int callIndex = m_calls.count() - 1;
1304
1305 if (from) {
1306 callIndex = m_calls.indexOf(from) - 1;
1307 }
1308
1309 for (int i = callIndex; i >= 0; --i) {
1310 ApiTraceCall *call = m_calls[i];
1311 if (call->contains(str, sensitivity)) {
1312 return call;
1313 }
1314 }
1315 return 0;
1316}
Zack Rusin851d0b02011-09-14 22:04:07 -04001317
1318void ApiTraceFrame::setLastCallIndex(unsigned index)
1319{
1320 m_lastCallIndex = index;
1321}
1322
1323unsigned ApiTraceFrame::lastCallIndex() const
1324{
1325 if (m_loaded && !m_calls.isEmpty()) {
1326 return m_calls.last()->index();
1327 } else {
1328 return m_lastCallIndex;
1329 }
1330}
Dan McCabe10bd4242012-03-05 17:20:40 -08001331
José Fonseca8759ae02012-03-24 07:44:43 +00001332void ApiTraceFrame::setThumbnail(const QImage & thumbnail)
Dan McCabe10bd4242012-03-05 17:20:40 -08001333{
1334 m_thumbnail = thumbnail;
1335}
1336
José Fonseca8759ae02012-03-24 07:44:43 +00001337const QImage & ApiTraceFrame::thumbnail() const
Dan McCabe10bd4242012-03-05 17:20:40 -08001338{
1339 return m_thumbnail;
1340}