1 #include "traceloader.h"
7 #define FRAMES_TO_CACHE 100
10 apiCallFromTraceCall(const Trace::Call *call,
11 const QHash<QString, QUrl> &helpHash,
15 ApiTraceCall *apiCall = new ApiTraceCall(frame, loader, call);
17 apiCall->setHelpUrl(helpHash.value(apiCall->name()));
22 TraceLoader::TraceLoader(QObject *parent)
24 m_frameMarker(ApiTrace::FrameMarker_SwapBuffers)
28 TraceLoader::~TraceLoader()
33 void TraceLoader::loadTrace(const QString &filename)
35 if (m_helpHash.isEmpty()) {
39 if (!m_parser.open(filename.toLatin1())) {
40 qDebug() << "error: failed to open " << filename;
43 qDebug()<<"load trace with "<<filename;
44 emit startedParsing();
46 qDebug() <<"\t support offsets = "<<m_parser.supportsOffsets();
47 if (m_parser.supportsOffsets()) {
50 //Load the entire file into memory
54 emit finishedParsing();
57 void TraceLoader::loadFrame(ApiTraceFrame *currentFrame)
59 if (m_parser.supportsOffsets()) {
60 unsigned frameIdx = currentFrame->number;
61 int numOfCalls = numberOfCallsInFrame(frameIdx);
64 quint64 binaryDataSize = 0;
65 QVector<ApiTraceCall*> calls(numOfCalls);
66 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
68 m_parser.setBookmark(frameBookmark.start);
72 while ((call = m_parser.parse_call())) {
73 ApiTraceCall *apiCall =
74 apiCallFromTraceCall(call, m_helpHash,
76 calls[parsedCalls] = apiCall;
77 Q_ASSERT(calls[parsedCalls]);
78 if (apiCall->hasBinaryData()) {
81 apiCall->binaryDataIndex()].toByteArray();
82 binaryDataSize += data.size();
89 if (ApiTrace::isCallAFrameMarker(apiCall, m_frameMarker)) {
94 assert(parsedCalls == numOfCalls);
95 Q_ASSERT(parsedCalls == calls.size());
96 Q_ASSERT(parsedCalls == currentFrame->numChildrenToLoad());
98 currentFrame->setCalls(calls, binaryDataSize);
99 emit frameLoaded(currentFrame);
104 void TraceLoader::setFrameMarker(ApiTrace::FrameMarker marker)
106 m_frameMarker = marker;
109 bool TraceLoader::isCallAFrameMarker(const Trace::Call *call) const
111 std::string name = call->name();
113 switch (m_frameMarker) {
114 case ApiTrace::FrameMarker_SwapBuffers:
115 return name.find("SwapBuffers") != std::string::npos ||
116 name == "CGLFlushDrawable" ||
117 name == "glFrameTerminatorGREMEDY";
119 case ApiTrace::FrameMarker_Flush:
120 return name == "glFlush";
122 case ApiTrace::FrameMarker_Finish:
123 return name == "glFinish";
125 case ApiTrace::FrameMarker_Clear:
126 return name == "glClear";
132 int TraceLoader::numberOfFrames() const
134 return m_frameBookmarks.size();
137 int TraceLoader::numberOfCallsInFrame(int frameIdx) const
139 if (frameIdx > m_frameBookmarks.size()) {
142 FrameBookmarks::const_iterator itr =
143 m_frameBookmarks.find(frameIdx);
144 return itr->numberOfCalls;
147 void TraceLoader::loadHelpFile()
149 QFile file(":/resources/glreference.tsv");
150 if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
152 while (!file.atEnd()) {
153 line = file.readLine();
154 QString function = line.section('\t', 0, 0).trimmed();
155 QUrl url = QUrl(line.section('\t', 1, 1).trimmed());
156 //qDebug()<<"function = "<<function<<", url = "<<url.toString();
157 m_helpHash.insert(function, url);
160 qWarning() << "Couldn't open reference file "
166 void TraceLoader::scanTrace()
168 QList<ApiTraceFrame*> frames;
169 ApiTraceFrame *currentFrame = 0;
172 Trace::ParseBookmark startBookmark;
175 int lastPercentReport = 0;
177 m_parser.getBookmark(startBookmark);
179 while ((call = m_parser.scan_call())) {
182 if (isCallAFrameMarker(call)) {
183 FrameBookmark frameBookmark(startBookmark);
184 frameBookmark.numberOfCalls = numOfCalls;
186 currentFrame = new ApiTraceFrame();
187 currentFrame->number = numOfFrames;
188 currentFrame->setNumChildren(numOfCalls);
189 frames.append(currentFrame);
191 m_frameBookmarks[numOfFrames] = frameBookmark;
194 if (m_parser.percentRead() - lastPercentReport >= 5) {
195 emit parsed(m_parser.percentRead());
196 lastPercentReport = m_parser.percentRead();
198 m_parser.getBookmark(startBookmark);
205 //Trace::File::Bookmark endBookmark = m_parser.currentBookmark();
206 FrameBookmark frameBookmark(startBookmark);
207 frameBookmark.numberOfCalls = numOfCalls;
209 currentFrame = new ApiTraceFrame();
210 currentFrame->number = numOfFrames;
211 currentFrame->setNumChildren(numOfCalls);
212 frames.append(currentFrame);
214 m_frameBookmarks[numOfFrames] = frameBookmark;
220 emit framesLoaded(frames);
223 void TraceLoader::parseTrace()
225 QList<ApiTraceFrame*> frames;
226 ApiTraceFrame *currentFrame = 0;
228 QVector<ApiTraceCall*> calls;
229 quint64 binaryDataSize = 0;
231 int lastPercentReport = 0;
233 Trace::Call *call = m_parser.parse_call();
235 //std::cout << *call;
237 currentFrame = new ApiTraceFrame();
238 currentFrame->number = frameCount;
241 ApiTraceCall *apiCall =
242 apiCallFromTraceCall(call, m_helpHash, currentFrame, this);
243 calls.append(apiCall);
244 if (apiCall->hasBinaryData()) {
246 apiCall->arguments()[apiCall->binaryDataIndex()].toByteArray();
247 binaryDataSize += data.size();
249 if (ApiTrace::isCallAFrameMarker(apiCall,
252 currentFrame->setCalls(calls, binaryDataSize);
254 frames.append(currentFrame);
257 if (frames.count() >= FRAMES_TO_CACHE) {
258 emit framesLoaded(frames);
261 if (m_parser.percentRead() - lastPercentReport >= 5) {
262 emit parsed(m_parser.percentRead());
263 lastPercentReport = m_parser.percentRead();
267 call = m_parser.parse_call();
270 //last frames won't have markers
271 // it's just a bunch of Delete calls for every object
272 // after the last SwapBuffers
275 currentFrame->setCalls(calls, binaryDataSize);
276 frames.append(currentFrame);
279 if (frames.count()) {
280 emit framesLoaded(frames);
285 ApiTraceCallSignature * TraceLoader::signature(unsigned id)
287 if (id >= m_signatures.count()) {
288 m_signatures.resize(id + 1);
291 return m_signatures[id];
295 void TraceLoader::addSignature(unsigned id, ApiTraceCallSignature *signature)
297 m_signatures[id] = signature;
300 ApiTraceEnumSignature * TraceLoader::enumSignature(unsigned id)
302 if (id >= m_enumSignatures.count()) {
303 m_enumSignatures.resize(id + 1);
306 return m_enumSignatures[id];
310 void TraceLoader::addEnumSignature(unsigned id, ApiTraceEnumSignature *signature)
312 m_enumSignatures[id] = signature;
315 #include "traceloader.moc"