Compare commits

...

1 Commits

Author SHA1 Message Date
Matthias Clasen
87c4262bd9 wip: Add lightboxes to graphics offload
Add GTK_GRAHPICS_OFFLOAD_ENABLED_WITH_LIGHTBOX, and pass that
on to the subsurface.
2024-04-09 18:05:49 -04:00
9 changed files with 77 additions and 17 deletions

View File

@@ -114,6 +114,7 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
const graphene_rect_t *source,
const graphene_rect_t *dest,
GdkTextureTransform transform,
gboolean lightbox,
gboolean above,
GdkSubsurface *sibling)
{
@@ -156,7 +157,7 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
}
}
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, source, dest, transform, above, sibling);
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, source, dest, transform, lightbox, above, sibling);
}
void
@@ -213,3 +214,10 @@ gdk_subsurface_get_transform (GdkSubsurface *subsurface)
return GDK_SUBSURFACE_GET_CLASS (subsurface)->get_transform (subsurface);
}
gboolean
gdk_subsurface_get_lightbox (GdkSubsurface *subsurface)
{
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), FALSE);
return GDK_SUBSURFACE_GET_CLASS (subsurface)->get_lightbox (subsurface);
}

View File

@@ -67,6 +67,7 @@ struct _GdkSubsurfaceClass
const graphene_rect_t *source,
const graphene_rect_t *dest,
GdkTextureTransform transform,
gboolean lightbox,
gboolean above,
GdkSubsurface *sibling);
void (* detach) (GdkSubsurface *subsurface);
@@ -77,6 +78,7 @@ struct _GdkSubsurfaceClass
graphene_rect_t *dest);
GdkTextureTransform
(* get_transform) (GdkSubsurface *subsurface);
gboolean (* get_lightbox) (GdkSubsurface *subsurface);
};
GType gdk_subsurface_get_type (void) G_GNUC_CONST;
@@ -88,6 +90,7 @@ gboolean gdk_subsurface_attach (GdkSubsurface *subsurfac
const graphene_rect_t *source,
const graphene_rect_t *dest,
GdkTextureTransform transform,
gboolean lightbox,
gboolean above,
GdkSubsurface *sibling);
void gdk_subsurface_detach (GdkSubsurface *subsurface);
@@ -99,6 +102,7 @@ void gdk_subsurface_get_dest (GdkSubsurface *subsurfac
gboolean gdk_subsurface_is_above_parent (GdkSubsurface *subsurface);
GdkTextureTransform
gdk_subsurface_get_transform (GdkSubsurface *subsurface);
gboolean gdk_subsurface_get_lightbox (GdkSubsurface *subsurface);
G_END_DECLS

View File

@@ -25,6 +25,7 @@ struct _GdkWaylandSubsurface
cairo_rectangle_int_t dest;
graphene_rect_t source;
enum wl_output_transform transform;
gboolean lightbox;
struct wl_region *opaque_region;

View File

@@ -168,6 +168,7 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
const graphene_rect_t *dest,
GdkTextureTransform transform,
gboolean above,
gboolean lightbox,
GdkSubsurface *sibling)
{
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
@@ -202,6 +203,7 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
self->source.size.height = source->size.height;
self->transform = gdk_texture_transform_to_wl (transform);
self->lightbox = lightbox;
scale = gdk_fractional_scale_to_double (&parent->scale);
@@ -430,6 +432,14 @@ gdk_wayland_subsurface_get_transform (GdkSubsurface *sub)
return wl_output_transform_to_gdk (self->transform);
}
static gboolean
gdk_wayland_subsurface_get_lightbox (GdkSubsurface *sub)
{
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
return self->lightbox;
}
static void
gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class)
{
@@ -444,6 +454,7 @@ gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class)
subsurface_class->get_source = gdk_wayland_subsurface_get_source;
subsurface_class->get_dest = gdk_wayland_subsurface_get_dest;
subsurface_class->get_transform = gdk_wayland_subsurface_get_transform;
subsurface_class->get_lightbox = gdk_wayland_subsurface_get_lightbox;
};
static void

View File

@@ -82,34 +82,59 @@ find_texture_transform (GskTransform *transform)
static GdkTexture *
find_texture_to_attach (GskOffload *self,
GdkSubsurface *subsurface,
const GskRenderNode *node,
const GskRenderNode *subsurface_node,
graphene_rect_t *out_clip,
GdkTextureTransform *out_texture_transform)
GdkTextureTransform *out_texture_transform,
gboolean *out_lightbox)
{
GdkSubsurface *subsurface;
const GskRenderNode *node;
gboolean has_clip = FALSE;
graphene_rect_t clip;
GskTransform *transform = NULL;
GdkTexture *ret = NULL;
*out_texture_transform = GDK_TEXTURE_TRANSFORM_NORMAL;
*out_lightbox = FALSE;
subsurface = gsk_subsurface_node_get_subsurface (subsurface_node);
node = subsurface_node;
for (;;)
{
switch ((int) GSK_RENDER_NODE_TYPE (node))
{
case GSK_DEBUG_NODE:
case GSK_SUBSURFACE_NODE:
node = gsk_debug_node_get_child (node);
break;
case GSK_CONTAINER_NODE:
if (gsk_container_node_get_n_children (node) != 1)
if (gsk_container_node_get_n_children (node) == 1)
{
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
"Can't offload subsurface %p: too much content, container with %d children",
subsurface, gsk_container_node_get_n_children (node));
goto out;
node = gsk_container_node_get_child (node, 0);
break;
}
node = gsk_container_node_get_child (node, 0);
break;
else if (gsk_container_node_get_n_children (node) == 2)
{
GskRenderNode *child;
child = gsk_container_node_get_child (node, 0);
if (GSK_RENDER_NODE_TYPE (child) == GSK_COLOR_NODE &&
gsk_rect_equal (&child->bounds, &subsurface_node->bounds) &&
gdk_rgba_equal (gsk_color_node_get_color (child), &(GdkRGBA) { 0, 0, 0, 1 }))
{
g_print ("found lightbox\n");
*out_lightbox = TRUE;
node = gsk_container_node_get_child (node, 1);
break;
}
}
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
"Can't offload subsurface %p: too much content, container with %d children",
subsurface, gsk_container_node_get_n_children (node));
goto out;
case GSK_TRANSFORM_NODE:
{
@@ -615,7 +640,7 @@ complex_clip:
}
else
{
info->texture = find_texture_to_attach (self, subsurface, gsk_subsurface_node_get_child (node), &info->source, &info->transform);
info->texture = find_texture_to_attach (self, node, &info->source, &info->transform, &info->lightbox);
if (info->texture)
{
info->can_offload = TRUE;
@@ -691,6 +716,7 @@ gsk_offload_new (GdkSurface *surface,
&info->source,
&info->dest,
info->transform,
info->lightbox,
TRUE, NULL);
else
info->is_offloaded = gdk_subsurface_attach (info->subsurface,
@@ -698,6 +724,7 @@ gsk_offload_new (GdkSurface *surface,
&info->source,
&info->dest,
info->transform,
info->lightbox,
info->place_above != NULL,
info->place_above);
}

View File

@@ -34,6 +34,7 @@ typedef struct
graphene_rect_t dest;
graphene_rect_t source;
GdkTextureTransform transform;
gboolean lightbox;
guint was_offloaded : 1;
guint can_offload : 1;

View File

@@ -208,6 +208,13 @@ gtk_graphics_offload_snapshot (GtkWidget *widget,
if (self->subsurface)
gtk_snapshot_push_subsurface (snapshot, self->subsurface);
if (self->enabled == GTK_GRAPHICS_OFFLOAD_ENABLED_WITH_LIGHTBOX)
gtk_snapshot_append_color (snapshot,
&(GdkRGBA) { 0, 0, 0, 1 },
&GRAPHENE_RECT_INIT (0, 0,
gtk_widget_get_width (widget),
gtk_widget_get_height (widget)));
gtk_widget_snapshot_child (widget, self->child, snapshot);
if (self->subsurface)

View File

@@ -57,6 +57,7 @@ typedef enum
{
GTK_GRAPHICS_OFFLOAD_ENABLED,
GTK_GRAPHICS_OFFLOAD_DISABLED,
GTK_GRAPHICS_OFFLOAD_ENABLED_WITH_LIGHTBOX,
} GtkGraphicsOffloadEnabled;
GDK_AVAILABLE_IN_4_14

View File

@@ -42,9 +42,9 @@ test_subsurface_stacking (void)
texture = gdk_texture_new_from_resource ("/org/gtk/libgtk/icons/16x16/actions/media-eject.png");
gdk_subsurface_attach (sub0, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, TRUE, NULL);
gdk_subsurface_attach (sub1, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, TRUE, NULL);
gdk_subsurface_attach (sub2, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, TRUE, NULL);
gdk_subsurface_attach (sub0, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, FALSE, TRUE, NULL);
gdk_subsurface_attach (sub1, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, FALSE, TRUE, NULL);
gdk_subsurface_attach (sub2, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, FALSE, TRUE, NULL);
g_assert_true (surface->subsurfaces_above == sub2);
g_assert_true (sub2->sibling_below == NULL);
@@ -67,7 +67,7 @@ test_subsurface_stacking (void)
g_assert_true (sub0->sibling_above == NULL);
g_assert_true (sub0->above_parent);
gdk_subsurface_attach (sub2, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, FALSE, NULL);
gdk_subsurface_attach (sub2, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, FALSE, FALSE, NULL);
g_assert_true (surface->subsurfaces_above == sub0);
g_assert_true (sub0->sibling_below == NULL);
@@ -79,7 +79,7 @@ test_subsurface_stacking (void)
g_assert_true (sub2->sibling_above == NULL);
g_assert_false (sub2->above_parent);
gdk_subsurface_attach (sub1, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, TRUE, sub2);
gdk_subsurface_attach (sub1, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, FALSE, TRUE, sub2);
g_assert_true (surface->subsurfaces_below == sub1);
g_assert_true (sub1->sibling_above == NULL);