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