]> git.cworth.org Git - apitrace/blob - trace_loader.cpp
254d2cb0af61fdfe1b68692fb99e54fcdd50741b
[apitrace] / trace_loader.cpp
1 #include "trace_loader.hpp"
2
3 #include "trace_snappyfile.hpp"
4
5 using namespace Trace;
6
7 Loader::Loader()
8     : m_frameMarker(FrameMarker_SwapBuffers),
9       file(0)
10 {
11 }
12
13 Loader::~Loader()
14 {
15     close();
16 }
17
18 Loader::FrameMarker Loader::frameMarker() const
19 {
20     return m_frameMarker;
21 }
22
23 void Loader::setFrameMarker(Loader::FrameMarker marker)
24 {
25     m_frameMarker = marker;
26 }
27
28 int Loader::numberOfFrames() const
29 {
30     return m_frameOffsets.size();
31 }
32
33 int Loader::numberOfCallsInFrame(int frameIdx)
34 {
35     if (frameIdx > m_frameOffsets.size()) {
36         return 0;
37     }
38
39     return m_frameOffsets[frameIdx].numberOfCalls;
40 }
41
42 bool Loader::open(const char *filename)
43 {
44     if (!m_parser.open(filename)) {
45         std::cerr << "error: failed to open " << filename << "\n";
46         return false;
47     }
48     if (!m_parser.supportsOffsets()) {
49         std::cerr << "error: " <<filename<< " doesn't support seeking "
50                   << "\n";
51         return false;
52     }
53
54     Trace::Call *call;
55     File::Offset startOffset;
56     int numOfFrames = 0;
57     int numOfCalls = 0;
58
59     startOffset = m_parser.currentOffset();
60
61     while ((call = m_parser.parse_call())) {
62
63         ++numOfCalls;
64
65         if (isCallAFrameMarker(call)) {
66             File::Offset endOffset = m_parser.currentOffset();
67             FrameOffset frameOffset(startOffset, endOffset);
68
69             frameOffset.numberOfCalls = numOfCalls;
70             m_frameOffsets[numOfFrames] = frameOffset;
71             ++numOfFrames;
72
73             startOffset = endOffset;
74             numOfCalls = 0;
75         }
76         //call->dump(std::cout, color);
77         delete call;
78     }
79     return true;
80 }
81
82 void Loader::close()
83 {
84     m_parser.close();
85 }
86
87 bool Loader::isCallAFrameMarker(const Trace::Call *call) const
88 {
89     std::string name = call->name();
90
91     switch (m_frameMarker) {
92     case FrameMarker_SwapBuffers:
93         return  name.find("SwapBuffers") != std::string::npos ||
94                 name == "CGLFlushDrawable" ||
95                 name == "glFrameTerminatorGREMEDY";
96         break;
97     case FrameMarker_Flush:
98         return name == "glFlush";
99         break;
100     case FrameMarker_Finish:
101         return name == "glFinish";
102         break;
103     case FrameMarker_Clear:
104         return name == "glClear";
105         break;
106     }
107     return false;
108 }
109
110 std::vector<Trace::Call *> Loader::frame(int idx)
111 {
112     int numOfCalls = numberOfCallsInFrame(idx);
113     if (numOfCalls) {
114         std::vector<Trace::Call*> calls(numOfCalls);
115         m_parser.setCurrentOffset(m_frameOffsets[idx].start);
116
117         Trace::Call *call;
118         int parsedCalls = 0;
119         while ((call = m_parser.parse_call())) {
120
121             calls[parsedCalls] = call;
122             ++parsedCalls;
123
124             if (isCallAFrameMarker(call)) {
125                 break;
126             }
127
128         }
129         assert(parsedCalls == numOfCalls);
130         return calls;
131     }
132     return std::vector<Trace::Call*>();
133 }