[mutter/gbsneto/content: 105/111] WIP shaped-texture: Implement ClutterContent
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/content: 105/111] WIP shaped-texture: Implement ClutterContent
- Date: Wed, 23 Jan 2019 15:55:40 +0000 (UTC)
commit 2d62d1be3252060b69aa6a0ceca44b9fb3430076
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Wed Dec 26 13:41:26 2018 -0200
WIP shaped-texture: Implement ClutterContent
* MetaShapedTexture now manually tracks scale-x and
scale-y
* We now paint into ClutterPaintNode instead of the
direct framebuffer.
* Various pieces of Wayland code now use MetaSurfaceActor
instead of MetaShapedTexture.
* MetaSurfaceActorWayland doesn't override size negotiation
vfuncs anymore
src/compositor/meta-shaped-texture-private.h | 8 +
src/compositor/meta-shaped-texture.c | 526 ++++++++++++++++++++-------
src/compositor/meta-surface-actor-wayland.c | 50 ---
src/compositor/meta-surface-actor.c | 16 +-
src/compositor/meta-window-actor.c | 16 +-
src/meta/meta-window-actor.h | 3 +-
src/wayland/meta-wayland-actor-surface.c | 2 +-
src/wayland/meta-wayland-data-device.c | 2 +-
src/wayland/meta-wayland-surface.c | 4 +-
src/wayland/meta-wayland-tablet-tool.c | 2 +-
10 files changed, 429 insertions(+), 200 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index 44816a14d..f926a272c 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -44,5 +44,13 @@ gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
cairo_region_t * meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex);
void meta_shaped_texture_set_transform (MetaShapedTexture *stex,
MetaMonitorTransform transform);
+void meta_shaped_texture_cull_out (MetaShapedTexture *stex,
+ cairo_region_t *unobscured_region,
+ cairo_region_t *clip_region,
+ uint8_t opacity);
+void meta_shaped_texture_reset_culling (MetaShapedTexture *stex);
+void meta_shaped_texture_set_scale (MetaShapedTexture *stex,
+ double scale);
+double meta_shaped_texture_get_scale (MetaShapedTexture *stex);
#endif
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 9f96d6718..bc56168b1 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -57,21 +57,7 @@
static void meta_shaped_texture_dispose (GObject *object);
-static void meta_shaped_texture_paint (ClutterActor *actor);
-
-static void meta_shaped_texture_get_preferred_width (ClutterActor *self,
- gfloat for_height,
- gfloat *min_width_p,
- gfloat *natural_width_p);
-
-static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
- gfloat for_width,
- gfloat *min_height_p,
- gfloat *natural_height_p);
-
-static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
-
-static void cullable_iface_init (MetaCullableInterface *iface);
+static void clutter_content_iface_init (ClutterContentIface *iface);
enum {
SIZE_CHANGED,
@@ -83,7 +69,7 @@ static guint signals[LAST_SIGNAL];
struct _MetaShapedTexture
{
- ClutterActor parent;
+ GObject parent;
MetaTextureTower *paint_tower;
@@ -116,25 +102,23 @@ struct _MetaShapedTexture
guint remipmap_timeout_id;
gint64 earliest_remipmap;
+ unsigned int attached_actors;
+
+ double scale;
+
guint create_mipmaps : 1;
};
-G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR,
- G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
+G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, clutter_content_iface_init));
static void
meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
- ClutterActorClass *actor_class = (ClutterActorClass *) klass;
gobject_class->dispose = meta_shaped_texture_dispose;
- actor_class->get_preferred_width = meta_shaped_texture_get_preferred_width;
- actor_class->get_preferred_height = meta_shaped_texture_get_preferred_height;
- actor_class->paint = meta_shaped_texture_paint;
- actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
-
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
@@ -154,16 +138,12 @@ meta_shaped_texture_init (MetaShapedTexture *stex)
{
stex->paint_tower = meta_texture_tower_new ();
+ stex->scale = 1.0;
stex->texture = NULL;
stex->mask_texture = NULL;
stex->create_mipmaps = TRUE;
stex->is_y_inverted = TRUE;
stex->transform = META_MONITOR_TRANSFORM_NORMAL;
-
- g_signal_connect (stex,
- "notify::scale-x",
- G_CALLBACK (invalidate_size),
- stex);
}
static void
@@ -207,7 +187,7 @@ update_size (MetaShapedTexture *stex)
stex->dst_width = dst_width;
stex->dst_height = dst_height;
meta_shaped_texture_set_mask_texture (stex, NULL);
- clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
+ clutter_content_invalidate_size (CLUTTER_CONTENT (stex));
g_signal_emit (stex, signals[SIZE_CHANGED], 0);
}
}
@@ -436,6 +416,40 @@ paint_clipped_rectangle (CoglFramebuffer *fb,
&coords[0], 8);
}
+static void
+paint_clipped_rectangle_node (ClutterPaintNode *root_node,
+ CoglPipeline *pipeline,
+ cairo_rectangle_int_t *rect,
+ ClutterActorBox *alloc)
+{
+ g_autoptr(ClutterPaintNode) node = NULL;
+ float coords[8];
+
+ coords[0] = rect->x / (alloc->x2 - alloc->x1);
+ coords[1] = rect->y / (alloc->y2 - alloc->y1);
+ coords[2] = (rect->x + rect->width) / (alloc->x2 - alloc->x1);
+ coords[3] = (rect->y + rect->height) / (alloc->y2 - alloc->y1);
+
+ coords[4] = coords[0];
+ coords[5] = coords[1];
+ coords[6] = coords[2];
+ coords[7] = coords[3];
+
+ node = clutter_pipeline_node_new (pipeline);
+ clutter_paint_node_set_name (node, "MetaShapedTexture (clipped)");
+ clutter_paint_node_add_child (root_node, node);
+
+ clutter_paint_node_add_multitexture_rectangle (node,
+ &(ClutterActorBox)
+ {
+ .x1 = rect->x,
+ .x2 = rect->x + rect->width,
+ .y1 = rect->y,
+ .y2 = rect->y + rect->height,
+ },
+ coords, 8);
+}
+
static void
set_cogl_texture (MetaShapedTexture *stex,
CoglTexture *cogl_tex)
@@ -476,6 +490,8 @@ set_cogl_texture (MetaShapedTexture *stex,
if (stex->create_mipmaps)
meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex);
+
+ clutter_content_invalidate (CLUTTER_CONTENT (stex));
}
static gboolean
@@ -486,12 +502,31 @@ texture_is_idle_and_not_mipmapped (gpointer user_data)
if ((g_get_monotonic_time () - stex->earliest_remipmap) < 0)
return G_SOURCE_CONTINUE;
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
+ clutter_content_invalidate (CLUTTER_CONTENT (stex));
stex->remipmap_timeout_id = 0;
return G_SOURCE_REMOVE;
}
+static cairo_region_t *
+effective_unobscured_region (MetaShapedTexture *stex)
+{
+ /*
+ ClutterActor *actor;
+
+ actor = CLUTTER_ACTOR (stex);
+ do
+ {
+ if (clutter_actor_has_mapped_clones (actor))
+ return NULL;
+ actor = clutter_actor_get_parent (actor);
+ }
+ while (actor != NULL);
+ */
+
+ return stex->unobscured_region;
+}
+
static void
do_paint (MetaShapedTexture *stex,
CoglFramebuffer *fb,
@@ -696,52 +731,234 @@ do_paint (MetaShapedTexture *stex,
}
static void
-meta_shaped_texture_paint (ClutterActor *actor)
+do_paint_content (MetaShapedTexture *stex,
+ ClutterPaintNode *root_node,
+ CoglTexture *paint_tex,
+ ClutterActorBox *alloc,
+ double tex_scale,
+ guchar opacity)
+
{
- MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
- CoglTexture *paint_tex;
- CoglFramebuffer *fb;
+ int dst_width, dst_height;
+ cairo_rectangle_int_t tex_rect;
+ gboolean use_opaque_region;
+ cairo_region_t *clip_tex_region;
+ cairo_region_t *opaque_tex_region;
+ cairo_region_t *blended_tex_region;
+ CoglContext *ctx;
+ CoglPipelineFilter filter;
- if (!stex->texture)
- return;
+ ensure_size_valid (stex);
- if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
+ dst_width = stex->dst_width;
+ dst_height = stex->dst_height;
+
+ if (dst_width == 0 || dst_height == 0) /* no contents yet */
return;
- if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
- clutter_actor_realize (CLUTTER_ACTOR (stex));
+ tex_rect = (cairo_rectangle_int_t) { 0, 0, dst_width, dst_height };
- /* The GL EXT_texture_from_pixmap extension does allow for it to be
- * used together with SGIS_generate_mipmap, however this is very
- * rarely supported. Also, even when it is supported there
- * are distinct performance implications from:
- *
- * - Updating mipmaps that we don't need
- * - Having to reallocate pixmaps on the server into larger buffers
+ /* Use nearest-pixel interpolation if the texture is unscaled. This
+ * improves performance, especially with software rendering.
+ */
+
+ filter = COGL_PIPELINE_FILTER_LINEAR;
+
+ /* FIXME: evil cogl_get_draw_framebuffer() */
+ if (meta_actor_painting_untransformed (cogl_get_draw_framebuffer (),
+ dst_width, dst_height,
+ NULL, NULL))
+ filter = COGL_PIPELINE_FILTER_NEAREST;
+
+ ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
+
+ if (stex->opaque_region && opacity == 255)
+ {
+ opaque_tex_region =
+ meta_region_scale_double (stex->opaque_region,
+ 1.0 / tex_scale,
+ META_ROUNDING_STRATEGY_SHRINK);
+ use_opaque_region = TRUE;
+ }
+ else
+ {
+ opaque_tex_region = NULL;
+ use_opaque_region = FALSE;
+ }
+
+ if (stex->clip_region)
+ {
+ clip_tex_region =
+ meta_region_scale_double (stex->clip_region,
+ 1.0 / tex_scale,
+ META_ROUNDING_STRATEGY_GROW);
+ }
+ else
+ {
+ clip_tex_region = NULL;
+ }
+
+ if (use_opaque_region)
+ {
+ if (clip_tex_region)
+ blended_tex_region = cairo_region_copy (clip_tex_region);
+ else
+ blended_tex_region = cairo_region_create_rectangle (&tex_rect);
+
+ cairo_region_subtract (blended_tex_region, opaque_tex_region);
+ }
+ else
+ {
+ if (clip_tex_region)
+ blended_tex_region = cairo_region_reference (clip_tex_region);
+ else
+ blended_tex_region = NULL;
+ }
+
+ /* Limit to how many separate rectangles we'll draw; beyond this just
+ * fall back and draw the whole thing */
+#define MAX_RECTS 16
+
+ if (blended_tex_region)
+ {
+ int n_rects = cairo_region_num_rectangles (blended_tex_region);
+ if (n_rects > MAX_RECTS)
+ {
+ /* Fall back to taking the fully blended path. */
+ use_opaque_region = FALSE;
+
+ g_clear_pointer (&blended_tex_region, cairo_region_destroy);
+ }
+ }
+
+ /* First, paint the unblended parts, which are part of the opaque region. */
+ if (use_opaque_region)
+ {
+ cairo_region_t *region;
+ int n_rects;
+ int i;
+
+ if (clip_tex_region)
+ {
+ region = cairo_region_copy (clip_tex_region);
+ cairo_region_intersect (region, opaque_tex_region);
+ }
+ else
+ {
+ region = cairo_region_reference (opaque_tex_region);
+ }
+
+ if (!cairo_region_is_empty (region))
+ {
+ CoglPipeline *opaque_pipeline;
+
+ opaque_pipeline = get_unblended_pipeline (stex, ctx);
+ cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
+ cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
+
+ n_rects = cairo_region_num_rectangles (region);
+ for (i = 0; i < n_rects; i++)
+ {
+ cairo_rectangle_int_t rect;
+ cairo_region_get_rectangle (region, i, &rect);
+ paint_clipped_rectangle_node (root_node, opaque_pipeline, &rect, alloc);
+ }
+ }
+
+ cairo_region_destroy (region);
+ }
+
+ /* Now, go ahead and paint the blended parts. */
+
+ /* We have three cases:
+ * 1) blended_tex_region has rectangles - paint the rectangles.
+ * 2) blended_tex_region is empty - don't paint anything
+ * 3) blended_tex_region is NULL - paint fully-blended.
*
- * So, we just unconditionally use our mipmap emulation code. If we
- * wanted to use SGIS_generate_mipmap, we'd have to query COGL to
- * see if it was supported (no API currently), and then if and only
- * if that was the case, set the clutter texture quality to HIGH.
- * Setting the texture quality to high without SGIS_generate_mipmap
- * support for TFP textures will result in fallbacks to XGetImage.
+ * 1) and 3) are the times where we have to paint stuff. This tests
+ * for 1) and 3).
*/
- if (stex->create_mipmaps)
+ if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region))
{
- int64_t now = g_get_monotonic_time ();
- int64_t age = now - stex->last_invalidation;
+ CoglPipeline *blended_pipeline;
- if (age >= MIN_MIPMAP_AGE_USEC ||
- stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
+ if (stex->mask_texture == NULL)
{
- paint_tex = meta_texture_tower_get_paint_texture (stex->paint_tower);
- if (!paint_tex)
- paint_tex = stex->texture;
+ blended_pipeline = get_unmasked_pipeline (stex, ctx);
}
else
{
- paint_tex = stex->texture;
+ blended_pipeline = get_masked_pipeline (stex, ctx);
+ cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
+ cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
+ }
+ cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
+ cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
+
+ CoglColor color;
+ cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
+ cogl_pipeline_set_color (blended_pipeline, &color);
+
+ if (blended_tex_region)
+ {
+ /* 1) blended_tex_region is not empty. Paint the rectangles. */
+ int i;
+ int n_rects = cairo_region_num_rectangles (blended_tex_region);
+
+ for (i = 0; i < n_rects; i++)
+ {
+ cairo_rectangle_int_t rect;
+ cairo_region_get_rectangle (blended_tex_region, i, &rect);
+
+ if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
+ continue;
+
+ paint_clipped_rectangle_node (root_node, blended_pipeline, &rect, alloc);
+ }
+ }
+ else
+ {
+ g_autoptr(ClutterPaintNode) node = NULL;
+
+ node = clutter_pipeline_node_new (blended_pipeline);
+ clutter_paint_node_set_name (node, "MetaShapedTexture (unclipped)");
+ clutter_paint_node_add_child (root_node, node);
+
+ /* 3) blended_tex_region is NULL. Do a full paint. */
+ clutter_paint_node_add_rectangle (node, alloc);
+ }
+ }
+
+ g_clear_pointer (&clip_tex_region, cairo_region_destroy);
+ g_clear_pointer (&opaque_tex_region, cairo_region_destroy);
+ g_clear_pointer (&blended_tex_region, cairo_region_destroy);
+}
+
+static CoglTexture *
+select_texture_for_paint (MetaShapedTexture *stex)
+{
+ CoglTexture *texture = NULL;
+ gint64 now = g_get_monotonic_time ();
+
+ if (stex->create_mipmaps && stex->last_invalidation)
+ {
+ gint64 age = now - stex->last_invalidation;
+
+ if (age >= MIN_MIPMAP_AGE_USEC ||
+ stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
+ texture = meta_texture_tower_get_paint_texture (stex->paint_tower);
+ }
+
+ if (texture == NULL)
+ {
+ texture = COGL_TEXTURE (stex->texture);
+
+ if (texture == NULL)
+ return NULL;
+
+ if (stex->create_mipmaps)
+ {
/* Minus 1000 to ensure we don't fail the age test in timeout */
stex->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000;
@@ -752,74 +969,97 @@ meta_shaped_texture_paint (ClutterActor *actor)
stex);
}
}
- else
- {
- paint_tex = COGL_TEXTURE (stex->texture);
- }
- if (cogl_texture_get_width (paint_tex) == 0 ||
- cogl_texture_get_height (paint_tex) == 0)
+ return texture;
+}
+
+static void
+meta_shaped_texture_paint_content (ClutterContent *content,
+ ClutterActor *actor,
+ ClutterPaintNode *root_node)
+{
+ MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
+ ClutterActorBox alloc;
+ CoglTexture *paint_tex = NULL;
+ double tex_scale;
+ guchar opacity;
+
+ if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
+ return;
+
+ /* The GL EXT_texture_from_pixmap extension does allow for it to be
+ * used together with SGIS_generate_mipmap, however this is very
+ * rarely supported. Also, even when it is supported there
+ * are distinct performance implications from:
+ *
+ * - Updating mipmaps that we don't need
+ * - Having to reallocate pixmaps on the server into larger buffers
+ *
+ * So, we just unconditionally use our mipmap emulation code. If we
+ * wanted to use SGIS_generate_mipmap, we'd have to query COGL to
+ * see if it was supported (no API currently), and then if and only
+ * if that was the case, set the clutter texture quality to HIGH.
+ * Setting the texture quality to high without SGIS_generate_mipmap
+ * support for TFP textures will result in fallbacks to XGetImage.
+ */
+ paint_tex = select_texture_for_paint (stex);
+ if (!paint_tex)
return;
- fb = cogl_get_draw_framebuffer ();
- do_paint (META_SHAPED_TEXTURE (actor), fb, paint_tex, stex->clip_region);
+ clutter_actor_get_scale (actor, &tex_scale, NULL);
+ opacity = clutter_actor_get_paint_opacity (actor);
+ clutter_actor_get_content_box (actor, &alloc);
+
+ do_paint_content (stex, root_node, paint_tex, &alloc, tex_scale, opacity);
}
-static void
-meta_shaped_texture_get_preferred_width (ClutterActor *self,
- gfloat for_height,
- gfloat *min_width_p,
- gfloat *natural_width_p)
+static gboolean
+meta_shaped_texture_get_preferred_size (ClutterContent *content,
+ float *width,
+ float *height)
{
- MetaShapedTexture *stex = META_SHAPED_TEXTURE (self);
+ MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
ensure_size_valid (stex);
- if (min_width_p)
- *min_width_p = stex->dst_width;
- if (natural_width_p)
- *natural_width_p = stex->dst_width;
+ if (width)
+ *width = stex->dst_width * stex->scale;
+
+ if (height)
+ *height = stex->dst_height * stex->scale;
+
+ return TRUE;
}
static void
-meta_shaped_texture_get_preferred_height (ClutterActor *self,
- gfloat for_width,
- gfloat *min_height_p,
- gfloat *natural_height_p)
+meta_shaped_texture_attached (ClutterContent *content,
+ ClutterActor *actor)
{
- MetaShapedTexture *stex = META_SHAPED_TEXTURE (self);
+ MetaShapedTexture *shaped_texture = META_SHAPED_TEXTURE (content);
- ensure_size_valid (stex);
+ shaped_texture->attached_actors++;
- if (min_height_p)
- *min_height_p = stex->dst_height;
- if (natural_height_p)
- *natural_height_p = stex->dst_height;
+ g_message ("%s: Attached! (%u)", G_STRFUNC, shaped_texture->attached_actors);
}
-static cairo_region_t *
-effective_unobscured_region (MetaShapedTexture *stex)
+static void
+meta_shaped_texture_detached (ClutterContent *content,
+ ClutterActor *actor)
{
- ClutterActor *actor;
+ MetaShapedTexture *shaped_texture = META_SHAPED_TEXTURE (content);
- /* Fail if we have any mapped clones. */
- actor = CLUTTER_ACTOR (stex);
- do
- {
- if (clutter_actor_has_mapped_clones (actor))
- return NULL;
- actor = clutter_actor_get_parent (actor);
- }
- while (actor != NULL);
+ shaped_texture->attached_actors--;
- return stex->unobscured_region;
+ g_message ("%s: Detached! (%u)", G_STRFUNC, shaped_texture->attached_actors);
}
-static gboolean
-meta_shaped_texture_get_paint_volume (ClutterActor *actor,
- ClutterPaintVolume *volume)
+static void
+clutter_content_iface_init (ClutterContentIface *iface)
{
- return clutter_paint_volume_set_from_allocation (volume, actor);
+ iface->paint_content = meta_shaped_texture_paint_content;
+ iface->get_preferred_size = meta_shaped_texture_get_preferred_size;
+ iface->attached = meta_shaped_texture_attached;
+ iface->detached = meta_shaped_texture_detached;
}
void
@@ -853,7 +1093,7 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
cogl_object_ref (stex->mask_texture);
}
- clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
+ clutter_content_invalidate (CLUTTER_CONTENT (stex));
}
gboolean
@@ -944,7 +1184,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
{
cairo_rectangle_int_t damage_rect;
cairo_region_get_extents (intersection, &damage_rect);
- clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &damage_rect);
+ clutter_content_invalidate (CLUTTER_CONTENT (stex));
+ //clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &damage_rect);
cairo_region_destroy (intersection);
return TRUE;
}
@@ -954,7 +1195,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
}
else
{
- clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
+ clutter_content_invalidate (CLUTTER_CONTENT (stex));
+ //clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
return TRUE;
}
}
@@ -1230,7 +1472,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
transformed_clip = alloca (sizeof (cairo_rectangle_int_t));
- clutter_actor_get_scale (CLUTTER_ACTOR (stex), &tex_scale, NULL);
+ tex_scale = stex->scale;
meta_rectangle_scale_double (clip, 1.0 / tex_scale,
META_ROUNDING_STRATEGY_GROW,
transformed_clip);
@@ -1318,17 +1560,47 @@ meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
invalidate_size (stex);
}
-static void
-meta_shaped_texture_cull_out (MetaCullable *cullable,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region)
+ClutterActor *
+meta_shaped_texture_new (void)
{
- MetaShapedTexture *stex = META_SHAPED_TEXTURE (cullable);
+ return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
+}
+
+void
+meta_shaped_texture_set_scale (MetaShapedTexture *stex,
+ double scale)
+{
+ g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
+
+ if (scale == stex->scale)
+ return;
+
+ stex->scale = scale;
+
+ invalidate_size (stex);
+ clutter_content_invalidate_size (CLUTTER_CONTENT (stex));
+}
+
+double
+meta_shaped_texture_get_scale (MetaShapedTexture *stex)
+{
+ g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0.0);
+
+ return stex->scale;
+}
+
+void
+meta_shaped_texture_cull_out (MetaShapedTexture *stex,
+ cairo_region_t *unobscured_region,
+ cairo_region_t *clip_region,
+ uint8_t opacity)
+{
+ g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
set_unobscured_region (stex, unobscured_region);
set_clip_region (stex, clip_region);
- if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (stex)) == 0xff)
+ if (opacity == 0xff)
{
if (stex->opaque_region)
{
@@ -1340,22 +1612,10 @@ meta_shaped_texture_cull_out (MetaCullable *cullable,
}
}
-static void
-meta_shaped_texture_reset_culling (MetaCullable *cullable)
-{
- MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable);
- set_clip_region (self, NULL);
-}
-
-static void
-cullable_iface_init (MetaCullableInterface *iface)
+void
+meta_shaped_texture_reset_culling (MetaShapedTexture *stex)
{
- iface->cull_out = meta_shaped_texture_cull_out;
- iface->reset_culling = meta_shaped_texture_reset_culling;
-}
+ g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-ClutterActor *
-meta_shaped_texture_new (void)
-{
- return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
+ set_clip_region (stex, NULL);
}
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index f8d6c32b7..27c600c59 100644
--- a/src/compositor/meta-surface-actor-wayland.c
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -110,54 +110,6 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
return surface->window;
}
-static void
-meta_surface_actor_wayland_get_preferred_width (ClutterActor *actor,
- gfloat for_height,
- gfloat *min_width_p,
- gfloat *natural_width_p)
-{
- MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
- MetaShapedTexture *stex;
- double scale;
-
- stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
- clutter_actor_get_scale (CLUTTER_ACTOR (stex), &scale, NULL);
- clutter_actor_get_preferred_width (CLUTTER_ACTOR (stex),
- for_height,
- min_width_p,
- natural_width_p);
-
- if (min_width_p)
- *min_width_p *= scale;
-
- if (natural_width_p)
- *natural_width_p *= scale;
-}
-
-static void
-meta_surface_actor_wayland_get_preferred_height (ClutterActor *actor,
- gfloat for_width,
- gfloat *min_height_p,
- gfloat *natural_height_p)
-{
- MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
- MetaShapedTexture *stex;
- double scale;
-
- stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
- clutter_actor_get_scale (CLUTTER_ACTOR (stex), NULL, &scale);
- clutter_actor_get_preferred_height (CLUTTER_ACTOR (stex),
- for_width,
- min_height_p,
- natural_height_p);
-
- if (min_height_p)
- *min_height_p *= scale;
-
- if (natural_height_p)
- *natural_height_p *= scale;
-}
-
static void
meta_surface_actor_wayland_paint (ClutterActor *actor)
{
@@ -203,8 +155,6 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- actor_class->get_preferred_width = meta_surface_actor_wayland_get_preferred_width;
- actor_class->get_preferred_height = meta_surface_actor_wayland_get_preferred_height;
actor_class->paint = meta_surface_actor_wayland_paint;
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 9a7d0ef5b..6d02dbbcc 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -158,13 +158,22 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
{
- meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
+ MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
+ MetaSurfaceActorPrivate *priv =
+ meta_surface_actor_get_instance_private (surface_actor);
+ uint8_t opacity = clutter_actor_get_opacity (CLUTTER_ACTOR (cullable));
+
+ meta_shaped_texture_cull_out (priv->texture, unobscured_region, clip_region, opacity);
}
static void
meta_surface_actor_reset_culling (MetaCullable *cullable)
{
- meta_cullable_reset_culling_children (cullable);
+ MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
+ MetaSurfaceActorPrivate *priv =
+ meta_surface_actor_get_instance_private (surface_actor);
+
+ meta_shaped_texture_reset_culling (priv->texture);
}
static void
@@ -191,7 +200,8 @@ meta_surface_actor_init (MetaSurfaceActor *self)
priv->texture = META_SHAPED_TEXTURE (meta_shaped_texture_new ());
g_signal_connect_object (priv->texture, "size-changed",
G_CALLBACK (texture_size_changed), self, 0);
- clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->texture));
+ clutter_actor_set_content (CLUTTER_ACTOR (self), CLUTTER_CONTENT (priv->texture));
+ clutter_actor_set_request_mode (CLUTTER_ACTOR (self), CLUTTER_REQUEST_CONTENT_SIZE);
}
cairo_surface_t *
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 20a22062f..d471f622a 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -829,14 +829,14 @@ meta_window_actor_get_meta_window (MetaWindowActor *self)
*
* Return value: (transfer none): the #ClutterActor for the contents
*/
-ClutterActor *
+MetaShapedTexture *
meta_window_actor_get_texture (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv =
meta_window_actor_get_instance_private (self);
if (priv->surface)
- return CLUTTER_ACTOR (meta_surface_actor_get_texture (priv->surface));
+ return meta_surface_actor_get_texture (priv->surface);
else
return NULL;
}
@@ -1875,19 +1875,19 @@ meta_window_actor_get_frame_bounds (MetaScreenCastWindow *screen_cast_window,
MetaShapedTexture *stex;
MetaRectangle buffer_rect;
MetaRectangle frame_rect;
- double scale_x, scale_y;
+ double scale;
stex = meta_surface_actor_get_texture (priv->surface);
- clutter_actor_get_scale (CLUTTER_ACTOR (stex), &scale_x, &scale_y);
+ scale = meta_shaped_texture_get_scale (stex);
window = priv->window;
meta_window_get_buffer_rect (window, &buffer_rect);
meta_window_get_frame_rect (window, &frame_rect);
- bounds->x = (int) floor ((frame_rect.x - buffer_rect.x) / scale_x);
- bounds->y = (int) floor ((frame_rect.y - buffer_rect.y) / scale_y);
- bounds->width = (int) ceil (frame_rect.width / scale_x);
- bounds->height = (int) ceil (frame_rect.height / scale_y);
+ bounds->x = (int) floor ((frame_rect.x - buffer_rect.x) / scale);
+ bounds->y = (int) floor ((frame_rect.y - buffer_rect.y) / scale);
+ bounds->width = (int) ceil (frame_rect.width / scale);
+ bounds->height = (int) ceil (frame_rect.height / scale);
}
static void
diff --git a/src/meta/meta-window-actor.h b/src/meta/meta-window-actor.h
index 0b1f79d45..7de3f422e 100644
--- a/src/meta/meta-window-actor.h
+++ b/src/meta/meta-window-actor.h
@@ -27,6 +27,7 @@
#include "clutter/clutter.h"
#include "meta/compositor.h"
+#include "meta/meta-shaped-texture.h"
#define META_TYPE_WINDOW_ACTOR (meta_window_actor_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaWindowActor,
@@ -36,7 +37,7 @@ G_DECLARE_DERIVABLE_TYPE (MetaWindowActor,
Window meta_window_actor_get_x_window (MetaWindowActor *self);
MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self);
-ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self);
+MetaShapedTexture *meta_window_actor_get_texture (MetaWindowActor *self);
void meta_window_actor_sync_visibility (MetaWindowActor *self);
gboolean meta_window_actor_is_destroyed (MetaWindowActor *self);
diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
index 56ea66e1e..a85fde49f 100644
--- a/src/wayland/meta-wayland-actor-surface.c
+++ b/src/wayland/meta-wayland-actor-surface.c
@@ -163,7 +163,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
stex = meta_surface_actor_get_texture (surface_actor);
actor_scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
- clutter_actor_set_scale (CLUTTER_ACTOR (stex), actor_scale, actor_scale);
+ meta_shaped_texture_set_scale (stex, actor_scale);
/* Wayland surface coordinate space -> stage coordinate space */
geometry_scale = meta_wayland_actor_surface_get_geometry_scale (actor_surface);
diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c
index 122604965..447ebbda5 100644
--- a/src/wayland/meta-wayland-data-device.c
+++ b/src/wayland/meta-wayland-data-device.c
@@ -1123,7 +1123,7 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
surface_actor = meta_wayland_surface_get_actor (surface);
- clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface_actor)),
+ clutter_actor_transform_stage_point (CLUTTER_ACTOR (surface_actor),
seat->pointer->grab_x,
seat->pointer->grab_y,
&surface_pos.x, &surface_pos.y);
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index f75fefd87..2d0f05703 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -1514,7 +1514,7 @@ meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface,
else
{
ClutterActor *actor =
- CLUTTER_ACTOR (meta_surface_actor_get_texture (meta_wayland_surface_get_actor (surface)));
+ CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
clutter_actor_transform_stage_point (actor, abs_x, abs_y, sx, sy);
*sx /= surface->scale;
@@ -1530,7 +1530,7 @@ meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface,
float *y)
{
ClutterActor *actor =
- CLUTTER_ACTOR (meta_surface_actor_get_texture (meta_wayland_surface_get_actor (surface)));
+ CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
ClutterVertex sv = {
.x = sx * surface->scale,
.y = sy * surface->scale,
diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c
index 222b46633..abfe533ff 100644
--- a/src/wayland/meta-wayland-tablet-tool.c
+++ b/src/wayland/meta-wayland-tablet-tool.c
@@ -640,7 +640,7 @@ meta_wayland_tablet_tool_get_relative_coordinates (MetaWaylandTabletTool *tool,
surface_actor = meta_wayland_surface_get_actor (surface);
clutter_event_get_coords (event, &xf, &yf);
- clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface_actor)),
+ clutter_actor_transform_stage_point (CLUTTER_ACTOR (surface_actor),
xf, yf, &xf, &yf);
*sx = wl_fixed_from_double (xf) / surface->scale;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]