diff --git a/gsk/Makefile.am b/gsk/Makefile.am index 9541fe5998..77bfc0e5a1 100644 --- a/gsk/Makefile.am +++ b/gsk/Makefile.am @@ -22,6 +22,13 @@ DISTCLEANFILES = noinst_LTLIBRARIES = +if HAVE_VULKAN +gsk_private_vulan_source_h = \ + gskvulkanrendererprivate.h +gsk_private_vulkan_source_c = \ + gskvulkanrenderer.c +endif + gsk_public_source_h = \ gskenums.h \ gskrenderer.h \ @@ -30,6 +37,7 @@ gsk_public_source_h = \ gsktexture.h \ gsktypes.h gsk_private_source_h = \ + $(gsk_private_vulkan_source_h) \ gskcairorendererprivate.h \ gskdebugprivate.h \ gskgldriverprivate.h \ @@ -40,6 +48,7 @@ gsk_private_source_h = \ gskrendererprivate.h \ gskrendernodeprivate.h \ gskshaderbuilderprivate.h \ + gskvulkanrendererprivate.h \ gsktextureprivate.h gsk_public_source_c = \ gskrenderer.c \ @@ -47,6 +56,7 @@ gsk_public_source_c = \ gskrendernodeiter.c \ gsktexture.c gsk_private_source_c = \ + $(gsk_private_vulkan_source_c) \ gskcairorenderer.c \ gskdebug.c \ gskgldriver.c \ diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index d4ed4e2a7d..da2b714e11 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -56,6 +56,9 @@ #ifdef GDK_WINDOWING_WAYLAND #include #endif +#ifdef GDK_WINDOWING_VULKAN +#include "gskvulkanrendererprivate.h" +#endif typedef struct { @@ -724,6 +727,10 @@ get_renderer_for_env_var (GdkWindow *window) env_var_type = GSK_TYPE_CAIRO_RENDERER; else if (g_ascii_strcasecmp (renderer_name, "opengl") == 0) env_var_type = GSK_TYPE_GL_RENDERER; +#ifdef GDK_WINDOWING_VULKAN + else if (g_ascii_strcasecmp (renderer_name, "vulkan") == 0) + env_var_type = GSK_TYPE_VULKAN_RENDERER; +#endif else env_var_type = G_TYPE_INVALID; } diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c new file mode 100644 index 0000000000..32fefcd548 --- /dev/null +++ b/gsk/gskvulkanrenderer.c @@ -0,0 +1,98 @@ +#include "config.h" + +#include "gskvulkanrendererprivate.h" + +#include "gskdebugprivate.h" +#include "gskrendererprivate.h" +#include "gskrendernodeiter.h" +#include "gskrendernodeprivate.h" +#include "gsktextureprivate.h" + +#ifdef G_ENABLE_DEBUG +typedef struct { + GQuark cpu_time; + GQuark gpu_time; +} ProfileTimers; +#endif + +struct _GskVulkanRenderer +{ + GskRenderer parent_instance; + + GdkVulkanContext *vulkan; +#ifdef G_ENABLE_DEBUG + ProfileTimers profile_timers; +#endif +}; + +struct _GskVulkanRendererClass +{ + GskRendererClass parent_class; +}; + +G_DEFINE_TYPE (GskVulkanRenderer, gsk_vulkan_renderer, GSK_TYPE_RENDERER) + +static gboolean +gsk_vulkan_renderer_realize (GskRenderer *renderer, + GdkWindow *window, + GError **error) +{ + GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer); + + self->vulkan = gdk_window_create_vulkan_context (window, error); + if (self->vulkan == NULL) + return FALSE; + + return TRUE; +} + +static void +gsk_vulkan_renderer_unrealize (GskRenderer *renderer) +{ + GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer); + + g_clear_object (&self->vulkan); +} + +static void +gsk_vulkan_renderer_render (GskRenderer *renderer, + GskRenderNode *root) +{ + GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer); +#ifdef G_ENABLE_DEBUG + GskProfiler *profiler; + gint64 cpu_time; +#endif + +#ifdef G_ENABLE_DEBUG + profiler = gsk_renderer_get_profiler (renderer); + gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time); +#endif + +#ifdef G_ENABLE_DEBUG + cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time); + gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time); + + gsk_profiler_push_samples (profiler); +#endif +} + +static void +gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass) +{ + GskRendererClass *renderer_class = GSK_RENDERER_CLASS (klass); + + renderer_class->realize = gsk_vulkan_renderer_realize; + renderer_class->unrealize = gsk_vulkan_renderer_unrealize; + renderer_class->render = gsk_vulkan_renderer_render; +} + +static void +gsk_vulkan_renderer_init (GskVulkanRenderer *self) +{ +#ifdef G_ENABLE_DEBUG + GskProfiler *profiler = gsk_renderer_get_profiler (GSK_RENDERER (self)); + + self->profile_timers.cpu_time = gsk_profiler_add_timer (profiler, "cpu-time", "CPU time", FALSE, TRUE); +#endif +} diff --git a/gsk/gskvulkanrendererprivate.h b/gsk/gskvulkanrendererprivate.h new file mode 100644 index 0000000000..a4a07f47cb --- /dev/null +++ b/gsk/gskvulkanrendererprivate.h @@ -0,0 +1,24 @@ +#ifndef __GSK_VULKAN_RENDERER_PRIVATE_H__ +#define __GSK_VULKAN_RENDERER_PRIVATE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GSK_TYPE_VULKAN_RENDERER (gsk_vulkan_renderer_get_type ()) + +#define GSK_VULKAN_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_VULKAN_RENDERER, GskVulkanRenderer)) +#define GSK_IS_VULKAN_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_VULKAN_RENDERER)) +#define GSK_VULKAN_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_VULKAN_RENDERER, GskVulkanRendererClass)) +#define GSK_IS_VULKAN_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_VULKAN_RENDERER)) +#define GSK_VULKAN_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_VULKAN_RENDERER, GskVulkanRendererClass)) + +typedef struct _GskVulkanRenderer GskVulkanRenderer; +typedef struct _GskVulkanRendererClass GskVulkanRendererClass; + +GType gsk_vulkan_renderer_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GSK_VULKAN_RENDERER_PRIVATE_H__ */