blob: ffe9ae845fdd0dd01b18078123ede16344b01dd2 [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:
Zack Rusinead6aad2011-04-15 22:16:18 -040032 return call->name().contains(QLatin1String("SwapBuffers"));
Zack Rusinf6667d12011-03-30 11:03:37 -040033 case FrameMarker_Flush:
Zack Rusinead6aad2011-04-15 22:16:18 -040034 return call->name() == QLatin1String("glFlush");
Zack Rusinf6667d12011-03-30 11:03:37 -040035 case FrameMarker_Finish:
Zack Rusinead6aad2011-04-15 22:16:18 -040036 return call->name() == QLatin1String("glFinish");
Zack Rusinf6667d12011-03-30 11:03:37 -040037 case FrameMarker_Clear:
Zack Rusinead6aad2011-04-15 22:16:18 -040038 return call->name() == QLatin1String("glClear");
Zack Rusinf6667d12011-03-30 11:03:37 -040039 }
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 }
Zack Rusinca164112011-04-11 02:23:09 -0400109 m_frames.clear();
110 m_calls.clear();
Zack Rusinf6667d12011-03-30 11:03:37 -0400111 emit invalidated();
112
113 m_loader->loadFile(m_fileName);
114 }
115}
116
117void ApiTrace::setFrameMarker(FrameMarker marker)
118{
119 if (m_frameMarker != marker) {
120 emit framesInvalidated();
121
122 qDeleteAll(m_frames);
123 m_frames.clear();
124 detectFrames();
125 }
126}
127
128void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
129{
130 int currentFrames = m_frames.count();
131 int numNewFrames = frames.count();
132 m_frames += frames;
133
134 int currentCalls = m_calls.count();
135 int numNewCalls = 0;
136 foreach(ApiTraceFrame *frame, frames) {
Zack Rusin7c1793e2011-04-16 23:14:25 -0400137 frame->setParentTrace(this);
Zack Rusinf6667d12011-03-30 11:03:37 -0400138 numNewCalls += frame->calls.count();
139 m_calls += frame->calls;
140 }
141
142 emit framesAdded(currentFrames, numNewFrames);
143 emit callsAdded(currentCalls, numNewCalls);
144}
145
146void ApiTrace::detectFrames()
147{
148 if (m_calls.isEmpty())
149 return;
150
151 ApiTraceFrame *currentFrame = 0;
152 foreach(ApiTraceCall *apiCall, m_calls) {
153 if (!currentFrame) {
154 currentFrame = new ApiTraceFrame();
Zack Rusin7c1793e2011-04-16 23:14:25 -0400155 currentFrame->setParentTrace(this);
Zack Rusinf6667d12011-03-30 11:03:37 -0400156 currentFrame->number = m_frames.count();
157 }
Zack Rusinead6aad2011-04-15 22:16:18 -0400158 apiCall->setParentFrame(currentFrame);
Zack Rusinf6667d12011-03-30 11:03:37 -0400159 currentFrame->calls.append(apiCall);
160 if (ApiTrace::isCallAFrameMarker(apiCall,
161 m_frameMarker)) {
162 m_frames.append(currentFrame);
163 currentFrame = 0;
164 }
165 }
166 //last frames won't have markers
167 // it's just a bunch of Delete calls for every object
168 // after the last SwapBuffers
169 if (currentFrame) {
170 m_frames.append(currentFrame);
171 currentFrame = 0;
172 }
173 emit framesAdded(0, m_frames.count());
174}
175
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400176ApiTraceCall * ApiTrace::callWithIndex(int idx) const
177{
178 for (int i = 0; i < m_calls.count(); ++i) {
179 ApiTraceCall *call = m_calls[i];
Zack Rusinead6aad2011-04-15 22:16:18 -0400180 if (call->index() == idx)
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400181 return call;
182 }
183 return NULL;
184}
185
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400186ApiTraceState ApiTrace::defaultState() const
187{
188 ApiTraceFrame *frame = frameAt(0);
189 if (!frame)
190 return ApiTraceState();
191
192 return frame->state();
193}
194
Zack Rusin661842d2011-04-17 01:59:16 -0400195void ApiTrace::callEdited(ApiTraceCall *call)
196{
197 m_editedCalls.insert(call);
198 emit changed(call);
199}
200
201void ApiTrace::callReverted(ApiTraceCall *call)
202{
203 m_editedCalls.remove(call);
204 emit changed(call);
205}
206
207bool ApiTrace::isEdited() const
208{
209 return !m_editedCalls.isEmpty();
210}
211
Zack Rusinf6667d12011-03-30 11:03:37 -0400212#include "apitrace.moc"