**************************************************************************/
#include "trace_profiler.hpp"
+#include "os_time.hpp"
#include <iostream>
+#include <string.h>
+#include <sstream>
namespace trace {
Profiler::Profiler()
- : lastProgram(0),
- baseGpuTime(0),
+ : baseGpuTime(0),
baseCpuTime(0),
+ minCpuTime(1000),
cpuTimes(false),
gpuTimes(true),
pixelsDrawn(false)
gpuTimes = gpuTimes_;
pixelsDrawn = pixelsDrawn_;
- std::cout << "# frame begin <no> <gpu_start> <cpu_start>" << std::endl;
- std::cout << "# frame end <no> <gpu_end> <gpu_dura> <cpu_end> <cpu_dura>" << std::endl;
- std::cout << "# call <no> <gpu_start> <gpu_dura> <cpu_start> <cpu_dura> <pixels> <function>" << std::endl;
- std::cout << "# use shader program <no>" << std::endl;
+ std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura pixels program name" << std::endl;
}
-void Profiler::addCall(unsigned no,
- const char *name,
- unsigned program,
- uint64_t pixels,
- uint64_t gpuStart, uint64_t gpuDuration,
- uint64_t cpuStart, uint64_t cpuDuration)
+int64_t Profiler::getBaseCpuTime()
{
- if (baseGpuTime == 0)
- baseGpuTime = gpuStart;
-
- if (baseCpuTime == 0)
- baseCpuTime = cpuStart;
-
- if (program != lastProgram) {
- std::cout << "use shader program " << program << std::endl;
- lastProgram = program;
- }
-
- std::cout << "call " << no;
-
- if (gpuTimes) {
- std::cout << " "
- << (gpuStart - baseGpuTime) << " "
- << gpuDuration;
- } else {
- std::cout << " _ _";
- }
-
- if (cpuTimes) {
- std::cout << " "
- << (cpuStart - baseCpuTime) << " "
- << cpuDuration;
- } else {
- std::cout << " _ _";
- }
+ return baseCpuTime;
+}
- if (pixelsDrawn) {
- std::cout << " " << pixels;
- } else {
- std::cout << " _";
- }
+int64_t Profiler::getBaseGpuTime()
+{
+ return baseGpuTime;
+}
- std::cout << " " << name << std::endl;
+void Profiler::setBaseCpuTime(int64_t cpuStart)
+{
+ baseCpuTime = cpuStart;
}
-void Profiler::addFrameStart(unsigned no, uint64_t gpuStart, uint64_t cpuStart)
+void Profiler::setBaseGpuTime(int64_t gpuStart)
{
- if (baseGpuTime == 0)
- baseGpuTime = gpuStart;
+ baseGpuTime = gpuStart;
+}
- if (baseCpuTime == 0)
- baseCpuTime = cpuStart;
+bool Profiler::hasBaseTimes()
+{
+ return baseCpuTime != 0 || baseGpuTime != 0;
+}
- lastFrame.no = no;
- lastFrame.gpuStart = gpuStart - baseGpuTime;
+void Profiler::addCall(unsigned no,
+ const char *name,
+ unsigned program,
+ int64_t pixels,
+ int64_t gpuStart, int64_t gpuDuration,
+ int64_t cpuStart, int64_t cpuDuration)
+{
+ if (gpuTimes && gpuStart) {
+ gpuStart -= baseGpuTime;
+ } else {
+ gpuStart = 0;
+ gpuDuration = 0;
+ }
- std::cout << "frame begin " << lastFrame.no;
+ if (cpuTimes && cpuStart) {
+ double cpuTimeScale = 1.0E9 / os::timeFrequency;
+ cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale;
+ cpuDuration = cpuDuration * cpuTimeScale;
- if (gpuTimes) {
- std::cout << " " << lastFrame.gpuStart;
+ if (cpuDuration < minCpuTime) {
+ return;
+ }
} else {
- std::cout << " _";
+ cpuStart = 0;
+ cpuDuration = 0;
}
- if (gpuTimes) {
- std::cout << " " << lastFrame.cpuStart;
- } else {
- std::cout << " _";
+ if (!pixelsDrawn) {
+ pixels = 0;
}
- std::cout << std::endl;
+ std::cout << "call"
+ << " " << no
+ << " " << gpuStart
+ << " " << gpuDuration
+ << " " << cpuStart
+ << " " << cpuDuration
+ << " " << pixels
+ << " " << program
+ << " " << name
+ << std::endl;
}
-void Profiler::addFrameEnd(uint64_t gpuEnd, uint64_t cpuEnd)
+void Profiler::addFrameEnd()
{
- if (baseGpuTime == 0)
- baseGpuTime = gpuEnd;
-
- if (baseCpuTime == 0)
- baseCpuTime = cpuEnd;
+ std::cout << "frame_end" << std::endl;
+}
- lastFrame.gpuEnd = gpuEnd - baseGpuTime;
+void Profiler::parseLine(const char* in, Profile* profile)
+{
+ std::stringstream line(in, std::ios_base::in);
+ std::string type;
+ static int64_t lastGpuTime;
+ static int64_t lastCpuTime;
- std::cout << "frame end " << lastFrame.no;
+ if (in[0] == '#' || strlen(in) < 4)
+ return;
- if (gpuTimes) {
- std::cout << " " << lastFrame.gpuEnd << " " << (lastFrame.gpuEnd - lastFrame.gpuStart);
- } else {
- std::cout << " _ _";
+ if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) {
+ lastGpuTime = 0;
+ lastCpuTime = 0;
}
- if (cpuTimes) {
- std::cout << " " << lastFrame.cpuEnd << " " << (lastFrame.cpuEnd - lastFrame.cpuStart);
- } else {
- std::cout << " _ _";
+ line >> type;
+
+ if (type.compare("call") == 0) {
+ Profile::Call call;
+
+ line >> call.no
+ >> call.gpuStart
+ >> call.gpuDuration
+ >> call.cpuStart
+ >> call.cpuDuration
+ >> call.pixels
+ >> call.program
+ >> call.name;
+
+ if (lastGpuTime < call.gpuStart + call.gpuDuration) {
+ lastGpuTime = call.gpuStart + call.gpuDuration;
+ }
+
+ if (lastCpuTime < call.cpuStart + call.cpuDuration) {
+ lastCpuTime = call.cpuStart + call.cpuDuration;
+ }
+
+ profile->calls.push_back(call);
+
+ if (call.pixels >= 0) {
+ if (profile->programs.size() <= call.program) {
+ profile->programs.resize(call.program + 1);
+ }
+
+ Profile::Program& program = profile->programs[call.program];
+ program.cpuTotal += call.cpuDuration;
+ program.gpuTotal += call.gpuDuration;
+ program.pixelTotal += call.pixels;
+ program.calls.push_back(profile->calls.size() - 1);
+ }
+ } else if (type.compare("frame_end") == 0) {
+ Profile::Frame frame;
+ frame.no = profile->frames.size();
+
+ if (frame.no == 0) {
+ frame.gpuStart = 0;
+ frame.cpuStart = 0;
+ frame.calls.begin = 0;
+ } else {
+ frame.gpuStart = profile->frames.back().gpuStart + profile->frames.back().gpuDuration;
+ frame.cpuStart = profile->frames.back().cpuStart + profile->frames.back().cpuDuration;
+ frame.calls.begin = profile->frames.back().calls.end + 1;
+ }
+
+ frame.gpuDuration = lastGpuTime - frame.gpuStart;
+ frame.cpuDuration = lastCpuTime - frame.cpuStart;
+ frame.calls.end = profile->calls.size() - 1;
+
+ profile->frames.push_back(frame);
}
-
- std::cout << std::endl;
}
}