From f1d81bb7df9b717ce8305c90f59ba8bbfb6f7ce0 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 26 Jun 2023 01:38:50 +0200 Subject: [PATCH] vulkan: Add a Cairo upload node ... and use it for cairo nodes. --- gsk/meson.build | 1 + gsk/vulkan/gskvulkanrenderpass.c | 21 ++++ gsk/vulkan/gskvulkanuploadcairoop.c | 134 +++++++++++++++++++++ gsk/vulkan/gskvulkanuploadcairoopprivate.h | 18 +++ 4 files changed, 174 insertions(+) create mode 100644 gsk/vulkan/gskvulkanuploadcairoop.c create mode 100644 gsk/vulkan/gskvulkanuploadcairoopprivate.h diff --git a/gsk/meson.build b/gsk/meson.build index fd201a583f..df886cb4c9 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -135,6 +135,7 @@ if have_vulkan 'vulkan/gskvulkantextpipeline.c', 'vulkan/gskvulkantexturepipeline.c', 'vulkan/gskvulkantextureop.c', + 'vulkan/gskvulkanuploadcairoop.c', 'vulkan/gskvulkanuploadop.c', ]) diff --git a/gsk/vulkan/gskvulkanrenderpass.c b/gsk/vulkan/gskvulkanrenderpass.c index 5f9d5c9f01..cf430d0537 100644 --- a/gsk/vulkan/gskvulkanrenderpass.c +++ b/gsk/vulkan/gskvulkanrenderpass.c @@ -28,6 +28,7 @@ #include "gskvulkanpushconstantsprivate.h" #include "gskvulkanscissoropprivate.h" #include "gskvulkantextureopprivate.h" +#include "gskvulkanuploadcairoopprivate.h" #include "gskvulkanuploadopprivate.h" #include "gskprivate.h" @@ -393,6 +394,26 @@ gsk_vulkan_render_pass_get_node_as_image (GskVulkanRenderPass *self, return result; } + case GSK_CAIRO_NODE: + { + graphene_rect_t clipped; + + graphene_rect_offset_r (&state->clip.rect.bounds, - state->offset.x, - state->offset.y, &clipped); + graphene_rect_intersection (&clipped, &node->bounds, &clipped); + + if (clipped.size.width == 0 || clipped.size.height == 0) + return NULL; + + result = gsk_vulkan_upload_cairo_op_init (gsk_vulkan_render_pass_alloc_op (self, gsk_vulkan_upload_cairo_op_size ()), + self->vulkan, + node, + &state->scale, + &clipped); + + *tex_bounds = clipped; + return result; + } + default: { graphene_rect_t clipped; diff --git a/gsk/vulkan/gskvulkanuploadcairoop.c b/gsk/vulkan/gskvulkanuploadcairoop.c new file mode 100644 index 0000000000..c3cbf0e729 --- /dev/null +++ b/gsk/vulkan/gskvulkanuploadcairoop.c @@ -0,0 +1,134 @@ +#include "config.h" + +#include "gskvulkanuploadcairoopprivate.h" + +typedef struct _GskVulkanUploadCairoOp GskVulkanUploadCairoOp; + +struct _GskVulkanUploadCairoOp +{ + GskVulkanOp op; + + GskVulkanImage *image; + GskRenderNode *node; + graphene_rect_t viewport; +}; + +static void +gsk_vulkan_upload_cairo_op_finish (GskVulkanOp *op) +{ + GskVulkanUploadCairoOp *self = (GskVulkanUploadCairoOp *) op; + + g_object_unref (self->image); + gsk_render_node_unref (self->node); +} + +static void +gsk_vulkan_upload_cairo_op_upload (GskVulkanOp *op, + GskVulkanRenderPass *pass, + GskVulkanRender *render, + GskVulkanUploader *uploader, + const graphene_rect_t *clip, + const graphene_vec2_t *scale) +{ + GskVulkanUploadCairoOp *self = (GskVulkanUploadCairoOp *) op; + GskVulkanImageMap map; + cairo_surface_t *surface; + cairo_t *cr; + int width, height; + + width = gsk_vulkan_image_get_width (self->image); + height = gsk_vulkan_image_get_height (self->image); + + gsk_vulkan_image_map_memory (self->image, uploader, GSK_VULKAN_WRITE, &map); + surface = cairo_image_surface_create_for_data (map.data, + CAIRO_FORMAT_ARGB32, + width, height, + map.stride); + cairo_surface_set_device_scale (surface, + width / self->viewport.size.width, + height / self->viewport.size.height); + cr = cairo_create (surface); + cairo_translate (cr, -self->viewport.origin.x, -self->viewport.origin.y); + + gsk_render_node_draw (self->node, cr); + + cairo_destroy (cr); + + cairo_surface_finish (surface); + cairo_surface_destroy (surface); + + gsk_vulkan_image_unmap_memory (self->image, uploader, &map); +} + +static gsize +gsk_vulkan_upload_cairo_op_count_vertex_data (GskVulkanOp *op, + gsize n_bytes) +{ + return n_bytes; +} + +static void +gsk_vulkan_upload_cairo_op_collect_vertex_data (GskVulkanOp *op, + GskVulkanRenderPass *pass, + GskVulkanRender *render, + guchar *data) +{ +} + +static void +gsk_vulkan_upload_cairo_op_reserve_descriptor_sets (GskVulkanOp *op, + GskVulkanRender *render) +{ +} + +static GskVulkanPipeline * +gsk_vulkan_upload_cairo_op_get_pipeline (GskVulkanOp *op) +{ + return NULL; +} + +static void +gsk_vulkan_upload_cairo_op_command (GskVulkanOp *op, + GskVulkanRender *render, + VkPipelineLayout pipeline_layout, + VkCommandBuffer command_buffer) +{ +} + +static const GskVulkanOpClass GSK_VULKAN_UPLOAD_CAIRO_OP_CLASS = { + GSK_VULKAN_OP_SIZE (GskVulkanUploadCairoOp), + gsk_vulkan_upload_cairo_op_finish, + gsk_vulkan_upload_cairo_op_upload, + gsk_vulkan_upload_cairo_op_count_vertex_data, + gsk_vulkan_upload_cairo_op_collect_vertex_data, + gsk_vulkan_upload_cairo_op_reserve_descriptor_sets, + gsk_vulkan_upload_cairo_op_get_pipeline, + gsk_vulkan_upload_cairo_op_command +}; + +gsize +gsk_vulkan_upload_cairo_op_size (void) +{ + return GSK_VULKAN_UPLOAD_CAIRO_OP_CLASS.size; +} + +GskVulkanImage * +gsk_vulkan_upload_cairo_op_init (GskVulkanOp *op, + GdkVulkanContext *context, + GskRenderNode *node, + const graphene_vec2_t *scale, + const graphene_rect_t *viewport) +{ + GskVulkanUploadCairoOp *self = (GskVulkanUploadCairoOp *) op; + + gsk_vulkan_op_init (op, &GSK_VULKAN_UPLOAD_CAIRO_OP_CLASS); + + self->node = gsk_render_node_ref (node); + self->image = gsk_vulkan_image_new_for_upload (context, + GDK_MEMORY_DEFAULT, + ceil (graphene_vec2_get_x (scale) * viewport->size.width), + ceil (graphene_vec2_get_y (scale) * viewport->size.height)); + self->viewport = *viewport; + + return self->image; +} diff --git a/gsk/vulkan/gskvulkanuploadcairoopprivate.h b/gsk/vulkan/gskvulkanuploadcairoopprivate.h new file mode 100644 index 0000000000..398f854fb3 --- /dev/null +++ b/gsk/vulkan/gskvulkanuploadcairoopprivate.h @@ -0,0 +1,18 @@ +#pragma once + +#include "gskvulkanopprivate.h" + +G_BEGIN_DECLS + +gsize gsk_vulkan_upload_cairo_op_size (void) G_GNUC_CONST; + +GskVulkanImage * gsk_vulkan_upload_cairo_op_init (GskVulkanOp *op, + GdkVulkanContext *context, + GskRenderNode *node, + const graphene_vec2_t *scale, + const graphene_rect_t *viewport); + + + +G_END_DECLS + -- 2.30.2