blob: 03ff02e1ab0655c48bcbf4ddccc93cc8f4bed3e5 [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 }
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) {
137 numNewCalls += frame->calls.count();
138 m_calls += frame->calls;
139 }
140
141 emit framesAdded(currentFrames, numNewFrames);
142 emit callsAdded(currentCalls, numNewCalls);
143}
144
145void ApiTrace::detectFrames()
146{
147 if (m_calls.isEmpty())
148 return;
149
150 ApiTraceFrame *currentFrame = 0;
151 foreach(ApiTraceCall *apiCall, m_calls) {
152 if (!currentFrame) {
153 currentFrame = new ApiTraceFrame();
154 currentFrame->number = m_frames.count();
155 }
156 apiCall->parentFrame = currentFrame;
Zack Rusinf6667d12011-03-30 11:03:37 -0400157 currentFrame->calls.append(apiCall);
158 if (ApiTrace::isCallAFrameMarker(apiCall,
159 m_frameMarker)) {
160 m_frames.append(currentFrame);
161 currentFrame = 0;
162 }
163 }
164 //last frames won't have markers
165 // it's just a bunch of Delete calls for every object
166 // after the last SwapBuffers
167 if (currentFrame) {
168 m_frames.append(currentFrame);
169 currentFrame = 0;
170 }
171 emit framesAdded(0, m_frames.count());
172}
173
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400174ApiTraceCall * ApiTrace::callWithIndex(int idx) const
175{
176 for (int i = 0; i < m_calls.count(); ++i) {
177 ApiTraceCall *call = m_calls[i];
178 if (call->index == idx)
179 return call;
180 }
181 return NULL;
182}
183
Zack Rusinf6667d12011-03-30 11:03:37 -0400184#include "apitrace.moc"