]> git.cworth.org Git - apitrace/blob - gui/apitrace.cpp
Set a parent trace on all the frames.
[apitrace] / gui / apitrace.cpp
1 #include "apitrace.h"
2
3 #include "loaderthread.h"
4
5 ApiTrace::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*>)));
11     connect(m_loader, SIGNAL(started()),
12             this, SIGNAL(startedLoadingTrace()));
13     connect(m_loader, SIGNAL(finished()),
14             this, SIGNAL(finishedLoadingTrace()));
15 }
16
17 ApiTrace::~ApiTrace()
18 {
19     qDeleteAll(m_calls);
20     qDeleteAll(m_frames);
21     delete m_loader;
22 }
23
24 bool 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
46 bool ApiTrace::isEmpty() const
47 {
48     return m_calls.isEmpty();
49 }
50
51 QString ApiTrace::fileName() const
52 {
53     return m_fileName;
54 }
55
56 ApiTrace::FrameMarker ApiTrace::frameMarker() const
57 {
58     return m_frameMarker;
59 }
60
61 QList<ApiTraceCall*> ApiTrace::calls() const
62 {
63     return m_calls;
64 }
65
66 ApiTraceCall * ApiTrace::callAt(int idx) const
67 {
68     return m_calls.value(idx);
69 }
70
71 int ApiTrace::numCalls() const
72 {
73     return m_calls.count();
74 }
75
76 QList<ApiTraceFrame*> ApiTrace::frames() const
77 {
78     return m_frames;
79 }
80
81 ApiTraceFrame * ApiTrace::frameAt(int idx) const
82 {
83     return m_frames.value(idx);
84 }
85
86 int ApiTrace::numFrames() const
87 {
88     return m_frames.count();
89 }
90
91 int 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
100 void 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         m_frames.clear();
110         m_calls.clear();
111         emit invalidated();
112
113         m_loader->loadFile(m_fileName);
114     }
115 }
116
117 void 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
128 void 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         frame->setParentTrace(this);
138         numNewCalls += frame->calls.count();
139         m_calls += frame->calls;
140     }
141
142     emit framesAdded(currentFrames, numNewFrames);
143     emit callsAdded(currentCalls, numNewCalls);
144 }
145
146 void 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();
155             currentFrame->setParentTrace(this);
156             currentFrame->number = m_frames.count();
157         }
158         apiCall->setParentFrame(currentFrame);
159         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
176 ApiTraceCall * ApiTrace::callWithIndex(int idx) const
177 {
178     for (int i = 0; i < m_calls.count(); ++i) {
179         ApiTraceCall *call = m_calls[i];
180         if (call->index() == idx)
181             return call;
182     }
183     return NULL;
184 }
185
186 ApiTraceState ApiTrace::defaultState() const
187 {
188     ApiTraceFrame *frame = frameAt(0);
189     if (!frame)
190         return ApiTraceState();
191
192     return frame->state();
193 }
194
195 #include "apitrace.moc"