]> git.cworth.org Git - apitrace/blobdiff - common/trace_profiler.cpp
Improve profiling.
[apitrace] / common / trace_profiler.cpp
index 6fc00395cd1d3de808d8ae999f05f9540f10a86a..642ba6e88325560e235dd1d9cab0bc2aa6e023d2 100644 (file)
  **************************************************************************/
 
 #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)
@@ -47,109 +50,152 @@ void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_)
     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->cpuCalls.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::DrawCall draw;
+        unsigned program;
+
+        line >> draw.no
+             >> draw.gpuStart
+             >> draw.gpuDuration
+             >> draw.cpuStart
+             >> draw.cpuDuration
+             >> draw.pixels
+             >> program
+             >> draw.name;
+
+        if (lastGpuTime < draw.gpuStart + draw.gpuDuration) {
+            lastGpuTime = draw.gpuStart + draw.gpuDuration;
+        }
+
+        if (lastCpuTime < draw.cpuStart + draw.cpuDuration) {
+            lastCpuTime = draw.cpuStart + draw.cpuDuration;
+        }
+
+        if (draw.pixels >= 0) {
+            if (profile->programs.size() <= program) {
+                profile->programs.resize(program + 1);
+            }
+
+            profile->programs[program].cpuTotal += draw.cpuDuration;
+            profile->programs[program].gpuTotal += draw.gpuDuration;
+            profile->programs[program].pixelTotal += draw.pixels;
+            profile->programs[program].drawCalls.push_back(draw);
+        }
+
+        Profile::CpuCall call;
+        call.no          = draw.no;
+        call.name        = draw.name;
+        call.cpuStart    = draw.cpuStart;
+        call.cpuDuration = draw.cpuDuration;
+        profile->cpuCalls.push_back(call);
+    } 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;
+        } else {
+            frame.gpuStart = profile->frames.back().gpuStart + profile->frames.back().gpuDuration;
+            frame.cpuStart = profile->frames.back().cpuStart + profile->frames.back().cpuDuration;
+        }
+
+        frame.gpuDuration = lastGpuTime - frame.gpuStart;
+        frame.cpuDuration = lastCpuTime - frame.cpuStart;
+        profile->frames.push_back(frame);
     }
-
-    std::cout << std::endl;
 }
 }