Merge branch 'subsurface-api-tweaks' into 'main'

subsurface: Replace place_above/below

See merge request GNOME/gtk!6595
This commit is contained in:
Matthias Clasen
2023-11-21 18:52:07 +00:00
4 changed files with 58 additions and 106 deletions

View File

@@ -58,13 +58,16 @@ gdk_subsurface_get_parent (GdkSubsurface *subsurface)
gboolean
gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *rect)
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling)
{
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), FALSE);
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
g_return_val_if_fail (rect != NULL, FALSE);
g_return_val_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling), FALSE);
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, rect);
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, rect, above, sibling);
}
void
@@ -93,28 +96,6 @@ gdk_subsurface_get_rect (GdkSubsurface *subsurface,
GDK_SUBSURFACE_GET_CLASS (subsurface)->get_rect (subsurface, rect);
}
/* If sibling is NULL, place the subsurface above its parent */
void
gdk_subsurface_place_above (GdkSubsurface *subsurface,
GdkSubsurface *sibling)
{
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
g_return_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling));
GDK_SUBSURFACE_GET_CLASS (subsurface)->place_above (subsurface, sibling);
}
/* If sibling is NULL, place the subsurface below its parent */
void
gdk_subsurface_place_below (GdkSubsurface *subsurface,
GdkSubsurface *sibling)
{
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
g_return_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling));
GDK_SUBSURFACE_GET_CLASS (subsurface)->place_below (subsurface, sibling);
}
gboolean
gdk_subsurface_is_above_parent (GdkSubsurface *subsurface)
{

View File

@@ -50,15 +50,13 @@ struct _GdkSubsurfaceClass
gboolean (* attach) (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *rect);
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling);
void (* detach) (GdkSubsurface *subsurface);
GdkTexture * (* get_texture) (GdkSubsurface *subsurface);
void (* get_rect) (GdkSubsurface *subsurface,
graphene_rect_t *rect);
void (* place_above) (GdkSubsurface *subsurface,
GdkSubsurface *sibling);
void (* place_below) (GdkSubsurface *subsurface,
GdkSubsurface *sibling);
gboolean (* is_above_parent) (GdkSubsurface *subsurface);
};
@@ -67,15 +65,13 @@ GType gdk_subsurface_get_type (void) G_GNUC_CONST;
GdkSurface * gdk_subsurface_get_parent (GdkSubsurface *subsurface);
gboolean gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *rect);
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling);
void gdk_subsurface_detach (GdkSubsurface *subsurface);
GdkTexture * gdk_subsurface_get_texture (GdkSubsurface *subsurface);
void gdk_subsurface_get_rect (GdkSubsurface *subsurface,
graphene_rect_t *rect);
void gdk_subsurface_place_above (GdkSubsurface *subsurface,
GdkSubsurface *sibling);
void gdk_subsurface_place_below (GdkSubsurface *subsurface,
GdkSubsurface *sibling);
gboolean gdk_subsurface_is_above_parent (GdkSubsurface *subsurface);

View File

@@ -152,15 +152,24 @@ get_wl_buffer (GdkWaylandSubsurface *self,
static gboolean
gdk_wayland_subsurface_attach (GdkSubsurface *sub,
GdkTexture *texture,
const graphene_rect_t *rect)
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling)
{
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
struct wl_buffer *buffer = NULL;
gboolean result = FALSE;
GdkWaylandSubsurface *sib = sibling ? GDK_WAYLAND_SUBSURFACE (sibling) : NULL;
gboolean will_be_above;
if (sib)
will_be_above = sib->above_parent;
else
will_be_above = above;
if (sub->parent == NULL)
{
g_warning ("Can't draw to destroyed subsurface %p", self);
g_warning ("Can't attach to destroyed subsurface %p", self);
return FALSE;
}
@@ -191,10 +200,11 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
G_OBJECT_TYPE_NAME (texture),
self);
}
else if (gdk_memory_format_alpha (gdk_texture_get_format (texture)) != GDK_MEMORY_ALPHA_OPAQUE)
else if (!will_be_above &&
gdk_memory_format_alpha (gdk_texture_get_format (texture)) != GDK_MEMORY_ALPHA_OPAQUE)
{
GDK_DISPLAY_DEBUG (gdk_surface_get_display (sub->parent), OFFLOAD,
"Cannot offload non-opaque %dx%d texture, hiding subsurface %p",
"Cannot offload non-opaque %dx%d texture below, hiding subsurface %p",
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
self);
@@ -250,6 +260,7 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
0, 0,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture));
}
result = TRUE;
@@ -261,6 +272,26 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
wl_surface_attach (self->surface, NULL, 0, 0);
}
if (sib)
{
if (above)
wl_subsurface_place_above (self->subsurface, sib->surface);
else
wl_subsurface_place_below (self->subsurface, sib->surface);
self->above_parent = sib->above_parent;
}
else
{
if (above)
wl_subsurface_place_above (self->subsurface,
GDK_WAYLAND_SURFACE (sub->parent)->display_server.wl_surface);
else
wl_subsurface_place_below (self->subsurface,
GDK_WAYLAND_SURFACE (sub->parent)->display_server.wl_surface);
self->above_parent = above;
}
wl_surface_commit (self->surface);
((GdkWaylandSurface *)sub->parent)->has_pending_subsurface_commits = TRUE;
@@ -308,62 +339,6 @@ gdk_wayland_subsurface_get_rect (GdkSubsurface *sub,
rect->size.height = self->dest.height;
}
static void
gdk_wayland_subsurface_place_above (GdkSubsurface *sub,
GdkSubsurface *sibling)
{
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
GdkWaylandSubsurface *sib = sibling ? GDK_WAYLAND_SUBSURFACE (sibling) : NULL;
gboolean above_parent;
g_return_if_fail (sibling == NULL || sub->parent == sibling->parent);
if (sib)
{
wl_subsurface_place_above (self->subsurface, sib->surface);
above_parent = sib->above_parent;
}
else
{
wl_subsurface_place_above (self->subsurface,
GDK_WAYLAND_SURFACE (sub->parent)->display_server.wl_surface);
above_parent = TRUE;
}
if (self->above_parent != above_parent)
self->above_parent = above_parent;
((GdkWaylandSurface *)sub->parent)->has_pending_subsurface_commits = TRUE;
}
static void
gdk_wayland_subsurface_place_below (GdkSubsurface *sub,
GdkSubsurface *sibling)
{
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
GdkWaylandSubsurface *sib = sibling ? GDK_WAYLAND_SUBSURFACE (sibling) : NULL;
gboolean above_parent;
g_return_if_fail (sibling == NULL || sub->parent == sibling->parent);
if (sib)
{
wl_subsurface_place_below (self->subsurface, sib->surface);
above_parent = sib->above_parent;
}
else
{
wl_subsurface_place_below (self->subsurface,
GDK_WAYLAND_SURFACE (sub->parent)->display_server.wl_surface);
above_parent = FALSE;
}
if (self->above_parent != above_parent)
self->above_parent = above_parent;
((GdkWaylandSurface *)sub->parent)->has_pending_subsurface_commits = TRUE;
}
static gboolean
gdk_wayland_subsurface_is_above_parent (GdkSubsurface *sub)
{
@@ -384,8 +359,6 @@ gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class)
subsurface_class->detach = gdk_wayland_subsurface_detach;
subsurface_class->get_texture = gdk_wayland_subsurface_get_texture;
subsurface_class->get_rect = gdk_wayland_subsurface_get_rect;
subsurface_class->place_above = gdk_wayland_subsurface_place_above;
subsurface_class->place_below = gdk_wayland_subsurface_place_below;
subsurface_class->is_above_parent = gdk_wayland_subsurface_is_above_parent;
};

View File

@@ -588,8 +588,6 @@ gsk_offload_new (GdkSurface *surface,
info->subsurface = gdk_surface_get_subsurface (self->surface, i);
info->was_offloaded = gdk_subsurface_get_texture (info->subsurface) != NULL;
info->was_above = gdk_subsurface_is_above_parent (info->subsurface);
/* Stack them all below, initially */
gdk_subsurface_place_below (info->subsurface, NULL);
}
if (self->n_subsurfaces > 0)
@@ -609,12 +607,17 @@ gsk_offload_new (GdkSurface *surface,
if (info->can_offload)
{
info->is_offloaded = gdk_subsurface_attach (info->subsurface,
info->texture,
&info->rect);
if (info->place_above)
gdk_subsurface_place_above (info->subsurface, info->place_above);
if (info->can_raise)
info->is_offloaded = gdk_subsurface_attach (info->subsurface,
info->texture,
&info->rect,
TRUE, NULL);
else
info->is_offloaded = gdk_subsurface_attach (info->subsurface,
info->texture,
&info->rect,
info->place_above != NULL,
info->place_above);
}
else
{
@@ -626,10 +629,9 @@ gsk_offload_new (GdkSurface *surface,
}
}
if (info->can_raise)
if (info->is_offloaded && gdk_subsurface_is_above_parent (info->subsurface))
{
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Raising subsurface %p", info->subsurface);
gdk_subsurface_place_above (info->subsurface, NULL);
info->is_above = TRUE;
}
}