]> git.cworth.org Git - apitrace/blobdiff - gui/profiling.h
Rewrote profile graph drawing code.
[apitrace] / gui / profiling.h
diff --git a/gui/profiling.h b/gui/profiling.h
new file mode 100644 (file)
index 0000000..a5b1266
--- /dev/null
@@ -0,0 +1,128 @@
+#ifndef PROFILING_H
+#define PROFILING_H
+
+#include <QString>
+#include <QLocale>
+#include "trace_profiler.hpp"
+
+class Profiling {
+public:
+    /**
+     * Select and show the call in main window.
+     */
+    static void jumpToCall(int index);
+
+    /**
+     * Convert a CPU / GPU time to a textual representation.
+     * This includes automatic unit selection.
+     */
+    static QString getTimeString(int64_t time, int64_t unitTime = 0)
+    {
+        QString text;
+        QString unit = " ns";
+        double unitScale = 1;
+
+        if (unitTime == 0) {
+            unitTime = time;
+        }
+
+        if (unitTime >= 60e9) {
+            int64_t mins = time / 60e9;
+            text += QString("%1 m ").arg(mins);
+
+            time -= mins * 60e9;
+            unit = " s";
+            unitScale = 1e9;
+        } else if (unitTime >= 1e9) {
+            unit = " s";
+            unitScale = 1e9;
+        } else if (unitTime >= 1e6) {
+            unit = " ms";
+            unitScale = 1e6;
+        } else if (unitTime >= 1e3) {
+            unit = QString::fromUtf8(" µs");
+            unitScale = 1e3;
+        }
+
+        /* 3 decimal places */
+        text += QString("%1").arg(time / unitScale, 0, 'f', 3);
+
+        /* Remove trailing 0 */
+        while(text.endsWith('0'))
+            text.truncate(text.length() - 1);
+
+        /* Remove trailing decimal point */
+        if (text.endsWith(QLocale::system().decimalPoint()))
+            text.truncate(text.length() - 1);
+
+        return text + unit;
+    }
+
+    template<typename val_ty, int64_t val_ty::* mem_ptr_start, int64_t val_ty::* mem_ptr_dura>
+    static typename std::vector<val_ty>::const_iterator binarySearchTimespan(
+            typename std::vector<val_ty>::const_iterator begin,
+            typename std::vector<val_ty>::const_iterator end,
+            int64_t time,
+            bool nearest = false)
+    {
+        int lower = 0;
+        int upper = end - begin;
+        int pos = (lower + upper) / 2;
+        typename std::vector<val_ty>::const_iterator itr = begin + pos;
+
+        while (!((*itr).*mem_ptr_start <= time && (*itr).*mem_ptr_start + (*itr).*mem_ptr_dura > time) && (lower <= upper)) {
+            if ((*itr).*mem_ptr_start > time) {
+                upper = pos - 1;
+            } else {
+                lower = pos + 1;
+            }
+
+            pos = (lower + upper) / 2;
+            itr = begin + pos;
+        }
+
+        if (nearest || lower <= upper) {
+            return itr;
+        } else {
+            return end;
+        }
+    }
+
+    static std::vector<unsigned>::const_iterator binarySearchTimespanIndexed(
+            const std::vector<trace::Profile::Call>& calls,
+            std::vector<unsigned>::const_iterator begin,
+            std::vector<unsigned>::const_iterator end,
+            int64_t time,
+            bool nearest = false)
+    {
+        int lower = 0;
+        int upper = end - begin - 1;
+        int pos = (lower + upper) / 2;
+        std::vector<unsigned>::const_iterator itr = begin + pos;
+
+        while (lower <= upper) {
+            const trace::Profile::Call& call = calls[*itr];
+
+            if (call.gpuStart <= time && call.gpuStart + call.gpuDuration > time) {
+                break;
+            }
+
+            if (call.gpuStart > time) {
+                upper = pos - 1;
+            } else {
+                lower = pos + 1;
+            }
+
+            pos = (lower + upper) / 2;
+            itr = begin + pos;
+        }
+
+        if (nearest || lower <= upper) {
+            return itr;
+        } else {
+            return end;
+        }
+    }
+};
+
+#endif