mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 22:20:24 +00:00
gpu: Only run a single renderpass
Instead of running one renderpass per clip region, run one renderpass for the whole clip extents, and just set the scissor to the individual clip rects. This means that we need to use LOAD_OP_LOAD in cases where we don't redraw the full extents, but nonetheless, the eprformance wins of avoiding renderpasses are worth it, in particualr on tilers like the Raspberry Pi or other mobile chips and the Apple M1/2.
This commit is contained in:
parent
cfe0da1eed
commit
54758bee1f
@ -141,8 +141,14 @@ typedef struct _GskGpuFirstNodeInfo GskGpuFirstNodeInfo;
|
||||
struct _GskGpuFirstNodeInfo
|
||||
{
|
||||
GskGpuImage *target;
|
||||
cairo_rectangle_int_t extents;
|
||||
GskRenderPassType pass_type;
|
||||
gsize min_occlusion_pixels;
|
||||
float background_color[4];
|
||||
|
||||
guint whole_area : 1;
|
||||
guint has_background : 1;
|
||||
guint has_started_rendering : 1;
|
||||
};
|
||||
|
||||
static void gsk_gpu_node_processor_add_node (GskGpuNodeProcessor *self,
|
||||
@ -1104,13 +1110,54 @@ gsk_gpu_first_node_begin_rendering (GskGpuNodeProcessor *self,
|
||||
GskGpuFirstNodeInfo *info,
|
||||
float clear_color[4])
|
||||
{
|
||||
gsk_gpu_render_pass_begin_op (self->frame,
|
||||
info->target,
|
||||
&self->scissor,
|
||||
clear_color ? GSK_GPU_LOAD_OP_CLEAR
|
||||
: GSK_GPU_LOAD_OP_DONT_CARE,
|
||||
clear_color,
|
||||
info->pass_type);
|
||||
if (info->has_started_rendering)
|
||||
{
|
||||
if (clear_color &&
|
||||
(!info->has_background ||
|
||||
(info->has_background &&
|
||||
(clear_color[0] != info->background_color[0] ||
|
||||
clear_color[1] != info->background_color[1] ||
|
||||
clear_color[2] != info->background_color[2] ||
|
||||
clear_color[3] != info->background_color[3]))))
|
||||
{
|
||||
gsk_gpu_clear_op (self->frame, &self->scissor, clear_color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GskGpuLoadOp load_op;
|
||||
|
||||
if (!info->whole_area)
|
||||
{
|
||||
info->has_background = FALSE;
|
||||
load_op = GSK_GPU_LOAD_OP_LOAD;
|
||||
}
|
||||
else if (clear_color)
|
||||
{
|
||||
info->background_color[0] = clear_color[0];
|
||||
info->background_color[1] = clear_color[1];
|
||||
info->background_color[2] = clear_color[2];
|
||||
info->background_color[3] = clear_color[3];
|
||||
info->has_background = TRUE;
|
||||
load_op = GSK_GPU_LOAD_OP_CLEAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->has_background = FALSE;
|
||||
load_op = GSK_GPU_LOAD_OP_DONT_CARE;
|
||||
}
|
||||
|
||||
info->has_started_rendering = TRUE;
|
||||
gsk_gpu_render_pass_begin_op (self->frame,
|
||||
info->target,
|
||||
&info->extents,
|
||||
load_op,
|
||||
clear_color,
|
||||
info->pass_type);
|
||||
|
||||
if (!info->whole_area && clear_color)
|
||||
gsk_gpu_clear_op (self->frame, &self->scissor, clear_color);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4095,13 +4142,16 @@ gsk_gpu_node_processor_render (GskGpuNodeProcessor *self,
|
||||
GskRenderNode *node,
|
||||
GskRenderPassType pass_type)
|
||||
{
|
||||
GskGpuFirstNodeInfo info;
|
||||
GskGpuFirstNodeInfo info = {
|
||||
.target = target,
|
||||
.pass_type = pass_type,
|
||||
};
|
||||
int i, n, best, best_size;
|
||||
cairo_rectangle_int_t rect;
|
||||
gboolean do_culling;
|
||||
|
||||
info.target = target;
|
||||
info.pass_type = pass_type;
|
||||
cairo_region_get_extents (clip, &info.extents);
|
||||
info.whole_area = cairo_region_contains_rectangle (clip, &info.extents) == CAIRO_REGION_OVERLAP_IN;
|
||||
info.min_occlusion_pixels = gsk_gpu_image_get_width (target) * gsk_gpu_image_get_height (target) *
|
||||
MIN_PERCENTAGE_FOR_OCCLUSION_PASS / 100;
|
||||
info.min_occlusion_pixels = MAX (info.min_occlusion_pixels, MIN_PIXELS_FOR_OCCLUSION_PASS);
|
||||
@ -4150,10 +4200,6 @@ gsk_gpu_node_processor_render (GskGpuNodeProcessor *self,
|
||||
&GDK_COLOR_SRGB (1.0, 1.0, 1.0, 0.6));
|
||||
}
|
||||
|
||||
gsk_gpu_render_pass_end_op (self->frame,
|
||||
target,
|
||||
pass_type);
|
||||
|
||||
cairo_region_subtract_rectangle (clip, &self->scissor);
|
||||
}
|
||||
|
||||
@ -4173,7 +4219,10 @@ gsk_gpu_node_processor_render (GskGpuNodeProcessor *self,
|
||||
gsk_gpu_first_node_begin_rendering (self, &info, GSK_VEC4_TRANSPARENT);
|
||||
gsk_gpu_node_processor_add_node (self, node);
|
||||
}
|
||||
}
|
||||
|
||||
if (info.has_started_rendering)
|
||||
{
|
||||
gsk_gpu_render_pass_end_op (self->frame,
|
||||
target,
|
||||
pass_type);
|
||||
|
Loading…
Reference in New Issue
Block a user