mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-24 20:51:10 +00:00
vulkan: Add a clear op
The op emits a vkCmdClearAttachments() with a given color. That can be used with color nodes that are pixel-aligned and opaque to significantly speed up rendering when the window background is a solid color. However, currently this fails a bit outside of fullscreen when rounded clip rectangles are in use to draw rounded corners.
This commit is contained in:
parent
5e1fd56345
commit
bb2cd7225e
@ -111,6 +111,7 @@ if have_vulkan
|
||||
'vulkan/gskvulkanblurop.c',
|
||||
'vulkan/gskvulkanborderop.c',
|
||||
'vulkan/gskvulkanbuffer.c',
|
||||
'vulkan/gskvulkanclearop.c',
|
||||
'vulkan/gskvulkanclip.c',
|
||||
'vulkan/gskvulkancolormatrixop.c',
|
||||
'vulkan/gskvulkancolorop.c',
|
||||
|
124
gsk/vulkan/gskvulkanclearop.c
Normal file
124
gsk/vulkan/gskvulkanclearop.c
Normal file
@ -0,0 +1,124 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskvulkanclearopprivate.h"
|
||||
|
||||
#include "gskvulkanprivate.h"
|
||||
|
||||
typedef struct _GskVulkanClearOp GskVulkanClearOp;
|
||||
|
||||
struct _GskVulkanClearOp
|
||||
{
|
||||
GskVulkanOp op;
|
||||
|
||||
cairo_rectangle_int_t rect;
|
||||
GdkRGBA color;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_vulkan_clear_op_finish (GskVulkanOp *op)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_clear_op_print (GskVulkanOp *op,
|
||||
GString *string,
|
||||
guint indent)
|
||||
{
|
||||
GskVulkanClearOp *self = (GskVulkanClearOp *) op;
|
||||
|
||||
print_indent (string, indent);
|
||||
print_int_rect (string, &self->rect);
|
||||
g_string_append_printf (string, "clear ");
|
||||
print_rgba (string, &self->color);
|
||||
print_newline (string);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_clear_op_upload (GskVulkanOp *op,
|
||||
GskVulkanUploader *uploader)
|
||||
{
|
||||
}
|
||||
|
||||
static gsize
|
||||
gsk_vulkan_clear_op_count_vertex_data (GskVulkanOp *op,
|
||||
gsize n_bytes)
|
||||
{
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_clear_op_collect_vertex_data (GskVulkanOp *op,
|
||||
guchar *data)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_clear_op_reserve_descriptor_sets (GskVulkanOp *op,
|
||||
GskVulkanRender *render)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_init_clear_value (VkClearValue *value,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
gsk_vulkan_rgba_to_float (rgba, value->color.float32);
|
||||
}
|
||||
|
||||
static GskVulkanOp *
|
||||
gsk_vulkan_clear_op_command (GskVulkanOp *op,
|
||||
GskVulkanRender *render,
|
||||
VkPipelineLayout pipeline_layout,
|
||||
VkCommandBuffer command_buffer)
|
||||
{
|
||||
GskVulkanClearOp *self = (GskVulkanClearOp *) op;
|
||||
VkClearValue clear_value;
|
||||
|
||||
gsk_vulkan_init_clear_value (&clear_value, &self->color);
|
||||
|
||||
vkCmdClearAttachments (command_buffer,
|
||||
1,
|
||||
&(VkClearAttachment) {
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
0,
|
||||
clear_value,
|
||||
},
|
||||
1,
|
||||
&(VkClearRect) {
|
||||
{
|
||||
{ self->rect.x, self->rect.y },
|
||||
{ self->rect.width, self->rect.height },
|
||||
},
|
||||
0,
|
||||
1
|
||||
});
|
||||
|
||||
return op->next;
|
||||
}
|
||||
|
||||
static const GskVulkanOpClass GSK_VULKAN_SCISSOR_OP_CLASS = {
|
||||
GSK_VULKAN_OP_SIZE (GskVulkanClearOp),
|
||||
GSK_VULKAN_STAGE_COMMAND,
|
||||
NULL,
|
||||
NULL,
|
||||
gsk_vulkan_clear_op_finish,
|
||||
gsk_vulkan_clear_op_print,
|
||||
gsk_vulkan_clear_op_upload,
|
||||
gsk_vulkan_clear_op_count_vertex_data,
|
||||
gsk_vulkan_clear_op_collect_vertex_data,
|
||||
gsk_vulkan_clear_op_reserve_descriptor_sets,
|
||||
gsk_vulkan_clear_op_command
|
||||
};
|
||||
|
||||
void
|
||||
gsk_vulkan_clear_op (GskVulkanRender *render,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
GskVulkanClearOp *self;
|
||||
|
||||
self = (GskVulkanClearOp *) gsk_vulkan_op_alloc (render, &GSK_VULKAN_SCISSOR_OP_CLASS);
|
||||
|
||||
self->rect = *rect;
|
||||
self->color = *color;
|
||||
}
|
13
gsk/vulkan/gskvulkanclearopprivate.h
Normal file
13
gsk/vulkan/gskvulkanclearopprivate.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "gskvulkanopprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_vulkan_clear_op (GskVulkanRender *render,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
const GdkRGBA *color);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "gskvulkanblendmodeopprivate.h"
|
||||
#include "gskvulkanbluropprivate.h"
|
||||
#include "gskvulkanborderopprivate.h"
|
||||
#include "gskvulkanclearopprivate.h"
|
||||
#include "gskvulkanclipprivate.h"
|
||||
#include "gskvulkancolormatrixopprivate.h"
|
||||
#include "gskvulkancoloropprivate.h"
|
||||
@ -349,11 +350,46 @@ gsk_vulkan_render_pass_add_color_node (GskVulkanRenderPass *self,
|
||||
const GskVulkanParseState *state,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
cairo_rectangle_int_t int_clipped;
|
||||
graphene_rect_t rect, clipped;
|
||||
const GdkRGBA *color;
|
||||
|
||||
color = gsk_color_node_get_color (node);
|
||||
graphene_rect_offset_r (&node->bounds,
|
||||
state->offset.x, state->offset.y,
|
||||
&rect);
|
||||
graphene_rect_intersection (&state->clip.rect.bounds, &rect, &clipped);
|
||||
|
||||
if (gdk_rgba_is_opaque (color) &&
|
||||
gsk_vulkan_parse_rect_is_integer (state, &clipped, &int_clipped))
|
||||
{
|
||||
/* now handle all the clip */
|
||||
if (!gdk_rectangle_intersect (&int_clipped, &state->scissor, &int_clipped))
|
||||
return TRUE;
|
||||
|
||||
/* we have handled the bounds, now do the corners */
|
||||
if (state->clip.type != GSK_VULKAN_CLIP_ROUNDED ||
|
||||
gsk_vulkan_clip_contains_rect (&state->clip,
|
||||
graphene_point_zero (),
|
||||
&GRAPHENE_RECT_INIT (
|
||||
int_clipped.x / graphene_vec2_get_x (&state->scale),
|
||||
int_clipped.y / graphene_vec2_get_y (&state->scale),
|
||||
int_clipped.width / graphene_vec2_get_x (&state->scale),
|
||||
int_clipped.height / graphene_vec2_get_y (&state->scale)
|
||||
)))
|
||||
{
|
||||
gsk_vulkan_clear_op (render,
|
||||
&int_clipped,
|
||||
color);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gsk_vulkan_color_op (render,
|
||||
gsk_vulkan_clip_get_clip_type (&state->clip, &state->offset, &node->bounds),
|
||||
&node->bounds,
|
||||
&state->offset,
|
||||
gsk_color_node_get_color (node));
|
||||
&rect,
|
||||
graphene_point_zero (),
|
||||
color);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user