]> git.cworth.org Git - apitrace/blob - common/trace_profiler.cpp
Merge branch 'profile-gui'
[apitrace] / common / trace_profiler.cpp
1 /**************************************************************************
2  *
3  * Copyright 2012 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #include "trace_profiler.hpp"
27 #include <iostream>
28 #include <string.h>
29 #include <assert.h>
30 #include <sstream>
31 #include "os_time.hpp"
32
33 namespace trace {
34 Profiler::Profiler()
35     : baseGpuTime(0),
36       baseCpuTime(0),
37       cpuTimes(false),
38       gpuTimes(true),
39       pixelsDrawn(false)
40 {
41 }
42
43 Profiler::~Profiler()
44 {
45 }
46
47 void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_)
48 {
49     cpuTimes = cpuTimes_;
50     gpuTimes = gpuTimes_;
51     pixelsDrawn = pixelsDrawn_;
52
53     std::cout << "# frame_begin no gpu_start cpu_start" << std::endl;
54     std::cout << "# frame_end no gpu_end gpu_dura cpu_end cpu_dura" << std::endl;
55     std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura pixels program name" << std::endl;
56 }
57
58 void Profiler::addCall(unsigned no,
59                        const char *name,
60                        unsigned program,
61                        uint64_t pixels,
62                        uint64_t gpuStart, uint64_t gpuDuration,
63                        uint64_t cpuStart, uint64_t cpuDuration)
64 {
65     if (baseGpuTime == 0) {
66         baseGpuTime = gpuStart;
67     }
68
69     if (baseCpuTime == 0) {
70         baseCpuTime = cpuStart;
71     }
72
73     if (gpuTimes) {
74         gpuStart -= baseGpuTime;
75     } else {
76         gpuStart = 0;
77         gpuDuration = 0;
78     }
79
80     if (cpuTimes) {
81         double cpuTimeScale = 1.0E9 / os::timeFrequency;
82         cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale;
83         cpuDuration = cpuDuration * cpuTimeScale;
84     } else {
85         cpuStart = 0;
86         cpuDuration = 0;
87     }
88
89     if (!pixelsDrawn) {
90         pixels = 0;
91     }
92
93     std::cout << "call"
94               << " " << no
95               << " " << gpuStart
96               << " " << gpuDuration
97               << " " << cpuStart
98               << " " << cpuDuration
99               << " " << pixels
100               << " " << program
101               << " " << name
102               << std::endl;
103 }
104
105 void Profiler::addFrameStart(unsigned no, uint64_t gpuStart, uint64_t cpuStart)
106 {
107     if (baseGpuTime == 0) {
108         baseGpuTime = gpuStart;
109     }
110
111     if (baseCpuTime == 0) {
112         baseCpuTime = cpuStart;
113     }
114         
115     lastFrame.no = no;
116     lastFrame.gpuStart = gpuStart;
117     lastFrame.cpuStart = cpuStart;
118
119     if (gpuTimes) {
120         gpuStart = gpuStart - baseGpuTime;
121     } else {
122         gpuStart = 0;
123     }
124
125     if (cpuTimes) {
126         double cpuTimeScale = 1.0E9 / os::timeFrequency;
127         cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale;
128     } else {
129         cpuStart = 0;
130     }
131
132     std::cout << "frame_begin"
133               << " " << no
134               << " " << gpuStart
135               << " " << cpuStart
136               << std::endl;
137 }
138
139 void Profiler::addFrameEnd(uint64_t gpuEnd, uint64_t cpuEnd)
140 {
141     uint64_t gpuDuration, cpuDuration;
142
143     if (gpuTimes) {
144         gpuDuration = gpuEnd - lastFrame.gpuStart;
145         gpuEnd = gpuEnd - baseGpuTime;
146     } else {
147         gpuEnd = 0;
148         gpuDuration = 0;
149     }
150
151     if (cpuTimes) {
152         double cpuTimeScale = 1.0E9 / os::timeFrequency;
153         cpuDuration = (cpuEnd - lastFrame.cpuStart) * cpuTimeScale;
154         cpuEnd = (cpuEnd - baseCpuTime) * cpuTimeScale;
155     } else {
156         cpuEnd = 0;
157         cpuDuration = 0;
158     }
159
160     std::cout << "frame_end"
161               << " " << lastFrame.no
162               << " " << gpuEnd
163               << " " << gpuDuration
164               << " " << cpuEnd
165               << " " << cpuDuration
166               << std::endl;
167 }
168
169 void Profiler::parseLine(const char* in, Profile* profile)
170 {
171     std::stringstream line(in, std::ios_base::in);
172     std::string type;
173
174     if (in[0] == '#' || strlen(in) < 12)
175         return;
176
177     line >> type;
178
179     if (type.compare("call") == 0) {
180         assert(profile->frames.size());
181         Profile::Call call;
182
183         line >> call.no
184              >> call.gpuStart
185              >> call.gpuDuration
186              >> call.cpuStart
187              >> call.cpuDuration
188              >> call.pixels
189              >> call.program
190              >> call.name;
191
192         profile->frames.back().calls.push_back(call);
193     } else if (type.compare("frame_begin") == 0) {
194         Profile::Frame frame;
195         frame.gpuDuration = 0;
196         frame.cpuDuration = 0;
197
198         line >> frame.no
199              >> frame.gpuStart
200              >> frame.cpuStart;
201
202         profile->frames.push_back(frame);
203     } else if (type.compare("frame_end") == 0) {
204         assert(profile->frames.size());
205         Profile::Frame& frame = profile->frames.back();
206         int64_t skipi64;
207
208         line >> frame.no
209              >> skipi64
210              >> frame.gpuDuration
211              >> skipi64
212              >> frame.cpuDuration;
213     }
214 }
215 }