From 53e7277584c18b025e9f28121aee1b337b9d4870 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 26 Jun 2023 01:40:45 +0200 Subject: [PATCH] vulkan: Implement fallback using new nodes With Cairo upload and texture nodes being available, we can do that now. --- gsk/vulkan/gskvulkanrenderpass.c | 188 +++++-------------------------- 1 file changed, 28 insertions(+), 160 deletions(-) diff --git a/gsk/vulkan/gskvulkanrenderpass.c b/gsk/vulkan/gskvulkanrenderpass.c index 646d6ba347..48c287772a 100644 --- a/gsk/vulkan/gskvulkanrenderpass.c +++ b/gsk/vulkan/gskvulkanrenderpass.c @@ -53,9 +53,6 @@ typedef struct _GskVulkanOpPushConstants GskVulkanOpPushConstants; typedef enum { /* GskVulkanOpRender */ - GSK_VULKAN_OP_FALLBACK, - GSK_VULKAN_OP_FALLBACK_CLIP, - GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP, GSK_VULKAN_OP_COLOR, GSK_VULKAN_OP_LINEAR_GRADIENT, GSK_VULKAN_OP_BLUR, @@ -80,7 +77,6 @@ struct _GskVulkanOpRender GskRenderNode *node; /* node that's the source of this op */ graphene_point_t offset; /* offset of the node */ GskVulkanPipeline *pipeline; /* pipeline to use */ - GskRoundedRect clip; /* clip rect (or random memory if not relevant) */ GskVulkanImage *source; /* source image to render */ GskVulkanImage *source2; /* second source image to render (if relevant) */ gsize vertex_offset; /* offset into vertex buffer */ @@ -98,7 +94,6 @@ struct _GskVulkanOpText GskRenderNode *node; /* node that's the source of this op */ graphene_point_t offset; /* offset of the node */ GskVulkanPipeline *pipeline; /* pipeline to use */ - GskRoundedRect clip; /* clip rect (or random memory if not relevant) */ GskVulkanImage *source; /* source image to render */ gsize vertex_offset; /* offset into vertex buffer */ guint32 image_descriptor[2]; /* index into descriptor for the (image, sampler) */ @@ -464,32 +459,36 @@ gsk_vulkan_render_pass_add_fallback_node (GskVulkanRenderPass *self, const GskVulkanParseState *state, GskRenderNode *node) { - GskVulkanOpRender op = { - .node = node, - .offset = state->offset, - }; + GskVulkanPipelineType pipeline_type; + GskVulkanImage *image; + graphene_rect_t clipped; - switch (state->clip.type) - { - case GSK_VULKAN_CLIP_NONE: - op.type = GSK_VULKAN_OP_FALLBACK; - break; - case GSK_VULKAN_CLIP_RECT: - op.type = GSK_VULKAN_OP_FALLBACK_CLIP; - gsk_rounded_rect_init_copy (&op.clip, &state->clip.rect); - break; - case GSK_VULKAN_CLIP_ROUNDED: - op.type = GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP; - gsk_rounded_rect_init_copy (&op.clip, &state->clip.rect); - break; - case GSK_VULKAN_CLIP_ALL_CLIPPED: - default: - g_assert_not_reached (); - return FALSE; - } + graphene_rect_offset_r (&state->clip.rect.bounds, - state->offset.x, - state->offset.y, &clipped); + graphene_rect_intersection (&clipped, &node->bounds, &clipped); - op.pipeline = gsk_vulkan_render_pass_get_pipeline (self, render, GSK_VULKAN_PIPELINE_TEXTURE); - gsk_vulkan_render_pass_add_op (self, (GskVulkanOp *) &op); + if (clipped.size.width == 0 || clipped.size.height == 0) + return TRUE; + + image = 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); + + if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds)) + pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE; + else if (state->clip.type == GSK_VULKAN_CLIP_RECT) + pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP; + else + pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP_ROUNDED; + + gsk_vulkan_texture_op_init (gsk_vulkan_render_pass_alloc_op (self, gsk_vulkan_texture_op_size ()), + gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type), + image, + GSK_VULKAN_SAMPLER_DEFAULT, + &node->bounds, + &state->offset, + &clipped); return TRUE; } @@ -1626,108 +1625,6 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self, return result; } -static void -gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self, - GskVulkanOpRender *op, - GskVulkanRender *render, - GskVulkanUploader *uploader) -{ - GskRenderNode *node; - GskVulkanImageMap map; - gsize width, height; - cairo_surface_t *surface; - cairo_t *cr; - - node = op->node; - - GSK_RENDERER_DEBUG (gsk_vulkan_render_get_renderer (render), FALLBACK, - "Upload op=%s, node %s[%p], bounds %gx%g", - op->type == GSK_VULKAN_OP_FALLBACK_CLIP ? "fallback-clip" : - (op->type == GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP ? "fallback-rounded-clip" : "fallback"), - g_type_name_from_instance ((GTypeInstance *) node), node, - ceil (node->bounds.size.width), - ceil (node->bounds.size.height)); -#ifdef G_ENABLE_DEBUG - { - GskProfiler *profiler = gsk_renderer_get_profiler (gsk_vulkan_render_get_renderer (render)); - gsk_profiler_counter_add (profiler, - fallback_pixels_quark, - ceil (node->bounds.size.width) * ceil (node->bounds.size.height)); - } -#endif - - /* XXX: We could intersect bounds with clip bounds here */ - width = ceil (node->bounds.size.width * graphene_vec2_get_x (&self->scale)); - height = ceil (node->bounds.size.height * graphene_vec2_get_y (&self->scale)); - - op->source = gsk_vulkan_image_new_for_upload (self->vulkan, GDK_MEMORY_DEFAULT, width, height); - gsk_vulkan_image_map_memory (op->source, 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 / node->bounds.size.width, - height / node->bounds.size.height); - cr = cairo_create (surface); - cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y); - - if (op->type == GSK_VULKAN_OP_FALLBACK_CLIP) - { - cairo_rectangle (cr, - op->clip.bounds.origin.x - op->offset.x, - op->clip.bounds.origin.y - op->offset.y, - op->clip.bounds.size.width, - op->clip.bounds.size.height); - cairo_clip (cr); - } - else if (op->type == GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP) - { - cairo_translate (cr, - op->offset.x, - op->offset.y); - gsk_rounded_rect_path (&op->clip, cr); - cairo_translate (cr, op->offset.x, op->offset.y); - cairo_clip (cr); - } - else - { - g_assert (op->type == GSK_VULKAN_OP_FALLBACK); - } - - gsk_render_node_draw (node, cr); - -#ifdef G_ENABLE_DEBUG - if (GSK_RENDERER_DEBUG_CHECK (gsk_vulkan_render_get_renderer (render), FALLBACK)) - { - cairo_rectangle (cr, - op->clip.bounds.origin.x - op->offset.x, - op->clip.bounds.origin.y - op->offset.y, - op->clip.bounds.size.width, - op->clip.bounds.size.height); - if (gsk_render_node_get_node_type (node) == GSK_CAIRO_NODE) - cairo_set_source_rgba (cr, 0.3, 0, 1, 0.25); - else - cairo_set_source_rgba (cr, 1, 0, 0, 0.25); - cairo_fill_preserve (cr); - if (gsk_render_node_get_node_type (node) == GSK_CAIRO_NODE) - cairo_set_source_rgba (cr, 0.3, 0, 1, 1); - else - cairo_set_source_rgba (cr, 1, 0, 0, 1); - cairo_stroke (cr); - } -#endif - - cairo_destroy (cr); - - cairo_surface_finish (surface); - cairo_surface_destroy (surface); - - gsk_vulkan_image_unmap_memory (op->source, uploader, &map); - gsk_vulkan_render_add_cleanup_image (render, op->source); - - op->source_rect = GRAPHENE_RECT_INIT(0, 0, 1, 1); -} - void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, GskVulkanRender *render, @@ -1765,12 +1662,6 @@ gsk_vulkan_render_op_upload (GskVulkanOp *op_, switch (op->any.type) { - case GSK_VULKAN_OP_FALLBACK: - case GSK_VULKAN_OP_FALLBACK_CLIP: - case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP: - gsk_vulkan_render_pass_upload_fallback (self, &op->render, render, uploader); - break; - case GSK_VULKAN_OP_TEXT: case GSK_VULKAN_OP_COLOR_TEXT: { @@ -1961,9 +1852,6 @@ gsk_vulkan_render_op_count_vertex_data (GskVulkanOp *op_, switch (op->any.type) { - case GSK_VULKAN_OP_FALLBACK: - case GSK_VULKAN_OP_FALLBACK_CLIP: - case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP: case GSK_VULKAN_OP_REPEAT: case GSK_VULKAN_OP_COLOR: case GSK_VULKAN_OP_LINEAR_GRADIENT: @@ -2023,17 +1911,6 @@ gsk_vulkan_render_op_collect_vertex_data (GskVulkanOp *op_, switch (op->any.type) { - case GSK_VULKAN_OP_FALLBACK: - case GSK_VULKAN_OP_FALLBACK_CLIP: - case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP: - gsk_vulkan_texture_pipeline_collect_vertex_data (GSK_VULKAN_TEXTURE_PIPELINE (op->render.pipeline), - data + op->render.vertex_offset, - op->render.image_descriptor, - &op->render.offset, - &op->render.node->bounds, - &op->render.source_rect); - break; - case GSK_VULKAN_OP_REPEAT: gsk_vulkan_texture_pipeline_collect_vertex_data (GSK_VULKAN_TEXTURE_PIPELINE (op->render.pipeline), data + op->render.vertex_offset, @@ -2239,9 +2116,6 @@ gsk_vulkan_render_op_reserve_descriptor_sets (GskVulkanOp *op_, switch (op->any.type) { - case GSK_VULKAN_OP_FALLBACK: - case GSK_VULKAN_OP_FALLBACK_CLIP: - case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP: case GSK_VULKAN_OP_BLUR: if (op->render.source) { @@ -2349,9 +2223,6 @@ gsk_vulkan_render_op_get_pipeline (GskVulkanOp *op_) switch (op->any.type) { - case GSK_VULKAN_OP_FALLBACK: - case GSK_VULKAN_OP_FALLBACK_CLIP: - case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP: case GSK_VULKAN_OP_REPEAT: case GSK_VULKAN_OP_COLOR: case GSK_VULKAN_OP_LINEAR_GRADIENT: @@ -2386,9 +2257,6 @@ gsk_vulkan_render_op_command (GskVulkanOp *op_, switch (op->any.type) { - case GSK_VULKAN_OP_FALLBACK: - case GSK_VULKAN_OP_FALLBACK_CLIP: - case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP: case GSK_VULKAN_OP_REPEAT: if (!op->render.source) break; -- 2.30.2