[mutter/wayland] window-actor: Split into two subclasses of MetaSurfaceActor
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wayland] window-actor: Split into two subclasses of MetaSurfaceActor
- Date: Thu, 20 Feb 2014 19:45:16 +0000 (UTC)
commit 83aca0b53dc8706bea232cc2208c9fc1bc701607
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Sat Feb 1 17:21:11 2014 -0500
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
src/Makefile.am | 4 +
src/compositor/meta-surface-actor-wayland.c | 153 ++++++++
src/compositor/meta-surface-actor-wayland.h | 66 ++++
src/compositor/meta-surface-actor-x11.c | 453 ++++++++++++++++++++++
src/compositor/meta-surface-actor-x11.h | 69 ++++
src/compositor/meta-surface-actor.c | 205 +++++++----
src/compositor/meta-surface-actor.h | 43 ++-
src/compositor/meta-window-actor.c | 548 +++++----------------------
src/core/display.c | 5 +-
src/wayland/meta-wayland-seat.c | 5 +-
src/wayland/meta-wayland-surface.c | 13 +-
11 files changed, 1011 insertions(+), 553 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index ec8b2ec..ba029b7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -80,6 +80,10 @@ libmutter_wayland_la_SOURCES = \
compositor/meta-shaped-texture-private.h \
compositor/meta-surface-actor.c \
compositor/meta-surface-actor.h \
+ compositor/meta-surface-actor-x11.c \
+ compositor/meta-surface-actor-x11.h \
+ compositor/meta-surface-actor-wayland.c \
+ compositor/meta-surface-actor-wayland.h \
compositor/meta-texture-rectangle.c \
compositor/meta-texture-rectangle.h \
compositor/meta-texture-tower.c \
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
new file mode 100644
index 0000000..9fe1e82
--- /dev/null
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -0,0 +1,153 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2013 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#include "config.h"
+
+#include "meta-surface-actor-wayland.h"
+
+#include <cogl/cogl-wayland-server.h>
+#include "meta-shaped-texture-private.h"
+
+struct _MetaSurfaceActorWaylandPrivate
+{
+ MetaWaylandSurface *surface;
+ MetaWaylandBuffer *buffer;
+};
+typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorWayland, meta_surface_actor_wayland, META_TYPE_SURFACE_ACTOR)
+
+static void
+meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor,
+ int x, int y, int width, int height)
+{
+ MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
+ MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
+
+ 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_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0,
NULL);
+ }
+
+ meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height);
+}
+
+static void
+meta_surface_actor_wayland_pre_paint (MetaSurfaceActor *actor)
+{
+}
+
+static gboolean
+meta_surface_actor_wayland_is_argb32 (MetaSurfaceActor *actor)
+{
+ /* XXX -- look at the SHM buffer format. */
+ return TRUE;
+}
+
+static gboolean
+meta_surface_actor_wayland_is_visible (MetaSurfaceActor *actor)
+{
+ /* TODO: ensure that the buffer isn't NULL, implement
+ * wayland mapping semantics */
+ return TRUE;
+}
+
+static gboolean
+meta_surface_actor_wayland_should_unredirect (MetaSurfaceActor *actor)
+{
+ return FALSE;
+}
+
+static void
+meta_surface_actor_wayland_set_unredirected (MetaSurfaceActor *actor,
+ gboolean unredirected)
+{
+ /* Do nothing. In the future, we'll use KMS to set this
+ * up as a hardware overlay or something. */
+}
+
+static gboolean
+meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
+{
+ return FALSE;
+}
+
+static void
+meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
+{
+ MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
+
+ surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
+ surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
+ surface_actor_class->is_argb32 = meta_surface_actor_wayland_is_argb32;
+ surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible;
+
+ surface_actor_class->should_unredirect = meta_surface_actor_wayland_should_unredirect;
+ surface_actor_class->set_unredirected = meta_surface_actor_wayland_set_unredirected;
+ surface_actor_class->is_unredirected = meta_surface_actor_wayland_is_unredirected;
+}
+
+static void
+meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self)
+{
+}
+
+MetaSurfaceActor *
+meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
+{
+ MetaSurfaceActorWayland *self = g_object_new (META_TYPE_SURFACE_ACTOR_WAYLAND, NULL);
+ MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
+
+ g_assert (meta_is_wayland_compositor ());
+
+ priv->surface = surface;
+
+ return META_SURFACE_ACTOR (self);
+}
+
+void
+meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
+ MetaWaylandBuffer *buffer)
+{
+ MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
+ MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
+
+ priv->buffer = buffer;
+
+ if (buffer)
+ meta_shaped_texture_set_texture (stex, buffer->texture);
+ else
+ meta_shaped_texture_set_texture (stex, NULL);
+}
+
+MetaWaylandSurface *
+meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self)
+{
+ MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
+ return priv->surface;
+}
diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h
new file mode 100644
index 0000000..89c6b30
--- /dev/null
+++ b/src/compositor/meta-surface-actor-wayland.h
@@ -0,0 +1,66 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2013 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#ifndef __META_SURFACE_ACTOR_WAYLAND_H__
+#define __META_SURFACE_ACTOR_WAYLAND_H__
+
+#include <glib-object.h>
+
+#include "meta-surface-actor.h"
+
+#include "meta-wayland-private.h"
+
+G_BEGIN_DECLS
+
+#define META_TYPE_SURFACE_ACTOR_WAYLAND (meta_surface_actor_wayland_get_type ())
+#define META_SURFACE_ACTOR_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWayland))
+#define META_SURFACE_ACTOR_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWaylandClass))
+#define META_IS_SURFACE_ACTOR_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
META_TYPE_SURFACE_ACTOR_WAYLAND))
+#define META_IS_SURFACE_ACTOR_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
META_TYPE_SURFACE_ACTOR_WAYLAND))
+#define META_SURFACE_ACTOR_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
META_TYPE_SURFACE_ACTOR_WAYLAND, MetaSurfaceActorWaylandClass))
+
+typedef struct _MetaSurfaceActorWayland MetaSurfaceActorWayland;
+typedef struct _MetaSurfaceActorWaylandClass MetaSurfaceActorWaylandClass;
+
+struct _MetaSurfaceActorWayland
+{
+ MetaSurfaceActor parent;
+};
+
+struct _MetaSurfaceActorWaylandClass
+{
+ MetaSurfaceActorClass parent_class;
+};
+
+GType meta_surface_actor_wayland_get_type (void);
+
+MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface);
+MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self);
+
+void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
+ MetaWaylandBuffer *buffer);
+
+G_END_DECLS
+
+#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */
diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c
new file mode 100644
index 0000000..3eea2c3
--- /dev/null
+++ b/src/compositor/meta-surface-actor-x11.c
@@ -0,0 +1,453 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2013 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ * Owen Taylor <otaylor redhat com>
+ * Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#include "config.h"
+
+#include "meta-surface-actor-x11.h"
+
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xrender.h>
+#include <cogl/cogl-texture-pixmap-x11.h>
+
+#include <meta/errors.h>
+#include "window-private.h"
+#include "meta-shaped-texture-private.h"
+#include "meta-cullable.h"
+
+struct _MetaSurfaceActorX11Private
+{
+ MetaWindow *window;
+
+ MetaDisplay *display;
+
+ CoglTexture *texture;
+ Pixmap pixmap;
+ Damage damage;
+
+ int last_width;
+ int last_height;
+
+ /* This is used to detect fullscreen windows that need to be unredirected */
+ guint full_damage_frames_count;
+ guint does_full_damage : 1;
+
+ /* Other state... */
+ guint argb32 : 1;
+ guint received_damage : 1;
+ guint size_changed : 1;
+
+ guint unredirected : 1;
+};
+typedef struct _MetaSurfaceActorX11Private MetaSurfaceActorX11Private;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorX11, meta_surface_actor_x11, META_TYPE_SURFACE_ACTOR)
+
+static void
+free_damage (MetaSurfaceActorX11 *self)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+ MetaDisplay *display = priv->display;
+ Display *xdisplay = meta_display_get_xdisplay (display);
+
+ if (priv->damage == None)
+ return;
+
+ meta_error_trap_push (display);
+ XDamageDestroy (xdisplay, priv->damage);
+ priv->damage = None;
+ meta_error_trap_pop (display);
+}
+
+static void
+detach_pixmap (MetaSurfaceActorX11 *self)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+ MetaDisplay *display = priv->display;
+ Display *xdisplay = meta_display_get_xdisplay (display);
+ MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
+
+ if (priv->pixmap == None)
+ return;
+
+ /* Get rid of all references to the pixmap before freeing it; it's unclear whether
+ * 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
+ */
+ meta_shaped_texture_set_texture (stex, NULL);
+ cogl_flush ();
+
+ meta_error_trap_push (display);
+ XFreePixmap (xdisplay, priv->pixmap);
+ priv->pixmap = None;
+ meta_error_trap_pop (display);
+
+ cogl_object_unref (priv->texture);
+ priv->texture = NULL;
+}
+
+static void
+set_pixmap (MetaSurfaceActorX11 *self,
+ Pixmap pixmap)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+
+ CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
+ MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
+ CoglTexture *texture;
+
+ g_assert (priv->pixmap == None);
+ priv->pixmap = pixmap;
+
+ texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->pixmap, FALSE, NULL));
+
+ if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
+ g_warning ("NOTE: Not using GLX TFP!\n");
+
+ priv->texture = texture;
+ meta_shaped_texture_set_texture (stex, texture);
+}
+
+static void
+update_pixmap (MetaSurfaceActorX11 *self)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+ MetaDisplay *display = priv->display;
+ Display *xdisplay = meta_display_get_xdisplay (display);
+
+ if (priv->size_changed)
+ {
+ detach_pixmap (self);
+ priv->size_changed = FALSE;
+ }
+
+ if (priv->pixmap == None)
+ {
+ Pixmap new_pixmap;
+ Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
+
+ meta_error_trap_push (display);
+ new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow);
+
+ if (meta_error_trap_pop_with_return (display) != Success)
+ {
+ /* Probably a BadMatch if the window isn't viewable; we could
+ * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync
+ * to avoid this, but there's no reason to take two round trips
+ * when one will do. (We need that Sync if we want to handle failures
+ * for any reason other than !viewable. That's unlikely, but maybe
+ * we'll BadAlloc or something.)
+ */
+ new_pixmap = None;
+ }
+
+ if (new_pixmap == None)
+ {
+ meta_verbose ("Unable to get named pixmap for %s\n",
+ meta_window_get_description (priv->window));
+ return;
+ }
+
+ set_pixmap (self, new_pixmap);
+ }
+}
+
+static gboolean
+is_visible (MetaSurfaceActorX11 *self)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+ return (priv->pixmap != None) && !priv->unredirected;
+}
+
+static void
+damage_area (MetaSurfaceActorX11 *self,
+ int x, int y, int width, int height)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+
+ if (!is_visible (self))
+ return;
+
+ cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height);
+ meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height);
+}
+
+static void
+meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
+ int x, int y, int width, int height)
+{
+ MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+
+ priv->received_damage = TRUE;
+
+ if (meta_window_is_fullscreen (priv->window) && !priv->unredirected && !priv->does_full_damage)
+ {
+ MetaRectangle window_rect;
+ meta_window_get_frame_rect (priv->window, &window_rect);
+
+ if (window_rect.x == x &&
+ window_rect.y == y &&
+ window_rect.width == width &&
+ window_rect.height == height)
+ priv->full_damage_frames_count++;
+ else
+ priv->full_damage_frames_count = 0;
+
+ if (priv->full_damage_frames_count >= 100)
+ priv->does_full_damage = TRUE;
+ }
+
+ /* Drop damage event for unredirected windows */
+ if (priv->unredirected)
+ return;
+
+ damage_area (self, x, y, width, height);
+}
+
+static void
+meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor)
+{
+ MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+ MetaDisplay *display = priv->display;
+ Display *xdisplay = meta_display_get_xdisplay (display);
+
+ if (priv->received_damage)
+ {
+ meta_error_trap_push (display);
+ XDamageSubtract (xdisplay, priv->damage, None, None);
+ meta_error_trap_pop (display);
+
+ /* We need to make sure that any X drawing that happens before the
+ * XDamageSubtract() above is visible to subsequent GL rendering;
+ * the only standardized way to do this is EXT_x11_sync_object,
+ * which isn't yet widely available. For now, we count on details
+ * of Xorg and the open source drivers, and hope for the best
+ * otherwise.
+ *
+ * Xorg and open source driver specifics:
+ *
+ * The X server makes sure to flush drawing to the kernel before
+ * sending out damage events, but since we use DamageReportBoundingBox
+ * there may be drawing between the last damage event and the
+ * XDamageSubtract() that needs to be flushed as well.
+ *
+ * Xorg always makes sure that drawing is flushed to the kernel
+ * before writing events or responses to the client, so any round trip
+ * request at this point is sufficient to flush the GLX buffers.
+ */
+ XSync (xdisplay, False);
+
+ priv->received_damage = FALSE;
+ }
+
+ update_pixmap (self);
+}
+
+static void
+update_is_argb32 (MetaSurfaceActorX11 *self)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+ MetaDisplay *display = priv->display;
+ Display *xdisplay = meta_display_get_xdisplay (display);
+
+ XRenderPictFormat *format;
+ format = XRenderFindVisualFormat (xdisplay, priv->window->xvisual);
+
+ priv->argb32 = (format && format->type == PictTypeDirect && format->direct.alphaMask);
+}
+
+static gboolean
+meta_surface_actor_x11_is_argb32 (MetaSurfaceActor *actor)
+{
+ MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+
+ return priv->argb32;
+}
+
+static gboolean
+meta_surface_actor_x11_is_visible (MetaSurfaceActor *actor)
+{
+ MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
+ return is_visible (self);
+}
+
+static gboolean
+meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor)
+{
+ MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+
+ MetaWindow *window = priv->window;
+
+ if (meta_window_requested_dont_bypass_compositor (window))
+ return FALSE;
+
+ if (window->opacity != 0xFF)
+ return FALSE;
+
+ if (window->shape_region != NULL)
+ return FALSE;
+
+ if (priv->argb32 && !meta_window_requested_bypass_compositor (window))
+ return FALSE;
+
+ if (!meta_window_is_monitor_sized (window))
+ return FALSE;
+
+ if (meta_window_requested_bypass_compositor (window))
+ return TRUE;
+
+ if (meta_window_is_override_redirect (window))
+ return TRUE;
+
+ if (priv->does_full_damage)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+sync_unredirected (MetaSurfaceActorX11 *self)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+ MetaDisplay *display = priv->display;
+ Display *xdisplay = meta_display_get_xdisplay (display);
+ Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
+
+ meta_error_trap_push (display);
+
+ if (priv->unredirected)
+ {
+ detach_pixmap (self);
+ XCompositeUnredirectWindow (xdisplay, xwindow, CompositeRedirectManual);
+ }
+ else
+ {
+ XCompositeRedirectWindow (xdisplay, xwindow, CompositeRedirectManual);
+ }
+
+ meta_error_trap_pop (display);
+}
+
+static void
+meta_surface_actor_x11_set_unredirected (MetaSurfaceActor *actor,
+ gboolean unredirected)
+{
+ MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+
+ if (priv->unredirected == unredirected)
+ return;
+
+ priv->unredirected = unredirected;
+ sync_unredirected (self);
+}
+
+static gboolean
+meta_surface_actor_x11_is_unredirected (MetaSurfaceActor *actor)
+{
+ MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+
+ return priv->unredirected;
+}
+
+static void
+meta_surface_actor_x11_dispose (GObject *object)
+{
+ MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object);
+
+ detach_pixmap (self);
+ free_damage (self);
+
+ G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object);
+}
+
+static void
+meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
+
+ object_class->dispose = meta_surface_actor_x11_dispose;
+
+ surface_actor_class->process_damage = meta_surface_actor_x11_process_damage;
+ surface_actor_class->pre_paint = meta_surface_actor_x11_pre_paint;
+ surface_actor_class->is_argb32 = meta_surface_actor_x11_is_argb32;
+ surface_actor_class->is_visible = meta_surface_actor_x11_is_visible;
+
+ surface_actor_class->should_unredirect = meta_surface_actor_x11_should_unredirect;
+ surface_actor_class->set_unredirected = meta_surface_actor_x11_set_unredirected;
+ surface_actor_class->is_unredirected = meta_surface_actor_x11_is_unredirected;
+}
+
+static void
+meta_surface_actor_x11_init (MetaSurfaceActorX11 *self)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+
+ priv->last_width = -1;
+ priv->last_height = -1;
+}
+
+MetaSurfaceActor *
+meta_surface_actor_x11_new (MetaWindow *window)
+{
+ MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL);
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+ MetaDisplay *display = meta_window_get_display (window);
+ Display *xdisplay = meta_display_get_xdisplay (display);
+ Window xwindow = meta_window_get_toplevel_xwindow (window);
+
+ g_assert (!meta_is_wayland_compositor ());
+
+ priv->window = window;
+ priv->display = display;
+
+ priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox);
+ update_is_argb32 (self);
+
+ priv->unredirected = FALSE;
+ sync_unredirected (self);
+
+ return META_SURFACE_ACTOR (self);
+}
+
+void
+meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
+ int width, int height)
+{
+ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+
+ if (priv->last_width == width &&
+ priv->last_height == height)
+ return;
+
+ priv->size_changed = TRUE;
+ priv->last_width = width;
+ priv->last_height = height;
+}
diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h
new file mode 100644
index 0000000..0e692ee
--- /dev/null
+++ b/src/compositor/meta-surface-actor-x11.h
@@ -0,0 +1,69 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2013 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ * Owen Taylor <otaylor redhat com>
+ * Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#ifndef __META_SURFACE_ACTOR_X11_H__
+#define __META_SURFACE_ACTOR_X11_H__
+
+#include <glib-object.h>
+
+#include "meta-surface-actor.h"
+
+#include <X11/extensions/Xdamage.h>
+
+#include <meta/display.h>
+#include <meta/window.h>
+
+G_BEGIN_DECLS
+
+#define META_TYPE_SURFACE_ACTOR_X11 (meta_surface_actor_x11_get_type ())
+#define META_SURFACE_ACTOR_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11))
+#define META_SURFACE_ACTOR_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11Class))
+#define META_IS_SURFACE_ACTOR_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
META_TYPE_SURFACE_ACTOR_X11))
+#define META_IS_SURFACE_ACTOR_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
META_TYPE_SURFACE_ACTOR_X11))
+#define META_SURFACE_ACTOR_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
META_TYPE_SURFACE_ACTOR_X11, MetaSurfaceActorX11Class))
+
+typedef struct _MetaSurfaceActorX11 MetaSurfaceActorX11;
+typedef struct _MetaSurfaceActorX11Class MetaSurfaceActorX11Class;
+
+struct _MetaSurfaceActorX11
+{
+ MetaSurfaceActor parent;
+};
+
+struct _MetaSurfaceActorX11Class
+{
+ MetaSurfaceActorClass parent_class;
+};
+
+GType meta_surface_actor_x11_get_type (void);
+
+MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window);
+
+void meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
+ int width, int height);
+
+G_END_DECLS
+
+#endif /* __META_SURFACE_ACTOR_X11_H__ */
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 5afa4d7..f82a6a9 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -10,30 +10,38 @@
*/
#include <config.h>
+
+#include "meta-surface-actor.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-wayland-private.h"
#include "meta-cullable.h"
-
#include "meta-shaped-texture-private.h"
struct _MetaSurfaceActorPrivate
{
- MetaWaylandSurface *surface;
-
MetaShapedTexture *texture;
- MetaWaylandBuffer *buffer;
cairo_region_t *input_region;
+
+ /* Freeze/thaw accounting */
+ guint freeze_count;
+ guint needs_damage_all : 1;
};
static void cullable_iface_init (MetaCullableInterface *iface);
-G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR,
- G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR,
+ G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
+
+enum {
+ REPAINT_SCHEDULED,
+
+ LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL];
gboolean
meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
@@ -114,6 +122,13 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
object_class->dispose = meta_surface_actor_dispose;
actor_class->pick = meta_surface_actor_pick;
+ signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
+
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
}
@@ -164,118 +179,154 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self)
return self->priv->texture;
}
-static void
-update_area (MetaSurfaceActor *self,
- int x, int y, int width, int height)
+void
+meta_surface_actor_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_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y,
0, NULL);
- }
- }
- 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);
- }
+ if (meta_shaped_texture_update_area (priv->texture, x, y, width, height))
+ g_signal_emit (self, signals[REPAINT_SCHEDULED], 0);
}
gboolean
-meta_surface_actor_damage_all (MetaSurfaceActor *self)
+meta_surface_actor_is_obscured (MetaSurfaceActor *self)
{
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 (priv->texture, 0, 0, cogl_texture_get_width (texture),
cogl_texture_get_height (texture));
+ return meta_shaped_texture_is_obscured (priv->texture);
}
-gboolean
-meta_surface_actor_damage_area (MetaSurfaceActor *self,
- int x,
- int y,
- int width,
- int height)
+void
+meta_surface_actor_set_input_region (MetaSurfaceActor *self,
+ cairo_region_t *region)
{
MetaSurfaceActorPrivate *priv = self->priv;
- update_area (self, x, y, width, height);
- return meta_shaped_texture_update_area (priv->texture, x, y, width, height);
+ if (priv->input_region)
+ cairo_region_destroy (priv->input_region);
+
+ if (region)
+ priv->input_region = cairo_region_reference (region);
+ else
+ priv->input_region = NULL;
}
-gboolean
-meta_surface_actor_is_obscured (MetaSurfaceActor *self)
+void
+meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
+ cairo_region_t *region)
{
MetaSurfaceActorPrivate *priv = self->priv;
- return meta_shaped_texture_is_obscured (priv->texture);
+ meta_shaped_texture_set_opaque_region (priv->texture, region);
}
-void
-meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self,
- MetaWaylandBuffer *buffer)
+static gboolean
+is_frozen (MetaSurfaceActor *self)
{
MetaSurfaceActorPrivate *priv = self->priv;
- priv->buffer = buffer;
-
- if (buffer)
- meta_shaped_texture_set_texture (priv->texture, buffer->texture);
- else
- meta_shaped_texture_set_texture (priv->texture, NULL);
+ return (priv->freeze_count > 0);
}
void
-meta_surface_actor_set_texture (MetaSurfaceActor *self,
- CoglTexture *texture)
+meta_surface_actor_process_damage (MetaSurfaceActor *self,
+ int x, int y, int width, int height)
{
MetaSurfaceActorPrivate *priv = self->priv;
- meta_shaped_texture_set_texture (priv->texture, texture);
+
+ if (is_frozen (self))
+ {
+ /* The window is frozen due to an effect in progress: we ignore damage
+ * here on the off chance that this will stop the corresponding
+ * texture_from_pixmap from being update.
+ *
+ * needs_damage_all tracks that some unknown damage happened while the
+ * window was frozen so that when the window becomes unfrozen we can
+ * issue a full window update to cover any lost damage.
+ *
+ * It should be noted that this is an unreliable mechanism since it's
+ * quite likely that drivers will aim to provide a zero-copy
+ * implementation of the texture_from_pixmap extension and in those cases
+ * any drawing done to the window is always immediately reflected in the
+ * texture regardless of damage event handling.
+ */
+ priv->needs_damage_all = TRUE;
+ return;
+ }
+
+ META_SURFACE_ACTOR_GET_CLASS (self)->process_damage (self, x, y, width, height);
}
void
-meta_surface_actor_set_input_region (MetaSurfaceActor *self,
- cairo_region_t *region)
+meta_surface_actor_pre_paint (MetaSurfaceActor *self)
{
- MetaSurfaceActorPrivate *priv = self->priv;
+ META_SURFACE_ACTOR_GET_CLASS (self)->pre_paint (self);
+}
- if (priv->input_region)
- cairo_region_destroy (priv->input_region);
+gboolean
+meta_surface_actor_is_argb32 (MetaSurfaceActor *self)
+{
+ return META_SURFACE_ACTOR_GET_CLASS (self)->is_argb32 (self);
+}
- if (region)
- priv->input_region = cairo_region_reference (region);
- else
- priv->input_region = NULL;
+gboolean
+meta_surface_actor_is_visible (MetaSurfaceActor *self)
+{
+ return META_SURFACE_ACTOR_GET_CLASS (self)->is_visible (self);
}
void
-meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
- cairo_region_t *region)
+meta_surface_actor_freeze (MetaSurfaceActor *self)
{
MetaSurfaceActorPrivate *priv = self->priv;
- meta_shaped_texture_set_opaque_region (priv->texture, region);
+
+ priv->freeze_count ++;
}
-MetaWaylandSurface *
-meta_surface_actor_get_surface (MetaSurfaceActor *self)
+void
+meta_surface_actor_thaw (MetaSurfaceActor *self)
{
MetaSurfaceActorPrivate *priv = self->priv;
- return priv->surface;
+
+ if (priv->freeze_count == 0)
+ {
+ g_critical ("Error in freeze/thaw accounting.");
+ return;
+ }
+
+ priv->freeze_count --;
+
+ /* Since we ignore damage events while a window is frozen for certain effects
+ * we may need to issue an update_area() covering the whole pixmap if we
+ * don't know what real damage has happened. */
+ if (priv->needs_damage_all)
+ {
+ meta_surface_actor_process_damage (self, 0, 0,
+ clutter_actor_get_width (CLUTTER_ACTOR (priv->texture)),
+ clutter_actor_get_height (CLUTTER_ACTOR (priv->texture)));
+ priv->needs_damage_all = FALSE;
+ }
+}
+
+gboolean
+meta_surface_actor_is_frozen (MetaSurfaceActor *self)
+{
+ return is_frozen (self);
}
-MetaSurfaceActor *
-meta_surface_actor_new (MetaWaylandSurface *surface)
+gboolean
+meta_surface_actor_should_unredirect (MetaSurfaceActor *self)
{
- MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
- MetaSurfaceActorPrivate *priv = self->priv;
+ return META_SURFACE_ACTOR_GET_CLASS (self)->should_unredirect (self);
+}
- priv->surface = surface;
+void
+meta_surface_actor_set_unredirected (MetaSurfaceActor *self,
+ gboolean unredirected)
+{
+ META_SURFACE_ACTOR_GET_CLASS (self)->set_unredirected (self, unredirected);
+}
- return self;
+gboolean
+meta_surface_actor_is_unredirected (MetaSurfaceActor *self)
+{
+ return META_SURFACE_ACTOR_GET_CLASS (self)->is_unredirected (self);
}
diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h
index e42deb4..763f91d 100644
--- a/src/compositor/meta-surface-actor.h
+++ b/src/compositor/meta-surface-actor.h
@@ -6,7 +6,6 @@
#include <config.h>
#include <meta/meta-shaped-texture.h>
-#include "meta-wayland-types.h"
G_BEGIN_DECLS
@@ -25,6 +24,17 @@ struct _MetaSurfaceActorClass
{
/*< private >*/
ClutterActorClass parent_class;
+
+ void (* process_damage) (MetaSurfaceActor *actor,
+ int x, int y, int width, int height);
+ void (* pre_paint) (MetaSurfaceActor *actor);
+ gboolean (* is_argb32) (MetaSurfaceActor *actor);
+ gboolean (* is_visible) (MetaSurfaceActor *actor);
+
+ gboolean (* should_unredirect) (MetaSurfaceActor *actor);
+ void (* set_unredirected) (MetaSurfaceActor *actor,
+ gboolean unredirected);
+ gboolean (* is_unredirected) (MetaSurfaceActor *actor);
};
struct _MetaSurfaceActor
@@ -36,34 +46,37 @@ struct _MetaSurfaceActor
GType meta_surface_actor_get_type (void);
-MetaSurfaceActor *meta_surface_actor_new (MetaWaylandSurface *surface);
-
cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self,
cairo_rectangle_int_t *clip);
MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self);
-gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self);
-gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self,
- int x,
- int y,
- int width,
- int height);
-
gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self);
gboolean meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
cairo_rectangle_int_t *unobscured_bounds);
-void meta_surface_actor_set_texture (MetaSurfaceActor *self,
- CoglTexture *texture);
-void meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self,
- MetaWaylandBuffer *buffer);
void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
cairo_region_t *region);
void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
cairo_region_t *region);
-MetaWaylandSurface *meta_surface_actor_get_surface (MetaSurfaceActor *surface);
+void meta_surface_actor_update_area (MetaSurfaceActor *actor,
+ int x, int y, int width, int height);
+
+void meta_surface_actor_process_damage (MetaSurfaceActor *actor,
+ int x, int y, int width, int height);
+void meta_surface_actor_pre_paint (MetaSurfaceActor *actor);
+gboolean meta_surface_actor_is_argb32 (MetaSurfaceActor *actor);
+gboolean meta_surface_actor_is_visible (MetaSurfaceActor *actor);
+
+void meta_surface_actor_freeze (MetaSurfaceActor *actor);
+void meta_surface_actor_thaw (MetaSurfaceActor *actor);
+gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor);
+
+gboolean meta_surface_actor_should_unredirect (MetaSurfaceActor *actor);
+void meta_surface_actor_set_unredirected (MetaSurfaceActor *actor,
+ gboolean unredirected);
+gboolean meta_surface_actor_is_unredirected (MetaSurfaceActor *actor);
G_END_DECLS
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index d0e57d3..597a209 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -10,10 +10,6 @@
#include <math.h>
-#include <X11/extensions/Xcomposite.h>
-#include <X11/extensions/Xdamage.h>
-#include <X11/extensions/Xrender.h>
-
#include <clutter/x11/clutter-x11.h>
#include <cogl/cogl-texture-pixmap-x11.h>
#include <gdk/gdk.h> /* for gdk_rectangle_union() */
@@ -30,13 +26,15 @@
#include "meta-shaped-texture-private.h"
#include "meta-shadow-factory-private.h"
#include "meta-window-actor-private.h"
-#include "meta-surface-actor.h"
#include "meta-texture-rectangle.h"
#include "region-utils.h"
#include "meta-wayland-private.h"
#include "monitor-private.h"
#include "meta-cullable.h"
+#include "meta-surface-actor.h"
+#include "meta-surface-actor-x11.h"
+
struct _MetaWindowActorPrivate
{
MetaWindow *window;
@@ -63,19 +61,13 @@ struct _MetaWindowActorPrivate
/* The region we should clip to when painting the shadow */
cairo_region_t *shadow_clip;
- guint send_frame_messages_timer;
- gint64 frame_drawn_time;
-
/* Extracted size-invariant shape used for shadows */
MetaWindowShape *shadow_shape;
-
- gint last_width;
- gint last_height;
-
- gint freeze_count;
-
char * shadow_class;
+ guint send_frame_messages_timer;
+ gint64 frame_drawn_time;
+
/*
* These need to be counters rather than flags, since more plugins
* can implement same effect; the practicality of stacking effects
@@ -90,11 +82,7 @@ struct _MetaWindowActorPrivate
/* List of FrameData for recent frames */
GList *frames;
- Pixmap back_pixmap; /* Not used in wayland compositor mode */
- Damage damage; /* Not used in wayland compositor mode */
-
guint visible : 1;
- guint argb32 : 1;
guint disposed : 1;
guint redecorating : 1;
@@ -111,22 +99,7 @@ struct _MetaWindowActorPrivate
guint no_shadow : 1;
-
- /*
- * None of these are used in wayland compositor mode...
- */
-
- guint needs_damage_all : 1;
- guint received_x11_damage : 1;
-
- guint x11_size_changed : 1;
guint updates_frozen : 1;
-
- guint unredirected : 1;
-
- /* This is used to detect fullscreen windows that need to be unredirected */
- guint full_damage_frames_count;
- guint does_full_damage : 1;
};
typedef struct _FrameData FrameData;
@@ -163,7 +136,6 @@ static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume);
-static void meta_window_actor_detach_x11_pixmap (MetaWindowActor *self);
static gboolean meta_window_actor_has_shadow (MetaWindowActor *self);
static void meta_window_actor_handle_updates (MetaWindowActor *self);
@@ -254,9 +226,6 @@ window_decorated_notify (MetaWindow *mw,
{
MetaWindowActor *self = META_WINDOW_ACTOR (data);
MetaWindowActorPrivate *priv = self->priv;
- MetaScreen *screen = priv->screen;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
/*
* Basically, we have to reconstruct the the internals of this object
@@ -264,23 +233,6 @@ window_decorated_notify (MetaWindow *mw,
*/
priv->redecorating = TRUE;
- if (!meta_is_wayland_compositor ())
- {
- meta_window_actor_detach_x11_pixmap (self);
-
- /*
- * First of all, clean up any resources we are currently using and will
- * be replacing.
- */
- if (priv->damage != None)
- {
- meta_error_trap_push (display);
- XDamageDestroy (xdisplay, priv->damage);
- meta_error_trap_pop (display);
- priv->damage = None;
- }
- }
-
/*
* Recreate the contents.
*/
@@ -305,57 +257,85 @@ surface_allocation_changed_notify (ClutterActor *actor,
meta_window_actor_update_shape (self);
}
+static void
+surface_repaint_scheduled (MetaSurfaceActor *actor,
+ gpointer user_data)
+{
+ MetaWindowActor *self = META_WINDOW_ACTOR (user_data);
+ MetaWindowActorPrivate *priv = self->priv;
+
+ priv->repaint_scheduled = TRUE;
+}
+
+static gboolean
+is_argb32 (MetaWindowActor *self)
+{
+ MetaWindowActorPrivate *priv = self->priv;
+ return meta_surface_actor_is_argb32 (priv->surface);
+}
+
static gboolean
is_non_opaque (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
MetaWindow *window = priv->window;
- return priv->argb32 || (window->opacity != 0xFF);
+ return is_argb32 (self) || (window->opacity != 0xFF);
+}
+
+static gboolean
+is_frozen (MetaWindowActor *self)
+{
+ MetaWindowActorPrivate *priv = self->priv;
+ return meta_surface_actor_is_frozen (priv->surface);
}
static void
-meta_window_actor_constructed (GObject *object)
+meta_window_actor_freeze (MetaWindowActor *self)
{
- MetaWindowActor *self = META_WINDOW_ACTOR (object);
- MetaWindowActorPrivate *priv = self->priv;
- MetaWindow *window = priv->window;
- Window xwindow = meta_window_get_toplevel_xwindow (window);
- MetaScreen *screen = meta_window_get_screen (window);
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
+ MetaWindowActorPrivate *priv = self->priv;
+ meta_surface_actor_freeze (priv->surface);
+}
- priv->screen = screen;
+static void
+meta_window_actor_thaw (MetaWindowActor *self)
+{
+ MetaWindowActorPrivate *priv = self->priv;
- if (!meta_is_wayland_compositor ())
- priv->damage = XDamageCreate (xdisplay, xwindow,
- XDamageReportBoundingBox);
+ meta_surface_actor_thaw (priv->surface);
- if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
- {
- XRenderPictFormat *format;
+ if (is_frozen (self))
+ return;
- format = XRenderFindVisualFormat (xdisplay, window->xvisual);
+ /* We sometimes ignore moves and resizes on frozen windows */
+ meta_window_actor_sync_actor_geometry (self, FALSE);
- if (format && format->type == PictTypeDirect && format->direct.alphaMask)
- priv->argb32 = TRUE;
- }
- else
- {
- /* XXX: parse shm formats to determine argb32 */
- priv->argb32 = TRUE;
- }
+ /* We do this now since we might be going right back into the
+ * frozen state */
+ meta_window_actor_handle_updates (self);
+}
+
+static void
+meta_window_actor_constructed (GObject *object)
+{
+ MetaWindowActor *self = META_WINDOW_ACTOR (object);
+ MetaWindowActorPrivate *priv = self->priv;
+ MetaWindow *window = priv->window;
+
+ priv->screen = window->screen;
if (!priv->surface)
{
if (window->surface)
priv->surface = window->surface->surface_actor;
else
- priv->surface = meta_surface_actor_new (NULL);
+ priv->surface = meta_surface_actor_x11_new (window);
g_object_ref_sink (priv->surface);
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
+ g_signal_connect_object (priv->surface, "repaint-scheduled",
+ G_CALLBACK (surface_repaint_scheduled), self, 0);
g_signal_connect_object (priv->surface, "allocation-changed",
G_CALLBACK (surface_allocation_changed_notify), self, 0);
meta_window_actor_update_shape (self);
@@ -374,8 +354,6 @@ meta_window_actor_dispose (GObject *object)
MetaWindowActor *self = META_WINDOW_ACTOR (object);
MetaWindowActorPrivate *priv = self->priv;
MetaScreen *screen;
- MetaDisplay *display;
- Display *xdisplay;
MetaCompScreen *info;
if (priv->disposed)
@@ -386,9 +364,6 @@ meta_window_actor_dispose (GObject *object)
screen = priv->screen;
info = meta_screen_get_compositor_data (screen);
- if (!meta_is_wayland_compositor ())
- meta_window_actor_detach_x11_pixmap (self);
-
if (priv->send_frame_messages_timer != 0)
{
g_source_remove (priv->send_frame_messages_timer);
@@ -403,18 +378,6 @@ meta_window_actor_dispose (GObject *object)
g_clear_pointer (&priv->unfocused_shadow, meta_shadow_unref);
g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref);
- if (!meta_is_wayland_compositor () && priv->damage != None)
- {
- display = meta_screen_get_display (screen);
- xdisplay = meta_display_get_xdisplay (display);
-
- meta_error_trap_push (display);
- XDamageDestroy (xdisplay, priv->damage);
- meta_error_trap_pop (display);
-
- priv->damage = None;
- }
-
info->windows = g_list_remove (info->windows, (gconstpointer) self);
g_clear_object (&priv->window);
@@ -825,13 +788,6 @@ meta_window_actor_is_destroyed (MetaWindowActor *self)
return self->priv->disposed;
}
-static void
-meta_window_actor_freeze (MetaWindowActor *self)
-{
- if (!meta_is_wayland_compositor ())
- self->priv->freeze_count++;
-}
-
static gboolean
send_frame_messages_timeout (gpointer data)
{
@@ -886,55 +842,6 @@ 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);
}
-static void
-meta_window_actor_damage_all (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv = self->priv;
- gboolean redraw_queued;
-
- if (!priv->needs_damage_all)
- return;
-
- if (priv->back_pixmap == None)
- return;
-
- redraw_queued = meta_surface_actor_damage_all (priv->surface);
- priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
- priv->needs_damage_all = FALSE;
-}
-
-static void
-meta_window_actor_thaw (MetaWindowActor *self)
-{
- if (!meta_is_wayland_compositor ())
- {
- self->priv->freeze_count--;
-
- if (G_UNLIKELY (self->priv->freeze_count < 0))
- {
- g_warning ("Error in freeze/thaw accounting.");
- self->priv->freeze_count = 0;
- return;
- }
-
- if (self->priv->freeze_count)
- return;
-
- /* We sometimes ignore moves and resizes on frozen windows */
- meta_window_actor_sync_actor_geometry (self, FALSE);
-
- /* We do this now since we might be going right back into the
- * frozen state */
- meta_window_actor_handle_updates (self);
-
- /* Since we ignore damage events while a window is frozen for certain effects
- * we may need to issue an update_area() covering the whole pixmap if we
- * don't know what real damage has happened. */
- if (self->priv->needs_damage_all)
- meta_window_actor_damage_all (self);
- }
-}
-
void
meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
gboolean no_delay_frame)
@@ -990,12 +897,6 @@ meta_window_actor_effect_in_progress (MetaWindowActor *self)
}
static gboolean
-is_frozen (MetaWindowActor *self)
-{
- return self->priv->freeze_count ? TRUE : FALSE;
-}
-
-static gboolean
is_freeze_thaw_effect (gulong event)
{
switch (event)
@@ -1075,12 +976,6 @@ meta_window_actor_after_effects (MetaWindowActor *self)
meta_window_actor_sync_visibility (self);
meta_window_actor_sync_actor_geometry (self, FALSE);
-
- if (!meta_is_wayland_compositor ())
- {
- if (priv->back_pixmap == None)
- clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
- }
}
void
@@ -1155,93 +1050,19 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
meta_window_actor_after_effects (self);
}
-/* Called to drop our reference to a window backing pixmap that we
- * previously obtained with XCompositeNameWindowPixmap. We do this
- * when the window is unmapped or when we want to update to a new
- * pixmap for a new size.
- */
-static void
-meta_window_actor_detach_x11_pixmap (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv = self->priv;
- MetaScreen *screen = priv->screen;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
-
- if (!priv->back_pixmap)
- return;
-
- /* Get rid of all references to the pixmap before freeing it; it's unclear whether
- * 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
- */
- meta_surface_actor_set_texture (priv->surface, NULL);
- cogl_flush();
-
- XFreePixmap (xdisplay, priv->back_pixmap);
- priv->back_pixmap = None;
-}
-
gboolean
meta_window_actor_should_unredirect (MetaWindowActor *self)
{
- MetaWindow *metaWindow = meta_window_actor_get_meta_window (self);
MetaWindowActorPrivate *priv = self->priv;
-
- if (meta_is_wayland_compositor ())
- return FALSE;
-
- if (meta_window_requested_dont_bypass_compositor (metaWindow))
- return FALSE;
-
- if (metaWindow->opacity != 0xFF)
- return FALSE;
-
- if (metaWindow->shape_region != NULL)
- return FALSE;
-
- if (priv->argb32 && !meta_window_requested_bypass_compositor (metaWindow))
- return FALSE;
-
- if (!meta_window_is_monitor_sized (metaWindow))
- return FALSE;
-
- if (meta_window_requested_bypass_compositor (metaWindow))
- return TRUE;
-
- if (meta_window_is_override_redirect (metaWindow))
- return TRUE;
-
- if (priv->does_full_damage)
- return TRUE;
-
- return FALSE;
+ return meta_surface_actor_should_unredirect (priv->surface);
}
void
meta_window_actor_set_unredirected (MetaWindowActor *self,
gboolean unredirected)
{
- MetaWindow *metaWindow = meta_window_actor_get_meta_window (self);
- MetaDisplay *display = meta_window_get_display (metaWindow);
-
- Display *xdisplay = meta_display_get_xdisplay (display);
- Window xwin = meta_window_get_toplevel_xwindow (metaWindow);
-
- meta_error_trap_push (display);
-
- if (unredirected)
- {
- XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual);
- }
- else
- {
- XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual);
- meta_window_actor_detach_x11_pixmap (self);
- }
-
- self->priv->unredirected = unredirected;
- meta_error_trap_pop (display);
+ MetaWindowActorPrivate *priv = self->priv;
+ meta_surface_actor_set_unredirected (priv->surface, unredirected);
}
void
@@ -1301,19 +1122,11 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
meta_window_get_input_rect (priv->window, &window_rect);
- /* When running as a display server we catch size changes when new
- buffers are attached */
- if (!meta_is_wayland_compositor ())
- {
- if (priv->last_width != window_rect.width ||
- priv->last_height != window_rect.height)
- {
- priv->x11_size_changed = TRUE;
-
- priv->last_width = window_rect.width;
- priv->last_height = window_rect.height;
- }
- }
+ /* When running as a Wayland compositor we catch size changes when new
+ * buffers are attached */
+ if (META_IS_SURFACE_ACTOR_X11 (priv->surface))
+ meta_surface_actor_x11_set_size (META_SURFACE_ACTOR_X11 (priv->surface),
+ window_rect.width, window_rect.height);
/* Normally we want freezing a window to also freeze its position; this allows
* windows to atomically move and resize together, either under app control,
@@ -1325,15 +1138,6 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
if (is_frozen (self) && !did_placement)
return;
- if (!meta_is_wayland_compositor ())
- {
- if (priv->x11_size_changed)
- {
- meta_window_actor_detach_x11_pixmap (self);
- meta_window_actor_update_shape (self);
- }
- }
-
if (meta_window_actor_effect_in_progress (self))
return;
@@ -1500,20 +1304,13 @@ meta_window_actor_new (MetaWindow *window)
priv = self->priv;
- if (!meta_is_wayland_compositor ())
- {
- priv->last_width = -1;
- priv->last_height = -1;
-
- meta_window_actor_set_updates_frozen (self,
- meta_window_updates_are_frozen (priv->window));
+ meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window));
- /* If a window doesn't start off with updates frozen, we should
- * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn.
- */
- if (priv->window->extended_sync_request_counter && !priv->updates_frozen)
- meta_window_actor_queue_frame_drawn (self, FALSE);
- }
+ /* If a window doesn't start off with updates frozen, we should
+ * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn.
+ */
+ if (priv->window->extended_sync_request_counter && !priv->updates_frozen)
+ meta_window_actor_queue_frame_drawn (self, FALSE);
meta_window_actor_sync_actor_geometry (self, priv->window->placed);
@@ -1622,13 +1419,6 @@ meta_window_actor_cull_out (MetaCullable *cullable,
cairo_region_t *clip_region)
{
MetaWindowActor *self = META_WINDOW_ACTOR (cullable);
- MetaWindowActorPrivate *priv = self->priv;
-
- meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
-
- /* Don't do any culling for the unredirected window */
- if (priv->unredirected)
- return;
meta_window_actor_set_clip_region_beneath (self, clip_region);
}
@@ -1651,65 +1441,6 @@ cullable_iface_init (MetaCullableInterface *iface)
iface->reset_culling = meta_window_actor_reset_culling;
}
-/* When running as a wayland compositor we don't make requests for
- * replacement pixmaps when resizing windows, we will instead be
- * asked to attach replacement buffers by the clients. */
-static void
-check_needs_x11_pixmap (MetaWindowActor *self)
-{
- MetaWindowActorPrivate *priv = self->priv;
- MetaDisplay *display = meta_screen_get_display (priv->screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
- Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
-
- /* If the size changed while we were frozen, the old pixmap
- * will still be attached, and we need to create a new one. */
- if (priv->x11_size_changed)
- {
- meta_window_actor_detach_x11_pixmap (self);
- priv->x11_size_changed = FALSE;
- }
-
- meta_error_trap_push (display);
-
- if (priv->back_pixmap == None)
- {
- CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
- CoglTexture *texture;
-
- meta_error_trap_push (display);
-
- priv->back_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow);
-
- if (meta_error_trap_pop_with_return (display) != Success)
- {
- /* Probably a BadMatch if the window isn't viewable; we could
- * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync
- * to avoid this, but there's no reason to take two round trips
- * when one will do. (We need that Sync if we want to handle failures
- * for any reason other than !viewable. That's unlikely, but maybe
- * we'll BadAlloc or something.)
- */
- priv->back_pixmap = None;
- }
-
- if (priv->back_pixmap == None)
- {
- meta_verbose ("Unable to get named pixmap for %p\n", self);
- goto out;
- }
-
- 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))))
- g_warning ("NOTE: Not using GLX TFP!\n");
-
- meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture);
- }
-
- out:
- meta_error_trap_pop (display);
-}
-
static void
check_needs_shadow (MetaWindowActor *self)
{
@@ -1777,61 +1508,12 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
XDamageNotifyEvent *event)
{
MetaWindowActorPrivate *priv = self->priv;
- MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen);
- gboolean redraw_queued;
- priv->received_x11_damage = TRUE;
-
- if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self &&
!priv->unredirected)
- {
- MetaRectangle window_rect;
- meta_window_get_frame_rect (priv->window, &window_rect);
-
- if (window_rect.x == event->area.x &&
- window_rect.y == event->area.y &&
- window_rect.width == event->area.width &&
- window_rect.height == event->area.height)
- priv->full_damage_frames_count++;
- else
- priv->full_damage_frames_count = 0;
-
- if (priv->full_damage_frames_count >= 100)
- priv->does_full_damage = TRUE;
- }
-
- /* Drop damage event for unredirected windows */
- if (priv->unredirected)
- return;
-
- if (is_frozen (self))
- {
- /* The window is frozen due to an effect in progress: we ignore damage
- * here on the off chance that this will stop the corresponding
- * texture_from_pixmap from being update.
- *
- * needs_damage_all tracks that some unknown damage happened while the
- * window was frozen so that when the window becomes unfrozen we can
- * issue a full window update to cover any lost damage.
- *
- * It should be noted that this is an unreliable mechanism since it's
- * quite likely that drivers will aim to provide a zero-copy
- * implementation of the texture_from_pixmap extension and in those cases
- * any drawing done to the window is always immediately reflected in the
- * texture regardless of damage event handling.
- */
- priv->needs_damage_all = TRUE;
- return;
- }
-
- if (priv->back_pixmap == None)
- return;
-
- redraw_queued = meta_surface_actor_damage_area (priv->surface,
- event->area.x,
- event->area.y,
- event->area.width,
- event->area.height);
- priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
+ meta_surface_actor_process_damage (priv->surface,
+ event->area.x,
+ event->area.y,
+ event->area.width,
+ event->area.height);
}
void
@@ -2059,8 +1741,9 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
cairo_region_t *opaque_region;
+ gboolean argb32 = is_argb32 (self);
- if (priv->argb32 && priv->window->opaque_region != NULL)
+ if (argb32 && priv->window->opaque_region != NULL)
{
MetaFrameBorders borders;
@@ -2080,7 +1763,7 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self)
cairo_region_translate (opaque_region, borders.total.left, borders.total.top);
cairo_region_intersect (opaque_region, priv->shape_region);
}
- else if (priv->argb32)
+ else if (argb32)
opaque_region = NULL;
else
opaque_region = cairo_region_reference (priv->shape_region);
@@ -2137,9 +1820,6 @@ static void
meta_window_actor_handle_updates (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
- MetaScreen *screen = priv->screen;
- MetaDisplay *display = meta_screen_get_display (screen);
- Display *xdisplay = meta_display_get_xdisplay (display);
if (is_frozen (self))
{
@@ -2148,45 +1828,13 @@ meta_window_actor_handle_updates (MetaWindowActor *self)
return;
}
- if (!meta_is_wayland_compositor ())
- {
- if (priv->unredirected)
- {
- /* Nothing to do here until/if the window gets redirected again */
- return;
- }
+ if (meta_surface_actor_is_unredirected (priv->surface))
+ return;
- if (priv->received_x11_damage)
- {
- meta_error_trap_push (display);
- XDamageSubtract (xdisplay, priv->damage, None, None);
- meta_error_trap_pop (display);
-
- /* We need to make sure that any X drawing that happens before the
- * XDamageSubtract() above is visible to subsequent GL rendering;
- * the only standardized way to do this is EXT_x11_sync_object,
- * which isn't yet widely available. For now, we count on details
- * of Xorg and the open source drivers, and hope for the best
- * otherwise.
- *
- * Xorg and open source driver specifics:
- *
- * The X server makes sure to flush drawing to the kernel before
- * sending out damage events, but since we use DamageReportBoundingBox
- * there may be drawing between the last damage event and the
- * XDamageSubtract() that needs to be flushed as well.
- *
- * Xorg always makes sure that drawing is flushed to the kernel
- * before writing events or responses to the client, so any round trip
- * request at this point is sufficient to flush the GLX buffers.
- */
- XSync (xdisplay, False);
-
- priv->received_x11_damage = FALSE;
- }
+ meta_surface_actor_pre_paint (priv->surface);
- check_needs_x11_pixmap (self);
- }
+ if (!meta_surface_actor_is_visible (priv->surface))
+ return;
check_needs_reshape (self);
check_needs_shadow (self);
@@ -2375,20 +2023,16 @@ void
meta_window_actor_set_updates_frozen (MetaWindowActor *self,
gboolean updates_frozen)
{
- /* On wayland we shouldn't need to ever freeze updates... */
- if (!meta_is_wayland_compositor ())
- {
- MetaWindowActorPrivate *priv = self->priv;
+ MetaWindowActorPrivate *priv = self->priv;
- updates_frozen = updates_frozen != FALSE;
+ updates_frozen = updates_frozen != FALSE;
- if (priv->updates_frozen != updates_frozen)
- {
- priv->updates_frozen = updates_frozen;
- if (updates_frozen)
- meta_window_actor_freeze (self);
- else
- meta_window_actor_thaw (self);
- }
+ if (priv->updates_frozen != updates_frozen)
+ {
+ priv->updates_frozen = updates_frozen;
+ if (updates_frozen)
+ meta_window_actor_freeze (self);
+ else
+ meta_window_actor_thaw (self);
}
}
diff --git a/src/core/display.c b/src/core/display.c
index 907f1a5..d3a03bd 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -73,6 +73,7 @@
#include <unistd.h>
#include "meta-xwayland-private.h"
+#include "meta-surface-actor-wayland.h"
#define GRAB_OP_IS_WINDOW_SWITCH(g) \
(g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \
@@ -1682,9 +1683,9 @@ get_window_for_event (MetaDisplay *display,
return display->grab_window;
source = clutter_event_get_source (event);
- if (META_IS_SURFACE_ACTOR (source))
+ if (META_IS_SURFACE_ACTOR_WAYLAND (source))
{
- MetaWaylandSurface *surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (source));
+ MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND
(source));
g_assert (surface != NULL);
return surface->window;
}
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index df8e781..d730729 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -38,6 +38,7 @@
#include "meta-shaped-texture-private.h"
#include "meta-wayland-stage.h"
#include "meta-cursor-tracker-private.h"
+#include "meta-surface-actor-wayland.h"
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
@@ -420,8 +421,8 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
else
seat->current_stage = NULL;
- if (META_IS_SURFACE_ACTOR (actor))
- surface = meta_surface_actor_get_surface (META_SURFACE_ACTOR (actor));
+ if (META_IS_SURFACE_ACTOR_WAYLAND (actor))
+ surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor));
pointer->current = surface;
if (surface != pointer->focus_surface)
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 7d92573..0783316 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -44,11 +44,11 @@
#include "meta-wayland-private.h"
#include "meta-xwayland-private.h"
#include "meta-wayland-stage.h"
-#include "meta-surface-actor.h"
#include "meta-wayland-seat.h"
#include "meta-wayland-keyboard.h"
#include "meta-wayland-pointer.h"
#include "meta-wayland-data-device.h"
+
#include "meta-cursor-tracker-private.h"
#include "display-private.h"
#include "window-private.h"
@@ -58,6 +58,9 @@
#include "meta-idle-monitor-private.h"
#include "monitor-private.h"
+#include "meta-surface-actor.h"
+#include "meta-surface-actor-wayland.h"
+
typedef enum
{
META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE,
@@ -114,8 +117,8 @@ surface_process_damage (MetaWaylandSurface *surface,
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (region, i, &rect);
- meta_surface_actor_damage_area (surface->surface_actor,
- rect.x, rect.y, rect.width, rect.height);
+ meta_surface_actor_process_damage (surface->surface_actor,
+ rect.x, rect.y, rect.width, rect.height);
}
}
@@ -295,7 +298,7 @@ actor_surface_commit (MetaWaylandSurface *surface,
if (buffer_changed)
{
ensure_buffer_texture (buffer);
- meta_surface_actor_attach_wayland_buffer (surface_actor, buffer);
+ meta_surface_actor_wayland_set_buffer (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), buffer);
}
surface_process_damage (surface, pending->damage);
@@ -645,7 +648,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
wl_resource_set_implementation (surface->resource, &meta_wayland_surface_interface, surface,
wl_surface_destructor);
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
- surface->surface_actor = g_object_ref_sink (meta_surface_actor_new (surface));
+ surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface));
clutter_actor_set_reactive (CLUTTER_ACTOR (surface->surface_actor), TRUE);
double_buffered_state_init (&surface->pending);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]