|
|
@@ -0,0 +1,106 @@
|
|
|
+/**************************************************************************/
|
|
|
+/* profiling.h */
|
|
|
+/**************************************************************************/
|
|
|
+/* This file is part of: */
|
|
|
+/* GODOT ENGINE */
|
|
|
+/* https://godotengine.org */
|
|
|
+/**************************************************************************/
|
|
|
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
|
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
|
+/* */
|
|
|
+/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
|
+/* a copy of this software and associated documentation files (the */
|
|
|
+/* "Software"), to deal in the Software without restriction, including */
|
|
|
+/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
|
+/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
|
+/* permit persons to whom the Software is furnished to do so, subject to */
|
|
|
+/* the following conditions: */
|
|
|
+/* */
|
|
|
+/* The above copyright notice and this permission notice shall be */
|
|
|
+/* included in all copies or substantial portions of the Software. */
|
|
|
+/* */
|
|
|
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
|
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
|
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
|
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
|
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
|
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
|
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
|
+/**************************************************************************/
|
|
|
+
|
|
|
+#pragma once
|
|
|
+
|
|
|
+#include "core/typedefs.h"
|
|
|
+#include "profiling.gen.h"
|
|
|
+
|
|
|
+#if defined(GODOT_USE_TRACY)
|
|
|
+// Use the tracy profiler.
|
|
|
+
|
|
|
+#define TRACY_ENABLE
|
|
|
+#include <tracy/Tracy.hpp>
|
|
|
+
|
|
|
+#ifndef TRACY_CALLSTACK
|
|
|
+#define TRACY_CALLSTACK 0
|
|
|
+#endif
|
|
|
+
|
|
|
+// Define tracing macros.
|
|
|
+#define GodotProfileFrameMark FrameMark
|
|
|
+#define GodotProfileZone(m_zone_name) ZoneScopedN(m_zone_name)
|
|
|
+#define GodotProfileZoneGroupedFirst(m_group_name, m_zone_name) ZoneNamedN(__godot_tracy_zone_##m_group_name, m_zone_name, true)
|
|
|
+#define GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name) __godot_tracy_zone_##m_group_name.~ScopedZone();
|
|
|
+#define GodotProfileZoneGrouped(m_group_name, m_zone_name) \
|
|
|
+ GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name); \
|
|
|
+ static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location, TracyLine){ m_zone_name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; \
|
|
|
+ new (&__godot_tracy_zone_##m_group_name) tracy::ScopedZone(&TracyConcat(__tracy_source_location, TracyLine), TRACY_CALLSTACK, true)
|
|
|
+
|
|
|
+static void godot_init_profiler() {
|
|
|
+ // Send our first event to tracy; otherwise it doesn't start collecting data.
|
|
|
+ // FrameMark is kind of fitting because it communicates "this is where we started tracing".
|
|
|
+ FrameMark;
|
|
|
+}
|
|
|
+
|
|
|
+#elif defined(GODOT_USE_PERFETTO)
|
|
|
+// Use the perfetto profiler.
|
|
|
+
|
|
|
+#include <perfetto.h>
|
|
|
+
|
|
|
+PERFETTO_DEFINE_CATEGORIES(
|
|
|
+ perfetto::Category("godot")
|
|
|
+ .SetDescription("All Godot Events"), );
|
|
|
+
|
|
|
+// See PERFETTO_INTERNAL_SCOPED_EVENT_FINALIZER
|
|
|
+struct PerfettoGroupedEventEnder {
|
|
|
+ _FORCE_INLINE_ void _end_now() {
|
|
|
+ TRACE_EVENT_END("godot");
|
|
|
+ }
|
|
|
+
|
|
|
+ _FORCE_INLINE_ ~PerfettoGroupedEventEnder() {
|
|
|
+ _end_now();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+#define GodotProfileFrameMark // TODO
|
|
|
+#define GodotProfileZone(m_zone_name) TRACE_EVENT("godot", m_zone_name);
|
|
|
+#define GodotProfileZoneGroupedFirst(m_group_name, m_zone_name) \
|
|
|
+ TRACE_EVENT_BEGIN("godot", m_zone_name); \
|
|
|
+ PerfettoGroupedEventEnder __godot_perfetto_zone_##m_group_name
|
|
|
+#define GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name) __godot_perfetto_zone_##m_group_name.~PerfettoGroupedEventEnder()
|
|
|
+#define GodotProfileZoneGrouped(m_group_name, m_zone_name) \
|
|
|
+ __godot_perfetto_zone_##m_group_name._end_now(); \
|
|
|
+ TRACE_EVENT_BEGIN("godot", m_zone_name);
|
|
|
+
|
|
|
+void godot_init_profiler();
|
|
|
+
|
|
|
+#else
|
|
|
+// No profiling; all macros are stubs.
|
|
|
+
|
|
|
+static void godot_init_profiler() {
|
|
|
+}
|
|
|
+
|
|
|
+#define GodotProfileFrameMark
|
|
|
+#define GodotProfileZone(m_zone_name)
|
|
|
+#define GodotProfileZoneGroupedFirst(m_group_name, m_zone_name)
|
|
|
+#define GodotProfileZoneGroupedEndEarly(m_group_name, m_zone_name)
|
|
|
+#define GodotProfileZoneGrouped(m_group_name, m_zone_name)
|
|
|
+
|
|
|
+#endif
|