[metacity] compositor-xrender: move damage to MetaSurface



commit b6486d57bb03722e6aebfcaa76b3adb1a6d584e0
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Oct 3 23:45:18 2019 +0300

    compositor-xrender: move damage to MetaSurface

 src/compositor/meta-compositor-xrender.c |  36 +--------
 src/compositor/meta-compositor.c         |  58 +++++++++++++-
 src/compositor/meta-surface.c            | 126 +++++++++++++++++++++++++++++++
 src/compositor/meta-surface.h            |  10 ++-
 4 files changed, 192 insertions(+), 38 deletions(-)
---
diff --git a/src/compositor/meta-compositor-xrender.c b/src/compositor/meta-compositor-xrender.c
index 9edf15ba..3b05a250 100644
--- a/src/compositor/meta-compositor-xrender.c
+++ b/src/compositor/meta-compositor-xrender.c
@@ -101,7 +101,6 @@ typedef struct _MetaCompWindow
 
   XserverRegion shape_region;
 
-  Damage damage;
   Picture picture;
   Picture mask;
   Picture alpha_pict;
@@ -1683,25 +1682,13 @@ repair_win (MetaCompositorXRender *xrender,
   Display *xdisplay = meta_display_get_xdisplay (display);
   XserverRegion parts;
 
-  meta_error_trap_push (display);
-
   if (!cw->damaged)
     {
       parts = win_extents (xrender, cw);
-      XDamageSubtract (xdisplay, cw->damage, None, None);
-    }
-  else
-    {
-      parts = XFixesCreateRegion (xdisplay, 0, 0);
-      XDamageSubtract (xdisplay, cw->damage, None, parts);
-      XFixesTranslateRegion (xdisplay, parts, cw->rect.x, cw->rect.y);
+      meta_compositor_add_damage (compositor, "repair_win", parts);
+      XFixesDestroyRegion (xdisplay, parts);
     }
 
-  meta_error_trap_pop (display);
-
-  meta_compositor_add_damage (compositor, "repair_win", parts);
-  XFixesDestroyRegion (xdisplay, parts);
-
   cw->damaged = TRUE;
 }
 
@@ -1789,12 +1776,6 @@ free_win (MetaCompWindow *cw,
 
   if (destroy)
     {
-      if (cw->damage != None)
-        {
-          XDamageDestroy (xdisplay, cw->damage);
-          cw->damage = None;
-        }
-
       if (cw->shaded_surface != NULL)
         {
           cairo_surface_destroy (cw->shaded_surface);
@@ -1948,12 +1929,6 @@ notify_decorated_cb (MetaWindow            *window,
       cw->shape_region = None;
     }
 
-  if (cw->damage != None)
-    {
-      XDamageDestroy (xrender->xdisplay, cw->damage);
-      cw->damage = None;
-    }
-
   if (cw->picture != None)
     {
       XRenderFreePicture (xrender->xdisplay, cw->picture);
@@ -2009,10 +1984,6 @@ notify_decorated_cb (MetaWindow            *window,
       cw->border_clip = None;
     }
 
-  cw->damage = XDamageCreate (xrender->xdisplay,
-                              meta_window_get_toplevel_xwindow (window),
-                              XDamageReportNonEmpty);
-
   determine_mode (xrender, cw);
   cw->needs_shadow = window_has_shadow (xrender, cw);
 
@@ -2475,9 +2446,6 @@ meta_compositor_xrender_add_window (MetaCompositor *compositor,
                              cw->rect.x, cw->rect.y);
     }
 
-  xwindow = meta_window_get_toplevel_xwindow (window);
-  cw->damage = XDamageCreate (xrender->xdisplay, xwindow, XDamageReportNonEmpty);
-
   cw->alpha_pict = None;
 
   cw->window_region = None;
diff --git a/src/compositor/meta-compositor.c b/src/compositor/meta-compositor.c
index 12d2380b..723f050d 100644
--- a/src/compositor/meta-compositor.c
+++ b/src/compositor/meta-compositor.c
@@ -25,6 +25,7 @@
 
 #include "display-private.h"
 #include "errors.h"
+#include "frame.h"
 #include "util.h"
 #include "screen-private.h"
 
@@ -126,6 +127,43 @@ debug_damage_region (MetaCompositor *compositor,
     }
 }
 
+static MetaSurface *
+find_surface_by_xwindow (MetaCompositor *compositor,
+                         Window          xwindow)
+{
+  MetaCompositorPrivate *priv;
+  MetaSurface *surface;
+  GHashTableIter iter;
+
+  priv = meta_compositor_get_instance_private (compositor);
+  surface = NULL;
+
+  g_hash_table_iter_init (&iter, priv->surfaces);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer) &surface))
+    {
+      MetaWindow *window;
+      MetaFrame *frame;
+
+      window = meta_surface_get_window (surface);
+      frame = meta_window_get_frame (window);
+
+      if (frame != NULL)
+        {
+          if (meta_frame_get_xwindow (frame) == xwindow)
+            break;
+        }
+      else
+        {
+          if (meta_window_get_xwindow (window) == xwindow)
+            break;
+        }
+
+      surface = NULL;
+    }
+
+  return surface;
+}
+
 static gboolean
 redraw_idle_cb (gpointer user_data)
 {
@@ -472,11 +510,29 @@ meta_compositor_process_event (MetaCompositor *compositor,
                                XEvent         *event,
                                MetaWindow     *window)
 {
+  MetaCompositorPrivate *priv;
   MetaCompositorClass *compositor_class;
 
-  compositor_class = META_COMPOSITOR_GET_CLASS (compositor);
+  priv = meta_compositor_get_instance_private (compositor);
 
+  compositor_class = META_COMPOSITOR_GET_CLASS (compositor);
   compositor_class->process_event (compositor, event, window);
+
+  if (event->type == meta_display_get_damage_event_base (priv->display) + XDamageNotify)
+    {
+      XDamageNotifyEvent *damage_event;
+      MetaSurface *surface;
+
+      damage_event = (XDamageNotifyEvent *) event;
+
+      if (window != NULL)
+        surface = g_hash_table_lookup (priv->surfaces, window);
+      else
+        surface = find_surface_by_xwindow (compositor, damage_event->drawable);
+
+      if (surface != NULL)
+        meta_surface_process_damage (surface, damage_event);
+    }
 }
 
 cairo_surface_t *
diff --git a/src/compositor/meta-surface.c b/src/compositor/meta-surface.c
index f7bca565..c62633b2 100644
--- a/src/compositor/meta-surface.c
+++ b/src/compositor/meta-surface.c
@@ -18,10 +18,17 @@
 #include "config.h"
 #include "meta-surface-private.h"
 
+#include "display-private.h"
+#include "errors.h"
+#include "meta-compositor-private.h"
+#include "window-private.h"
+
 typedef struct
 {
   MetaCompositor *compositor;
   MetaWindow     *window;
+
+  Damage          damage;
 } MetaSurfacePrivate;
 
 enum
@@ -38,6 +45,89 @@ static GParamSpec *surface_properties[LAST_PROP] = { NULL };
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaSurface, meta_surface, G_TYPE_OBJECT)
 
+static void
+destroy_damage (MetaSurface *self)
+{
+  MetaSurfacePrivate *priv;
+  MetaDisplay *display;
+  Display *xdisplay;
+
+  priv = meta_surface_get_instance_private (self);
+
+  if (priv->damage == None)
+    return;
+
+  display = meta_compositor_get_display (priv->compositor);
+  xdisplay = meta_display_get_xdisplay (display);
+
+  meta_error_trap_push (display);
+
+  XDamageDestroy (xdisplay, priv->damage);
+  priv->damage = None;
+
+  meta_error_trap_pop (display);
+}
+
+static void
+create_damage (MetaSurface *self)
+{
+  MetaSurfacePrivate *priv;
+  MetaDisplay *display;
+  Display *xdisplay;
+
+  priv = meta_surface_get_instance_private (self);
+  display = meta_compositor_get_display (priv->compositor);
+  xdisplay = meta_display_get_xdisplay (display);
+
+  meta_error_trap_push (display);
+
+  g_assert (priv->damage == None);
+  priv->damage = XDamageCreate (xdisplay,
+                                meta_window_get_toplevel_xwindow (priv->window),
+                                XDamageReportNonEmpty);
+
+  meta_error_trap_pop (display);
+}
+
+static void
+notify_decorated_cb (MetaWindow  *window,
+                     GParamSpec  *pspec,
+                     MetaSurface *self)
+{
+  destroy_damage (self);
+  create_damage (self);
+}
+
+static void
+meta_surface_constructed (GObject *object)
+{
+  MetaSurface *self;
+  MetaSurfacePrivate *priv;
+
+  self = META_SURFACE (object);
+  priv = meta_surface_get_instance_private (self);
+
+  G_OBJECT_CLASS (meta_surface_parent_class)->constructed (object);
+
+  create_damage (self);
+
+  g_signal_connect_object (priv->window, "notify::decorated",
+                           G_CALLBACK (notify_decorated_cb),
+                           self, 0);
+}
+
+static void
+meta_surface_finalize (GObject *object)
+{
+  MetaSurface *self;
+
+  self = META_SURFACE (object);
+
+  destroy_damage (self);
+
+  G_OBJECT_CLASS (meta_surface_parent_class)->finalize (object);
+}
+
 static void
 meta_surface_get_property (GObject    *object,
                            guint       property_id,
@@ -122,6 +212,8 @@ meta_surface_class_init (MetaSurfaceClass *self_class)
 
   object_class = G_OBJECT_CLASS (self_class);
 
+  object_class->constructed = meta_surface_constructed;
+  object_class->finalize = meta_surface_finalize;
   object_class->get_property = meta_surface_get_property;
   object_class->set_property = meta_surface_set_property;
 
@@ -153,8 +245,42 @@ meta_surface_get_window (MetaSurface *self)
   return priv->window;
 }
 
+void
+meta_surface_process_damage (MetaSurface        *self,
+                             XDamageNotifyEvent *event)
+{
+  MetaSurfacePrivate *priv;
+
+  priv = meta_surface_get_instance_private (self);
+
+  meta_compositor_queue_redraw (priv->compositor);
+}
+
 void
 meta_surface_pre_paint (MetaSurface *self)
 {
+  MetaSurfacePrivate *priv;
+  MetaDisplay *display;
+  Display *xdisplay;
+  MetaRectangle rect;
+  XserverRegion parts;
+
+  priv = meta_surface_get_instance_private (self);
+  display = meta_compositor_get_display (priv->compositor);
+  xdisplay = meta_display_get_xdisplay (display);
+
+  meta_window_get_input_rect (priv->window, &rect);
+
+  meta_error_trap_push (display);
+
+  parts = XFixesCreateRegion (xdisplay, 0, 0);
+  XDamageSubtract (xdisplay, priv->damage, None, parts);
+  XFixesTranslateRegion (xdisplay, parts, rect.x, rect.y);
+
+  meta_error_trap_pop (display);
+
+  meta_compositor_add_damage (priv->compositor, "meta_surface_pre_paint", parts);
+  XFixesDestroyRegion (xdisplay, parts);
+
   META_SURFACE_GET_CLASS (self)->pre_paint (self);
 }
diff --git a/src/compositor/meta-surface.h b/src/compositor/meta-surface.h
index e975b187..ab17b5db 100644
--- a/src/compositor/meta-surface.h
+++ b/src/compositor/meta-surface.h
@@ -18,6 +18,7 @@
 #ifndef META_SURFACE_H
 #define META_SURFACE_H
 
+#include <X11/extensions/Xdamage.h>
 #include "meta-compositor.h"
 #include "window.h"
 
@@ -26,11 +27,14 @@ G_BEGIN_DECLS
 #define META_TYPE_SURFACE (meta_surface_get_type ())
 G_DECLARE_DERIVABLE_TYPE (MetaSurface, meta_surface, META, SURFACE, GObject)
 
-MetaCompositor *meta_surface_get_compositor (MetaSurface *self);
+MetaCompositor *meta_surface_get_compositor (MetaSurface        *self);
 
-MetaWindow     *meta_surface_get_window     (MetaSurface *self);
+MetaWindow     *meta_surface_get_window     (MetaSurface        *self);
 
-void            meta_surface_pre_paint      (MetaSurface *self);
+void            meta_surface_process_damage (MetaSurface        *self,
+                                             XDamageNotifyEvent *event);
+
+void            meta_surface_pre_paint      (MetaSurface        *self);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]