]> git.cworth.org Git - apitrace/blob - trace_loader.cpp
c16e59e33c2fd6f0f0658c48e93ab9c3eb709a66
[apitrace] / 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 int Loader::numberOfFrames() const
27 {
28     return m_frameOffsets.size();
29 }
30
31 int Loader::numberOfCallsInFrame(int frameIdx) const
32 {
33     if (frameIdx > m_frameOffsets.size()) {
34         return 0;
35     }
36     FrameOffsets::const_iterator itr =
37         m_frameOffsets.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     File::Offset startOffset;
55     int numOfFrames = 0;
56     int numOfCalls = 0;
57     unsigned callNum = 0;
58     int lastPercentReport = 0;
59
60     startOffset = m_parser.currentOffset();
61     callNum = m_parser.currentCallNumber();
62
63     while ((call = m_parser.scan_call())) {
64         ++numOfCalls;
65
66         if (isCallAFrameMarker(call)) {
67             File::Offset endOffset = m_parser.currentOffset();
68             FrameOffset frameOffset(startOffset);
69             frameOffset.numberOfCalls = numOfCalls;
70             frameOffset.callNumber = callNum;
71
72             m_frameOffsets[numOfFrames] = frameOffset;
73             ++numOfFrames;
74
75             if (m_parser.percentRead() - lastPercentReport >= 5) {
76                 std::cerr << "\tPercent scanned = "
77                           << m_parser.percentRead()
78                           << "..."<<std::endl;
79                 lastPercentReport = m_parser.percentRead();
80             }
81             startOffset = endOffset;
82             callNum = m_parser.currentCallNumber();
83             numOfCalls = 0;
84         }
85         //call->dump(std::cout, color);
86         delete call;
87     }
88     return true;
89 }
90
91 void Loader::close()
92 {
93     m_parser.close();
94 }
95
96 bool Loader::isCallAFrameMarker(const Trace::Call *call) const
97 {
98     std::string name = call->name();
99
100     switch (m_frameMarker) {
101     case FrameMarker_SwapBuffers:
102         return  name.find("SwapBuffers") != std::string::npos ||
103                 name == "CGLFlushDrawable" ||
104                 name == "glFrameTerminatorGREMEDY";
105         break;
106     case FrameMarker_Flush:
107         return name == "glFlush";
108         break;
109     case FrameMarker_Finish:
110         return name == "glFinish";
111         break;
112     case FrameMarker_Clear:
113         return name == "glClear";
114         break;
115     }
116     return false;
117 }
118
119 std::vector<Trace::Call *> Loader::frame(int idx)
120 {
121     int numOfCalls = numberOfCallsInFrame(idx);
122     if (numOfCalls) {
123         const FrameOffset &frameOffset = m_frameOffsets[idx];
124         std::vector<Trace::Call*> calls(numOfCalls);
125         m_parser.setCurrentOffset(frameOffset.start);
126         m_parser.setCurrentCallNumber(frameOffset.callNumber);
127
128         Trace::Call *call;
129         int parsedCalls = 0;
130         while ((call = m_parser.parse_call())) {
131
132             calls[parsedCalls] = call;
133             ++parsedCalls;
134
135             if (isCallAFrameMarker(call)) {
136                 break;
137             }
138
139         }
140         assert(parsedCalls == numOfCalls);
141         return calls;
142     }
143     return std::vector<Trace::Call*>();
144 }