gdk: Introduce gdk_surface_is_opaque()

... and use it in the mac backend instead of a hand-rolled version.
This commit is contained in:
Benjamin Otte 2024-08-09 19:38:25 +02:00
parent 16c7003acb
commit 999d9bc73b
6 changed files with 40 additions and 26 deletions

View File

@ -52,6 +52,16 @@ gdk_rectangle_transform_affine (const GdkRectangle *src,
dest->height = ceilf (MAX (y1, y2)) - dest->y;
}
static inline gboolean
gdk_rectangle_contains (const GdkRectangle *rect,
const GdkRectangle *contained)
{
return contained->x >= rect->x
&& contained->y >= rect->y
&& contained->x + contained->width <= rect->x + rect->width
&& contained->y + contained->height <= rect->y + rect->height;
}
G_END_DECLS

View File

@ -40,7 +40,7 @@
#include <glib/gi18n-lib.h>
#include "gdkmarshalers.h"
#include "gdkpopupprivate.h"
#include "gdkrectangle.h"
#include "gdkrectangleprivate.h"
#include "gdktoplevelprivate.h"
#include "gdkvulkancontext.h"
#include "gdksubsurfaceprivate.h"
@ -2738,6 +2738,33 @@ gdk_surface_set_opaque_rect (GdkSurface *self,
gdk_surface_update_opaque_region (self);
}
/*
* gdk_surface_is_opaque:
* @self: a surface
*
* Checks if the whole surface is known to be opaque.
* This allows using an RGBx buffer instead of RGBA.
*
* This function works for the currently rendered frame inside
* begin_frame() implementations.
*
* Returns: %TRUE if the whole surface is provably opaque
**/
gboolean
gdk_surface_is_opaque (GdkSurface *self)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self);
cairo_rectangle_int_t whole = { 0, 0, self->width, self->height };
if (gdk_rectangle_contains (&priv->opaque_rect, &whole))
return TRUE;
if (cairo_region_contains_rectangle (priv->opaque_region, &whole) == CAIRO_REGION_OVERLAP_IN)
return TRUE;
return FALSE;
}
void
gdk_surface_set_state (GdkSurface *surface,
GdkToplevelState new_state)

View File

@ -261,6 +261,7 @@ void _gdk_surface_clear_update_area (GdkSurface *surface);
void _gdk_surface_update_size (GdkSurface *surface);
void gdk_surface_set_opaque_rect (GdkSurface *self,
const graphene_rect_t *rect);
gboolean gdk_surface_is_opaque (GdkSurface *self);
GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface,
GError **error);

View File

@ -242,7 +242,7 @@ gdk_macos_gl_context_allocate (GdkMacosGLContext *self)
return;
/* Alter to an opaque surface if necessary */
opaque = _gdk_macos_surface_is_opaque (GDK_MACOS_SURFACE (surface));
opaque = gdk_surface_is_opaque (surface);
if (opaque != self->last_opaque)
{
self->last_opaque = !!opaque;

View File

@ -86,7 +86,6 @@ CGDirectDisplayID _gdk_macos_surface_get_screen_id (GdkMacosSurface
const char *_gdk_macos_surface_get_title (GdkMacosSurface *self);
void _gdk_macos_surface_set_title (GdkMacosSurface *self,
const char *title);
gboolean _gdk_macos_surface_is_opaque (GdkMacosSurface *self);
NSView *_gdk_macos_surface_get_view (GdkMacosSurface *self);
gboolean _gdk_macos_surface_get_modal_hint (GdkMacosSurface *self);
void _gdk_macos_surface_set_modal_hint (GdkMacosSurface *self,

View File

@ -553,29 +553,6 @@ gdk_macos_surface_init (GdkMacosSurface *self)
self->monitors = g_ptr_array_new_with_free_func (g_object_unref);
}
gboolean
_gdk_macos_surface_is_opaque (GdkMacosSurface *self)
{
GdkSurface *surface = (GdkSurface *)self;
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (self), FALSE);
if (surface->opaque_region != NULL &&
cairo_region_num_rectangles (surface->opaque_region) == 1)
{
cairo_rectangle_int_t extents;
cairo_region_get_extents (surface->opaque_region, &extents);
return (extents.x == 0 &&
extents.y == 0 &&
extents.width == GDK_SURFACE (self)->width &&
extents.height == GDK_SURFACE (self)->height);
}
return FALSE;
}
const char *
_gdk_macos_surface_get_title (GdkMacosSurface *self)
{