blob: 8bdaa684807a50481e5fdf17aae8e61dcbbc5578 [file] [log] [blame]
Zack Rusin91065372011-03-26 01:54:10 -04001#include "apitracecall.h"
2
Zack Rusin661842d2011-04-17 01:59:16 -04003#include "apitrace.h"
Zack Rusinebf971e2011-09-06 17:44:43 -04004#include "traceloader.h"
Zack Rusin91065372011-03-26 01:54:10 -04005#include "trace_model.hpp"
6
7#include <QDebug>
Zack Rusin9e292fc2011-04-26 23:03:42 -04008#include <QLocale>
Zack Rusin35451522011-04-02 23:44:53 -04009#include <QObject>
Zack Rusin5e277b02011-04-16 21:52:26 -040010#define QT_USE_FAST_OPERATOR_PLUS
11#include <QStringBuilder>
José Fonsecae8a1aa92011-04-21 09:13:23 +010012#include <QTextDocument>
Zack Rusin91065372011-03-26 01:54:10 -040013
Zack Rusinb53b1612011-04-19 01:33:58 -040014const char * const styleSheet =
15 ".call {\n"
16 " font-weight:bold;\n"
17 // text shadow looks great but doesn't work well in qtwebkit 4.7
18 " /*text-shadow: 0px 2px 3px #555;*/\n"
Zack Rusin5a74d3c2011-11-16 23:52:15 -050019 " font-size: 1.1em;\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040020 "}\n"
21 ".arg-name {\n"
22 " border: 1px solid rgb(238,206,0);\n"
23 " border-radius: 4px;\n"
24 " background: yellow;\n"
25 " padding: 2px;\n"
26 " box-shadow: 0px 1px 3px dimgrey;\n"
27 " -webkit-transition: background 1s linear;\n"
28 "}\n"
29 ".arg-name:hover {\n"
30 " background: white;\n"
31 "}\n"
32 ".arg-value {\n"
33 " color: #0000ff;\n"
34 "}\n"
Vladimir Vukicevica9c42472013-11-30 13:40:31 -050035 ".thread-id {\n"
36 " color: #aaaaaa;\n"
37 " min-width: 3em;\n"
38 "}\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040039 ".error {\n"
Zack Rusincc0b4912011-04-19 01:59:20 -040040 " border: 1px solid rgb(255,0,0);\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040041 " margin: 10px;\n"
Zack Rusincc0b4912011-04-19 01:59:20 -040042 " padding: 1;\n"
43 " border-radius: 4px;\n"
44 // also looks great but qtwebkit doesn't support it
45 //" background: #6fb2e5;\n"
46 //" box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
47 //" -o-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
48 //" -webkit-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
49 //" -moz-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040050 "}\n";
51
Zack Rusin91065372011-03-26 01:54:10 -040052
José Fonsecae8a1aa92011-04-21 09:13:23 +010053// Qt::convertFromPlainText doesn't do precisely what we want
54static QString
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -050055plainTextToHTML(const QString & plain, bool multiLine, bool forceNoQuote = false)
José Fonsecae8a1aa92011-04-21 09:13:23 +010056{
57 int col = 0;
58 bool quote = false;
59 QString rich;
Jose Fonseca010f9962016-03-05 14:45:41 +000060 for (auto & ch : plain) {
61 if (ch == QLatin1Char('\n')){
José Fonsecae8a1aa92011-04-21 09:13:23 +010062 if (multiLine) {
63 rich += QLatin1String("<br>\n");
64 } else {
65 rich += QLatin1String("\\n");
66 }
67 col = 0;
68 quote = true;
69 } else {
Jose Fonseca010f9962016-03-05 14:45:41 +000070 if (ch == QLatin1Char('\t')){
José Fonsecae8a1aa92011-04-21 09:13:23 +010071 if (multiLine) {
72 rich += QChar(0x00a0U);
73 ++col;
74 while (col % 8) {
75 rich += QChar(0x00a0U);
76 ++col;
77 }
78 } else {
79 rich += QLatin1String("\\t");
80 }
81 quote = true;
Jose Fonseca010f9962016-03-05 14:45:41 +000082 } else if (ch.isSpace()) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010083 rich += QChar(0x00a0U);
84 quote = true;
Jose Fonseca010f9962016-03-05 14:45:41 +000085 } else if (ch == QLatin1Char('<')) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010086 rich += QLatin1String("&lt;");
Jose Fonseca010f9962016-03-05 14:45:41 +000087 } else if (ch == QLatin1Char('>')) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010088 rich += QLatin1String("&gt;");
Jose Fonseca010f9962016-03-05 14:45:41 +000089 } else if (ch == QLatin1Char('&')) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010090 rich += QLatin1String("&amp;");
91 } else {
Jose Fonseca010f9962016-03-05 14:45:41 +000092 rich += ch;
José Fonsecae8a1aa92011-04-21 09:13:23 +010093 }
94 ++col;
95 }
96 }
97
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -050098 if (quote && !forceNoQuote) {
José Fonsecae8a1aa92011-04-21 09:13:23 +010099 return QLatin1Literal("\"") + rich + QLatin1Literal("\"");
100 }
101
102 return rich;
103}
104
Zack Rusina1a3ad52011-08-27 19:19:18 -0400105QString
106apiVariantToString(const QVariant &variant, bool multiLine)
Zack Rusin91065372011-03-26 01:54:10 -0400107{
José Fonseca1fa61832011-11-05 08:50:25 +0000108 if (variant.isNull()) {
109 return QLatin1String("?");
110 }
111
José Fonsecaea4b99f2011-11-25 13:37:37 +0000112 if (variant.userType() == QMetaType::Float) {
Zack Rusin91065372011-03-26 01:54:10 -0400113 return QString::number(variant.toFloat());
114 }
José Fonsecaea4b99f2011-11-25 13:37:37 +0000115 if (variant.userType() == QVariant::Double) {
116 return QString::number(variant.toDouble());
117 }
Zack Rusin35451522011-04-02 23:44:53 -0400118 if (variant.userType() == QVariant::ByteArray) {
Zack Rusin8e7a4ff2011-04-07 01:15:48 -0400119 if (variant.toByteArray().size() < 1024) {
120 int bytes = variant.toByteArray().size();
121 return QObject::tr("[binary data, size = %1 bytes]").arg(bytes);
122 } else {
123 float kb = variant.toByteArray().size()/1024.;
124 return QObject::tr("[binary data, size = %1 kb]").arg(kb);
125 }
Zack Rusin35451522011-04-02 23:44:53 -0400126 }
Zack Rusin91065372011-03-26 01:54:10 -0400127
José Fonsecae8a1aa92011-04-21 09:13:23 +0100128 if (variant.userType() == QVariant::String) {
129 return plainTextToHTML(variant.toString(), multiLine);
130 }
131
Zack Rusin91065372011-03-26 01:54:10 -0400132 if (variant.userType() < QVariant::UserType) {
133 return variant.toString();
134 }
135
136 if (variant.canConvert<ApiPointer>()) {
137 return variant.value<ApiPointer>().toString();
138 }
139 if (variant.canConvert<ApiBitmask>()) {
140 return variant.value<ApiBitmask>().toString();
141 }
142 if (variant.canConvert<ApiStruct>()) {
José Fonsecaa596a9e2011-09-27 10:19:28 +0100143 return variant.value<ApiStruct>().toString(multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400144 }
145 if (variant.canConvert<ApiArray>()) {
José Fonsecaa596a9e2011-09-27 10:19:28 +0100146 return variant.value<ApiArray>().toString(multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400147 }
Zack Rusind54055e2011-04-17 18:27:28 -0400148 if (variant.canConvert<ApiEnum>()) {
149 return variant.value<ApiEnum>().toString();
150 }
Zack Rusin91065372011-03-26 01:54:10 -0400151
152 return QString();
153}
154
Zack Rusina1a3ad52011-08-27 19:19:18 -0400155
José Fonsecab4a3d142011-10-27 07:43:19 +0100156void VariantVisitor::visit(trace::Null *)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400157{
158 m_variant = QVariant::fromValue(ApiPointer(0));
159}
160
José Fonsecab4a3d142011-10-27 07:43:19 +0100161void VariantVisitor::visit(trace::Bool *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400162{
163 m_variant = QVariant(node->value);
164}
165
José Fonsecab4a3d142011-10-27 07:43:19 +0100166void VariantVisitor::visit(trace::SInt *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400167{
168 m_variant = QVariant(node->value);
169}
170
José Fonsecab4a3d142011-10-27 07:43:19 +0100171void VariantVisitor::visit(trace::UInt *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400172{
173 m_variant = QVariant(node->value);
174}
175
José Fonsecab4a3d142011-10-27 07:43:19 +0100176void VariantVisitor::visit(trace::Float *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400177{
178 m_variant = QVariant(node->value);
179}
180
Carl Worthe935ee12011-11-17 14:04:16 -0800181void VariantVisitor::visit(trace::Double *node)
182{
183 m_variant = QVariant(node->value);
184}
185
José Fonsecab4a3d142011-10-27 07:43:19 +0100186void VariantVisitor::visit(trace::String *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400187{
José Fonseca26e84ee2014-06-18 17:42:08 +0100188 m_variant = QVariant(QString::fromLatin1(node->value));
Zack Rusina1a3ad52011-08-27 19:19:18 -0400189}
190
José Fonsecad5cda7c2014-09-25 15:19:09 +0100191void VariantVisitor::visit(trace::WString *node)
192{
193 m_variant = QVariant(QString::fromWCharArray(node->value));
194}
195
José Fonsecab4a3d142011-10-27 07:43:19 +0100196void VariantVisitor::visit(trace::Enum *e)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400197{
José Fonseca446ca502014-12-19 16:22:39 +0000198 m_variant = QVariant::fromValue(ApiEnum(e->sig, e->value));
Zack Rusina1a3ad52011-08-27 19:19:18 -0400199}
200
José Fonsecab4a3d142011-10-27 07:43:19 +0100201void VariantVisitor::visit(trace::Bitmask *bitmask)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400202{
203 m_variant = QVariant::fromValue(ApiBitmask(bitmask));
204}
205
José Fonsecab4a3d142011-10-27 07:43:19 +0100206void VariantVisitor::visit(trace::Struct *str)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400207{
208 m_variant = QVariant::fromValue(ApiStruct(str));
209}
210
José Fonsecab4a3d142011-10-27 07:43:19 +0100211void VariantVisitor::visit(trace::Array *array)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400212{
213 m_variant = QVariant::fromValue(ApiArray(array));
214}
215
José Fonsecab4a3d142011-10-27 07:43:19 +0100216void VariantVisitor::visit(trace::Blob *blob)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400217{
Zack Rusin95237682011-09-27 12:04:10 -0400218 QByteArray barray = QByteArray(blob->buf, blob->size);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400219 m_variant = QVariant(barray);
220}
221
José Fonsecab4a3d142011-10-27 07:43:19 +0100222void VariantVisitor::visit(trace::Pointer *ptr)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400223{
224 m_variant = QVariant::fromValue(ApiPointer(ptr->value));
225}
226
José Fonseca112a1322012-04-27 17:15:32 +0100227void VariantVisitor::visit(trace::Repr *repr)
228{
229 /* TODO: Preserve both the human and machine value */
230 repr->humanValue->visit(*this);
231}
232
José Fonseca446ca502014-12-19 16:22:39 +0000233ApiEnum::ApiEnum(const trace::EnumSig *sig, signed long long value)
José Fonsecaeb644512011-12-11 10:33:55 +0000234 : m_sig(sig), m_value(value)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400235{
José Fonseca446ca502014-12-19 16:22:39 +0000236 Q_ASSERT(m_sig);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400237}
238
239QString ApiEnum::toString() const
240{
José Fonseca446ca502014-12-19 16:22:39 +0000241 Q_ASSERT(m_sig);
242
243 for (const trace::EnumValue *it = m_sig->values;
244 it != m_sig->values + m_sig->num_values; ++it) {
245 if (m_value == it->value) {
246 return QString::fromLatin1(it->name);
247 }
Zack Rusin35c27932011-08-28 21:16:22 -0400248 }
José Fonseca446ca502014-12-19 16:22:39 +0000249
250 return QString::fromLatin1("%1").arg(m_value);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400251}
252
253QVariant ApiEnum::value() const
254{
Zack Rusin35c27932011-08-28 21:16:22 -0400255 if (m_sig) {
José Fonsecaeb644512011-12-11 10:33:55 +0000256 return QVariant::fromValue(m_value);
Zack Rusin35c27932011-08-28 21:16:22 -0400257 }
258 Q_ASSERT(!"should never happen");
259 return QVariant();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400260}
261
Zack Rusina1a3ad52011-08-27 19:19:18 -0400262unsigned long long ApiBitmask::value() const
263{
264 return m_value;
265}
266
267ApiBitmask::Signature ApiBitmask::signature() const
268{
269 return m_sig;
270}
271
272ApiStruct::Signature ApiStruct::signature() const
273{
274 return m_sig;
275}
276
277QList<QVariant> ApiStruct::values() const
278{
279 return m_members;
280}
281
282ApiPointer::ApiPointer(unsigned long long val)
283 : m_value(val)
284{
285}
286
287
288unsigned long long ApiPointer::value() const
289{
290 return m_value;
291}
292
293QString ApiPointer::toString() const
294{
295 if (m_value)
296 return QString("0x%1").arg(m_value, 0, 16);
297 else
298 return QLatin1String("NULL");
299}
300
José Fonsecab4a3d142011-10-27 07:43:19 +0100301ApiBitmask::ApiBitmask(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400302 : m_value(0)
303{
304 init(bitmask);
305}
306
José Fonsecab4a3d142011-10-27 07:43:19 +0100307void ApiBitmask::init(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400308{
309 if (!bitmask)
310 return;
311
312 m_value = bitmask->value;
José Fonsecab4a3d142011-10-27 07:43:19 +0100313 for (const trace::BitmaskFlag *it = bitmask->sig->flags;
José Fonsecafcfbf172011-05-28 13:20:01 +0100314 it != bitmask->sig->flags + bitmask->sig->num_flags; ++it) {
Zack Rusin91065372011-03-26 01:54:10 -0400315 QPair<QString, unsigned long long> pair;
316
José Fonseca26e84ee2014-06-18 17:42:08 +0100317 pair.first = QString::fromLatin1(it->name);
José Fonseca31b183a2011-05-28 12:21:15 +0100318 pair.second = it->value;
Zack Rusin91065372011-03-26 01:54:10 -0400319
320 m_sig.append(pair);
321 }
322}
323
324QString ApiBitmask::toString() const
325{
326 QString str;
327 unsigned long long value = m_value;
328 bool first = true;
José Fonsecafc9939f2012-04-23 10:13:48 +0100329 for (Signature::const_iterator it = m_sig.begin(); it != m_sig.end(); ++it) {
330 Q_ASSERT(it->second || first);
331 if ((it->second && (value & it->second) == it->second) ||
332 (!it->second && value == 0)) {
Zack Rusin91065372011-03-26 01:54:10 -0400333 if (!first) {
334 str += QLatin1String(" | ");
335 }
336 str += it->first;
337 value &= ~it->second;
338 first = false;
339 }
José Fonsecafc9939f2012-04-23 10:13:48 +0100340 if (value == 0) {
341 break;
342 }
Zack Rusin91065372011-03-26 01:54:10 -0400343 }
344 if (value || first) {
345 if (!first) {
346 str += QLatin1String(" | ");
347 }
348 str += QString::fromLatin1("0x%1").arg(value, 0, 16);
349 }
350 return str;
351}
352
José Fonsecab4a3d142011-10-27 07:43:19 +0100353ApiStruct::ApiStruct(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400354{
355 init(s);
356}
357
José Fonsecaa596a9e2011-09-27 10:19:28 +0100358QString ApiStruct::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400359{
360 QString str;
361
362 str += QLatin1String("{");
363 for (unsigned i = 0; i < m_members.count(); ++i) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400364 str += m_sig.memberNames[i] %
365 QLatin1Literal(" = ") %
José Fonsecaa596a9e2011-09-27 10:19:28 +0100366 apiVariantToString(m_members[i], multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400367 if (i < m_members.count() - 1)
368 str += QLatin1String(", ");
369 }
370 str += QLatin1String("}");
371
372 return str;
373}
374
José Fonsecab4a3d142011-10-27 07:43:19 +0100375void ApiStruct::init(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400376{
377 if (!s)
378 return;
379
José Fonseca26e84ee2014-06-18 17:42:08 +0100380 m_sig.name = QString::fromLatin1(s->sig->name);
José Fonseca1b23ed22011-05-28 13:01:16 +0100381 for (unsigned i = 0; i < s->sig->num_members; ++i) {
José Fonseca446ca502014-12-19 16:22:39 +0000382 VariantVisitor vis;
Zack Rusin91065372011-03-26 01:54:10 -0400383 m_sig.memberNames.append(
José Fonseca26e84ee2014-06-18 17:42:08 +0100384 QString::fromLatin1(s->sig->member_names[i]));
Zack Rusin91065372011-03-26 01:54:10 -0400385 s->members[i]->visit(vis);
386 m_members.append(vis.variant());
387 }
388}
389
José Fonsecab4a3d142011-10-27 07:43:19 +0100390ApiArray::ApiArray(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400391{
392 init(arr);
393}
394
Zack Rusin77ff98a2011-08-28 22:30:35 -0400395ApiArray::ApiArray(const QVector<QVariant> &vals)
Zack Rusinabb3fde2011-04-16 02:16:49 -0400396 : m_array(vals)
397{
398}
399
Zack Rusin77ff98a2011-08-28 22:30:35 -0400400QVector<QVariant> ApiArray::values() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400401{
402 return m_array;
403}
404
José Fonsecaa596a9e2011-09-27 10:19:28 +0100405QString ApiArray::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400406{
407 QString str;
408 str += QLatin1String("[");
409 for(int i = 0; i < m_array.count(); ++i) {
410 const QVariant &var = m_array[i];
José Fonsecaa596a9e2011-09-27 10:19:28 +0100411 str += apiVariantToString(var, multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400412 if (i < m_array.count() - 1)
413 str += QLatin1String(", ");
414 }
415 str += QLatin1String("]");
416
417 return str;
418}
419
José Fonsecab4a3d142011-10-27 07:43:19 +0100420void ApiArray::init(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400421{
422 if (!arr)
423 return;
424
Zack Rusin3c70dbf2011-08-28 03:10:01 -0400425 m_array.reserve(arr->values.size());
Jose Fonseca010f9962016-03-05 14:45:41 +0000426 for (auto & value : arr->values) {
José Fonseca446ca502014-12-19 16:22:39 +0000427 VariantVisitor vis;
Jose Fonseca010f9962016-03-05 14:45:41 +0000428 value->visit(vis);
Zack Rusin91065372011-03-26 01:54:10 -0400429
430 m_array.append(vis.variant());
431 }
Zack Rusin77ff98a2011-08-28 22:30:35 -0400432 m_array.squeeze();
Zack Rusin91065372011-03-26 01:54:10 -0400433}
Zack Rusin18eade52011-03-26 14:23:35 -0400434
Zack Rusina1a3ad52011-08-27 19:19:18 -0400435ApiTraceState::ApiTraceState()
436{
437}
438
Martin Schulze638ec442015-10-11 12:37:42 +0200439static ApiTexture getTextureFrom(QVariantMap const &image, QString label)
440{
441 QSize size(image[QLatin1String("__width__")].toInt(),
442 image[QLatin1String("__height__")].toInt());
443 QString cls = image[QLatin1String("__class__")].toString();
444 int depth =
445 image[QLatin1String("__depth__")].toInt();
446 QString formatName =
447 image[QLatin1String("__format__")].toString();
448
449 QByteArray dataArray =
450 image[QLatin1String("__data__")].toByteArray();
451
452 QString userLabel =
453 image[QLatin1String("__label__")].toString();
454 if (!userLabel.isEmpty()) {
455 label += QString(", \"%1\"").arg(userLabel);
456 }
457
458 ApiTexture tex;
459 tex.setSize(size);
460 tex.setDepth(depth);
461 tex.setFormatName(formatName);
462 tex.setLabel(label);
463 tex.setData(dataArray);
464 return tex;
465}
466
Zack Rusina1a3ad52011-08-27 19:19:18 -0400467ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
468{
469 m_parameters = parsedJson[QLatin1String("parameters")].toMap();
470 QVariantMap attachedShaders =
471 parsedJson[QLatin1String("shaders")].toMap();
472 QVariantMap::const_iterator itr;
473
474
475 for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd();
476 ++itr) {
477 QString type = itr.key();
478 QString source = itr.value().toString();
479 m_shaderSources[type] = source;
480 }
481
482 m_uniforms = parsedJson[QLatin1String("uniforms")].toMap();
483
José Fonsecad1d1ecf2014-10-22 23:55:16 +0100484 m_buffers = parsedJson[QLatin1String("buffers")].toMap();
485
Martin Schulzee9e85782016-03-23 17:03:16 +0100486 m_shaderStorageBufferBlocks =
487 parsedJson[QLatin1String("shaderstoragebufferblocks")].toMap();
488
Martin Schulze638ec442015-10-11 12:37:42 +0200489 {
490 QVariantMap textures =
491 parsedJson[QLatin1String("textures")].toMap();
492 for (itr = textures.constBegin(); itr != textures.constEnd(); ++itr) {
493 m_textures.append(getTextureFrom(itr.value().toMap(), itr.key()));
José Fonseca42ec5632015-02-06 22:43:05 +0000494 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400495 }
496
497 QVariantMap fbos =
498 parsedJson[QLatin1String("framebuffer")].toMap();
499 for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) {
500 QVariantMap buffer = itr.value().toMap();
501 QSize size(buffer[QLatin1String("__width__")].toInt(),
502 buffer[QLatin1String("__height__")].toInt());
503 QString cls = buffer[QLatin1String("__class__")].toString();
Zack Rusinb25c4b92011-11-16 22:43:34 -0500504 int depth = buffer[QLatin1String("__depth__")].toInt();
Zack Rusine181b992011-11-17 16:00:41 -0500505 QString formatName = buffer[QLatin1String("__format__")].toString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400506
Zack Rusina1a3ad52011-08-27 19:19:18 -0400507 QByteArray dataArray =
508 buffer[QLatin1String("__data__")].toByteArray();
509
José Fonseca42ec5632015-02-06 22:43:05 +0000510 QString label = itr.key();
511 QString userLabel =
512 buffer[QLatin1String("__label__")].toString();
513 if (!userLabel.isEmpty()) {
514 label += QString(", \"%1\"").arg(userLabel);
515 }
516
Zack Rusina1a3ad52011-08-27 19:19:18 -0400517 ApiFramebuffer fbo;
518 fbo.setSize(size);
Zack Rusinb25c4b92011-11-16 22:43:34 -0500519 fbo.setDepth(depth);
Zack Rusine181b992011-11-17 16:00:41 -0500520 fbo.setFormatName(formatName);
José Fonseca42ec5632015-02-06 22:43:05 +0000521 fbo.setType(label);
Jose Fonseca93a7c0c2015-05-27 20:52:51 +0100522 fbo.setData(dataArray);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400523 m_framebuffers.append(fbo);
524 }
525}
526
527const QVariantMap & ApiTraceState::parameters() const
528{
529 return m_parameters;
530}
531
532const QMap<QString, QString> & ApiTraceState::shaderSources() const
533{
534 return m_shaderSources;
535}
536
537const QVariantMap & ApiTraceState::uniforms() const
538{
539 return m_uniforms;
540}
541
José Fonsecad1d1ecf2014-10-22 23:55:16 +0100542const QVariantMap & ApiTraceState::buffers() const
543{
544 return m_buffers;
545}
546
Martin Schulzee9e85782016-03-23 17:03:16 +0100547const QVariantMap &ApiTraceState::shaderStorageBufferBlocks() const
548{
549 return m_shaderStorageBufferBlocks;
550}
551
Zack Rusina1a3ad52011-08-27 19:19:18 -0400552bool ApiTraceState::isEmpty() const
553{
José Fonseca4e0bfee2012-11-28 10:45:08 +0000554 return m_parameters.isEmpty() &&
555 m_shaderSources.isEmpty() &&
556 m_textures.isEmpty() &&
557 m_framebuffers.isEmpty();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400558}
559
560const QList<ApiTexture> & ApiTraceState::textures() const
561{
562 return m_textures;
563}
564
565const QList<ApiFramebuffer> & ApiTraceState::framebuffers() const
566{
567 return m_framebuffers;
568}
569
Zack Rusin353f0532011-09-15 20:23:27 -0400570ApiFramebuffer ApiTraceState::colorBuffer() const
571{
572 foreach (ApiFramebuffer fbo, m_framebuffers) {
573 if (fbo.type() == QLatin1String("GL_BACK")) {
574 return fbo;
575 }
576 }
577 foreach (ApiFramebuffer fbo, m_framebuffers) {
578 if (fbo.type() == QLatin1String("GL_FRONT")) {
579 return fbo;
580 }
581 }
582 return ApiFramebuffer();
583}
584
585
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400586ApiTraceCallSignature::ApiTraceCallSignature(const QString &name,
587 const QStringList &argNames)
588 : m_name(name),
589 m_argNames(argNames)
590{
591}
592
593ApiTraceCallSignature::~ApiTraceCallSignature()
594{
595}
596
597QUrl ApiTraceCallSignature::helpUrl() const
598{
599 return m_helpUrl;
600}
601
602void ApiTraceCallSignature::setHelpUrl(const QUrl &url)
603{
604 m_helpUrl = url;
605}
606
Zack Rusina1a3ad52011-08-27 19:19:18 -0400607ApiTraceEvent::ApiTraceEvent()
608 : m_type(ApiTraceEvent::None),
José Fonsecafb5df2a2014-12-19 16:45:32 +0000609 m_binaryDataIndex(-1),
Zack Rusined40bc62011-08-28 17:11:02 -0400610 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400611 m_staticText(0)
612{
613}
614
615ApiTraceEvent::ApiTraceEvent(Type t)
616 : m_type(t),
José Fonsecafb5df2a2014-12-19 16:45:32 +0000617 m_binaryDataIndex(-1),
Zack Rusined40bc62011-08-28 17:11:02 -0400618 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400619 m_staticText(0)
620{
José Fonsecafb5df2a2014-12-19 16:45:32 +0000621 Q_ASSERT(m_type == t);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400622}
623
624ApiTraceEvent::~ApiTraceEvent()
625{
Zack Rusined40bc62011-08-28 17:11:02 -0400626 delete m_state;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400627 delete m_staticText;
628}
629
Zack Rusined40bc62011-08-28 17:11:02 -0400630ApiTraceState *ApiTraceEvent::state() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400631{
632 return m_state;
633}
634
Zack Rusined40bc62011-08-28 17:11:02 -0400635void ApiTraceEvent::setState(ApiTraceState *state)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400636{
637 m_state = state;
638}
639
Dan McCabeb6b6d7c2012-06-01 13:40:02 -0700640void ApiTraceEvent::setThumbnail(const QImage & thumbnail)
641{
642 m_thumbnail = thumbnail;
643}
644
645const QImage & ApiTraceEvent::thumbnail() const
646{
647 return m_thumbnail;
648}
649
Zack Rusinebf971e2011-09-06 17:44:43 -0400650ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame,
651 TraceLoader *loader,
José Fonsecab4a3d142011-10-27 07:43:19 +0100652 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400653 : ApiTraceEvent(ApiTraceEvent::Call),
Zack Rusind9d9d222013-10-11 18:02:26 -0400654 m_parentFrame(parentFrame),
655 m_parentCall(0)
656{
657 loadData(loader, call);
658}
659
660ApiTraceCall::ApiTraceCall(ApiTraceCall *parentCall,
661 TraceLoader *loader,
662 const trace::Call *call)
663 : ApiTraceEvent(ApiTraceEvent::Call),
664 m_parentFrame(parentCall->parentFrame()),
665 m_parentCall(parentCall)
666{
667 loadData(loader, call);
668}
669
670
671ApiTraceCall::~ApiTraceCall()
672{
673}
674
675
676void
677ApiTraceCall::loadData(TraceLoader *loader,
678 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400679{
Zack Rusina1a3ad52011-08-27 19:19:18 -0400680 m_index = call->no;
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500681 m_thread = call->thread_id;
Zack Rusinebf971e2011-09-06 17:44:43 -0400682 m_signature = loader->signature(call->sig->id);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400683
684 if (!m_signature) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100685 QString name = QString::fromLatin1(call->sig->name);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400686 QStringList argNames;
Zack Rusinf22d7992011-08-28 02:23:47 -0400687 argNames.reserve(call->sig->num_args);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400688 for (int i = 0; i < call->sig->num_args; ++i) {
José Fonseca26e84ee2014-06-18 17:42:08 +0100689 argNames += QString::fromLatin1(call->sig->arg_names[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400690 }
691 m_signature = new ApiTraceCallSignature(name, argNames);
Zack Rusinebf971e2011-09-06 17:44:43 -0400692 loader->addSignature(call->sig->id, m_signature);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400693 }
694 if (call->ret) {
José Fonseca446ca502014-12-19 16:22:39 +0000695 VariantVisitor retVisitor;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400696 call->ret->visit(retVisitor);
697 m_returnValue = retVisitor.variant();
698 }
Zack Rusinf22d7992011-08-28 02:23:47 -0400699 m_argValues.reserve(call->args.size());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400700 for (int i = 0; i < call->args.size(); ++i) {
Carl Wortha5b476e2011-11-16 17:22:40 -0800701 if (call->args[i].value) {
José Fonseca446ca502014-12-19 16:22:39 +0000702 VariantVisitor argVisitor;
Carl Wortha5b476e2011-11-16 17:22:40 -0800703 call->args[i].value->visit(argVisitor);
José Fonseca1fa61832011-11-05 08:50:25 +0000704 m_argValues.append(argVisitor.variant());
705 if (m_argValues[i].type() == QVariant::ByteArray) {
José Fonseca1fa61832011-11-05 08:50:25 +0000706 m_binaryDataIndex = i;
707 }
708 } else {
709 m_argValues.append(QVariant());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400710 }
711 }
Zack Rusinf736a622011-08-28 22:19:46 -0400712 m_argValues.squeeze();
José Fonseca340f5692011-11-30 07:04:44 +0000713 m_flags = call->flags;
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400714 if (call->backtrace != NULL) {
715 QString qbacktrace;
Jose Fonseca010f9962016-03-05 14:45:41 +0000716 for (auto frame : *call->backtrace) {
José Fonseca9c25e062013-05-06 07:25:40 +0100717 if (frame->module != NULL) {
718 qbacktrace += QString("%1 ").arg(frame->module);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400719 }
José Fonseca9c25e062013-05-06 07:25:40 +0100720 if (frame->function != NULL) {
721 qbacktrace += QString("at %1() ").arg(frame->function);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400722 }
José Fonseca9c25e062013-05-06 07:25:40 +0100723 if (frame->filename != NULL) {
724 qbacktrace += QString("at %1").arg(frame->filename);
725 if (frame->linenumber >= 0) {
726 qbacktrace += QString(":%1 ").arg(frame->linenumber);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400727 }
728 }
729 else {
José Fonseca9c25e062013-05-06 07:25:40 +0100730 if (frame->offset >= 0) {
731 qbacktrace += QString("[0x%1]").arg(frame->offset, 0, 16);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400732 }
733 }
734 qbacktrace += "\n";
735 }
736 this->setBacktrace(qbacktrace);
737 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400738}
739
Zack Rusind9d9d222013-10-11 18:02:26 -0400740ApiTraceCall *
741ApiTraceCall::parentCall() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400742{
Zack Rusind9d9d222013-10-11 18:02:26 -0400743 return m_parentCall;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400744}
745
746
Zack Rusind9d9d222013-10-11 18:02:26 -0400747ApiTraceEvent *
748ApiTraceCall::parentEvent() const
749{
750 if (m_parentCall)
751 return m_parentCall;
752 else
753 return m_parentFrame;
754}
755
756QVector<ApiTraceCall*>
757ApiTraceCall::children() const
758{
759 return m_children;
760}
761
762void
763ApiTraceCall::addChild(ApiTraceCall *call)
764{
765 m_children.append(call);
766}
767
768
769int
770ApiTraceCall::callIndex(ApiTraceCall *call) const
771{
772 return m_children.indexOf(call);
773}
774
775void
776ApiTraceCall::finishedAddingChildren()
777{
778 m_children.squeeze();
779}
780
Zack Rusina1a3ad52011-08-27 19:19:18 -0400781bool ApiTraceCall::hasError() const
782{
783 return !m_error.isEmpty();
784}
785
786QString ApiTraceCall::error() const
787{
788 return m_error;
789}
790
791void ApiTraceCall::setError(const QString &msg)
792{
793 if (m_error != msg) {
Zack Rusina1a3ad52011-08-27 19:19:18 -0400794 m_error = msg;
795 m_richText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400796 }
797}
798
799ApiTrace * ApiTraceCall::parentTrace() const
800{
801 if (m_parentFrame)
802 return m_parentFrame->parentTrace();
803 return NULL;
804}
805
Zack Rusinf736a622011-08-28 22:19:46 -0400806QVector<QVariant> ApiTraceCall::originalValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400807{
808 return m_argValues;
809}
810
Zack Rusinf736a622011-08-28 22:19:46 -0400811void ApiTraceCall::setEditedValues(const QVector<QVariant> &lst)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400812{
813 ApiTrace *trace = parentTrace();
814
815 m_editedValues = lst;
816 //lets regenerate data
817 m_richText = QString();
Zack Rusindc792082011-08-27 23:29:19 -0400818 m_searchText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400819 delete m_staticText;
820 m_staticText = 0;
821
822 if (trace) {
823 if (!lst.isEmpty()) {
824 trace->callEdited(this);
825 } else {
826 trace->callReverted(this);
827 }
828 }
829}
830
Zack Rusinf736a622011-08-28 22:19:46 -0400831QVector<QVariant> ApiTraceCall::editedValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400832{
833 return m_editedValues;
834}
835
836bool ApiTraceCall::edited() const
837{
838 return !m_editedValues.isEmpty();
839}
840
841void ApiTraceCall::revert()
842{
Zack Rusinf736a622011-08-28 22:19:46 -0400843 setEditedValues(QVector<QVariant>());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400844}
845
846void ApiTraceCall::setHelpUrl(const QUrl &url)
847{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400848 m_signature->setHelpUrl(url);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400849}
850
851void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
852{
853 m_parentFrame = frame;
854}
855
856ApiTraceFrame * ApiTraceCall::parentFrame()const
857{
858 return m_parentFrame;
859}
860
861int ApiTraceCall::index() const
862{
863 return m_index;
864}
865
866QString ApiTraceCall::name() const
867{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400868 return m_signature->name();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400869}
870
871QStringList ApiTraceCall::argNames() const
872{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400873 return m_signature->argNames();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400874}
875
Zack Rusinf736a622011-08-28 22:19:46 -0400876QVector<QVariant> ApiTraceCall::arguments() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400877{
878 if (m_editedValues.isEmpty())
879 return m_argValues;
880 else
881 return m_editedValues;
882}
883
Zack Rusind9d9d222013-10-11 18:02:26 -0400884ApiTraceEvent *
885ApiTraceCall::eventAtRow(int row) const
886{
887 if (row < m_children.count())
888 return m_children.value(row);
889 else
890 return NULL;
891}
892
Zack Rusina1a3ad52011-08-27 19:19:18 -0400893QVariant ApiTraceCall::returnValue() const
894{
895 return m_returnValue;
896}
897
José Fonseca340f5692011-11-30 07:04:44 +0000898trace::CallFlags ApiTraceCall::flags() const
899{
900 return m_flags;
901}
902
Zack Rusina1a3ad52011-08-27 19:19:18 -0400903QUrl ApiTraceCall::helpUrl() const
904{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400905 return m_signature->helpUrl();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400906}
907
908bool ApiTraceCall::hasBinaryData() const
909{
José Fonsecafb5df2a2014-12-19 16:45:32 +0000910 return m_binaryDataIndex >= 0;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400911}
912
913int ApiTraceCall::binaryDataIndex() const
914{
José Fonsecafb5df2a2014-12-19 16:45:32 +0000915 Q_ASSERT(hasBinaryData());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400916 return m_binaryDataIndex;
917}
918
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400919QString ApiTraceCall::backtrace() const
920{
921 return m_backtrace;
922}
923
924void ApiTraceCall::setBacktrace(QString backtrace)
925{
926 m_backtrace = backtrace;
927}
928
Zack Rusin18eade52011-03-26 14:23:35 -0400929QStaticText ApiTraceCall::staticText() const
930{
Zack Rusin53484b22011-04-16 11:56:19 -0400931 if (m_staticText && !m_staticText->text().isEmpty())
932 return *m_staticText;
Zack Rusin18eade52011-03-26 14:23:35 -0400933
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500934 QStringList argNames = m_signature->argNames();
Zack Rusinf736a622011-08-28 22:19:46 -0400935 QVector<QVariant> argValues = arguments();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400936
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500937 QString richText;
938
José Fonseca2258a6d2014-05-22 21:14:21 +0100939 // TODO: Toggle this via a menu option.
940 if (0) {
941 richText += QString::fromLatin1("<span style=\"color: #aaaaaa; min-width: 3em;\">@%1</span> ")
942 .arg(m_thread);
943 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -0500944
José Fonseca991723d2014-05-22 21:32:37 +0100945 if (m_flags & trace::CALL_FLAG_MARKER &&
946 argNames.count() &&
947 argValues.last().userType() == QVariant::String)
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500948 {
949 // special handling for string markers
José Fonseca991723d2014-05-22 21:32:37 +0100950 QString msgText = plainTextToHTML(argValues.last().toString(), false, true);
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500951 richText += QString::fromLatin1(
952 "<span style=\"font-weight:bold;color:green;\">%1</span>")
953 .arg(msgText);
954 } else {
955 richText += QString::fromLatin1(
956 "<span style=\"font-weight:bold\">%1</span>(").arg(
957 m_signature->name());
958 for (int i = 0; i < argNames.count(); ++i) {
959 richText += QLatin1String("<span style=\"color:#0000ff\">");
960 QString argText = apiVariantToString(argValues[i]);
961
962 //if arguments are really long (e.g. shader text), cut them
963 // and elide it
964 if (argText.length() > 40) {
965 QString shortened = argText.mid(0, 40);
966 shortened[argText.length() - 5] = '.';
967 shortened[argText.length() - 4] = '.';
968 shortened[argText.length() - 3] = '.';
969 shortened[argText.length() - 2] = argText.at(argText.length() - 2);
970 shortened[argText.length() - 1] = argText.at(argText.length() - 1);
971 richText += shortened;
972 } else {
973 richText += argText;
974 }
975 richText += QLatin1String("</span>");
976 if (i < argNames.count() - 1)
977 richText += QLatin1String(", ");
Zack Rusindd7f2302011-03-31 22:55:57 -0400978 }
Vladimir Vukicevicc2c91192013-12-05 18:38:54 -0500979 richText += QLatin1String(")");
980 if (m_returnValue.isValid()) {
981 richText +=
982 QLatin1Literal(" = ") %
983 QLatin1Literal("<span style=\"color:#0000ff\">") %
984 apiVariantToString(m_returnValue) %
985 QLatin1Literal("</span>");
986 }
José Fonseca908f38d2011-03-31 10:09:14 +0100987 }
Zack Rusin27cb2c42011-03-27 23:53:36 -0400988
Zack Rusin53484b22011-04-16 11:56:19 -0400989 if (!m_staticText)
990 m_staticText = new QStaticText(richText);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400991 else
992 m_staticText->setText(richText);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400993 QTextOption opt;
994 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -0400995 m_staticText->setTextOption(opt);
996 m_staticText->prepare();
Zack Rusin27cb2c42011-03-27 23:53:36 -0400997
Zack Rusin53484b22011-04-16 11:56:19 -0400998 return *m_staticText;
Zack Rusin27cb2c42011-03-27 23:53:36 -0400999}
1000
1001QString ApiTraceCall::toHtml() const
1002{
1003 if (!m_richText.isEmpty())
1004 return m_richText;
1005
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001006 m_richText += QLatin1String("<div class=\"call\">");
Zack Rusinb53b1612011-04-19 01:33:58 -04001007
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001008
1009 m_richText +=
José Fonseca2258a6d2014-05-22 21:14:21 +01001010 QString::fromLatin1("%1 ")
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001011 .arg(m_index);
1012 QString parentTip;
1013 if (m_parentFrame) {
1014 parentTip =
1015 QString::fromLatin1("Frame %1")
1016 .arg(m_parentFrame->number);
1017 }
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001018
José Fonseca2258a6d2014-05-22 21:14:21 +01001019 m_richText += QString::fromLatin1("<span class=\"thread-id\">@%1</span> ")
Vladimir Vukicevica9c42472013-11-30 13:40:31 -05001020 .arg(m_thread);
1021
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001022 QUrl helpUrl = m_signature->helpUrl();
1023 if (helpUrl.isEmpty()) {
Zack Rusinb53b1612011-04-19 01:33:58 -04001024 m_richText += QString::fromLatin1(
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001025 "<span class=\"callName\" title=\"%1\">%2</span>(")
1026 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001027 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001028 } else {
Zack Rusinb53b1612011-04-19 01:33:58 -04001029 m_richText += QString::fromLatin1(
Zack Rusin5a74d3c2011-11-16 23:52:15 -05001030 "<span class=\"callName\" title=\"%1\"><a href=\"%2\">%3</a></span>(")
1031 .arg(parentTip)
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001032 .arg(helpUrl.toString())
1033 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -04001034 }
1035
Zack Rusinf736a622011-08-28 22:19:46 -04001036 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001037 QStringList argNames = m_signature->argNames();
1038 for (int i = 0; i < argNames.count(); ++i) {
Zack Rusinb53b1612011-04-19 01:33:58 -04001039 m_richText +=
1040 QLatin1String("<span class=\"arg-name\">") +
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001041 argNames[i] +
Zack Rusinb53b1612011-04-19 01:33:58 -04001042 QLatin1String("</span>") +
1043 QLatin1Literal(" = ") +
1044 QLatin1Literal("<span class=\"arg-value\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001045 apiVariantToString(argValues[i], true) +
Zack Rusinb53b1612011-04-19 01:33:58 -04001046 QLatin1Literal("</span>");
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001047 if (i < argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -04001048 m_richText += QLatin1String(", ");
Zack Rusin18eade52011-03-26 14:23:35 -04001049 }
1050 m_richText += QLatin1String(")");
1051
Zack Rusinead6aad2011-04-15 22:16:18 -04001052 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -04001053 m_richText +=
1054 QLatin1String(" = ") +
1055 QLatin1String("<span style=\"color:#0000ff\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +01001056 apiVariantToString(m_returnValue, true) +
Zack Rusin5e277b02011-04-16 21:52:26 -04001057 QLatin1String("</span>");
Zack Rusin18eade52011-03-26 14:23:35 -04001058 }
Zack Rusinb53b1612011-04-19 01:33:58 -04001059 m_richText += QLatin1String("</div>");
1060
Zack Rusincc0b4912011-04-19 01:59:20 -04001061 if (hasError()) {
1062 QString errorStr =
1063 QString::fromLatin1(
1064 "<div class=\"error\">%1</div>")
1065 .arg(m_error);
1066 m_richText += errorStr;
1067 }
1068
Zack Rusinb53b1612011-04-19 01:33:58 -04001069 m_richText =
1070 QString::fromLatin1(
1071 "<html><head><style type=\"text/css\" media=\"all\">"
1072 "%1</style></head><body>%2</body></html>")
1073 .arg(styleSheet)
1074 .arg(m_richText);
Zack Rusin5e277b02011-04-16 21:52:26 -04001075 m_richText.squeeze();
Zack Rusinb53b1612011-04-19 01:33:58 -04001076
1077 //qDebug()<<m_richText;
Zack Rusin18eade52011-03-26 14:23:35 -04001078 return m_richText;
1079}
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001080
Zack Rusindc792082011-08-27 23:29:19 -04001081QString ApiTraceCall::searchText() const
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001082{
Zack Rusindc792082011-08-27 23:29:19 -04001083 if (!m_searchText.isEmpty())
1084 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001085
Zack Rusinf736a622011-08-28 22:19:46 -04001086 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001087 m_searchText = m_signature->name() + QLatin1Literal("(");
1088 QStringList argNames = m_signature->argNames();
1089 for (int i = 0; i < argNames.count(); ++i) {
1090 m_searchText += argNames[i] +
Zack Rusin5e277b02011-04-16 21:52:26 -04001091 QLatin1Literal(" = ") +
Zack Rusin9af5bff2011-04-18 01:05:50 -04001092 apiVariantToString(argValues[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -04001093 if (i < argNames.count() - 1)
Zack Rusindc792082011-08-27 23:29:19 -04001094 m_searchText += QLatin1String(", ");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001095 }
Zack Rusindc792082011-08-27 23:29:19 -04001096 m_searchText += QLatin1String(")");
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001097
Zack Rusinead6aad2011-04-15 22:16:18 -04001098 if (m_returnValue.isValid()) {
Zack Rusindc792082011-08-27 23:29:19 -04001099 m_searchText += QLatin1Literal(" = ") +
Zack Rusin5e277b02011-04-16 21:52:26 -04001100 apiVariantToString(m_returnValue);
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001101 }
Zack Rusindc792082011-08-27 23:29:19 -04001102 m_searchText.squeeze();
1103 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -04001104}
Zack Rusinf6667d12011-03-30 11:03:37 -04001105
Zack Rusina1a3ad52011-08-27 19:19:18 -04001106int ApiTraceCall::numChildren() const
1107{
Zack Rusind9d9d222013-10-11 18:02:26 -04001108 return m_children.count();
Zack Rusina1a3ad52011-08-27 19:19:18 -04001109}
1110
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001111bool ApiTraceCall::contains(const QString &str,
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +03001112 Qt::CaseSensitivity sensitivity,
1113 bool useRegex) const
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001114{
1115 QString txt = searchText();
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +03001116 return useRegex ? txt.contains(QRegExp(str, sensitivity))
1117 : txt.contains(str, sensitivity);
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001118}
1119
Dan McCabed1395322012-06-01 13:40:03 -07001120void ApiTraceCall::missingThumbnail()
1121{
1122 m_parentFrame->parentTrace()->missingThumbnail(this);
1123}
1124
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001125
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,
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +03001270 Qt::CaseSensitivity sensitivity,
1271 bool useRegex) const
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001272{
1273 Q_ASSERT(m_loaded);
1274
1275 int callIndex = 0;
1276
1277 if (from) {
1278 callIndex = m_calls.indexOf(from) + 1;
1279 }
1280
1281 for (int i = callIndex; i < m_calls.count(); ++i) {
1282 ApiTraceCall *call = m_calls[i];
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +03001283 if (call->contains(str, sensitivity, useRegex)) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001284 return call;
1285 }
1286 }
1287 return 0;
1288}
1289
1290ApiTraceCall *
1291ApiTraceFrame::findPrevCall(ApiTraceCall *from,
1292 const QString &str,
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +03001293 Qt::CaseSensitivity sensitivity,
1294 bool useRegex) const
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001295{
1296 Q_ASSERT(m_loaded);
1297
1298 int callIndex = m_calls.count() - 1;
1299
1300 if (from) {
1301 callIndex = m_calls.indexOf(from) - 1;
1302 }
1303
1304 for (int i = callIndex; i >= 0; --i) {
1305 ApiTraceCall *call = m_calls[i];
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +03001306 if (call->contains(str, sensitivity, useRegex)) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001307 return call;
1308 }
1309 }
1310 return 0;
1311}
Zack Rusin851d0b02011-09-14 22:04:07 -04001312
1313void ApiTraceFrame::setLastCallIndex(unsigned index)
1314{
1315 m_lastCallIndex = index;
1316}
1317
1318unsigned ApiTraceFrame::lastCallIndex() const
1319{
1320 if (m_loaded && !m_calls.isEmpty()) {
1321 return m_calls.last()->index();
1322 } else {
1323 return m_lastCallIndex;
1324 }
1325}
Dan McCabed1395322012-06-01 13:40:03 -07001326
1327void ApiTraceFrame::missingThumbnail()
1328{
1329 m_parentTrace->missingThumbnail(this);
1330}