shaped-texture: Use surface coordinates in get_image()
There were multiple bugs present after the ClutterContent transition. Refactor `get_image` to: - always assume surface coordinates for the clip - return a cairo_surface in buffer size - make the offscreen path take size arguments, so we can easily change the assumption in get_image - fix some clipping bugs on the way https://gitlab.gnome.org/GNOME/mutter/merge_requests/758
This commit is contained in:
parent
1d2913d9b9
commit
cd70595b50
@ -1114,7 +1114,9 @@ should_get_via_offscreen (MetaShapedTexture *stex)
|
|||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
get_image_via_offscreen (MetaShapedTexture *stex,
|
get_image_via_offscreen (MetaShapedTexture *stex,
|
||||||
cairo_rectangle_int_t *clip)
|
cairo_rectangle_int_t *clip,
|
||||||
|
int image_width,
|
||||||
|
int image_height)
|
||||||
{
|
{
|
||||||
g_autoptr (ClutterPaintNode) root_node = NULL;
|
g_autoptr (ClutterPaintNode) root_node = NULL;
|
||||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||||
@ -1132,16 +1134,16 @@ get_image_via_offscreen (MetaShapedTexture *stex,
|
|||||||
if (!clip)
|
if (!clip)
|
||||||
{
|
{
|
||||||
fallback_clip = (cairo_rectangle_int_t) {
|
fallback_clip = (cairo_rectangle_int_t) {
|
||||||
.width = stex->dst_width,
|
.width = image_width,
|
||||||
.height = stex->dst_height,
|
.height = image_height,
|
||||||
};
|
};
|
||||||
clip = &fallback_clip;
|
clip = &fallback_clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
image_texture =
|
image_texture =
|
||||||
COGL_TEXTURE (cogl_texture_2d_new_with_size (cogl_context,
|
COGL_TEXTURE (cogl_texture_2d_new_with_size (cogl_context,
|
||||||
stex->dst_width,
|
image_width,
|
||||||
stex->dst_height));
|
image_height));
|
||||||
cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (image_texture),
|
cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (image_texture),
|
||||||
FALSE);
|
FALSE);
|
||||||
if (!cogl_texture_allocate (COGL_TEXTURE (image_texture), &error))
|
if (!cogl_texture_allocate (COGL_TEXTURE (image_texture), &error))
|
||||||
@ -1164,11 +1166,11 @@ get_image_via_offscreen (MetaShapedTexture *stex,
|
|||||||
cogl_framebuffer_push_matrix (fb);
|
cogl_framebuffer_push_matrix (fb);
|
||||||
cogl_matrix_init_identity (&projection_matrix);
|
cogl_matrix_init_identity (&projection_matrix);
|
||||||
cogl_matrix_scale (&projection_matrix,
|
cogl_matrix_scale (&projection_matrix,
|
||||||
1.0 / (stex->dst_width / 2.0),
|
1.0 / (image_width / 2.0),
|
||||||
-1.0 / (stex->dst_height / 2.0), 0);
|
-1.0 / (image_height / 2.0), 0);
|
||||||
cogl_matrix_translate (&projection_matrix,
|
cogl_matrix_translate (&projection_matrix,
|
||||||
-(stex->dst_width / 2.0),
|
-(image_width / 2.0),
|
||||||
-(stex->dst_height / 2.0), 0);
|
-(image_height / 2.0), 0);
|
||||||
|
|
||||||
cogl_framebuffer_set_projection_matrix (fb, &projection_matrix);
|
cogl_framebuffer_set_projection_matrix (fb, &projection_matrix);
|
||||||
|
|
||||||
@ -1180,8 +1182,9 @@ get_image_via_offscreen (MetaShapedTexture *stex,
|
|||||||
do_paint_content (stex, root_node,
|
do_paint_content (stex, root_node,
|
||||||
stex->texture,
|
stex->texture,
|
||||||
&(ClutterActorBox) {
|
&(ClutterActorBox) {
|
||||||
clip->x, clip->y,
|
0, 0,
|
||||||
clip->width, clip->height,
|
image_width,
|
||||||
|
image_height,
|
||||||
},
|
},
|
||||||
255);
|
255);
|
||||||
|
|
||||||
@ -1219,7 +1222,7 @@ cairo_surface_t *
|
|||||||
meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
||||||
cairo_rectangle_int_t *clip)
|
cairo_rectangle_int_t *clip)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t *transformed_clip = NULL;
|
cairo_rectangle_int_t *image_clip = NULL;
|
||||||
CoglTexture *texture, *mask_texture;
|
CoglTexture *texture, *mask_texture;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
@ -1239,31 +1242,43 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
|||||||
{
|
{
|
||||||
cairo_rectangle_int_t dst_rect;
|
cairo_rectangle_int_t dst_rect;
|
||||||
|
|
||||||
transformed_clip = alloca (sizeof (cairo_rectangle_int_t));
|
image_clip = alloca (sizeof (cairo_rectangle_int_t));
|
||||||
|
|
||||||
meta_rectangle_scale_double (clip, stex->buffer_scale,
|
|
||||||
META_ROUNDING_STRATEGY_GROW,
|
|
||||||
transformed_clip);
|
|
||||||
|
|
||||||
dst_rect = (cairo_rectangle_int_t) {
|
dst_rect = (cairo_rectangle_int_t) {
|
||||||
.width = stex->dst_width,
|
.width = stex->dst_width,
|
||||||
.height = stex->dst_height,
|
.height = stex->dst_height,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!meta_rectangle_intersect (&dst_rect, transformed_clip,
|
if (!meta_rectangle_intersect (&dst_rect, clip,
|
||||||
transformed_clip))
|
image_clip))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
*image_clip = (MetaRectangle) {
|
||||||
|
.x = image_clip->x * stex->buffer_scale,
|
||||||
|
.y = image_clip->y * stex->buffer_scale,
|
||||||
|
.width = image_clip->width * stex->buffer_scale,
|
||||||
|
.height = image_clip->height * stex->buffer_scale,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_get_via_offscreen (stex))
|
if (should_get_via_offscreen (stex))
|
||||||
return get_image_via_offscreen (stex, transformed_clip);
|
{
|
||||||
|
int image_width;
|
||||||
|
int image_height;
|
||||||
|
|
||||||
if (transformed_clip)
|
image_width = stex->dst_width * stex->buffer_scale;
|
||||||
|
image_height = stex->dst_height * stex->buffer_scale;
|
||||||
|
return get_image_via_offscreen (stex,
|
||||||
|
image_clip,
|
||||||
|
image_width,
|
||||||
|
image_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image_clip)
|
||||||
texture = cogl_texture_new_from_sub_texture (texture,
|
texture = cogl_texture_new_from_sub_texture (texture,
|
||||||
transformed_clip->x,
|
image_clip->x,
|
||||||
transformed_clip->y,
|
image_clip->y,
|
||||||
transformed_clip->width,
|
image_clip->width,
|
||||||
transformed_clip->height);
|
image_clip->height);
|
||||||
|
|
||||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||||
cogl_texture_get_width (texture),
|
cogl_texture_get_width (texture),
|
||||||
@ -1275,7 +1290,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
|||||||
|
|
||||||
cairo_surface_mark_dirty (surface);
|
cairo_surface_mark_dirty (surface);
|
||||||
|
|
||||||
if (transformed_clip)
|
if (image_clip)
|
||||||
cogl_object_unref (texture);
|
cogl_object_unref (texture);
|
||||||
|
|
||||||
mask_texture = stex->mask_texture;
|
mask_texture = stex->mask_texture;
|
||||||
@ -1284,13 +1299,13 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
|||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
cairo_surface_t *mask_surface;
|
cairo_surface_t *mask_surface;
|
||||||
|
|
||||||
if (transformed_clip)
|
if (image_clip)
|
||||||
mask_texture =
|
mask_texture =
|
||||||
cogl_texture_new_from_sub_texture (mask_texture,
|
cogl_texture_new_from_sub_texture (mask_texture,
|
||||||
transformed_clip->x,
|
image_clip->x,
|
||||||
transformed_clip->y,
|
image_clip->y,
|
||||||
transformed_clip->width,
|
image_clip->width,
|
||||||
transformed_clip->height);
|
image_clip->height);
|
||||||
|
|
||||||
mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
|
mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
|
||||||
cogl_texture_get_width (mask_texture),
|
cogl_texture_get_width (mask_texture),
|
||||||
@ -1310,7 +1325,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
|||||||
|
|
||||||
cairo_surface_destroy (mask_surface);
|
cairo_surface_destroy (mask_surface);
|
||||||
|
|
||||||
if (transformed_clip)
|
if (image_clip)
|
||||||
cogl_object_unref (mask_texture);
|
cogl_object_unref (mask_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user