Skip to content

Commit

Permalink
feat: implemented gsttracy and added tracing to gst_wayland_display
Browse files Browse the repository at this point in the history
  • Loading branch information
ABeltramo committed May 31, 2024
1 parent 1ef8c3e commit 0e460c4
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 16 deletions.
14 changes: 14 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ target_link_libraries(wolf_core PUBLIC
PkgConfig::GSTREAMER
PkgConfig::GLIB2)

FetchContent_Declare(tracy
GIT_REPOSITORY https://github.com/wolfpld/tracy.git
GIT_TAG v0.10
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
)
set(TRACY_ENABLE ON)
set(TRACY_ON_DEMAND ON)
if (LIBUNWIND_FOUND)
set(TRACY_LIBUNWIND_BACKTRACE ON)
endif ()
FetchContent_MakeAvailable(tracy)
target_link_libraries(wolf_core PUBLIC TracyClient)

# Platform dependent code
if (UNIX AND NOT APPLE)
add_subdirectory(src/platforms/linux/pulseaudio)
Expand Down
14 changes: 14 additions & 0 deletions src/core/src/platforms/linux/virtual-display/wayland-display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <gst/app/gstappsrc.h>
#include <helpers/logger.hpp>
#include <immer/vector_transient.hpp>
#include <tracy/TracyC.h>

extern "C" {
#include <libgstwaylanddisplay/libgstwaylanddisplay.h>
Expand All @@ -18,6 +19,19 @@ struct WaylandState {
wl_state_ptr create_wayland_display(const immer::array<std::string> &input_devices, const std::string &render_node) {
logs::log(logs::debug, "[WAYLAND] Creating wayland display");
auto w_display = display_init(render_node.c_str());
display_set_trace_fn(
w_display,
[](const char *span_name) {
TracyCZoneN(zone, "gst-wayland-src", true);
TracyCZoneText(zone, span_name, strlen(span_name));
// avoiding address of local variable ‘zone’ returned
auto ctx = new TracyCZoneCtx{zone};
return (void *)ctx;
},
[](void *zone) {
TracyCZoneEnd(*((TracyCZoneCtx *)zone));
delete (TracyCZoneCtx *)zone;
});
immer::vector_transient<std::string> final_devices;
immer::vector_transient<std::string> final_env;

Expand Down
14 changes: 0 additions & 14 deletions src/moonlight-server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,6 @@ else ()
endif ()
FetchContent_MakeAvailable(cpptrace)

FetchContent_Declare(tracy
GIT_REPOSITORY https://github.com/wolfpld/tracy.git
GIT_TAG v0.10
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
)
set(TRACY_ENABLE ON)
set(TRACY_ON_DEMAND ON)
if (LIBUNWIND_FOUND)
set(TRACY_LIBUNWIND_BACKTRACE ON)
endif ()
FetchContent_MakeAvailable(tracy)

##############################

find_package(Threads REQUIRED)
Expand All @@ -92,7 +79,6 @@ target_link_libraries(
wolf::helpers
wolf::core
cpptrace::cpptrace
TracyClient
${Boost_LIBRARIES}
${CMAKE_DL_LIBS}
${CMAKE_THREAD_LIBS_INIT})
Expand Down
143 changes: 143 additions & 0 deletions src/moonlight-server/gst-plugin/gsttracy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include "gsttracy.hpp"
#include <cstring>
#include <helpers/logger.hpp>
#include <map>
#include <optional>
#include <string>
#include <tracy/TracyC.h>

GST_DEBUG_CATEGORY_STATIC(gst_tracy_debug);
#define GST_CAT_DEFAULT gst_tracy_debug

thread_local std::map<std::string, TracyCZoneCtx> zones;

G_DEFINE_TYPE(GstTracyTracer, gst_tracy_tracer, GST_TYPE_TRACER);

static void gst_tracy_tracer_class_init(GstTracyTracerClass *klass) {
GObjectClass *oclass = G_OBJECT_CLASS(klass);

GST_DEBUG_CATEGORY_INIT(gst_tracy_debug, "tracytracer", 0, "base tracy tracer");
}

GstPad *get_source_pad(GstPad *pad) {
while (pad) {
if (GST_IS_GHOST_PAD(pad)) {
pad = gst_ghost_pad_get_target(GST_GHOST_PAD(pad));
} else if (GST_OBJECT_PARENT(pad) && GST_IS_GHOST_PAD(GST_OBJECT_PARENT(pad))) {
pad = GST_PAD_PEER(GST_OBJECT_PARENT(pad));
} else {
break;
}
}
return pad;
}

static GstElement *get_real_pad_parent(GstPad *pad) {
GstObject *parent;

if (!pad)
return NULL;

parent = GST_OBJECT_PARENT(pad);

/* if parent of pad is a ghost-pad, then pad is a proxy_pad */
if (parent && GST_IS_GHOST_PAD(parent)) {
pad = GST_PAD_CAST(parent);
parent = GST_OBJECT_PARENT(pad);
}
return GST_ELEMENT_CAST(parent);
}

static std::optional<std::string> get_unique_name(GstPad *sender_pad) {
if (GST_IS_GHOST_PAD(sender_pad))
return {};

GstPad *receiver_pad = GST_PAD_PEER(sender_pad);
if (GST_IS_GHOST_PAD(receiver_pad))
return {};

receiver_pad = get_source_pad(receiver_pad);
sender_pad = get_source_pad(sender_pad);
GstElement *sender_element = get_real_pad_parent(sender_pad);
GstElement *receiver_element = GST_PAD_PARENT(receiver_pad);

return gst_element_get_name(sender_element) + std::string("->") + gst_element_get_name(receiver_element);
}

static void trace_pad_push_pre(GObject *self, GstClockTime ts, GstPad *sender_pad, GstBuffer *buffer) {
if (auto unique_name = get_unique_name(sender_pad)) {
TracyCZone(zone, true);
TracyCZoneText(zone, unique_name->c_str(), unique_name->length());
zones[*unique_name] = zone;
}
}

static void
trace_pad_push_list_pre(GObject *self, G_GNUC_UNUSED GstClockTime ts, GstPad *sender_pad, GstBufferList *list) {
if (auto unique_name = get_unique_name(sender_pad)) {
TracyCZone(zone, true);
TracyCZoneText(zone, unique_name->c_str(), unique_name->length());
zones[*unique_name] = zone;
}
}

static void trace_pad_push_post(GObject *self, G_GNUC_UNUSED GstClockTime ts, GstPad *sender_pad, GstBuffer *buffer) {
if (auto unique_name = get_unique_name(sender_pad)) {
if (auto zone = zones.find(*unique_name); zone != zones.end()) {
TracyCZoneEnd(zone->second);
zones.erase(zone);
} else {
logs::log(logs::warning, "Zone not found for {}", *unique_name);
}
}
}

static void
trace_pad_push_list_post(GObject *self, G_GNUC_UNUSED GstClockTime ts, GstPad *sender_pad, GstBufferList *list) {
if (auto unique_name = get_unique_name(sender_pad)) {
if (auto zone = zones.find(*unique_name); zone != zones.end()) {
TracyCZoneEnd(zone->second);
zones.erase(zone);
} else {
logs::log(logs::warning, "Zone not found for {}", *unique_name);
}
}
}

static void gst_tracy_tracer_init(GstTracyTracer *self) {
GstTracer *tracer = GST_TRACER(self);

gst_tracing_register_hook(tracer, "pad-push-pre", G_CALLBACK(trace_pad_push_pre));
gst_tracing_register_hook(tracer, "pad-push-list-pre", G_CALLBACK(trace_pad_push_list_pre));
gst_tracing_register_hook(tracer, "pad-push-post", G_CALLBACK(trace_pad_push_post));
gst_tracing_register_hook(tracer, "pad-push-list-post", G_CALLBACK(trace_pad_push_list_post));
}

static gboolean plugin_init(GstPlugin *plugin) {
if (!gst_tracer_register(plugin, "gsttracy", gst_tracy_tracer_get_type()))
return FALSE;
return TRUE;
}

#ifndef VERSION
#define VERSION "0.0.FIXME"
#endif
#ifndef PACKAGE
#define PACKAGE "FIXME_package"
#endif
#ifndef PACKAGE_NAME
#define PACKAGE_NAME "FIXME_package_name"
#endif
#ifndef GST_PACKAGE_ORIGIN
#define GST_PACKAGE_ORIGIN "http://FIXME.org/"
#endif

GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
GST_VERSION_MINOR,
gsttracy,
"FIXME plugin description",
plugin_init,
VERSION,
"LGPL",
PACKAGE_NAME,
GST_PACKAGE_ORIGIN)
20 changes: 20 additions & 0 deletions src/moonlight-server/gst-plugin/gsttracy.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef WOLF_GSTTRACY_HPP
#define WOLF_GSTTRACY_HPP

#include <gst/gst.h>
#include <gst/gsttracer.h>

G_BEGIN_DECLS

#define GST_TYPE_TRACY_TRACER (gst_tracy_tracer_get_type ())
G_DECLARE_DERIVABLE_TYPE (GstTracyTracer, gst_tracy_tracer, GST_TRACY, TRACER, GstTracer)

struct _GstTracyTracerClass {
GstTracerClass parent_class;
};

GType gst_tracy_tracer_get_type(void);

G_END_DECLS

#endif // WOLF_GSTTRACY_HPP
4 changes: 4 additions & 0 deletions src/moonlight-server/streaming/streaming.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include "gst-plugin/gsttracy.hpp"
#include "moonlight/fec.hpp"
#include <boost/asio.hpp>
#include <core/virtual-display.hpp>
Expand Down Expand Up @@ -61,6 +62,9 @@ inline void init() {
/* It is also possible to call the init function with two NULL arguments,
* in which case no command line options will be parsed by GStreamer.
*/
GstPlugin *tracy_plugin = gst_plugin_load_by_name("gsttracy");
gst_tracer_register(tracy_plugin, "gsttracy", GST_TYPE_TRACY_TRACER);

gst_init(nullptr, nullptr);
gst_debug_remove_log_function(gst_debug_log_default);
gst_debug_add_log_function(gst_debug_fn, nullptr, nullptr);
Expand Down
2 changes: 0 additions & 2 deletions src/moonlight-server/wolf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
#include <state/config.hpp>
#include <streaming/streaming.hpp>
#include <tracy/Tracy.hpp>
#include <tracy/TracyC.h>
#include <vector>

namespace ba = boost::asio;
namespace fs = std::filesystem;
Expand Down

0 comments on commit 0e460c4

Please sign in to comment.