blob: 4d7a17c427d2df8ad268c628f2afe4d6884260a4 [file] [log] [blame]
Zack Rusinf6667d12011-03-30 11:03:37 -04001#include "apitrace.h"
2
3#include "loaderthread.h"
4
5ApiTrace::ApiTrace()
6 : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers)
7{
8 m_loader = new LoaderThread(this);
9 connect(m_loader, SIGNAL(parsedFrames(const QList<ApiTraceFrame*>)),
10 this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
Zack Rusinde4ea412011-03-30 11:30:08 -040011 connect(m_loader, SIGNAL(started()),
12 this, SIGNAL(startedLoadingTrace()));
13 connect(m_loader, SIGNAL(finished()),
14 this, SIGNAL(finishedLoadingTrace()));
Zack Rusinf6667d12011-03-30 11:03:37 -040015}
16
17ApiTrace::~ApiTrace()
18{
19 qDeleteAll(m_calls);
20 qDeleteAll(m_frames);
21 delete m_loader;
22}
23
24bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
25 ApiTrace::FrameMarker marker)
26{
27 if (!call)
28 return false;
29
30 switch (marker) {
31 case FrameMarker_SwapBuffers:
32 return call->name.contains(QLatin1String("SwapBuffers"));
33 case FrameMarker_Flush:
34 return call->name == QLatin1String("glFlush");
35 case FrameMarker_Finish:
36 return call->name == QLatin1String("glFinish");
37 case FrameMarker_Clear:
38 return call->name == QLatin1String("glClear");
39 }
40
41 Q_ASSERT(!"unknown frame marker");
42
43 return false;
44}
45
46bool ApiTrace::isEmpty() const
47{
48 return m_calls.isEmpty();
49}
50
51QString ApiTrace::fileName() const
52{
53 return m_fileName;
54}
55
56ApiTrace::FrameMarker ApiTrace::frameMarker() const
57{
58 return m_frameMarker;
59}
60
61QList<ApiTraceCall*> ApiTrace::calls() const
62{
63 return m_calls;
64}
65
66ApiTraceCall * ApiTrace::callAt(int idx) const
67{
68 return m_calls.value(idx);
69}
70
71int ApiTrace::numCalls() const
72{
73 return m_calls.count();
74}
75
76QList<ApiTraceFrame*> ApiTrace::frames() const
77{
78 return m_frames;
79}
80
81ApiTraceFrame * ApiTrace::frameAt(int idx) const
82{
83 return m_frames.value(idx);
84}
85
86int ApiTrace::numFrames() const
87{
88 return m_frames.count();
89}
90
91int ApiTrace::numCallsInFrame(int idx) const
92{
93 const ApiTraceFrame *frame = frameAt(idx);
94 if (frame)
95 return frame->calls.count();
96 else
97 return 0;
98}
99
100void ApiTrace::setFileName(const QString &name)
101{
102 if (m_fileName != name) {
103 m_fileName = name;
104
105 if (m_loader->isRunning()) {
106 m_loader->terminate();
107 m_loader->wait();
108 }
109 emit invalidated();
110
111 m_loader->loadFile(m_fileName);
112 }
113}
114
115void ApiTrace::setFrameMarker(FrameMarker marker)
116{
117 if (m_frameMarker != marker) {
118 emit framesInvalidated();
119
120 qDeleteAll(m_frames);
121 m_frames.clear();
122 detectFrames();
123 }
124}
125
126void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
127{
128 int currentFrames = m_frames.count();
129 int numNewFrames = frames.count();
130 m_frames += frames;
131
132 int currentCalls = m_calls.count();
133 int numNewCalls = 0;
134 foreach(ApiTraceFrame *frame, frames) {
135 numNewCalls += frame->calls.count();
136 m_calls += frame->calls;
137 }
138
139 emit framesAdded(currentFrames, numNewFrames);
140 emit callsAdded(currentCalls, numNewCalls);
141}
142
143void ApiTrace::detectFrames()
144{
145 if (m_calls.isEmpty())
146 return;
147
148 ApiTraceFrame *currentFrame = 0;
149 foreach(ApiTraceCall *apiCall, m_calls) {
150 if (!currentFrame) {
151 currentFrame = new ApiTraceFrame();
152 currentFrame->number = m_frames.count();
153 }
154 apiCall->parentFrame = currentFrame;
155 apiCall->index = currentFrame->calls.count();
156 currentFrame->calls.append(apiCall);
157 if (ApiTrace::isCallAFrameMarker(apiCall,
158 m_frameMarker)) {
159 m_frames.append(currentFrame);
160 currentFrame = 0;
161 }
162 }
163 //last frames won't have markers
164 // it's just a bunch of Delete calls for every object
165 // after the last SwapBuffers
166 if (currentFrame) {
167 m_frames.append(currentFrame);
168 currentFrame = 0;
169 }
170 emit framesAdded(0, m_frames.count());
171}
172
173#include "apitrace.moc"