Merge branch 'subsurface-aboveness' into 'main'
offload: Keep was-raised for each subsurface Closes #6214 See merge request GNOME/gtk!6580
This commit is contained in:
@@ -53,7 +53,6 @@ struct _GskOffload
|
||||
Clip *current_clip;
|
||||
|
||||
GskOffloadInfo *last_info;
|
||||
gboolean can_raise;
|
||||
};
|
||||
|
||||
static GdkTexture *
|
||||
@@ -347,26 +346,31 @@ visit_node (GskOffload *self,
|
||||
{
|
||||
gboolean has_clip;
|
||||
|
||||
if (self->last_info && self->can_raise)
|
||||
for (gsize i = 0; i < self->n_subsurfaces; i++)
|
||||
{
|
||||
graphene_rect_t transformed_bounds;
|
||||
GskOffloadInfo *info = &self->subsurfaces[i];
|
||||
|
||||
transform_bounds (self, &node->bounds, &transformed_bounds);
|
||||
if (gsk_rect_intersects (&transformed_bounds, &self->last_info->rect))
|
||||
if (info->can_raise)
|
||||
{
|
||||
GskRenderNodeType type = GSK_RENDER_NODE_TYPE (node);
|
||||
graphene_rect_t transformed_bounds;
|
||||
|
||||
if (type != GSK_CONTAINER_NODE &&
|
||||
type != GSK_TRANSFORM_NODE &&
|
||||
type != GSK_CLIP_NODE &&
|
||||
type != GSK_ROUNDED_CLIP_NODE &&
|
||||
type != GSK_DEBUG_NODE)
|
||||
transform_bounds (self, &node->bounds, &transformed_bounds);
|
||||
if (gsk_rect_intersects (&transformed_bounds, &info->rect))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't raise subsurface %p because a %s overlaps",
|
||||
self->last_info->subsurface,
|
||||
g_type_name_from_instance ((GTypeInstance *) node));
|
||||
self->can_raise = FALSE;
|
||||
GskRenderNodeType type = GSK_RENDER_NODE_TYPE (node);
|
||||
|
||||
if (type != GSK_CONTAINER_NODE &&
|
||||
type != GSK_TRANSFORM_NODE &&
|
||||
type != GSK_CLIP_NODE &&
|
||||
type != GSK_ROUNDED_CLIP_NODE &&
|
||||
type != GSK_DEBUG_NODE)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't raise subsurface %p because a %s overlaps",
|
||||
info->subsurface,
|
||||
g_type_name_from_instance ((GTypeInstance *) node));
|
||||
info->can_raise = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -541,10 +545,10 @@ complex_clip:
|
||||
if (info->texture)
|
||||
{
|
||||
info->can_offload = TRUE;
|
||||
info->can_raise = TRUE;
|
||||
transform_bounds (self, &node->bounds, &info->rect);
|
||||
info->place_above = self->last_info ? self->last_info->subsurface : NULL;
|
||||
self->last_info = info;
|
||||
self->can_raise = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -583,6 +587,7 @@ gsk_offload_new (GdkSurface *surface,
|
||||
GskOffloadInfo *info = &self->subsurfaces[i];
|
||||
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);
|
||||
}
|
||||
@@ -620,12 +625,13 @@ gsk_offload_new (GdkSurface *surface,
|
||||
gdk_subsurface_detach (info->subsurface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self->can_raise && self->last_info)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Raising subsurface %p", self->last_info->subsurface);
|
||||
gdk_subsurface_place_above (self->last_info->subsurface, NULL);
|
||||
if (info->can_raise)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Raising subsurface %p", info->subsurface);
|
||||
gdk_subsurface_place_above (info->subsurface, NULL);
|
||||
info->is_above = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -644,27 +650,3 @@ gsk_offload_get_subsurface_info (GskOffload *self,
|
||||
{
|
||||
return find_subsurface_info (self, subsurface);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_offload_subsurface_was_offloaded (GskOffload *self,
|
||||
GdkSubsurface *subsurface)
|
||||
{
|
||||
GskOffloadInfo *info = find_subsurface_info (self, subsurface);
|
||||
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
return info->was_offloaded;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_offload_subsurface_is_offloaded (GskOffload *self,
|
||||
GdkSubsurface *subsurface)
|
||||
{
|
||||
GskOffloadInfo *info = find_subsurface_info (self, subsurface);
|
||||
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
return info->is_offloaded;
|
||||
}
|
||||
|
||||
@@ -32,9 +32,14 @@ typedef struct
|
||||
GdkTexture *texture;
|
||||
GdkSubsurface *place_above;
|
||||
graphene_rect_t rect;
|
||||
|
||||
guint was_offloaded : 1;
|
||||
guint can_offload : 1;
|
||||
guint is_offloaded : 1;
|
||||
|
||||
guint was_above : 1;
|
||||
guint can_raise : 1;
|
||||
guint is_above : 1;
|
||||
} GskOffloadInfo;
|
||||
|
||||
GskOffload * gsk_offload_new (GdkSurface *surface,
|
||||
@@ -43,10 +48,3 @@ void gsk_offload_free (GskOffload *self);
|
||||
|
||||
GskOffloadInfo * gsk_offload_get_subsurface_info (GskOffload *self,
|
||||
GdkSubsurface *subsurface);
|
||||
|
||||
gboolean gsk_offload_subsurface_was_offloaded (GskOffload *self,
|
||||
GdkSubsurface *subsurface);
|
||||
|
||||
gboolean gsk_offload_subsurface_is_offloaded (GskOffload *self,
|
||||
GdkSubsurface *subsurface);
|
||||
|
||||
|
||||
@@ -6717,27 +6717,37 @@ gsk_subsurface_node_diff (GskRenderNode *node1,
|
||||
{
|
||||
GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1;
|
||||
GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2;
|
||||
GskOffloadInfo *info1, *info2;
|
||||
|
||||
if (data->offload)
|
||||
if (!data->offload)
|
||||
{
|
||||
/* Include the full area if the offload status changed. */
|
||||
if (gsk_offload_subsurface_was_offloaded (data->offload, self1->subsurface) !=
|
||||
gsk_offload_subsurface_is_offloaded (data->offload, self1->subsurface))
|
||||
{
|
||||
gsk_render_node_diff_impossible (node1, node2, data);
|
||||
}
|
||||
else if (gsk_offload_subsurface_is_offloaded (data->offload, self1->subsurface))
|
||||
{
|
||||
if (!gsk_rect_equal (&node1->bounds, &node2->bounds))
|
||||
gsk_render_node_diff_impossible (node1, node2, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_render_node_data_diff (self1->child, self2->child, data);
|
||||
}
|
||||
gsk_render_node_data_diff (self1->child, self2->child, data);
|
||||
return;
|
||||
}
|
||||
|
||||
info1 = gsk_offload_get_subsurface_info (data->offload, self1->subsurface);
|
||||
info2 = gsk_offload_get_subsurface_info (data->offload, self2->subsurface);
|
||||
|
||||
if (!info1 || !info2)
|
||||
{
|
||||
gsk_render_node_data_diff (self1->child, self2->child, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info1->is_offloaded != info2->is_offloaded ||
|
||||
info1->is_above != info2->is_above)
|
||||
{
|
||||
gsk_render_node_diff_impossible (node1, node2, data);
|
||||
}
|
||||
else if (info1->is_offloaded && !info1->is_above &&
|
||||
!gsk_rect_equal (&info1->rect, &info2->rect))
|
||||
{
|
||||
gsk_render_node_diff_impossible (node1, node2, data);
|
||||
}
|
||||
else if (!info1->is_offloaded)
|
||||
{
|
||||
gsk_render_node_data_diff (self1->child, self2->child, data);
|
||||
}
|
||||
else
|
||||
gsk_render_node_data_diff (self1->child, self2->child, data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -192,7 +192,7 @@ collect_offload_info (GdkSurface *surface,
|
||||
|
||||
if (info->place_above)
|
||||
g_snprintf (above, sizeof (above), "%d",
|
||||
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (subsurface), "pos")));
|
||||
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info->place_above), "pos")));
|
||||
else
|
||||
g_snprintf (above, sizeof (above), "-");
|
||||
|
||||
@@ -488,6 +488,9 @@ parse_node_file (GFile *file, const char *generate)
|
||||
static gboolean
|
||||
test_file (GFile *file)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_test_message ("%s", g_file_peek_path (file));
|
||||
|
||||
return parse_node_file (file, FALSE);
|
||||
}
|
||||
|
||||
@@ -599,13 +602,27 @@ main (int argc, char **argv)
|
||||
|
||||
success = TRUE;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
if (argc > 1)
|
||||
{
|
||||
GFile *file = g_file_new_for_commandline_arg (argv[i]);
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
GFile *file = g_file_new_for_commandline_arg (argv[i]);
|
||||
|
||||
success &= test_file (file);
|
||||
success &= test_file (file);
|
||||
|
||||
g_object_unref (file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *basedir;
|
||||
GFile *dir;
|
||||
|
||||
basedir = g_test_get_dir (G_TEST_DIST);
|
||||
dir = g_file_new_for_path (basedir);
|
||||
success = test_files_in_directory (dir);
|
||||
|
||||
g_object_unref (dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
testsuite/gsk/offload/sidebyside.diff
Normal file
2
testsuite/gsk/offload/sidebyside.diff
Normal file
@@ -0,0 +1,2 @@
|
||||
0 0 30 10
|
||||
10 10 20 10
|
||||
20
testsuite/gsk/offload/sidebyside.node
Normal file
20
testsuite/gsk/offload/sidebyside.node
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
transform {
|
||||
transform: translate(0,0);
|
||||
child: subsurface {
|
||||
child: texture {
|
||||
bounds: 0 0 10 10;
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="10" height="10"></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transform {
|
||||
transform: translate(10,0);
|
||||
child: subsurface {
|
||||
child: texture {
|
||||
bounds: 0 0 20 20;
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="20" height="20"></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
20
testsuite/gsk/offload/sidebyside.node2
Normal file
20
testsuite/gsk/offload/sidebyside.node2
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
transform {
|
||||
transform: translate(10, 10);
|
||||
child: subsurface {
|
||||
child: texture {
|
||||
bounds: 0 0 10 10;
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="10" height="10"></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transform {
|
||||
transform: translate(10,0);
|
||||
child: subsurface {
|
||||
child: texture {
|
||||
bounds: 0 0 20 20;
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="20" height="20"></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
2
testsuite/gsk/offload/sidebyside.offload
Normal file
2
testsuite/gsk/offload/sidebyside.offload
Normal file
@@ -0,0 +1,2 @@
|
||||
0: offloaded, raised, above: -, texture: 10x10, rect: 0 0 10 10
|
||||
1: offloaded, raised, above: 0, texture: 20x20, rect: 10 0 20 20
|
||||
2
testsuite/gsk/offload/sidebyside.offload2
Normal file
2
testsuite/gsk/offload/sidebyside.offload2
Normal file
@@ -0,0 +1,2 @@
|
||||
0: offloaded, above: -, texture: 10x10, rect: 10 10 10 10
|
||||
1: offloaded, raised, above: 0, texture: 20x20, rect: 10 0 20 20
|
||||
@@ -1,3 +1,3 @@
|
||||
0: offloaded, above: -, texture: 13x17, rect: 20 20 50 50
|
||||
1: offloaded, raised, above: 1, texture: 10x21, rect: 0 100 500 500
|
||||
1: offloaded, raised, above: 0, texture: 10x21, rect: 0 100 500 500
|
||||
2: not offloaded
|
||||
|
||||
Reference in New Issue
Block a user