offload: Support dihedral transforms

When looking for the texture transform, allow dihedral transforms,
and pass them along when attaching to the subsurface.
This commit is contained in:
Matthias Clasen 2024-07-09 22:22:01 -04:00 committed by Benjamin Otte
parent a4a7255216
commit 4d2884bde7

View File

@ -25,7 +25,7 @@
#include "gskrendernode.h"
#include "gskrectprivate.h"
#include "gskroundedrectprivate.h"
#include "gsktransform.h"
#include "gsktransformprivate.h"
#include "gskdebugprivate.h"
#include "gskrendernodeprivate.h"
#include "gdksurfaceprivate.h"
@ -59,26 +59,14 @@ struct _GskOffload
static GdkDihedral
find_texture_transform (GskTransform *transform)
{
GdkDihedral dihedral;
float sx, sy, dx, dy;
g_assert (gsk_transform_get_category (transform) >= GSK_TRANSFORM_CATEGORY_2D_AFFINE);
g_assert (gsk_transform_get_fine_category (transform) >= GSK_FINE_TRANSFORM_CATEGORY_2D_DIHEDRAL);
gsk_transform_to_affine (transform, &sx, &sy, &dx, &dy);
gsk_transform_to_dihedral (transform, &dihedral, &sx, &sy, &dx, &dy);
if (sx > 0)
{
if (sy > 0)
return GDK_DIHEDRAL_NORMAL;
else
return GDK_DIHEDRAL_FLIPPED_180;
}
else
{
if (sy > 0)
return GDK_DIHEDRAL_FLIPPED;
else
return GDK_DIHEDRAL_180;
}
return dihedral;
}
static GdkTexture *
@ -145,11 +133,11 @@ find_texture_to_attach (GskOffload *self,
{
GskTransform *t = gsk_transform_node_get_transform (node);
if (gsk_transform_get_category (t) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
if (gsk_transform_get_fine_category (t) < GSK_FINE_TRANSFORM_CATEGORY_2D_DIHEDRAL)
{
char *s = gsk_transform_to_string (t);
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
"[%p] 🗙 Transform %s is not just scale/translate",
"[%p] 🗙 Transform %s is not dihedral",
subsurface, s);
g_free (s);
goto out;
@ -195,25 +183,36 @@ find_texture_to_attach (GskOffload *self,
case GSK_TEXTURE_NODE:
{
GdkTexture *texture = gsk_texture_node_get_texture (node);
int width, height;
if (gsk_transform_get_category (transform) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
if (gsk_transform_get_fine_category (transform) < GSK_FINE_TRANSFORM_CATEGORY_2D_DIHEDRAL)
{
char *s = gsk_transform_to_string (transform);
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
"[%p] 🗙 Transform %s is not just scale/translate",
"[%p] 🗙 Transform %s is not dihedral",
subsurface, s);
g_free (s);
goto out;
}
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
*out_texture_transform = find_texture_transform (transform);
if (gdk_dihedral_swaps_xy (*out_texture_transform))
{
int tmp = width;
width = height;
height = tmp;
}
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;
float sx = width / node->bounds.size.width;
float sy = height / node->bounds.size.height;
gsk_rect_intersection (&node->bounds, &clip, &clip);
@ -227,8 +226,8 @@ find_texture_to_attach (GskOffload *self,
gsk_transform_transform_bounds (transform, &node->bounds, out_texture_rect);
out_source_rect->origin.x = 0;
out_source_rect->origin.y = 0;
out_source_rect->size.width = gdk_texture_get_width (texture);
out_source_rect->size.height = gdk_texture_get_height (texture);
out_source_rect->size.width = width;
out_source_rect->size.height = height;
}
ret = texture;
@ -293,13 +292,16 @@ transform_rounded_rect (GskOffload *self,
GskRoundedRect *out_rect)
{
GskTransform *t = self->transforms ? self->transforms->data : NULL;
GdkDihedral dihedral;
float sx, sy, dx, dy;
GskRoundedRect tmp;
if (gsk_transform_get_category (t) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
if (gsk_transform_get_fine_category (t) < GSK_FINE_TRANSFORM_CATEGORY_2D_DIHEDRAL)
return FALSE;
gsk_transform_to_affine (t, &sx, &sy, &dx, &dy);
gsk_rounded_rect_scale_affine (out_rect, rect, sx, sy, dx, dy);
gsk_transform_to_dihedral (t, &dihedral, &sx, &sy, &dx, &dy);
gsk_rounded_rect_dihedral (&tmp, rect, dihedral);
gsk_rounded_rect_scale_affine (out_rect, &tmp, sx, sy, dx, dy);
return TRUE;
}
@ -587,7 +589,7 @@ visit_node (GskOffload *self,
if (!transform_rounded_rect (self, clip, &transformed_clip))
{
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
"🗙 Non-affine transform, giving up");
"🗙 Non-dihedral transform, giving up");
}
else if (self->current_clip->is_rectilinear)
{
@ -656,10 +658,10 @@ complex_clip:
"[%p] 🗙 Clipped",
subsurface);
}
else if (gsk_transform_get_category (transform) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
else if (gsk_transform_get_fine_category (transform) < GSK_FINE_TRANSFORM_CATEGORY_2D_DIHEDRAL)
{
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
"[%p] 🗙 Non-affine transform",
"[%p] 🗙 Non-dihedral transform",
subsurface);
}
else