mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-19 21:40:22 +00:00
offload: Find and use source rectangle
Look for nodes like subsurface { clip { texture {} } }, and use the clip to provide a source rectangle for subsetting the texture. Update affected tests, and add a new one.
This commit is contained in:
parent
9a30ea1f69
commit
1db696be79
@ -58,8 +58,12 @@ struct _GskOffload
|
||||
static GdkTexture *
|
||||
find_texture_to_attach (GskOffload *self,
|
||||
GdkSubsurface *subsurface,
|
||||
const GskRenderNode *node)
|
||||
const GskRenderNode *node,
|
||||
graphene_rect_t *out_clip)
|
||||
{
|
||||
gboolean has_clip = FALSE;
|
||||
graphene_rect_t clip;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
switch ((int)GSK_RENDER_NODE_TYPE (node))
|
||||
@ -82,6 +86,7 @@ find_texture_to_attach (GskOffload *self,
|
||||
case GSK_TRANSFORM_NODE:
|
||||
{
|
||||
GskTransform *t = gsk_transform_node_get_transform (node);
|
||||
|
||||
if (gsk_transform_get_category (t) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
|
||||
{
|
||||
char *s = gsk_transform_to_string (t);
|
||||
@ -91,12 +96,69 @@ find_texture_to_attach (GskOffload *self,
|
||||
g_free (s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (has_clip)
|
||||
{
|
||||
GskTransform *inv = gsk_transform_invert (gsk_transform_ref (t));
|
||||
gsk_transform_transform_bounds (inv, &clip, &clip);
|
||||
gsk_transform_unref (inv);
|
||||
}
|
||||
|
||||
node = gsk_transform_node_get_child (node);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case GSK_CLIP_NODE:
|
||||
{
|
||||
const graphene_rect_t *c = gsk_clip_node_get_clip (node);
|
||||
|
||||
if (has_clip)
|
||||
{
|
||||
if (!gsk_rect_intersection (c, &clip, &clip))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't offload subsurface %p: empty clip", subsurface);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clip = *c;
|
||||
has_clip = TRUE;
|
||||
}
|
||||
|
||||
node = gsk_clip_node_get_child (node);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_TEXTURE_NODE:
|
||||
return gsk_texture_node_get_texture (node);
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_node_get_texture (node);
|
||||
|
||||
if (has_clip)
|
||||
{
|
||||
float dx = node->bounds.origin.x;
|
||||
float dy = node->bounds.origin.y;
|
||||
float sx = gdk_texture_get_width (texture) / node->bounds.size.width;
|
||||
float sy = gdk_texture_get_height (texture) / node->bounds.size.height;
|
||||
|
||||
gsk_rect_intersection (&node->bounds, &clip, &clip);
|
||||
|
||||
out_clip->origin.x = (clip.origin.x - dx) * sx;
|
||||
out_clip->origin.y = (clip.origin.y - dy) * sy;
|
||||
out_clip->size.width = clip.size.width * sx;
|
||||
out_clip->size.height = clip.size.height * sy;
|
||||
}
|
||||
else
|
||||
{
|
||||
out_clip->origin.x = 0;
|
||||
out_clip->origin.y = 0;
|
||||
out_clip->size.width = gdk_texture_get_width (texture);
|
||||
out_clip->size.height = gdk_texture_get_height (texture);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
default:
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
@ -513,15 +575,14 @@ complex_clip:
|
||||
}
|
||||
else
|
||||
{
|
||||
info->texture = find_texture_to_attach (self, subsurface, gsk_subsurface_node_get_child (node));
|
||||
graphene_rect_t clip;
|
||||
|
||||
info->texture = find_texture_to_attach (self, subsurface, gsk_subsurface_node_get_child (node), &clip);
|
||||
if (info->texture)
|
||||
{
|
||||
info->can_offload = TRUE;
|
||||
info->can_raise = TRUE;
|
||||
graphene_rect_init (&info->source,
|
||||
0, 0,
|
||||
gdk_texture_get_width (info->texture),
|
||||
gdk_texture_get_height (info->texture));
|
||||
info->source = clip;
|
||||
transform_bounds (self, &node->bounds, &info->dest);
|
||||
info->place_above = self->last_info ? self->last_info->subsurface : NULL;
|
||||
self->last_info = info;
|
||||
|
@ -428,6 +428,8 @@ if os_linux
|
||||
'move.node',
|
||||
'start_offloading.node',
|
||||
'stop_offloading.node',
|
||||
'source.node',
|
||||
'nested.node',
|
||||
]
|
||||
|
||||
foreach test : offload_tests
|
||||
|
@ -209,6 +209,9 @@ collect_offload_info (GdkSurface *surface,
|
||||
g_string_append_printf (s, "texture: %dx%d, ",
|
||||
gdk_texture_get_width (info->texture),
|
||||
gdk_texture_get_height (info->texture));
|
||||
g_string_append_printf (s, "source: %g %g %g %g, ",
|
||||
info->source.origin.x, info->source.origin.y,
|
||||
info->source.size.width, info->source.size.height);
|
||||
g_string_append_printf (s, "dest: %g %g %g %g\n",
|
||||
info->dest.origin.x, info->dest.origin.y,
|
||||
info->dest.size.width, info->dest.size.height);
|
||||
|
@ -1,6 +1,6 @@
|
||||
0: offloaded, above: -, texture: 10x10, dest: 10 10 250 500
|
||||
0: offloaded, above: -, texture: 10x10, source: 0 0 10 10, dest: 10 10 250 500
|
||||
1: not offloaded
|
||||
2: not offloaded
|
||||
3: not offloaded
|
||||
4: not offloaded
|
||||
4: offloaded, above: 0, texture: 10x10, source: 0 0 10 10, dest: 0 0 50 50
|
||||
5: not offloaded
|
||||
|
0
testsuite/gsk/offload/deep.offload2
Normal file
0
testsuite/gsk/offload/deep.offload2
Normal file
@ -1 +1 @@
|
||||
0: offloaded, raised, above: -, texture: 16x16, dest: 20 20 16 16
|
||||
0: offloaded, raised, above: -, texture: 16x16, source: 0 0 16 16, dest: 20 20 16 16
|
||||
|
@ -1 +1 @@
|
||||
0: offloaded, raised, above: -, texture: 16x16, dest: 40 40 20 20
|
||||
0: offloaded, raised, above: -, texture: 16x16, source: 0 0 16 16, dest: 40 40 20 20
|
||||
|
38
testsuite/gsk/offload/nested.node
Normal file
38
testsuite/gsk/offload/nested.node
Normal file
@ -0,0 +1,38 @@
|
||||
subsurface {
|
||||
child: transform {
|
||||
transform: translate(0,100);
|
||||
child: transform {
|
||||
transform: scale(10, 10);
|
||||
child: texture {
|
||||
bounds: 0 0 10 21;
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="10" height="21"></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subsurface {
|
||||
child: clip {
|
||||
clip: 0 0 20 20;
|
||||
child: clip {
|
||||
clip: 5 5 200 200;
|
||||
child: texture {
|
||||
bounds: 0 0 40 40;
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="40" height="40"></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subsurface {
|
||||
child: clip {
|
||||
clip: 0 0 20 20;
|
||||
child: transform {
|
||||
transform: translate(10, 10);
|
||||
child: texture {
|
||||
bounds: 0 0 40 40;
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="40" height="40"></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
testsuite/gsk/offload/nested.offload
Normal file
3
testsuite/gsk/offload/nested.offload
Normal file
@ -0,0 +1,3 @@
|
||||
0: offloaded, raised, above: -, texture: 10x21, source: 0 0 10 21, dest: 0 100 100 210
|
||||
1: offloaded, raised, above: 0, texture: 40x40, source: 5 5 15 15, dest: 5 5 15 15
|
||||
2: offloaded, raised, above: 1, texture: 40x40, source: 0 0 10 10, dest: 10 10 10 10
|
@ -1,2 +1,2 @@
|
||||
0: offloaded, raised, above: -, texture: 10x10, dest: 0 0 10 10
|
||||
1: offloaded, raised, above: 0, texture: 20x20, dest: 10 0 20 20
|
||||
0: offloaded, raised, above: -, texture: 10x10, source: 0 0 10 10, dest: 0 0 10 10
|
||||
1: offloaded, raised, above: 0, texture: 20x20, source: 0 0 20 20, dest: 10 0 20 20
|
||||
|
@ -1,2 +1,2 @@
|
||||
0: offloaded, above: -, texture: 10x10, dest: 10 10 10 10
|
||||
1: offloaded, raised, above: 0, texture: 20x20, dest: 10 0 20 20
|
||||
0: offloaded, above: -, texture: 10x10, source: 0 0 10 10, dest: 10 10 10 10
|
||||
1: offloaded, raised, above: 0, texture: 20x20, 0 0 20 20, dest: 10 0 20 20
|
||||
|
@ -1,3 +1,3 @@
|
||||
0: offloaded, above: -, texture: 13x17, dest: 20 20 50 50
|
||||
1: offloaded, raised, above: 0, texture: 10x21, dest: 0 100 500 500
|
||||
0: offloaded, above: -, texture: 13x17, source: 0 0 13 17, dest: 20 20 50 50
|
||||
1: offloaded, raised, above: 0, texture: 10x21, source: 0 0 10 21, dest: 0 100 500 500
|
||||
2: not offloaded
|
||||
|
12
testsuite/gsk/offload/source.node
Normal file
12
testsuite/gsk/offload/source.node
Normal file
@ -0,0 +1,12 @@
|
||||
subsurface {
|
||||
child: transform {
|
||||
transform: scale(1);
|
||||
child: clip {
|
||||
clip: 4 4 40 40;
|
||||
child: texture {
|
||||
bounds: 0 0 48 48;
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="24" height="24"></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1
testsuite/gsk/offload/source.offload
Normal file
1
testsuite/gsk/offload/source.offload
Normal file
@ -0,0 +1 @@
|
||||
0: offloaded, raised, above: -, texture: 24x24, source: 2 2 20 20, dest: 4 4 40 40
|
@ -2,7 +2,7 @@ subsurface {
|
||||
child: clip {
|
||||
clip: 0 0 200 200;
|
||||
child: transform {
|
||||
transform: translate(16, 16);
|
||||
transform: rotate(4);
|
||||
child: texture {
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="16" height="16"></svg>');
|
||||
bounds: 0 0 16 16;
|
||||
|
@ -1,6 +1,12 @@
|
||||
subsurface {
|
||||
child: texture {
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="16" height="16"></svg>');
|
||||
bounds: 0 0 16 16;
|
||||
child: clip {
|
||||
clip: 0 0 200 200;
|
||||
child: transform {
|
||||
transform: translate(16, 16);
|
||||
child: texture {
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="16" height="16"></svg>');
|
||||
bounds: 0 0 16 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
0: offloaded, raised, above: -, texture: 16x16, dest: 0 0 16 16
|
||||
0: offloaded, raised, above: -, texture: 16x16, source: 0 0 16 16, dest: 16 16 16 16
|
||||
|
@ -1,2 +1 @@
|
||||
0 0 16 16
|
||||
16 16 16 16
|
||||
15 16 17 17
|
||||
|
@ -1,6 +1,12 @@
|
||||
subsurface {
|
||||
child: texture {
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="16" height="16"></svg>');
|
||||
bounds: 0 0 16 16;
|
||||
child: clip {
|
||||
clip: 0 0 200 200;
|
||||
child: transform {
|
||||
transform: translate(16, 16);
|
||||
child: texture {
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="16" height="16"></svg>');
|
||||
bounds: 0 0 16 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ subsurface {
|
||||
child: clip {
|
||||
clip: 0 0 200 200;
|
||||
child: transform {
|
||||
transform: translate(16, 16);
|
||||
transform: translate(16, 16) rotate(2);
|
||||
child: texture {
|
||||
texture: url('data:image/svg+xml;utf-8,<svg width="16" height="16"></svg>');
|
||||
bounds: 0 0 16 16;
|
||||
|
@ -1 +1 @@
|
||||
0: offloaded, raised, above: -, texture: 16x16, dest: 0 0 16 16
|
||||
0: offloaded, raised, above: -, texture: 16x16, source: 0 0 16 16, dest: 16 16 16 16
|
||||
|
@ -1,3 +1,3 @@
|
||||
0: not offloaded
|
||||
1: not offloaded
|
||||
2: offloaded, raised, above: -, texture: 16x16, dest: 1 2 50 50
|
||||
2: offloaded, raised, above: -, texture: 16x16, source: 0 0 16 16, dest: 1 2 50 50
|
||||
|
Loading…
Reference in New Issue
Block a user