diff --git a/gdk/gdkrectangleprivate.h b/gdk/gdkrectangleprivate.h index b7857d5037..3742764a41 100644 --- a/gdk/gdkrectangleprivate.h +++ b/gdk/gdkrectangleprivate.h @@ -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 diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c index ef444b123b..ddde1fd427 100644 --- a/gdk/gdksurface.c +++ b/gdk/gdksurface.c @@ -40,7 +40,7 @@ #include #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) diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h index 6a5353a3d3..04c8a39524 100644 --- a/gdk/gdksurfaceprivate.h +++ b/gdk/gdksurfaceprivate.h @@ -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); diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c index 86c2cc9015..039c4395bc 100644 --- a/gdk/macos/gdkmacosglcontext.c +++ b/gdk/macos/gdkmacosglcontext.c @@ -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; diff --git a/gdk/macos/gdkmacossurface-private.h b/gdk/macos/gdkmacossurface-private.h index ff0f297a8a..39d1ff28d8 100644 --- a/gdk/macos/gdkmacossurface-private.h +++ b/gdk/macos/gdkmacossurface-private.h @@ -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, diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c index eb167ec391..f4d50be92c 100644 --- a/gdk/macos/gdkmacossurface.c +++ b/gdk/macos/gdkmacossurface.c @@ -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) {