Introduce MetaSurfaceActor for drawing MetaWindowActor content

Instead of having MetaWindowActor only have one single MetaShapedTexture
as actor drawing its content, introduce a new abstract MetaSurfaceActor
that takes care of drawing.

This is one step in the direction to decouple MetaWaylandSurface with a
MetaWindow and MetaWindowActor (except for shell/xdg surfaces) in order
to finally support subsurfaces like features, or any feature where
window is not drawn using a single texture.

The first step, implemented in this patch, is to not have
MetaWindowActor work directly with a shaped texture. There are still
some cases where it simply gets the texture and goes on as before, but
this should be changed by either removing the need of going via
MetaWindowActor or by adding some generic interface to MetaSurfaceActor
that doesn't limit its functionality to one shaped texture.

There should be no visible difference nor after this patch, but
meta_window_actor_get_texture() and meta_surface_actor_get_texture()
should be deprecated when equivalent functionality has been introduced.

Signed-off-by: Jonas Ådahl <jadahl@gmail.com>

https://bugzilla.gnome.org/show_bug.cgi?id=705502
This commit is contained in:
Jonas Ådahl 2013-10-13 13:47:53 +02:00 committed by Jasper St. Pierre
parent a02d734243
commit ea916b6c49
5 changed files with 295 additions and 129 deletions

View File

@ -80,6 +80,8 @@ libmutter_wayland_la_SOURCES = \
compositor/meta-shadow-factory-private.h \ compositor/meta-shadow-factory-private.h \
compositor/meta-shaped-texture.c \ compositor/meta-shaped-texture.c \
compositor/meta-shaped-texture-private.h \ compositor/meta-shaped-texture-private.h \
compositor/meta-surface-actor.c \
compositor/meta-surface-actor.h \
compositor/meta-texture-rectangle.c \ compositor/meta-texture-rectangle.c \
compositor/meta-texture-rectangle.h \ compositor/meta-texture-rectangle.h \
compositor/meta-texture-tower.c \ compositor/meta-texture-tower.c \

View File

@ -0,0 +1,149 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* SECTION:meta-surface-actor
* @title: MetaSurfaceActor
* @short_description: An actor representing a surface in the scene graph
*
* A surface can be either a shaped texture, or a group of shaped texture,
* used to draw the content of a window.
*/
#include <config.h>
#include <clutter/clutter.h>
#include <cogl/cogl-wayland-server.h>
#include <cogl/cogl-texture-pixmap-x11.h>
#include <meta/meta-shaped-texture.h>
#include "meta-surface-actor.h"
#include "meta-shaped-texture-private.h"
struct _MetaSurfaceActorPrivate
{
MetaShapedTexture *texture;
MetaWaylandBuffer *buffer;
Pixmap pixmap;
};
G_DEFINE_TYPE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR);
static void
meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
{
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
}
static void
meta_surface_actor_init (MetaSurfaceActor *self)
{
MetaSurfaceActorPrivate *priv;
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
META_TYPE_SURFACE_ACTOR,
MetaSurfaceActorPrivate);
priv->texture = NULL;
}
MetaSurfaceActor *
meta_surface_actor_new (void)
{
MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
MetaShapedTexture *stex;
stex = META_SHAPED_TEXTURE (meta_shaped_texture_new ());
self->priv->texture = stex;
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (stex));
return self;
}
cairo_surface_t *
meta_surface_actor_get_image (MetaSurfaceActor *self,
cairo_rectangle_int_t *clip)
{
return meta_shaped_texture_get_image (self->priv->texture, clip);
}
MetaShapedTexture *
meta_surface_actor_get_texture (MetaSurfaceActor *self)
{
return self->priv->texture;
}
void
meta_surface_actor_set_clip_region (MetaSurfaceActor *self,
cairo_region_t *clip_region)
{
meta_shaped_texture_set_clip_region (self->priv->texture, clip_region);
}
static void
update_area (MetaSurfaceActor *self,
int x, int y, int width, int height)
{
MetaSurfaceActorPrivate *priv = self->priv;
if (meta_is_wayland_compositor ())
{
struct wl_resource *resource = priv->buffer->resource;
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource);
if (shm_buffer)
{
CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture);
cogl_wayland_texture_2d_update_area (texture, shm_buffer, x, y, width, height);
}
}
else
{
CoglTexturePixmapX11 *texture = COGL_TEXTURE_PIXMAP_X11 (meta_shaped_texture_get_texture (priv->texture));
cogl_texture_pixmap_x11_update_area (texture, x, y, width, height);
}
}
gboolean
meta_surface_actor_damage_all (MetaSurfaceActor *self,
cairo_region_t *unobscured_region)
{
MetaSurfaceActorPrivate *priv = self->priv;
CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture);
update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture));
return meta_shaped_texture_update_area (self->priv->texture,
0, 0,
cogl_texture_get_width (texture),
cogl_texture_get_height (texture),
unobscured_region);
}
gboolean
meta_surface_actor_damage_area (MetaSurfaceActor *self,
int x,
int y,
int width,
int height,
cairo_region_t *unobscured_region)
{
update_area (self, x, y, width, height);
return meta_shaped_texture_update_area (self->priv->texture,
x, y, width, height,
unobscured_region);
}
void
meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self,
MetaWaylandBuffer *buffer)
{
MetaSurfaceActorPrivate *priv = self->priv;
priv->buffer = buffer;
meta_shaped_texture_set_texture (self->priv->texture, buffer->texture);
}
void
meta_surface_actor_set_texture (MetaSurfaceActor *self,
CoglTexture *texture)
{
meta_shaped_texture_set_texture (self->priv->texture, texture);
}

View File

@ -0,0 +1,66 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef META_SURFACE_ACTOR_PRIVATE_H
#define META_SURFACE_ACTOR_PRIVATE_H
#include <config.h>
#include <meta/meta-shaped-texture.h>
#include "meta-wayland-private.h"
G_BEGIN_DECLS
#define META_TYPE_SURFACE_ACTOR (meta_surface_actor_get_type())
#define META_SURFACE_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SURFACE_ACTOR, MetaSurfaceActor))
#define META_SURFACE_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SURFACE_ACTOR, MetaSurfaceActorClass))
#define META_IS_SURFACE_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SURFACE_ACTOR))
#define META_IS_SURFACE_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SURFACE_ACTOR))
#define META_SURFACE_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SURFACE_ACTOR, MetaSurfaceActorClass))
typedef struct _MetaSurfaceActor MetaSurfaceActor;
typedef struct _MetaSurfaceActorClass MetaSurfaceActorClass;
typedef struct _MetaSurfaceActorPrivate MetaSurfaceActorPrivate;
struct _MetaSurfaceActorClass
{
/*< private >*/
ClutterActorClass parent_class;
};
struct _MetaSurfaceActor
{
ClutterActor parent;
MetaSurfaceActorPrivate *priv;
};
GType meta_surface_actor_get_type (void);
MetaSurfaceActor *meta_surface_actor_new (void);
cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self,
cairo_rectangle_int_t *clip);
MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self);
void meta_surface_actor_set_clip_region (MetaSurfaceActor *self,
cairo_region_t *clip_region);
gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self,
cairo_region_t *unobscured_region);
gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self,
int x,
int y,
int width,
int height,
cairo_region_t *unobscured_region);
void meta_surface_actor_set_texture (MetaSurfaceActor *self,
CoglTexture *texture);
void meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self,
MetaWaylandBuffer *buffer);
G_END_DECLS
#endif /* META_SURFACE_ACTOR_PRIVATE_H */

View File

@ -10,6 +10,7 @@
#include <X11/extensions/Xdamage.h> #include <X11/extensions/Xdamage.h>
#include <meta/compositor-mutter.h> #include <meta/compositor-mutter.h>
#include "meta-surface-actor.h"
MetaWindowActor *meta_window_actor_new (MetaWindow *window); MetaWindowActor *meta_window_actor_new (MetaWindow *window);
@ -80,4 +81,6 @@ void meta_window_actor_set_unobscured_region (MetaWindowActor *self,
void meta_window_actor_effect_completed (MetaWindowActor *actor, void meta_window_actor_effect_completed (MetaWindowActor *actor,
gulong event); gulong event);
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
#endif /* META_WINDOW_ACTOR_PRIVATE_H */ #endif /* META_WINDOW_ACTOR_PRIVATE_H */

View File

@ -16,7 +16,6 @@
#include <clutter/x11/clutter-x11.h> #include <clutter/x11/clutter-x11.h>
#include <cogl/cogl-texture-pixmap-x11.h> #include <cogl/cogl-texture-pixmap-x11.h>
#include <cogl/cogl-wayland-server.h>
#include <gdk/gdk.h> /* for gdk_rectangle_union() */ #include <gdk/gdk.h> /* for gdk_rectangle_union() */
#include <string.h> #include <string.h>
@ -31,6 +30,7 @@
#include "meta-shaped-texture-private.h" #include "meta-shaped-texture-private.h"
#include "meta-shadow-factory-private.h" #include "meta-shadow-factory-private.h"
#include "meta-window-actor-private.h" #include "meta-window-actor-private.h"
#include "meta-surface-actor.h"
#include "meta-texture-rectangle.h" #include "meta-texture-rectangle.h"
#include "region-utils.h" #include "region-utils.h"
#include "meta-wayland-private.h" #include "meta-wayland-private.h"
@ -51,9 +51,7 @@ struct _MetaWindowActorPrivate
Window xwindow; Window xwindow;
MetaScreen *screen; MetaScreen *screen;
ClutterActor *actor; MetaSurfaceActor *surface;
MetaWaylandBuffer *buffer;
/* MetaShadowFactory only caches shadows that are actually in use; /* MetaShadowFactory only caches shadows that are actually in use;
* to avoid unnecessary recomputation we do two things: 1) we store * to avoid unnecessary recomputation we do two things: 1) we store
@ -392,11 +390,11 @@ meta_window_actor_constructed (GObject *object)
priv->argb32 = TRUE; priv->argb32 = TRUE;
} }
if (!priv->actor) if (!priv->surface)
{ {
priv->actor = meta_shaped_texture_new (); priv->surface = meta_surface_actor_new ();
clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor); clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
/* /*
@ -406,7 +404,7 @@ meta_window_actor_constructed (GObject *object)
* via the container interface, we do not end up with a dangling pointer. * via the container interface, we do not end up with a dangling pointer.
* We will release it in dispose(). * We will release it in dispose().
*/ */
g_object_ref (priv->actor); g_object_ref (priv->surface);
g_signal_connect_object (window, "notify::decorated", g_signal_connect_object (window, "notify::decorated",
G_CALLBACK (window_decorated_notify), self, 0); G_CALLBACK (window_decorated_notify), self, 0);
@ -419,7 +417,7 @@ meta_window_actor_constructed (GObject *object)
* This is the case where existing window is gaining/loosing frame. * This is the case where existing window is gaining/loosing frame.
* Just ensure the actor is top most (i.e., above shadow). * Just ensure the actor is top most (i.e., above shadow).
*/ */
clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), priv->actor, NULL); clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface), NULL);
} }
meta_window_actor_update_opacity (self); meta_window_actor_update_opacity (self);
@ -487,7 +485,7 @@ meta_window_actor_dispose (GObject *object)
/* /*
* Release the extra reference we took on the actor. * Release the extra reference we took on the actor.
*/ */
g_clear_object (&priv->actor); g_clear_object (&priv->surface);
G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object); G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
} }
@ -883,7 +881,21 @@ meta_window_actor_get_meta_window (MetaWindowActor *self)
ClutterActor * ClutterActor *
meta_window_actor_get_texture (MetaWindowActor *self) meta_window_actor_get_texture (MetaWindowActor *self)
{ {
return self->priv->actor; return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface));
}
/**
* meta_window_actor_get_surface:
* @self: a #MetaWindowActor
*
* Gets the MetaSurfaceActor that draws the content of this window
*
* Return value: (transfer none): the #MetaSurfaceActor for the contents
*/
MetaSurfaceActor *
meta_window_actor_get_surface (MetaWindowActor *self)
{
return self->priv->surface;
} }
/** /**
@ -1014,60 +1026,26 @@ queue_send_frame_messages_timeout (MetaWindowActor *self)
priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL); priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL);
} }
static void
wayland_surface_update_area (MetaWindowActor *self,
int x, int y, int width, int height)
{
MetaWindowActorPrivate *priv = self->priv;
struct wl_resource *resource = priv->buffer->resource;
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource);
if (shm_buffer)
cogl_wayland_texture_2d_update_area (COGL_TEXTURE_2D (priv->buffer->texture),
shm_buffer, x, y, width, height);
}
static void
update_area (MetaWindowActor *self,
int x, int y, int width, int height)
{
MetaWindowActorPrivate *priv = self->priv;
CoglTexture *texture;
texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
if (meta_is_wayland_compositor ())
wayland_surface_update_area (self, x, y, width, height);
else
cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (texture),
x, y, width, height);
}
static void static void
meta_window_actor_damage_all (MetaWindowActor *self) meta_window_actor_damage_all (MetaWindowActor *self)
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
CoglTexture *texture; cairo_region_t *unobscured_region;
gboolean redraw_queued; gboolean redraw_queued;
if (!priv->needs_damage_all) if (!priv->needs_damage_all)
return; return;
texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
if (!priv->mapped || priv->needs_pixmap) if (!priv->mapped || priv->needs_pixmap)
return; return;
update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); unobscured_region =
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface))
0, 0, ? NULL : priv->unobscured_region;
cogl_texture_get_width (texture),
cogl_texture_get_height (texture),
clutter_actor_has_mapped_clones (priv->actor) ?
NULL : priv->unobscured_region);
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; redraw_queued = meta_surface_actor_damage_all (priv->surface, unobscured_region);
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
priv->needs_damage_all = FALSE; priv->needs_damage_all = FALSE;
} }
@ -1151,7 +1129,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
else if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap)) else if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap))
{ {
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
clutter_actor_queue_redraw_with_clip (priv->actor, &clip); clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (priv->surface), &clip);
priv->repaint_scheduled = TRUE; priv->repaint_scheduled = TRUE;
} }
} }
@ -1194,7 +1172,7 @@ meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self)
* *
* The compositor paint function repairs all windows. * The compositor paint function repairs all windows.
*/ */
clutter_actor_queue_redraw (priv->actor); clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
} }
static gboolean static gboolean
@ -1284,7 +1262,7 @@ meta_window_actor_after_effects (MetaWindowActor *self)
meta_window_actor_detach_x11_pixmap (self); meta_window_actor_detach_x11_pixmap (self);
if (priv->needs_pixmap) if (priv->needs_pixmap)
clutter_actor_queue_redraw (priv->actor); clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
} }
} }
@ -1380,7 +1358,7 @@ meta_window_actor_detach_x11_pixmap (MetaWindowActor *self)
* you are supposed to be able to free a GLXPixmap after freeing the underlying * you are supposed to be able to free a GLXPixmap after freeing the underlying
* pixmap, but it certainly doesn't work with current DRI/Mesa * pixmap, but it certainly doesn't work with current DRI/Mesa
*/ */
meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), NULL); meta_surface_actor_set_texture (priv->surface, NULL);
cogl_flush(); cogl_flush();
XFreePixmap (xdisplay, priv->back_pixmap); XFreePixmap (xdisplay, priv->back_pixmap);
@ -1912,8 +1890,7 @@ meta_window_actor_set_clip_region (MetaWindowActor *self,
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor), meta_surface_actor_set_clip_region (priv->surface, clip_region);
clip_region);
} }
/** /**
@ -1960,8 +1937,7 @@ meta_window_actor_reset_clip_regions (MetaWindowActor *self)
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor), meta_surface_actor_set_clip_region (priv->surface, NULL);
NULL);
g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
} }
@ -1976,7 +1952,6 @@ check_needs_x11_pixmap (MetaWindowActor *self)
MetaDisplay *display = meta_screen_get_display (screen); MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display); Display *xdisplay = meta_display_get_xdisplay (display);
MetaCompScreen *info = meta_screen_get_compositor_data (screen); MetaCompScreen *info = meta_screen_get_compositor_data (screen);
MetaCompositor *compositor;
Window xwindow = priv->xwindow; Window xwindow = priv->xwindow;
if (!priv->needs_pixmap) if (!priv->needs_pixmap)
@ -1989,8 +1964,6 @@ check_needs_x11_pixmap (MetaWindowActor *self)
xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage))) xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)))
return; return;
compositor = meta_display_get_compositor (display);
if (priv->x11_size_changed) if (priv->x11_size_changed)
{ {
meta_window_actor_detach_x11_pixmap (self); meta_window_actor_detach_x11_pixmap (self);
@ -2026,15 +1999,11 @@ check_needs_x11_pixmap (MetaWindowActor *self)
goto out; goto out;
} }
if (compositor->no_mipmaps)
meta_shaped_texture_set_create_mipmaps (META_SHAPED_TEXTURE (priv->actor),
FALSE);
texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL)); texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL));
if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
g_warning ("NOTE: Not using GLX TFP!\n"); g_warning ("NOTE: Not using GLX TFP!\n");
meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), texture); meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture);
/* ::size-changed is supposed to refer to meta_window_get_outer_rect(). /* ::size-changed is supposed to refer to meta_window_get_outer_rect().
* Emitting it here works pretty much OK because a new value of the * Emitting it here works pretty much OK because a new value of the
@ -2126,6 +2095,7 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen); MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen);
gboolean redraw_queued; gboolean redraw_queued;
cairo_region_t *unobscured_region;
priv->received_x11_damage = TRUE; priv->received_x11_damage = TRUE;
@ -2173,14 +2143,15 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
if (!priv->mapped || priv->needs_pixmap) if (!priv->mapped || priv->needs_pixmap)
return; return;
update_area (self, event->area.x, event->area.y, event->area.width, event->area.height); unobscured_region =
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface))
event->area.x, ? NULL : priv->unobscured_region;
event->area.y, redraw_queued = meta_surface_actor_damage_area (priv->surface,
event->area.width, event->area.x,
event->area.height, event->area.y,
clutter_actor_has_mapped_clones (priv->actor) ? event->area.width,
NULL : priv->unobscured_region); event->area.height,
unobscured_region);
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
@ -2194,16 +2165,19 @@ meta_window_actor_process_wayland_damage (MetaWindowActor *self,
int height) int height)
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
cairo_region_t *unobscured_region;
gboolean redraw_queued; gboolean redraw_queued;
if (!priv->mapped) if (!priv->mapped)
return; return;
update_area (self, x, y, width, height); unobscured_region =
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface))
x, y, width, height, ? NULL : priv->unobscured_region;
clutter_actor_has_mapped_clones (priv->actor) ? redraw_queued = meta_surface_actor_damage_area (priv->surface,
NULL : priv->unobscured_region); x, y, width, height,
unobscured_region);
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
} }
@ -2266,12 +2240,18 @@ build_and_scan_frame_mask (MetaWindowActor *self,
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
guchar *mask_data; guchar *mask_data;
guint tex_width, tex_height; guint tex_width, tex_height;
MetaShapedTexture *stex;
CoglTexture *paint_tex, *mask_texture; CoglTexture *paint_tex, *mask_texture;
int stride; int stride;
cairo_t *cr; cairo_t *cr;
cairo_surface_t *surface; cairo_surface_t *surface;
paint_tex = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); stex = meta_surface_actor_get_texture (priv->surface);
g_return_if_fail (stex);
meta_shaped_texture_set_mask_texture (stex, NULL);
paint_tex = meta_shaped_texture_get_texture (stex);
if (paint_tex == NULL) if (paint_tex == NULL)
return; return;
@ -2339,8 +2319,7 @@ build_and_scan_frame_mask (MetaWindowActor *self,
mask_data); mask_data);
} }
meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), meta_shaped_texture_set_mask_texture (stex, mask_texture);
mask_texture);
cogl_object_unref (mask_texture); cogl_object_unref (mask_texture);
g_free (mask_data); g_free (mask_data);
@ -2370,7 +2349,6 @@ meta_window_actor_update_shape_region (MetaWindowActor *self,
region = cairo_region_create_rectangle (client_area); region = cairo_region_create_rectangle (client_area);
} }
meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), NULL);
if ((priv->window->shape_region != NULL) || (priv->window->frame != NULL)) if ((priv->window->shape_region != NULL) || (priv->window->frame != NULL))
build_and_scan_frame_mask (self, client_area, region); build_and_scan_frame_mask (self, client_area, region);
@ -2387,9 +2365,12 @@ meta_window_actor_update_input_region (MetaWindowActor *self,
cairo_rectangle_int_t *client_area) cairo_rectangle_int_t *client_area)
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor); MetaShapedTexture *stex = meta_surface_actor_get_texture (priv->surface);
cairo_region_t *region = NULL; cairo_region_t *region = NULL;
if (!stex)
return;
if (priv->window->frame != NULL && priv->window->input_region != NULL) if (priv->window->frame != NULL && priv->window->input_region != NULL)
{ {
region = meta_frame_get_frame_bounds (priv->window->frame); region = meta_frame_get_frame_bounds (priv->window->frame);
@ -2422,6 +2403,11 @@ static void
meta_window_actor_update_opaque_region (MetaWindowActor *self) meta_window_actor_update_opaque_region (MetaWindowActor *self)
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
MetaShapedTexture *stex;
stex = meta_surface_actor_get_texture (priv->surface);
if (!stex)
return;
g_clear_pointer (&priv->opaque_region, cairo_region_destroy); g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
@ -2450,8 +2436,7 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self)
else else
priv->opaque_region = cairo_region_reference (priv->shape_region); priv->opaque_region = cairo_region_reference (priv->shape_region);
meta_shaped_texture_set_opaque_region (META_SHAPED_TEXTURE (priv->actor), meta_shaped_texture_set_opaque_region (stex, priv->opaque_region);
priv->opaque_region);
} }
static void static void
@ -2494,40 +2479,7 @@ meta_window_actor_update_shape (MetaWindowActor *self)
if (is_frozen (self)) if (is_frozen (self))
return; return;
clutter_actor_queue_redraw (priv->actor); clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
}
static void
maybe_emit_size_changed (MetaWindowActor *self,
MetaWaylandBuffer *new_buffer)
{
MetaWindowActorPrivate *priv = self->priv;
int width = 0, height = 0;
if (new_buffer)
{
width = new_buffer->width;
height = new_buffer->height;
}
if (priv->last_width != width || priv->last_height != height)
{
meta_window_actor_update_shape (self);
/* ::size-changed is supposed to refer to meta_window_get_outer_rect()
* but here we are only looking at buffer size changes.
*
* Emitting it here works pretty much OK because a new buffer size (which
* will correspond to the outer rect with the addition of invisible
* borders) also normally implies a change to the outer rect. In the rare
* case where a change to the window size was exactly balanced by a
* change to the invisible borders, we would miss emitting the signal.
*/
g_signal_emit (self, signals[SIZE_CHANGED], 0);
priv->last_width = width;
priv->last_height = height;
}
} }
void void
@ -2535,13 +2487,7 @@ meta_window_actor_attach_wayland_buffer (MetaWindowActor *self,
MetaWaylandBuffer *buffer) MetaWaylandBuffer *buffer)
{ {
MetaWindowActorPrivate *priv = self->priv; MetaWindowActorPrivate *priv = self->priv;
MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor); meta_surface_actor_attach_wayland_buffer (priv->surface, buffer);
priv->buffer = buffer;
meta_shaped_texture_set_texture (stex, buffer->texture);
meta_window_actor_sync_actor_geometry (self, FALSE);
maybe_emit_size_changed (self, buffer);
} }
static void static void
@ -2793,7 +2739,7 @@ meta_window_actor_update_opacity (MetaWindowActor *self)
opacity = 255; opacity = 255;
self->priv->opacity = opacity; self->priv->opacity = opacity;
clutter_actor_set_opacity (self->priv->actor, opacity); clutter_actor_set_opacity (CLUTTER_ACTOR (self->priv->surface), opacity);
} }
void void