blob: 2d41e25a4425f972b56d6f0daafabd8c694d5863 [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 Rusin91065372011-03-26 01:54:10 -04004#include "trace_model.hpp"
5
6#include <QDebug>
Zack Rusin35451522011-04-02 23:44:53 -04007#include <QObject>
Zack Rusin5e277b02011-04-16 21:52:26 -04008#define QT_USE_FAST_OPERATOR_PLUS
9#include <QStringBuilder>
Zack Rusin91065372011-03-26 01:54:10 -040010
Zack Rusinb53b1612011-04-19 01:33:58 -040011const char * const styleSheet =
12 ".call {\n"
13 " font-weight:bold;\n"
14 // text shadow looks great but doesn't work well in qtwebkit 4.7
15 " /*text-shadow: 0px 2px 3px #555;*/\n"
16 " font-size: 1.2em;\n"
17 "}\n"
18 ".arg-name {\n"
19 " border: 1px solid rgb(238,206,0);\n"
20 " border-radius: 4px;\n"
21 " background: yellow;\n"
22 " padding: 2px;\n"
23 " box-shadow: 0px 1px 3px dimgrey;\n"
24 " -webkit-transition: background 1s linear;\n"
25 "}\n"
26 ".arg-name:hover {\n"
27 " background: white;\n"
28 "}\n"
29 ".arg-value {\n"
30 " color: #0000ff;\n"
31 "}\n"
32 ".error {\n"
Zack Rusincc0b4912011-04-19 01:59:20 -040033 " border: 1px solid rgb(255,0,0);\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040034 " margin: 10px;\n"
Zack Rusincc0b4912011-04-19 01:59:20 -040035 " padding: 1;\n"
36 " border-radius: 4px;\n"
37 // also looks great but qtwebkit doesn't support it
38 //" background: #6fb2e5;\n"
39 //" box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
40 //" -o-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
41 //" -webkit-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
42 //" -moz-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040043 "}\n";
44
Zack Rusinc6247dd2011-04-17 22:56:58 -040045ApiPointer::ApiPointer(unsigned long long val)
Zack Rusin91065372011-03-26 01:54:10 -040046 : m_value(val)
47{
48}
49
50QString ApiPointer::toString() const
51{
52 if (m_value)
53 return QString("0x%1").arg(m_value, 0, 16);
54 else
55 return QLatin1String("NULL");
56}
57
58QString apiVariantToString(const QVariant &variant)
59{
60 if (variant.userType() == QVariant::Double) {
61 return QString::number(variant.toFloat());
62 }
Zack Rusin35451522011-04-02 23:44:53 -040063 if (variant.userType() == QVariant::ByteArray) {
Zack Rusin8e7a4ff2011-04-07 01:15:48 -040064 if (variant.toByteArray().size() < 1024) {
65 int bytes = variant.toByteArray().size();
66 return QObject::tr("[binary data, size = %1 bytes]").arg(bytes);
67 } else {
68 float kb = variant.toByteArray().size()/1024.;
69 return QObject::tr("[binary data, size = %1 kb]").arg(kb);
70 }
Zack Rusin35451522011-04-02 23:44:53 -040071 }
Zack Rusin91065372011-03-26 01:54:10 -040072
73 if (variant.userType() < QVariant::UserType) {
74 return variant.toString();
75 }
76
77 if (variant.canConvert<ApiPointer>()) {
78 return variant.value<ApiPointer>().toString();
79 }
80 if (variant.canConvert<ApiBitmask>()) {
81 return variant.value<ApiBitmask>().toString();
82 }
83 if (variant.canConvert<ApiStruct>()) {
84 return variant.value<ApiStruct>().toString();
85 }
86 if (variant.canConvert<ApiArray>()) {
87 return variant.value<ApiArray>().toString();
88 }
Zack Rusind54055e2011-04-17 18:27:28 -040089 if (variant.canConvert<ApiEnum>()) {
90 return variant.value<ApiEnum>().toString();
91 }
Zack Rusin91065372011-03-26 01:54:10 -040092
93 return QString();
94}
95
96ApiBitmask::ApiBitmask(const Trace::Bitmask *bitmask)
97 : m_value(0)
98{
99 init(bitmask);
100}
101
102
103void ApiBitmask::init(const Trace::Bitmask *bitmask)
104{
105 if (!bitmask)
106 return;
107
108 m_value = bitmask->value;
109 for (Trace::Bitmask::Signature::const_iterator it = bitmask->sig->begin();
110 it != bitmask->sig->end(); ++it) {
111 assert(it->second);
112 QPair<QString, unsigned long long> pair;
113
114 pair.first = QString::fromStdString(it->first);
115 pair.second = it->second;
116
117 m_sig.append(pair);
118 }
119}
120
121QString ApiBitmask::toString() const
122{
123 QString str;
124 unsigned long long value = m_value;
125 bool first = true;
126 for (Signature::const_iterator it = m_sig.begin();
127 value != 0 && it != m_sig.end(); ++it) {
128 Q_ASSERT(it->second);
129 if ((value & it->second) == it->second) {
130 if (!first) {
131 str += QLatin1String(" | ");
132 }
133 str += it->first;
134 value &= ~it->second;
135 first = false;
136 }
137 }
138 if (value || first) {
139 if (!first) {
140 str += QLatin1String(" | ");
141 }
142 str += QString::fromLatin1("0x%1").arg(value, 0, 16);
143 }
144 return str;
145}
146
147ApiStruct::ApiStruct(const Trace::Struct *s)
148{
149 init(s);
150}
151
152QString ApiStruct::toString() const
153{
154 QString str;
155
156 str += QLatin1String("{");
157 for (unsigned i = 0; i < m_members.count(); ++i) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400158 str += m_sig.memberNames[i] %
159 QLatin1Literal(" = ") %
160 apiVariantToString(m_members[i]);
Zack Rusin91065372011-03-26 01:54:10 -0400161 if (i < m_members.count() - 1)
162 str += QLatin1String(", ");
163 }
164 str += QLatin1String("}");
165
166 return str;
167}
168
169void ApiStruct::init(const Trace::Struct *s)
170{
171 if (!s)
172 return;
173
174 m_sig.name = QString::fromStdString(s->sig->name);
175 for (unsigned i = 0; i < s->members.size(); ++i) {
176 VariantVisitor vis;
177 m_sig.memberNames.append(
178 QString::fromStdString(s->sig->member_names[i]));
179 s->members[i]->visit(vis);
180 m_members.append(vis.variant());
181 }
182}
183
184void VariantVisitor::visit(Trace::Null *)
185{
Zack Rusin1d0d2292011-04-18 01:52:13 -0400186 m_variant = QVariant::fromValue(ApiPointer(0));
Zack Rusin91065372011-03-26 01:54:10 -0400187}
188
189void VariantVisitor::visit(Trace::Bool *node)
190{
191 m_variant = QVariant(node->value);
192}
193
194void VariantVisitor::visit(Trace::SInt *node)
195{
196 m_variant = QVariant(node->value);
197}
198
199void VariantVisitor::visit(Trace::UInt *node)
200{
201 m_variant = QVariant(node->value);
202}
203
204void VariantVisitor::visit(Trace::Float *node)
205{
206 m_variant = QVariant(node->value);
207}
208
209void VariantVisitor::visit(Trace::String *node)
210{
211 m_variant = QVariant(QString::fromStdString(node->value));
212}
213
214void VariantVisitor::visit(Trace::Enum *e)
215{
Zack Rusind54055e2011-04-17 18:27:28 -0400216 VariantVisitor vis;
217 e->sig->second->visit(vis);
218
219 QVariant val = vis.variant();
220
221 m_variant = QVariant::fromValue(
222 ApiEnum(QString::fromStdString(e->sig->first), val));
Zack Rusin91065372011-03-26 01:54:10 -0400223}
224
225void VariantVisitor::visit(Trace::Bitmask *bitmask)
226{
227 m_variant = QVariant::fromValue(ApiBitmask(bitmask));
228}
229
230void VariantVisitor::visit(Trace::Struct *str)
231{
232 m_variant = QVariant::fromValue(ApiStruct(str));
233}
234
235void VariantVisitor::visit(Trace::Array *array)
236{
237 m_variant = QVariant::fromValue(ApiArray(array));
238}
239
240void VariantVisitor::visit(Trace::Blob *blob)
241{
Zack Rusin2f8bb0b2011-04-18 00:22:50 -0400242 //XXX
243 //FIXME: this is a nasty hack. Trace::Blob's can't
244 // delete the contents in the destructor because
245 // the data is being used by other calls. We piggy back
246 // on that assumption and don't deep copy the data. If
247 // Blob's will start deleting the data we will need to
248 // start deep copying it or switch to using something like
249 // Boost's shared_ptr or Qt's QSharedPointer to handle it
Zack Rusin91065372011-03-26 01:54:10 -0400250 QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size);
251 m_variant = QVariant(barray);
252}
253
254void VariantVisitor::visit(Trace::Pointer *ptr)
255{
256 m_variant = QVariant::fromValue(ApiPointer(ptr->value));
257}
258
259ApiArray::ApiArray(const Trace::Array *arr)
260{
261 init(arr);
262}
263
Zack Rusinabb3fde2011-04-16 02:16:49 -0400264ApiArray::ApiArray(const QList<QVariant> &vals)
265 : m_array(vals)
266{
267}
268
Zack Rusin91065372011-03-26 01:54:10 -0400269QString ApiArray::toString() const
270{
271 QString str;
272 str += QLatin1String("[");
273 for(int i = 0; i < m_array.count(); ++i) {
274 const QVariant &var = m_array[i];
275 str += apiVariantToString(var);
276 if (i < m_array.count() - 1)
277 str += QLatin1String(", ");
278 }
279 str += QLatin1String("]");
280
281 return str;
282}
283
284void ApiArray::init(const Trace::Array *arr)
285{
286 if (!arr)
287 return;
288
289 for (int i = 0; i < arr->values.size(); ++i) {
290 VariantVisitor vis;
291 arr->values[i]->visit(vis);
292
293 m_array.append(vis.variant());
294 }
295}
Zack Rusin18eade52011-03-26 14:23:35 -0400296
297QStaticText ApiTraceCall::staticText() const
298{
Zack Rusin53484b22011-04-16 11:56:19 -0400299 if (m_staticText && !m_staticText->text().isEmpty())
300 return *m_staticText;
Zack Rusin18eade52011-03-26 14:23:35 -0400301
Zack Rusin9af5bff2011-04-18 01:05:50 -0400302 QVariantList argValues = arguments();
303
Zack Rusin53484b22011-04-16 11:56:19 -0400304 QString richText = QString::fromLatin1(
305 "<span style=\"font-weight:bold\">%1</span>(").arg(m_name);
Zack Rusinead6aad2011-04-15 22:16:18 -0400306 for (int i = 0; i < m_argNames.count(); ++i) {
Zack Rusin27cb2c42011-03-27 23:53:36 -0400307 richText += QLatin1String("<span style=\"color:#0000ff\">");
Zack Rusin9af5bff2011-04-18 01:05:50 -0400308 QString argText = apiVariantToString(argValues[i]);
Zack Rusindd7f2302011-03-31 22:55:57 -0400309
310 //if arguments are really long (e.g. shader text), cut them
311 // and elide it
312 if (argText.length() > 40) {
313 QString shortened = argText.mid(0, 40);
314 shortened[argText.length() - 5] = '.';
315 shortened[argText.length() - 4] = '.';
316 shortened[argText.length() - 3] = '.';
317 shortened[argText.length() - 2] = argText[argText.length() - 2];
318 shortened[argText.length() - 1] = argText[argText.length() - 1];
319 richText += shortened;
320 } else {
321 richText += argText;
322 }
Zack Rusin27cb2c42011-03-27 23:53:36 -0400323 richText += QLatin1String("</span>");
Zack Rusinead6aad2011-04-15 22:16:18 -0400324 if (i < m_argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -0400325 richText += QLatin1String(", ");
Zack Rusin27cb2c42011-03-27 23:53:36 -0400326 }
327 richText += QLatin1String(")");
Zack Rusinead6aad2011-04-15 22:16:18 -0400328 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400329 richText +=
330 QLatin1Literal(" = ") %
331 QLatin1Literal("<span style=\"color:#0000ff\">") %
332 apiVariantToString(m_returnValue) %
333 QLatin1Literal("</span>");
José Fonseca908f38d2011-03-31 10:09:14 +0100334 }
Zack Rusin27cb2c42011-03-27 23:53:36 -0400335
Zack Rusin53484b22011-04-16 11:56:19 -0400336 if (!m_staticText)
337 m_staticText = new QStaticText(richText);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400338 else
339 m_staticText->setText(richText);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400340 QTextOption opt;
341 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -0400342 m_staticText->setTextOption(opt);
343 m_staticText->prepare();
Zack Rusin27cb2c42011-03-27 23:53:36 -0400344
Zack Rusin53484b22011-04-16 11:56:19 -0400345 return *m_staticText;
Zack Rusin27cb2c42011-03-27 23:53:36 -0400346}
347
348QString ApiTraceCall::toHtml() const
349{
350 if (!m_richText.isEmpty())
351 return m_richText;
352
Zack Rusinb53b1612011-04-19 01:33:58 -0400353 m_richText = QLatin1String("<div class=\"call\">");
354
Zack Rusinead6aad2011-04-15 22:16:18 -0400355 if (m_helpUrl.isEmpty()) {
Zack Rusinb53b1612011-04-19 01:33:58 -0400356 m_richText += QString::fromLatin1(
357 "%1) <span class=\"callName\">%2</span>(")
358 .arg(m_index)
359 .arg(m_name);
Zack Rusinc97fadc2011-04-07 15:16:59 -0400360 } else {
Zack Rusinb53b1612011-04-19 01:33:58 -0400361 m_richText += QString::fromLatin1(
362 "%1) <span class=\"callName\"><a href=\"%2\">%3</a></span>(")
Zack Rusinead6aad2011-04-15 22:16:18 -0400363 .arg(m_index)
364 .arg(m_helpUrl.toString())
365 .arg(m_name);
Zack Rusinc97fadc2011-04-07 15:16:59 -0400366 }
367
Zack Rusin9af5bff2011-04-18 01:05:50 -0400368 QVariantList argValues = arguments();
Zack Rusinead6aad2011-04-15 22:16:18 -0400369 for (int i = 0; i < m_argNames.count(); ++i) {
Zack Rusinb53b1612011-04-19 01:33:58 -0400370 m_richText +=
371 QLatin1String("<span class=\"arg-name\">") +
372 m_argNames[i] +
373 QLatin1String("</span>") +
374 QLatin1Literal(" = ") +
375 QLatin1Literal("<span class=\"arg-value\">") +
376 apiVariantToString(argValues[i]) +
377 QLatin1Literal("</span>");
Zack Rusinead6aad2011-04-15 22:16:18 -0400378 if (i < m_argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -0400379 m_richText += QLatin1String(", ");
Zack Rusin18eade52011-03-26 14:23:35 -0400380 }
381 m_richText += QLatin1String(")");
382
Zack Rusinead6aad2011-04-15 22:16:18 -0400383 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400384 m_richText +=
385 QLatin1String(" = ") +
386 QLatin1String("<span style=\"color:#0000ff\">") +
387 apiVariantToString(m_returnValue) +
388 QLatin1String("</span>");
Zack Rusin18eade52011-03-26 14:23:35 -0400389 }
Zack Rusinb53b1612011-04-19 01:33:58 -0400390 m_richText += QLatin1String("</div>");
391
Zack Rusincc0b4912011-04-19 01:59:20 -0400392 if (hasError()) {
393 QString errorStr =
394 QString::fromLatin1(
395 "<div class=\"error\">%1</div>")
396 .arg(m_error);
397 m_richText += errorStr;
398 }
399
Zack Rusinb53b1612011-04-19 01:33:58 -0400400 m_richText =
401 QString::fromLatin1(
402 "<html><head><style type=\"text/css\" media=\"all\">"
403 "%1</style></head><body>%2</body></html>")
404 .arg(styleSheet)
405 .arg(m_richText);
Zack Rusin5e277b02011-04-16 21:52:26 -0400406 m_richText.squeeze();
Zack Rusinb53b1612011-04-19 01:33:58 -0400407
408 //qDebug()<<m_richText;
Zack Rusin18eade52011-03-26 14:23:35 -0400409 return m_richText;
410}
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400411
412QString ApiTraceCall::filterText() const
413{
414 if (!m_filterText.isEmpty())
415 return m_filterText;
416
Zack Rusin9af5bff2011-04-18 01:05:50 -0400417 QVariantList argValues = arguments();
Zack Rusin5e277b02011-04-16 21:52:26 -0400418 m_filterText = m_name + QLatin1Literal("(");
Zack Rusinead6aad2011-04-15 22:16:18 -0400419 for (int i = 0; i < m_argNames.count(); ++i) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400420 m_filterText += m_argNames[i] +
421 QLatin1Literal(" = ") +
Zack Rusin9af5bff2011-04-18 01:05:50 -0400422 apiVariantToString(argValues[i]);
423 if (argValues[i].type() == QVariant::ByteArray) {
Zack Rusin8e7a4ff2011-04-07 01:15:48 -0400424 m_hasBinaryData = true;
425 m_binaryDataIndex = i;
426 }
Zack Rusinead6aad2011-04-15 22:16:18 -0400427 if (i < m_argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -0400428 m_filterText += QLatin1String(", ");
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400429 }
430 m_filterText += QLatin1String(")");
431
Zack Rusinead6aad2011-04-15 22:16:18 -0400432 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400433 m_filterText += QLatin1Literal(" = ") +
434 apiVariantToString(m_returnValue);
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400435 }
Zack Rusin5e277b02011-04-16 21:52:26 -0400436 m_filterText.squeeze();
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400437 return m_filterText;
438}
Zack Rusinf6667d12011-03-30 11:03:37 -0400439
440QStaticText ApiTraceFrame::staticText() const
441{
Zack Rusin53484b22011-04-16 11:56:19 -0400442 if (m_staticText && !m_staticText->text().isEmpty())
443 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -0400444
445 QString richText =
446 QString::fromLatin1("<span style=\"font-weight:bold\">Frame %1</span>").arg(number);
447
Zack Rusin53484b22011-04-16 11:56:19 -0400448 if (!m_staticText)
449 m_staticText = new QStaticText(richText);
450
Zack Rusinf6667d12011-03-30 11:03:37 -0400451 QTextOption opt;
452 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -0400453 m_staticText->setTextOption(opt);
454 m_staticText->prepare();
Zack Rusinf6667d12011-03-30 11:03:37 -0400455
Zack Rusin53484b22011-04-16 11:56:19 -0400456 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -0400457}
458
459int ApiTraceCall::numChildren() const
460{
461 return 0;
462}
463
464int ApiTraceFrame::numChildren() const
465{
466 return calls.count();
467}
468
469ApiTraceFrame::ApiTraceFrame()
Zack Rusin7c1793e2011-04-16 23:14:25 -0400470 : ApiTraceEvent(ApiTraceEvent::Frame),
471 m_parentTrace(0)
Zack Rusinf6667d12011-03-30 11:03:37 -0400472{
473}
474
475ApiTraceCall::ApiTraceCall()
Zack Rusin8e7a4ff2011-04-07 01:15:48 -0400476 : ApiTraceEvent(ApiTraceEvent::Call),
477 m_hasBinaryData(false),
478 m_binaryDataIndex(0)
Zack Rusinf6667d12011-03-30 11:03:37 -0400479{
480}
481
482ApiTraceEvent::ApiTraceEvent()
Zack Rusin53484b22011-04-16 11:56:19 -0400483 : m_type(ApiTraceEvent::None),
484 m_staticText(0)
Zack Rusinf6667d12011-03-30 11:03:37 -0400485{
486}
487
488ApiTraceEvent::ApiTraceEvent(Type t)
Zack Rusin53484b22011-04-16 11:56:19 -0400489 : m_type(t),
490 m_staticText(0)
Zack Rusinf6667d12011-03-30 11:03:37 -0400491{
492}
493
494ApiTraceCall::~ApiTraceCall()
495{
496}
Zack Rusin581e3ff2011-03-31 23:58:07 -0400497
Zack Rusin7c814f12011-04-09 19:20:58 -0400498QVariantMap ApiTraceEvent::stateParameters() const
499{
500 return m_state.parameters();
501}
502
503ApiTraceState ApiTraceEvent::state() const
Zack Rusin581e3ff2011-03-31 23:58:07 -0400504{
505 return m_state;
506}
507
Zack Rusin7c814f12011-04-09 19:20:58 -0400508void ApiTraceEvent::setState(const ApiTraceState &state)
Zack Rusin581e3ff2011-03-31 23:58:07 -0400509{
510 m_state = state;
511}
Zack Rusin8e7a4ff2011-04-07 01:15:48 -0400512
513bool ApiTraceCall::hasBinaryData() const
514{
515 return m_hasBinaryData;
516}
517
518int ApiTraceCall::binaryDataIndex() const
519{
520 return m_binaryDataIndex;
521}
Zack Rusin7c814f12011-04-09 19:20:58 -0400522
523ApiTraceState::ApiTraceState()
524{
525}
526
527ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
528{
529 m_parameters = parsedJson[QLatin1String("parameters")].toMap();
José Fonsecaf7a6b622011-04-13 10:37:13 +0100530 QVariantMap attachedShaders =
José Fonseca3773dd62011-04-13 10:54:19 +0100531 parsedJson[QLatin1String("shaders")].toMap();
José Fonsecaf7a6b622011-04-13 10:37:13 +0100532 QVariantMap::const_iterator itr;
Zack Rusin7c814f12011-04-09 19:20:58 -0400533
534
Zack Rusin5e277b02011-04-16 21:52:26 -0400535 for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd();
536 ++itr) {
José Fonsecaf7a6b622011-04-13 10:37:13 +0100537 QString type = itr.key();
538 QString source = itr.value().toString();
539 m_shaderSources[type] = source;
Zack Rusin7c814f12011-04-09 19:20:58 -0400540 }
Zack Rusin952e9d42011-04-09 23:37:21 -0400541
542 QVariantList textureUnits =
543 parsedJson[QLatin1String("textures")].toList();
544 for (int i = 0; i < textureUnits.count(); ++i) {
545 QVariantMap unit = textureUnits[i].toMap();
Zack Rusin952e9d42011-04-09 23:37:21 -0400546 for (itr = unit.constBegin(); itr != unit.constEnd(); ++itr) {
547 QVariantMap target = itr.value().toMap();
548 if (target.count()) {
549 QVariantList levels = target[QLatin1String("levels")].toList();
550 for (int j = 0; j < levels.count(); ++j) {
551 QVariantMap level = levels[j].toMap();
552 QVariantMap image = level[QLatin1String("image")].toMap();
553 QSize size(image[QLatin1String("__width__")].toInt(),
554 image[QLatin1String("__height__")].toInt());
555 QString cls = image[QLatin1String("__class__")].toString();
556 QString type = image[QLatin1String("__type__")].toString();
José Fonseca3b9fc082011-04-10 19:25:01 +0100557 bool normalized =
558 image[QLatin1String("__normalized__")].toBool();
Zack Rusin952e9d42011-04-09 23:37:21 -0400559 int numChannels =
560 image[QLatin1String("__channels__")].toInt();
Zack Rusin952e9d42011-04-09 23:37:21 -0400561
José Fonseca3b9fc082011-04-10 19:25:01 +0100562 Q_ASSERT(type == QLatin1String("uint8"));
563 Q_ASSERT(normalized == true);
Zack Rusin952e9d42011-04-09 23:37:21 -0400564
565 QByteArray dataArray =
566 image[QLatin1String("__data__")].toByteArray();
567
568 ApiTexture tex;
569 tex.setSize(size);
José Fonsecab794df12011-04-12 08:28:45 +0100570 tex.setNumChannels(numChannels);
Zack Rusin952e9d42011-04-09 23:37:21 -0400571 tex.setLevel(j);
572 tex.setUnit(i);
573 tex.setTarget(itr.key());
574 tex.contentsFromBase64(dataArray);
575
576 m_textures.append(tex);
577 }
578 }
579 }
580 }
Zack Rusina6846412011-04-10 19:51:44 -0400581
582 QVariantMap fbos =
583 parsedJson[QLatin1String("framebuffer")].toMap();
Zack Rusina6846412011-04-10 19:51:44 -0400584 for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) {
585 QVariantMap buffer = itr.value().toMap();
586 QSize size(buffer[QLatin1String("__width__")].toInt(),
587 buffer[QLatin1String("__height__")].toInt());
588 QString cls = buffer[QLatin1String("__class__")].toString();
589 QString type = buffer[QLatin1String("__type__")].toString();
590 bool normalized = buffer[QLatin1String("__normalized__")].toBool();
591 int numChannels = buffer[QLatin1String("__channels__")].toInt();
592
Zack Rusina6846412011-04-10 19:51:44 -0400593 Q_ASSERT(type == QLatin1String("uint8"));
594 Q_ASSERT(normalized == true);
595
596 QByteArray dataArray =
597 buffer[QLatin1String("__data__")].toByteArray();
598
599 ApiFramebuffer fbo;
600 fbo.setSize(size);
José Fonsecab794df12011-04-12 08:28:45 +0100601 fbo.setNumChannels(numChannels);
Zack Rusina6846412011-04-10 19:51:44 -0400602 fbo.setType(itr.key());
603 fbo.contentsFromBase64(dataArray);
604 m_framebuffers.append(fbo);
605 }
Zack Rusin7c814f12011-04-09 19:20:58 -0400606}
607
608QVariantMap ApiTraceState::parameters() const
609{
610 return m_parameters;
611}
612
José Fonsecaf7a6b622011-04-13 10:37:13 +0100613QMap<QString, QString> ApiTraceState::shaderSources() const
Zack Rusin7c814f12011-04-09 19:20:58 -0400614{
615 return m_shaderSources;
616}
617
618bool ApiTraceState::isEmpty() const
619{
620 return m_parameters.isEmpty();
621}
622
Zack Rusin952e9d42011-04-09 23:37:21 -0400623QList<ApiTexture> ApiTraceState::textures() const
624{
625 return m_textures;
626}
627
Zack Rusina6846412011-04-10 19:51:44 -0400628QList<ApiFramebuffer> ApiTraceState::framebuffers() const
629{
630 return m_framebuffers;
631}
632
Zack Rusin963102f2011-04-15 01:45:05 -0400633QList<QVariant> ApiArray::values() const
634{
635 return m_array;
636}
Zack Rusinead6aad2011-04-15 22:16:18 -0400637
638int ApiTraceCall::index() const
639{
640 return m_index;
641}
642
643QString ApiTraceCall::name() const
644{
645 return m_name;
646}
647
648QStringList ApiTraceCall::argNames() const
649{
650 return m_argNames;
651}
652
653QVariantList ApiTraceCall::arguments() const
654{
Zack Rusin661842d2011-04-17 01:59:16 -0400655 if (m_editedValues.isEmpty())
656 return m_argValues;
657 else
658 return m_editedValues;
Zack Rusinead6aad2011-04-15 22:16:18 -0400659}
660
661QVariant ApiTraceCall::returnValue() const
662{
663 return m_returnValue;
664}
665
666QUrl ApiTraceCall::helpUrl() const
667{
668 return m_helpUrl;
669}
670
671ApiTraceCall::ApiTraceCall(const Trace::Call *call)
672 : ApiTraceEvent(ApiTraceEvent::Call),
673 m_hasBinaryData(false),
674 m_binaryDataIndex(0)
675{
676 m_name = QString::fromStdString(call->sig->name);
677 m_index = call->no;
678
679 QString argumentsText;
680 for (int i = 0; i < call->sig->arg_names.size(); ++i) {
681 m_argNames +=
682 QString::fromStdString(call->sig->arg_names[i]);
683 }
684 if (call->ret) {
685 VariantVisitor retVisitor;
686 call->ret->visit(retVisitor);
687 m_returnValue = retVisitor.variant();
688 }
689 for (int i = 0; i < call->args.size(); ++i) {
690 VariantVisitor argVisitor;
691 call->args[i]->visit(argVisitor);
692 m_argValues += argVisitor.variant();
693 }
694}
695
696void ApiTraceCall::setHelpUrl(const QUrl &url)
697{
698 m_helpUrl = url;
699}
700
701void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
702{
703 m_parentFrame = frame;
704}
705
706ApiTraceFrame * ApiTraceCall::parentFrame()const
707{
708 return m_parentFrame;
709}
Zack Rusinabb3fde2011-04-16 02:16:49 -0400710
Zack Rusin53484b22011-04-16 11:56:19 -0400711ApiTraceEvent::~ApiTraceEvent()
712{
713 delete m_staticText;
714}
715
Zack Rusine6bc9122011-04-16 23:07:05 -0400716void ApiTraceCall::revert()
717{
Zack Rusin0ddd2502011-04-17 02:34:45 -0400718 setEditedValues(QVariantList());
Zack Rusine6bc9122011-04-16 23:07:05 -0400719}
720
Zack Rusin7c1793e2011-04-16 23:14:25 -0400721ApiTrace * ApiTraceFrame::parentTrace() const
722{
723 return m_parentTrace;
724}
725
726void ApiTraceFrame::setParentTrace(ApiTrace *trace)
727{
728 m_parentTrace = trace;
729}
730
Zack Rusin661842d2011-04-17 01:59:16 -0400731QVariantList ApiTraceCall::originalValues() const
732{
733 return m_argValues;
734}
735
736void ApiTraceCall::setEditedValues(const QVariantList &lst)
737{
Zack Rusinb53b1612011-04-19 01:33:58 -0400738 ApiTrace *trace = parentTrace();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400739
Zack Rusin661842d2011-04-17 01:59:16 -0400740 m_editedValues = lst;
Zack Rusin9af5bff2011-04-18 01:05:50 -0400741 //lets regenerate data
742 m_richText = QString();
743 m_filterText = QString();
744 delete m_staticText;
745 m_staticText = 0;
Zack Rusin661842d2011-04-17 01:59:16 -0400746
747 if (trace) {
748 if (!lst.isEmpty()) {
749 trace->callEdited(this);
750 } else {
751 trace->callReverted(this);
752 }
753 }
754}
755
756QVariantList ApiTraceCall::editedValues() const
757{
758 return m_editedValues;
759}
760
761bool ApiTraceCall::edited() const
762{
763 return !m_editedValues.isEmpty();
764}
765
Zack Rusind54055e2011-04-17 18:27:28 -0400766ApiEnum::ApiEnum(const QString &name, const QVariant &val)
767 : m_name(name),
768 m_value(val)
769{
770}
771
772QString ApiEnum::toString() const
773{
774 return m_name;
775}
776
777QVariant ApiEnum::value() const
778{
779 return m_value;
780}
781
782QString ApiEnum::name() const
783{
784 return m_name;
785}
786
Zack Rusinc6247dd2011-04-17 22:56:58 -0400787unsigned long long ApiBitmask::value() const
788{
789 return m_value;
790}
791
792ApiBitmask::Signature ApiBitmask::signature() const
793{
794 return m_sig;
795}
796
797ApiStruct::Signature ApiStruct::signature() const
798{
799 return m_sig;
800}
801
802QList<QVariant> ApiStruct::values() const
803{
804 return m_members;
805}
806
807unsigned long long ApiPointer::value() const
808{
809 return m_value;
810}
811
Zack Rusinb53b1612011-04-19 01:33:58 -0400812bool ApiTraceCall::hasError() const
813{
814 return !m_error.isEmpty();
815}
816
817QString ApiTraceCall::error() const
818{
819 return m_error;
820}
821
822void ApiTraceCall::setError(const QString &msg)
823{
824 if (m_error != msg) {
825 ApiTrace *trace = parentTrace();
826 m_error = msg;
Zack Rusincc0b4912011-04-19 01:59:20 -0400827 m_richText = QString();
Zack Rusinb53b1612011-04-19 01:33:58 -0400828 if (trace)
829 trace->callError(this);
830 }
831}
832
833ApiTrace * ApiTraceCall::parentTrace() const
834{
835 if (m_parentFrame)
836 return m_parentFrame->parentTrace();
837 return NULL;
838}
839