gdk: Pass the opaque rect to begin_frame() actually

We know it at begin_frame() time, so if we pass it there instead of
end_frame(), we can use it then to make decisions about opacity.

For example, we could notice that the whole surface is opaque and choose
an RGBx format.
We don't do that yet, but now we could.
This commit is contained in:
Benjamin Otte 2024-08-09 19:26:43 +02:00
parent f64045c229
commit 16c7003acb
9 changed files with 67 additions and 57 deletions

View File

@ -330,11 +330,12 @@ gdk_draw_context_begin_frame (GdkDrawContext *context,
g_return_if_fail (priv->surface != NULL);
g_return_if_fail (region != NULL);
gdk_draw_context_begin_frame_full (context, GDK_MEMORY_U8, region);
gdk_draw_context_begin_frame_full (context, GDK_MEMORY_U8, region, NULL);
}
/*
* @depth: best depth to render in
* @opaque: (nullable): opaque region of the rendering
*
* If the given depth is not `GDK_MEMORY_U8`, GDK will see about providing a
* rendering target that supports a higher bit depth than 8 bits per channel.
@ -357,9 +358,10 @@ gdk_draw_context_begin_frame (GdkDrawContext *context,
* to choose.
*/
void
gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region)
gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
@ -384,6 +386,8 @@ gdk_draw_context_begin_frame_full (GdkDrawContext *context,
return;
}
gdk_surface_set_opaque_rect (priv->surface, opaque);
if (gdk_display_get_debug_flags (priv->display) & GDK_DEBUG_HIGH_DEPTH)
depth = GDK_MEMORY_FLOAT32;
@ -427,13 +431,10 @@ region_get_pixels (cairo_region_t *region)
#endif
void
gdk_draw_context_end_frame_full (GdkDrawContext *context,
const graphene_rect_t *opaque)
gdk_draw_context_end_frame_full (GdkDrawContext *context)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
gdk_surface_set_opaque_rect (priv->surface, opaque);
GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context, priv->frame_region);
gdk_profiler_set_int_counter (pixels_counter, region_get_pixels (priv->frame_region));
@ -486,7 +487,7 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
return;
}
gdk_draw_context_end_frame_full (context, NULL);
gdk_draw_context_end_frame_full (context);
}
/**

View File

@ -59,9 +59,9 @@ void gdk_draw_context_surface_resized (GdkDrawContext
void gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region);
void gdk_draw_context_end_frame_full (GdkDrawContext *context,
const cairo_region_t *region,
const graphene_rect_t *opaque);
void gdk_draw_context_end_frame_full (GdkDrawContext *context);
void gdk_draw_context_empty_frame (GdkDrawContext *context);

View File

@ -934,7 +934,7 @@ gsk_broadway_renderer_render (GskRenderer *renderer,
self->node_lookup = g_hash_table_new (g_direct_hash, g_direct_equal);
gdk_draw_context_begin_frame_full (GDK_DRAW_CONTEXT (self->draw_context), GDK_MEMORY_U8, update_area);
gdk_draw_context_begin_frame_full (GDK_DRAW_CONTEXT (self->draw_context), GDK_MEMORY_U8, update_area, NULL);
/* These are owned by the draw context between begin and end, but
cache them here for easier access during the render */
@ -946,7 +946,7 @@ gsk_broadway_renderer_render (GskRenderer *renderer,
self->nodes = NULL;
self->node_textures = NULL;
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->draw_context), NULL);
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->draw_context));
if (self->last_node_lookup)
g_hash_table_unref (self->last_node_lookup);

View File

@ -305,7 +305,8 @@ gsk_gl_renderer_render (GskRenderer *renderer,
graphene_rect_t viewport;
GskGLRenderJob *job;
GdkSurface *surface;
graphene_rect_t opaque;
graphene_rect_t opaque_tmp;
const graphene_rect_t *opaque;
float scale;
g_assert (GSK_IS_GL_RENDERER (renderer));
@ -325,9 +326,14 @@ gsk_gl_renderer_render (GskRenderer *renderer,
viewport.size.width = gdk_surface_get_width (surface) * scale;
viewport.size.height = gdk_surface_get_height (surface) * scale;
if (gsk_render_node_get_opaque_rect (root, &opaque_tmp))
opaque = &opaque_tmp;
else
opaque = NULL;
gdk_draw_context_begin_frame_full (GDK_DRAW_CONTEXT (self->context),
gsk_render_node_get_preferred_depth (root),
update_area);
update_area,
opaque);
gdk_gl_context_make_current (self->context);
@ -340,10 +346,7 @@ gsk_gl_renderer_render (GskRenderer *renderer,
gsk_gl_driver_end_frame (self->driver);
gsk_gl_render_job_free (job);
if (gsk_render_node_get_opaque_rect (root, &opaque))
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->context), &opaque);
else
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->context), NULL);
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->context));
gsk_gl_driver_after_frame (self->driver);

View File

@ -78,20 +78,20 @@ gsk_gpu_frame_default_cleanup (GskGpuFrame *self)
}
static void
gsk_gpu_frame_default_begin (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region)
gsk_gpu_frame_default_begin (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque)
{
gdk_draw_context_begin_frame_full (context, depth, region);
gdk_draw_context_begin_frame_full (context, depth, region, opaque);
}
static void
gsk_gpu_frame_default_end (GskGpuFrame *self,
GdkDrawContext *context,
const graphene_rect_t *opaque)
gsk_gpu_frame_default_end (GskGpuFrame *self,
GdkDrawContext *context)
{
gdk_draw_context_end_frame_full (context, opaque);
gdk_draw_context_end_frame_full (context);
}
static void
@ -203,17 +203,17 @@ void
gsk_gpu_frame_begin (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region)
const cairo_region_t *region,
const graphene_rect_t *opaque)
{
GSK_GPU_FRAME_GET_CLASS (self)->begin (self, context, depth, region);
GSK_GPU_FRAME_GET_CLASS (self)->begin (self, context, depth, region, opaque);
}
void
gsk_gpu_frame_end (GskGpuFrame *self,
GdkDrawContext *context,
const graphene_rect_t *opaque)
gsk_gpu_frame_end (GskGpuFrame *self,
GdkDrawContext *context)
{
GSK_GPU_FRAME_GET_CLASS (self)->end (self, context, opaque);
GSK_GPU_FRAME_GET_CLASS (self)->end (self, context);
}
GskGpuDevice *

View File

@ -30,10 +30,10 @@ struct _GskGpuFrameClass
void (* begin) (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region);
void (* end) (GskGpuFrame *self,
GdkDrawContext *context,
const cairo_region_t *region,
const graphene_rect_t *opaque);
void (* end) (GskGpuFrame *self,
GdkDrawContext *context);
GskGpuImage * (* upload_texture) (GskGpuFrame *self,
gboolean with_mipmap,
GdkTexture *texture);
@ -67,10 +67,10 @@ gsize gsk_gpu_frame_get_texture_vertex_size (GskGpuF
void gsk_gpu_frame_begin (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region);
void gsk_gpu_frame_end (GskGpuFrame *self,
GdkDrawContext *context,
const cairo_region_t *region,
const graphene_rect_t *opaque);
void gsk_gpu_frame_end (GskGpuFrame *self,
GdkDrawContext *context);
GdkDrawContext * gsk_gpu_frame_get_context (GskGpuFrame *self) G_GNUC_PURE;
GskGpuDevice * gsk_gpu_frame_get_device (GskGpuFrame *self) G_GNUC_PURE;

View File

@ -420,7 +420,8 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
GskGpuFrame *frame;
GskGpuImage *backbuffer;
cairo_region_t *render_region;
graphene_rect_t opaque;
graphene_rect_t opaque_tmp;
const graphene_rect_t *opaque;
double scale;
GdkMemoryDepth depth;
@ -438,7 +439,11 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
frame = gsk_gpu_renderer_get_frame (self);
scale = gsk_gpu_renderer_get_scale (self);
gsk_gpu_frame_begin (frame, priv->context, depth, region);
if (gsk_render_node_get_opaque_rect (root, &opaque_tmp))
opaque = &opaque_tmp;
else
opaque = NULL;
gsk_gpu_frame_begin (frame, priv->context, depth, region, opaque);
backbuffer = GSK_GPU_RENDERER_GET_CLASS (self)->get_backbuffer (self);
@ -457,10 +462,7 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
),
NULL);
if (gsk_render_node_get_opaque_rect (root, &opaque))
gsk_gpu_frame_end (frame, priv->context, &opaque);
else
gsk_gpu_frame_end (frame, priv->context, NULL);
gsk_gpu_frame_end (frame, priv->context);
gsk_gpu_device_queue_gc (priv->device);
}

View File

@ -148,15 +148,16 @@ gsk_vulkan_frame_cleanup (GskGpuFrame *frame)
}
static void
gsk_vulkan_frame_begin (GskGpuFrame *frame,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region)
gsk_vulkan_frame_begin (GskGpuFrame *frame,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque)
{
GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
gdk_vulkan_context_set_draw_semaphore (GDK_VULKAN_CONTEXT (context), self->vk_acquire_semaphore);
GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->begin (frame, context, depth, region);
GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->begin (frame, context, depth, region, opaque);
}
static GskGpuImage *

View File

@ -159,12 +159,18 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
const cairo_region_t *region)
{
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
graphene_rect_t opaque;
graphene_rect_t opaque_tmp;
const graphene_rect_t *opaque;
cairo_t *cr;
if (gsk_render_node_get_opaque_rect (root, &opaque_tmp))
opaque = &opaque_tmp;
else
opaque = NULL;
gdk_draw_context_begin_frame_full (GDK_DRAW_CONTEXT (self->cairo_context),
GDK_MEMORY_U8,
region);
region,
opaque);
cr = gdk_cairo_context_cairo_create (self->cairo_context);
g_return_if_fail (cr != NULL);
@ -190,10 +196,7 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
cairo_destroy (cr);
if (gsk_render_node_get_opaque_rect (root, &opaque))
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->cairo_context), &opaque);
else
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->cairo_context), NULL);
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->cairo_context));
}
static void