--- /dev/null
+#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