Compare commits
	
		
			3 Commits
		
	
	
		
			3.28.3
			...
			wip/surfac
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2210c30cba | ||
| 
						 | 
					6b98ac3d1f | ||
| 
						 | 
					13ddd366a9 | 
@@ -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		\
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										153
									
								
								src/compositor/meta-surface-actor-wayland.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								src/compositor/meta-surface-actor-wayland.c
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								src/compositor/meta-surface-actor-wayland.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/compositor/meta-surface-actor-wayland.h
									
									
									
									
									
										Normal file
									
								
							@@ -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__ */
 | 
			
		||||
							
								
								
									
										453
									
								
								src/compositor/meta-surface-actor-x11.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										453
									
								
								src/compositor/meta-surface-actor-x11.c
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								src/compositor/meta-surface-actor-x11.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/compositor/meta-surface-actor-x11.h
									
									
									
									
									
										Normal file
									
								
							@@ -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__ */
 | 
			
		||||
@@ -10,30 +10,30 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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 <clutter/clutter.h>
 | 
			
		||||
#include <meta/meta-shaped-texture.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));
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor      *self,
 | 
			
		||||
@@ -164,50 +164,11 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
  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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_surface_actor_damage_all (MetaSurfaceActor *self)
 | 
			
		||||
meta_surface_actor_update_area (MetaSurfaceActor *self,
 | 
			
		||||
                                int x, int y, int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  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));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_surface_actor_damage_area (MetaSurfaceActor *self,
 | 
			
		||||
                                int               x,
 | 
			
		||||
                                int               y,
 | 
			
		||||
                                int               width,
 | 
			
		||||
                                int               height)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  update_area (self, x, y, width, height);
 | 
			
		||||
  return meta_shaped_texture_update_area (priv->texture, x, y, width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -218,27 +179,6 @@ meta_surface_actor_is_obscured (MetaSurfaceActor *self)
 | 
			
		||||
  return meta_shaped_texture_is_obscured (priv->texture);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self,
 | 
			
		||||
                                          MetaWaylandBuffer *buffer)
 | 
			
		||||
{
 | 
			
		||||
  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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_set_texture (MetaSurfaceActor *self,
 | 
			
		||||
                                CoglTexture      *texture)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorPrivate *priv = self->priv;
 | 
			
		||||
  meta_shaped_texture_set_texture (priv->texture, texture);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_set_input_region (MetaSurfaceActor *self,
 | 
			
		||||
                                     cairo_region_t   *region)
 | 
			
		||||
@@ -262,20 +202,114 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
 | 
			
		||||
  meta_shaped_texture_set_opaque_region (priv->texture, region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWaylandSurface *
 | 
			
		||||
meta_surface_actor_get_surface (MetaSurfaceActor *self)
 | 
			
		||||
static gboolean
 | 
			
		||||
is_frozen (MetaSurfaceActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorPrivate *priv = self->priv;
 | 
			
		||||
  return priv->surface;
 | 
			
		||||
  return (priv->freeze_count > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaSurfaceActor *
 | 
			
		||||
meta_surface_actor_new (MetaWaylandSurface *surface)
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_process_damage (MetaSurfaceActor *self,
 | 
			
		||||
                                   int x, int y, int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActor *self = g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
 | 
			
		||||
  MetaSurfaceActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  priv->surface = surface;
 | 
			
		||||
  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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return self;
 | 
			
		||||
  META_SURFACE_ACTOR_GET_CLASS (self)->process_damage (self, x, y, width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_pre_paint (MetaSurfaceActor *self)
 | 
			
		||||
{
 | 
			
		||||
  META_SURFACE_ACTOR_GET_CLASS (self)->pre_paint (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_surface_actor_is_argb32 (MetaSurfaceActor *self)
 | 
			
		||||
{
 | 
			
		||||
  return META_SURFACE_ACTOR_GET_CLASS (self)->is_argb32 (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_surface_actor_is_visible (MetaSurfaceActor *self)
 | 
			
		||||
{
 | 
			
		||||
  return META_SURFACE_ACTOR_GET_CLASS (self)->is_visible (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_freeze (MetaSurfaceActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  priv->freeze_count ++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_thaw (MetaSurfaceActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_surface_actor_should_unredirect (MetaSurfaceActor *self)
 | 
			
		||||
{
 | 
			
		||||
  return META_SURFACE_ACTOR_GET_CLASS (self)->should_unredirect (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_set_unredirected (MetaSurfaceActor *self,
 | 
			
		||||
                                     gboolean          unredirected)
 | 
			
		||||
{
 | 
			
		||||
  META_SURFACE_ACTOR_GET_CLASS (self)->set_unredirected (self, unredirected);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_surface_actor_is_unredirected (MetaSurfaceActor *self)
 | 
			
		||||
{
 | 
			
		||||
  return META_SURFACE_ACTOR_GET_CLASS (self)->is_unredirected (self);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
gboolean 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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,24 +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		    needs_pixmap           : 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;
 | 
			
		||||
@@ -165,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);
 | 
			
		||||
@@ -256,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
 | 
			
		||||
@@ -266,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.
 | 
			
		||||
   */
 | 
			
		||||
@@ -307,13 +257,52 @@ surface_allocation_changed_notify (ClutterActor           *actor,
 | 
			
		||||
  meta_window_actor_update_shape (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_freeze (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  meta_surface_actor_freeze (priv->surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_actor_thaw (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  meta_surface_actor_thaw (priv->surface);
 | 
			
		||||
 | 
			
		||||
  if (is_frozen (self))
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -322,38 +311,15 @@ meta_window_actor_constructed (GObject *object)
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
  priv->screen = screen;
 | 
			
		||||
 | 
			
		||||
  if (!meta_is_wayland_compositor ())
 | 
			
		||||
    priv->damage = XDamageCreate (xdisplay, xwindow,
 | 
			
		||||
                                  XDamageReportBoundingBox);
 | 
			
		||||
 | 
			
		||||
  if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
 | 
			
		||||
    {
 | 
			
		||||
      XRenderPictFormat      *format;
 | 
			
		||||
 | 
			
		||||
      format = XRenderFindVisualFormat (xdisplay, window->xvisual);
 | 
			
		||||
 | 
			
		||||
      if (format && format->type == PictTypeDirect && format->direct.alphaMask)
 | 
			
		||||
        priv->argb32 = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* XXX: parse shm formats to determine argb32 */
 | 
			
		||||
      priv->argb32 = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  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));
 | 
			
		||||
@@ -376,8 +342,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)
 | 
			
		||||
@@ -388,9 +352,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);
 | 
			
		||||
@@ -405,18 +366,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);
 | 
			
		||||
@@ -827,13 +776,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)
 | 
			
		||||
{
 | 
			
		||||
@@ -888,55 +830,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->needs_pixmap)
 | 
			
		||||
    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)
 | 
			
		||||
@@ -991,33 +884,6 @@ meta_window_actor_effect_in_progress (MetaWindowActor *self)
 | 
			
		||||
	  self->priv->destroy_in_progress);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_frozen (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
  return self->priv->freeze_count ? TRUE : FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  priv->needs_pixmap = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (is_frozen (self))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* This will cause the compositor paint function to be run
 | 
			
		||||
   * if the actor is visible or a clone of the actor is visible.
 | 
			
		||||
   * if the actor isn't visible in any way, then we don't
 | 
			
		||||
   * need to repair the window anyways, and can wait until
 | 
			
		||||
   * the stage is redrawn for some other reason
 | 
			
		||||
   *
 | 
			
		||||
   * The compositor paint function repairs all windows.
 | 
			
		||||
   */
 | 
			
		||||
  clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_freeze_thaw_effect (gulong event)
 | 
			
		||||
{
 | 
			
		||||
@@ -1098,12 +964,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->needs_pixmap)
 | 
			
		||||
        clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -1178,95 +1038,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;
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_queue_create_x11_pixmap (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -1326,19 +1110,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,
 | 
			
		||||
@@ -1350,15 +1126,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_queue_create_x11_pixmap (self);
 | 
			
		||||
          meta_window_actor_update_shape (self);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (meta_window_actor_effect_in_progress (self))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
@@ -1525,22 +1292,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_queue_create_x11_pixmap (self);
 | 
			
		||||
 | 
			
		||||
      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);
 | 
			
		||||
 | 
			
		||||
@@ -1649,13 +1407,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);
 | 
			
		||||
}
 | 
			
		||||
@@ -1678,68 +1429,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 (!priv->needs_pixmap)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->needs_pixmap = FALSE;
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  meta_error_trap_pop (display);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
check_needs_shadow (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
@@ -1807,61 +1496,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->needs_pixmap)
 | 
			
		||||
    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
 | 
			
		||||
@@ -2089,8 +1729,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;
 | 
			
		||||
 | 
			
		||||
@@ -2110,7 +1751,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);
 | 
			
		||||
@@ -2167,9 +1808,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))
 | 
			
		||||
    {
 | 
			
		||||
@@ -2178,45 +1816,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);
 | 
			
		||||
  meta_surface_actor_pre_paint (priv->surface);
 | 
			
		||||
 | 
			
		||||
          /* 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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      check_needs_x11_pixmap (self);
 | 
			
		||||
    }
 | 
			
		||||
  if (!meta_surface_actor_is_visible (priv->surface))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  check_needs_reshape (self);
 | 
			
		||||
  check_needs_shadow (self);
 | 
			
		||||
@@ -2405,20 +2011,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;
 | 
			
		||||
 | 
			
		||||
  updates_frozen = updates_frozen != FALSE;
 | 
			
		||||
 | 
			
		||||
  if (priv->updates_frozen != updates_frozen)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
      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);
 | 
			
		||||
        }
 | 
			
		||||
      priv->updates_frozen = updates_frozen;
 | 
			
		||||
      if (updates_frozen)
 | 
			
		||||
        meta_window_actor_freeze (self);
 | 
			
		||||
      else
 | 
			
		||||
        meta_window_actor_thaw (self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user