]> git.cworth.org Git - apitrace/blob - gui/apitracecall.cpp
Start collecting the edited values.
[apitrace] / gui / apitracecall.cpp
1 #include "apitracecall.h"
2
3 #include "trace_model.hpp"
4
5 #include <QDebug>
6 #include <QObject>
7
8 ApiPointer::ApiPointer(int val)
9     : m_value(val)
10 {
11 }
12
13 QString ApiPointer::toString() const
14 {
15     if (m_value)
16         return QString("0x%1").arg(m_value, 0, 16);
17     else
18         return QLatin1String("NULL");
19 }
20
21 QString apiVariantToString(const QVariant &variant)
22 {
23     if (variant.userType() == QVariant::Double) {
24         return QString::number(variant.toFloat());
25     }
26     if (variant.userType() == QVariant::ByteArray) {
27         if (variant.toByteArray().size() < 1024) {
28             int bytes = variant.toByteArray().size();
29             return QObject::tr("[binary data, size = %1 bytes]").arg(bytes);
30         } else {
31             float kb = variant.toByteArray().size()/1024.;
32             return QObject::tr("[binary data, size = %1 kb]").arg(kb);
33         }
34     }
35
36     if (variant.userType() < QVariant::UserType) {
37         return variant.toString();
38     }
39
40     if (variant.canConvert<ApiPointer>()) {
41         return variant.value<ApiPointer>().toString();
42     }
43     if (variant.canConvert<ApiBitmask>()) {
44         return variant.value<ApiBitmask>().toString();
45     }
46     if (variant.canConvert<ApiStruct>()) {
47         return variant.value<ApiStruct>().toString();
48     }
49     if (variant.canConvert<ApiArray>()) {
50         return variant.value<ApiArray>().toString();
51     }
52
53     return QString();
54 }
55
56 ApiBitmask::ApiBitmask(const Trace::Bitmask *bitmask)
57     : m_value(0)
58 {
59     init(bitmask);
60 }
61
62
63 void ApiBitmask::init(const Trace::Bitmask *bitmask)
64 {
65     if (!bitmask)
66         return;
67
68     m_value = bitmask->value;
69     for (Trace::Bitmask::Signature::const_iterator it = bitmask->sig->begin();
70          it != bitmask->sig->end(); ++it) {
71         assert(it->second);
72         QPair<QString, unsigned long long> pair;
73
74         pair.first = QString::fromStdString(it->first);
75         pair.second = it->second;
76
77         m_sig.append(pair);
78     }
79 }
80
81 QString ApiBitmask::toString() const
82 {
83     QString str;
84     unsigned long long value = m_value;
85     bool first = true;
86     for (Signature::const_iterator it = m_sig.begin();
87          value != 0 && it != m_sig.end(); ++it) {
88         Q_ASSERT(it->second);
89         if ((value & it->second) == it->second) {
90             if (!first) {
91                 str += QLatin1String(" | ");
92             }
93             str += it->first;
94             value &= ~it->second;
95             first = false;
96         }
97     }
98     if (value || first) {
99         if (!first) {
100             str += QLatin1String(" | ");
101         }
102         str += QString::fromLatin1("0x%1").arg(value, 0, 16);
103     }
104     return str;
105 }
106
107 ApiStruct::ApiStruct(const Trace::Struct *s)
108 {
109     init(s);
110 }
111
112 QString ApiStruct::toString() const
113 {
114     QString str;
115
116     str += QLatin1String("{");
117     for (unsigned i = 0; i < m_members.count(); ++i) {
118         str += m_sig.memberNames[i];
119         str += QLatin1String(" = ");
120         str += apiVariantToString(m_members[i]);
121         if (i < m_members.count() - 1)
122             str += QLatin1String(", ");
123     }
124     str += QLatin1String("}");
125
126     return str;
127 }
128
129 void ApiStruct::init(const Trace::Struct *s)
130 {
131     if (!s)
132         return;
133
134     m_sig.name = QString::fromStdString(s->sig->name);
135     for (unsigned i = 0; i < s->members.size(); ++i) {
136         VariantVisitor vis;
137         m_sig.memberNames.append(
138             QString::fromStdString(s->sig->member_names[i]));
139         s->members[i]->visit(vis);
140         m_members.append(vis.variant());
141     }
142 }
143
144 void VariantVisitor::visit(Trace::Null *)
145 {
146     m_variant = QVariant(QLatin1String("NULL"));
147 }
148
149 void VariantVisitor::visit(Trace::Bool *node)
150 {
151     m_variant = QVariant(node->value);
152 }
153
154 void VariantVisitor::visit(Trace::SInt *node)
155 {
156     m_variant = QVariant(node->value);
157 }
158
159 void VariantVisitor::visit(Trace::UInt *node)
160 {
161     m_variant = QVariant(node->value);
162 }
163
164 void VariantVisitor::visit(Trace::Float *node)
165 {
166     m_variant = QVariant(node->value);
167 }
168
169 void VariantVisitor::visit(Trace::String *node)
170 {
171     m_variant = QVariant(QString::fromStdString(node->value));
172 }
173
174 void VariantVisitor::visit(Trace::Enum *e)
175 {
176     m_variant = QVariant(QString::fromStdString(e->sig->first));
177 }
178
179 void VariantVisitor::visit(Trace::Bitmask *bitmask)
180 {
181     m_variant = QVariant::fromValue(ApiBitmask(bitmask));
182 }
183
184 void VariantVisitor::visit(Trace::Struct *str)
185 {
186     m_variant = QVariant::fromValue(ApiStruct(str));
187 }
188
189 void VariantVisitor::visit(Trace::Array *array)
190 {
191     m_variant = QVariant::fromValue(ApiArray(array));
192 }
193
194 void VariantVisitor::visit(Trace::Blob *blob)
195 {
196     QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size);
197     m_variant = QVariant(barray);
198 }
199
200 void VariantVisitor::visit(Trace::Pointer *ptr)
201 {
202     m_variant = QVariant::fromValue(ApiPointer(ptr->value));
203 }
204
205 ApiArray::ApiArray(const Trace::Array *arr)
206 {
207     init(arr);
208 }
209
210 ApiArray::ApiArray(const QList<QVariant> &vals)
211     : m_array(vals)
212 {
213 }
214
215 QString ApiArray::toString() const
216 {
217     QString str;
218     str += QLatin1String("[");
219     for(int i = 0; i < m_array.count(); ++i) {
220         const QVariant &var = m_array[i];
221         str += apiVariantToString(var);
222         if (i < m_array.count() - 1)
223             str += QLatin1String(", ");
224     }
225     str += QLatin1String("]");
226
227     return str;
228 }
229
230 void ApiArray::init(const Trace::Array *arr)
231 {
232     if (!arr)
233         return;
234
235     for (int i = 0; i < arr->values.size(); ++i) {
236         VariantVisitor vis;
237         arr->values[i]->visit(vis);
238
239         m_array.append(vis.variant());
240     }
241 }
242
243 QStaticText ApiTraceCall::staticText() const
244 {
245     if (!m_staticText.text().isEmpty())
246         return m_staticText;
247
248     QString richText = QString::fromLatin1("<span style=\"font-weight:bold\">%1</span>(").arg(m_name);
249     for (int i = 0; i < m_argNames.count(); ++i) {
250         richText += QLatin1String("<span style=\"color:#0000ff\">");
251         QString argText = apiVariantToString(m_argValues[i]);
252
253         //if arguments are really long (e.g. shader text), cut them
254         // and elide it
255         if (argText.length() > 40) {
256             QString shortened = argText.mid(0, 40);
257             shortened[argText.length() - 5] = '.';
258             shortened[argText.length() - 4] = '.';
259             shortened[argText.length() - 3] = '.';
260             shortened[argText.length() - 2] = argText[argText.length() - 2];
261             shortened[argText.length() - 1] = argText[argText.length() - 1];
262             richText += shortened;
263         } else {
264             richText += argText;
265         }
266         richText += QLatin1String("</span>");
267         if (i < m_argNames.count() - 1)
268             richText += QString::fromLatin1(", ");
269     }
270     richText += QLatin1String(")");
271     if (m_returnValue.isValid()) {
272         richText += QLatin1String(" = ");
273         richText += QLatin1String("<span style=\"color:#0000ff\">");
274         richText += apiVariantToString(m_returnValue);
275         richText += QLatin1String("</span>");
276     }
277
278     m_staticText.setText(richText);
279     QTextOption opt;
280     opt.setWrapMode(QTextOption::NoWrap);
281     m_staticText.setTextOption(opt);
282     m_staticText.prepare();
283
284     return m_staticText;
285 }
286
287 QString ApiTraceCall::toHtml() const
288 {
289     if (!m_richText.isEmpty())
290         return m_richText;
291
292     if (m_helpUrl.isEmpty()) {
293         m_richText = QString::fromLatin1(
294             "%1) <span style=\"font-weight:bold\">%2</span>(")
295                      .arg(m_index)
296                      .arg(m_name);
297     } else {
298         m_richText = QString::fromLatin1(
299             "%1) <span style=\"font-weight:bold\"><a href=\"%2\">%3</a></span>(")
300                       .arg(m_index)
301                       .arg(m_helpUrl.toString())
302                       .arg(m_name);
303     }
304
305     for (int i = 0; i < m_argNames.count(); ++i) {
306         m_richText += m_argNames[i];
307         m_richText += QString::fromLatin1(" = ");
308         m_richText += QLatin1String("<span style=\"color:#0000ff\">");
309         m_richText += apiVariantToString(m_argValues[i]);
310         m_richText += QLatin1String("</span>");
311         if (i < m_argNames.count() - 1)
312             m_richText += QString::fromLatin1(", ");
313     }
314     m_richText += QLatin1String(")");
315
316     if (m_returnValue.isValid()) {
317         m_richText += QLatin1String(" = ");
318         m_richText += QLatin1String("<span style=\"color:#0000ff\">");
319         m_richText += apiVariantToString(m_returnValue);
320         m_richText += QLatin1String("</span>");
321     }
322     return m_richText;
323 }
324
325 QString ApiTraceCall::filterText() const
326 {
327     if (!m_filterText.isEmpty())
328         return m_filterText;
329
330     m_filterText = m_name;
331     m_filterText += QLatin1String("(");
332     for (int i = 0; i < m_argNames.count(); ++i) {
333         m_filterText += m_argNames[i];
334         m_filterText += QString::fromLatin1(" = ");
335
336         if (m_argValues[i].type() == QVariant::ByteArray) {
337             m_hasBinaryData = true;
338             m_binaryDataIndex = i;
339         }
340         m_filterText += apiVariantToString(m_argValues[i]);
341         if (i < m_argNames.count() - 1)
342             m_filterText += QString::fromLatin1(", ");
343     }
344     m_filterText += QLatin1String(")");
345
346     if (m_returnValue.isValid()) {
347         m_filterText += QLatin1String(" = ");
348         m_filterText += apiVariantToString(m_returnValue);
349     }
350     return m_filterText;
351 }
352
353 QStaticText ApiTraceFrame::staticText() const
354 {
355     if (!m_staticText.text().isEmpty())
356         return m_staticText;
357
358     QString richText =
359         QString::fromLatin1("<span style=\"font-weight:bold\">Frame %1</span>").arg(number);
360
361     m_staticText.setText(richText);
362     QTextOption opt;
363     opt.setWrapMode(QTextOption::NoWrap);
364     m_staticText.setTextOption(opt);
365     m_staticText.prepare();
366
367     return m_staticText;
368 }
369
370 int ApiTraceCall::numChildren() const
371 {
372     return 0;
373 }
374
375 int ApiTraceFrame::numChildren() const
376 {
377     return calls.count();
378 }
379
380 ApiTraceFrame::ApiTraceFrame()
381     : ApiTraceEvent(ApiTraceEvent::Frame)
382 {
383 }
384
385 ApiTraceCall::ApiTraceCall()
386     : ApiTraceEvent(ApiTraceEvent::Call),
387       m_hasBinaryData(false),
388       m_binaryDataIndex(0)
389 {
390 }
391
392 ApiTraceEvent::ApiTraceEvent()
393     : m_type(ApiTraceEvent::None)
394 {
395 }
396
397 ApiTraceEvent::ApiTraceEvent(Type t)
398     : m_type(t)
399 {
400 }
401
402 ApiTraceCall::~ApiTraceCall()
403 {
404 }
405
406 QVariantMap ApiTraceEvent::stateParameters() const
407 {
408     return m_state.parameters();
409 }
410
411 ApiTraceState ApiTraceEvent::state() const
412 {
413     return m_state;
414 }
415
416 void ApiTraceEvent::setState(const ApiTraceState &state)
417 {
418     m_state = state;
419 }
420
421 bool ApiTraceCall::hasBinaryData() const
422 {
423     return m_hasBinaryData;
424 }
425
426 int ApiTraceCall::binaryDataIndex() const
427 {
428     return m_binaryDataIndex;
429 }
430
431 ApiTraceState::ApiTraceState()
432 {
433 }
434
435 ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
436 {
437     m_parameters = parsedJson[QLatin1String("parameters")].toMap();
438     QVariantMap attachedShaders =
439         parsedJson[QLatin1String("shaders")].toMap();
440     QVariantMap::const_iterator itr;
441
442
443     for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd(); ++itr) {
444         QString type = itr.key();
445         QString source = itr.value().toString();
446         m_shaderSources[type] = source;
447     }
448
449     QVariantList textureUnits =
450         parsedJson[QLatin1String("textures")].toList();
451     for (int i = 0; i < textureUnits.count(); ++i) {
452         QVariantMap unit = textureUnits[i].toMap();
453         for (itr = unit.constBegin(); itr != unit.constEnd(); ++itr) {
454             QVariantMap target = itr.value().toMap();
455             if (target.count()) {
456                 QVariantList levels = target[QLatin1String("levels")].toList();
457                 for (int j = 0; j < levels.count(); ++j) {
458                     QVariantMap level = levels[j].toMap();
459                     QVariantMap image = level[QLatin1String("image")].toMap();
460                     QSize size(image[QLatin1String("__width__")].toInt(),
461                                image[QLatin1String("__height__")].toInt());
462                     QString cls = image[QLatin1String("__class__")].toString();
463                     QString type = image[QLatin1String("__type__")].toString();
464                     bool normalized =
465                         image[QLatin1String("__normalized__")].toBool();
466                     int numChannels =
467                         image[QLatin1String("__channels__")].toInt();
468
469                     Q_ASSERT(type == QLatin1String("uint8"));
470                     Q_ASSERT(normalized == true);
471
472                     QByteArray dataArray =
473                         image[QLatin1String("__data__")].toByteArray();
474
475                     ApiTexture tex;
476                     tex.setSize(size);
477                     tex.setNumChannels(numChannels);
478                     tex.setLevel(j);
479                     tex.setUnit(i);
480                     tex.setTarget(itr.key());
481                     tex.contentsFromBase64(dataArray);
482
483                     m_textures.append(tex);
484                 }
485             }
486         }
487     }
488
489     QVariantMap fbos =
490         parsedJson[QLatin1String("framebuffer")].toMap();
491     for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) {
492         QVariantMap buffer = itr.value().toMap();
493         QSize size(buffer[QLatin1String("__width__")].toInt(),
494                    buffer[QLatin1String("__height__")].toInt());
495         QString cls = buffer[QLatin1String("__class__")].toString();
496         QString type = buffer[QLatin1String("__type__")].toString();
497         bool normalized = buffer[QLatin1String("__normalized__")].toBool();
498         int numChannels = buffer[QLatin1String("__channels__")].toInt();
499
500         Q_ASSERT(type == QLatin1String("uint8"));
501         Q_ASSERT(normalized == true);
502
503         QByteArray dataArray =
504             buffer[QLatin1String("__data__")].toByteArray();
505
506         ApiFramebuffer fbo;
507         fbo.setSize(size);
508         fbo.setNumChannels(numChannels);
509         fbo.setType(itr.key());
510         fbo.contentsFromBase64(dataArray);
511         m_framebuffers.append(fbo);
512     }
513 }
514
515 QVariantMap ApiTraceState::parameters() const
516 {
517     return m_parameters;
518 }
519
520 QMap<QString, QString> ApiTraceState::shaderSources() const
521 {
522     return m_shaderSources;
523 }
524
525 bool ApiTraceState::isEmpty() const
526 {
527     return m_parameters.isEmpty();
528 }
529
530 QList<ApiTexture> ApiTraceState::textures() const
531 {
532     return m_textures;
533 }
534
535 QList<ApiFramebuffer> ApiTraceState::framebuffers() const
536 {
537     return m_framebuffers;
538 }
539
540 QList<QVariant> ApiArray::values() const
541 {
542     return m_array;
543 }
544
545 int ApiTraceCall::index() const
546 {
547     return m_index;
548 }
549
550 QString ApiTraceCall::name() const
551 {
552     return m_name;
553 }
554
555 QStringList ApiTraceCall::argNames() const
556 {
557     return m_argNames;
558 }
559
560 QVariantList ApiTraceCall::arguments() const
561 {
562     return m_argValues;
563 }
564
565 QVariant ApiTraceCall::returnValue() const
566 {
567     return m_returnValue;
568 }
569
570 QUrl ApiTraceCall::helpUrl() const
571 {
572     return m_helpUrl;
573 }
574
575 ApiTraceCall::ApiTraceCall(const Trace::Call *call)
576     : ApiTraceEvent(ApiTraceEvent::Call),
577       m_hasBinaryData(false),
578       m_binaryDataIndex(0)
579 {
580     m_name = QString::fromStdString(call->sig->name);
581     m_index = call->no;
582
583     QString argumentsText;
584     for (int i = 0; i < call->sig->arg_names.size(); ++i) {
585         m_argNames +=
586             QString::fromStdString(call->sig->arg_names[i]);
587     }
588     if (call->ret) {
589         VariantVisitor retVisitor;
590         call->ret->visit(retVisitor);
591         m_returnValue = retVisitor.variant();
592     }
593     for (int i = 0; i < call->args.size(); ++i) {
594         VariantVisitor argVisitor;
595         call->args[i]->visit(argVisitor);
596         m_argValues += argVisitor.variant();
597     }
598 }
599
600 void ApiTraceCall::setHelpUrl(const QUrl &url)
601 {
602     m_helpUrl = url;
603 }
604
605 void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
606 {
607     m_parentFrame = frame;
608 }
609
610 ApiTraceFrame * ApiTraceCall::parentFrame()const
611 {
612     return m_parentFrame;
613 }
614