[metacity] compositor-xrender: move shadow to MetaSurfaceXRender



commit ebd188833d0b7c95099c9d393e5b4bd2a5b552a8
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Wed Oct 23 00:49:05 2019 +0300

    compositor-xrender: move shadow to MetaSurfaceXRender

 src/compositor/meta-compositor-xrender.c | 225 +------------------------------
 src/compositor/meta-surface-xrender.c    | 175 ++++++++++++++++++++++--
 src/compositor/meta-surface-xrender.h    |  14 +-
 3 files changed, 181 insertions(+), 233 deletions(-)
---
diff --git a/src/compositor/meta-compositor-xrender.c b/src/compositor/meta-compositor-xrender.c
index 9a0cc474..be00d311 100644
--- a/src/compositor/meta-compositor-xrender.c
+++ b/src/compositor/meta-compositor-xrender.c
@@ -82,17 +82,6 @@ typedef struct _shadow
   guchar *shadow_top;
 } shadow;
 
-typedef struct _MetaCompWindow
-{
-  MetaWindow *window;
-
-  MetaRectangle rect;
-
-  MetaShadowXRender *shadow;
-
-  gboolean shadow_changed;
-} MetaCompWindow;
-
 struct _MetaCompositorXRender
 {
   MetaCompositor  parent;
@@ -725,76 +714,6 @@ paint_root (MetaCompositorXRender *xrender,
                     0, 0, 0, 0, 0, 0, width, height);
 }
 
-static void
-shadow_changed (MetaSurface *surface)
-{
-  MetaCompositor *compositor;
-  MetaCompositorXRender *xrender;
-  MetaCompWindow *cw;
-  XserverRegion shadow_region;
-
-  compositor = meta_surface_get_compositor (surface);
-  xrender = META_COMPOSITOR_XRENDER (compositor);
-
-  if (xrender->have_shadows == FALSE)
-    return;
-
-  cw = g_object_get_data (G_OBJECT (surface), "cw");
-
-  if (cw->shadow == NULL)
-    {
-      meta_compositor_queue_redraw (compositor);
-      return;
-    }
-
-  shadow_region = meta_shadow_xrender_get_region (cw->shadow);
-  XFixesTranslateRegion (xrender->xdisplay, shadow_region, cw->rect.x, cw->rect.y);
-  meta_compositor_add_damage (compositor, "shadow_changed", shadow_region);
-  XFixesDestroyRegion (xrender->xdisplay, shadow_region);
-
-  meta_shadow_xrender_free (cw->shadow);
-  cw->shadow = NULL;
-
-  cw->shadow_changed = TRUE;
-}
-
-static void
-paint_shadow (MetaCompositorXRender *xrender,
-              MetaSurfaceXRender    *surface_xrender,
-              XserverRegion          paint_region,
-              Picture                paint_buffer)
-{
-  MetaCompWindow *cw;
-  XserverRegion border_clip;
-  XserverRegion shadow_clip;
-
-  cw = g_object_get_data (G_OBJECT (surface_xrender), "cw");
-
-  if (cw->shadow == NULL)
-    return;
-
-  border_clip = meta_surface_xrender_get_border_clip (surface_xrender);
-
-  shadow_clip = XFixesCreateRegion (xrender->xdisplay, NULL, 0);
-  XFixesCopyRegion (xrender->xdisplay, shadow_clip, border_clip);
-
-  if (paint_region != None)
-    {
-      XFixesIntersectRegion (xrender->xdisplay,
-                             shadow_clip,
-                             shadow_clip,
-                             paint_region);
-    }
-
-  meta_shadow_xrender_paint (cw->shadow,
-                             shadow_clip,
-                             paint_buffer,
-                             cw->rect.x,
-                             cw->rect.y);
-
-  XFixesDestroyRegion (xrender->xdisplay, shadow_clip);
-}
-
 static void
 paint_dock_shadows (MetaCompositorXRender *xrender,
                     GList                 *surfaces,
@@ -816,7 +735,11 @@ paint_dock_shadows (MetaCompositorXRender *xrender,
       window = meta_surface_get_window (surface);
 
       if (window->type == META_WINDOW_DOCK)
-        paint_shadow (xrender, META_SURFACE_XRENDER (surface), region, root_buffer);
+        {
+          meta_surface_xrender_paint_shadow (META_SURFACE_XRENDER (surface),
+                                             region,
+                                             root_buffer);
+        }
     }
 }
 
@@ -906,7 +829,7 @@ paint_windows (MetaCompositorXRender *xrender,
       window = meta_surface_get_window (surface);
 
       if (window->type != META_WINDOW_DOCK)
-        paint_shadow (xrender, surface_xrender, None, root_buffer);
+        meta_surface_xrender_paint_shadow (surface_xrender, None, root_buffer);
 
       meta_surface_xrender_paint (surface_xrender, None, root_buffer, FALSE);
     }
@@ -954,46 +877,6 @@ paint_all (MetaCompositorXRender *xrender,
                     screen_width, screen_height);
 }
 
-static void
-cw_destroy_cb (gpointer data)
-{
-  MetaCompWindow *cw;
-
-  cw = (MetaCompWindow *) data;
-
-  if (cw->shadow != NULL)
-    {
-      meta_shadow_xrender_free (cw->shadow);
-      cw->shadow = NULL;
-    }
-
-  g_free (cw);
-}
-
-static void
-notify_appears_focused_cb (MetaWindow  *window,
-                           GParamSpec  *pspec,
-                           MetaSurface *surface)
-{
-  shadow_changed (surface);
-}
-
-static void
-notify_decorated_cb (MetaWindow  *window,
-                     GParamSpec  *pspec,
-                     MetaSurface *surface)
-{
-  shadow_changed (surface);
-}
-
-static void
-notify_window_type_cb (MetaWindow  *window,
-                       GParamSpec  *pspec,
-                       MetaSurface *surface)
-{
-  shadow_changed (surface);
-}
-
 /* event processors must all be called with an error trap in place */
 static void
 process_property_notify (MetaCompositorXRender *xrender,
@@ -1047,7 +930,7 @@ update_shadows (MetaPreference pref,
   stack = meta_compositor_get_stack (META_COMPOSITOR (data));
 
   for (index = stack; index; index = index->next)
-    shadow_changed (META_SURFACE (index->data));
+    meta_surface_xrender_update_shadow (META_SURFACE_XRENDER (index->data));
 }
 
 static void
@@ -1191,44 +1074,13 @@ static MetaSurface *
 meta_compositor_xrender_add_window (MetaCompositor *compositor,
                                     MetaWindow     *window)
 {
-  MetaCompositorXRender *xrender;
-  MetaDisplay *display;
   MetaSurface *surface;
-  MetaCompWindow *cw;
-
-  xrender = META_COMPOSITOR_XRENDER (compositor);
-  display = meta_compositor_get_display (compositor);
-
-  meta_error_trap_push (display);
 
   surface = g_object_new (META_TYPE_SURFACE_XRENDER,
                           "compositor", compositor,
                           "window", window,
                           NULL);
 
-  cw = g_new0 (MetaCompWindow, 1);
-  cw->window = window;
-
-  g_object_set_data_full (G_OBJECT (surface), "cw", cw, cw_destroy_cb);
-
-  meta_window_get_input_rect (window, &cw->rect);
-
-  g_signal_connect_object (window, "notify::appears-focused",
-                           G_CALLBACK (notify_appears_focused_cb),
-                           surface, 0);
-
-  g_signal_connect_object (window, "notify::decorated",
-                           G_CALLBACK (notify_decorated_cb),
-                           surface, 0);
-
-  g_signal_connect_object (window, "notify::window-type",
-                           G_CALLBACK (notify_window_type_cb),
-                           surface, 0);
-
-  cw->shadow_changed = xrender->have_shadows;
-
-  meta_error_trap_pop (display);
-
   return surface;
 }
 
@@ -1236,7 +1088,6 @@ static void
 meta_compositor_xrender_remove_window (MetaCompositor *compositor,
                                        MetaSurface    *surface)
 {
-  shadow_changed (surface);
 }
 
 static void
@@ -1244,14 +1095,12 @@ meta_compositor_xrender_hide_window (MetaCompositor *compositor,
                                      MetaSurface    *surface,
                                      MetaEffectType  effect)
 {
-  shadow_changed (surface);
 }
 
 static void
 meta_compositor_xrender_window_opacity_changed (MetaCompositor *compositor,
                                                 MetaSurface    *surface)
 {
-  shadow_changed (surface);
 }
 
 static void
@@ -1305,39 +1154,12 @@ static void
 meta_compositor_xrender_sync_window_geometry (MetaCompositor *compositor,
                                               MetaSurface    *surface)
 {
-  MetaCompositorXRender *xrender;
-  MetaCompWindow *cw;
-  MetaRectangle old_rect;
-
-  xrender = META_COMPOSITOR_XRENDER (compositor);
-
-  cw = g_object_get_data (G_OBJECT (surface), "cw");
-
-  old_rect = cw->rect;
-  meta_window_get_input_rect (cw->window, &cw->rect);
-
-  if (cw->rect.width != old_rect.width || cw->rect.height != old_rect.height)
-    {
-      shadow_changed (surface);
-    }
-  else if (cw->shadow != NULL)
-    {
-      XserverRegion region;
-
-      region = meta_shadow_xrender_get_region (cw->shadow);
-      XFixesTranslateRegion (xrender->xdisplay, region, old_rect.x, old_rect.y);
-
-      meta_compositor_add_damage (compositor, "sync_window_geometry", region);
-      XFixesDestroyRegion (xrender->xdisplay, region);
-    }
 }
 
 static void
 meta_compositor_xrender_pre_paint (MetaCompositor *compositor)
 {
   MetaCompositorXRender *xrender;
-  GList *stack;
-  GList *l;
 
   xrender = META_COMPOSITOR_XRENDER (compositor);
 
@@ -1348,39 +1170,6 @@ meta_compositor_xrender_pre_paint (MetaCompositor *compositor)
     xrender->root_tile = root_tile (xrender->screen);
 
   META_COMPOSITOR_CLASS (meta_compositor_xrender_parent_class)->pre_paint (compositor);
-
-  stack = meta_compositor_get_stack (compositor);
-
-  for (l = stack; l != NULL; l = l->next)
-    {
-      MetaSurface *surface;
-      MetaCompWindow *cw;
-
-      surface = META_SURFACE (l->data);
-      cw = g_object_get_data (G_OBJECT (surface), "cw");
-
-      if (cw->shadow_changed &&
-          meta_surface_has_shadow (surface))
-        {
-          XserverRegion shadow_region;
-
-          g_assert (cw->shadow == NULL);
-          cw->shadow = meta_compositor_xrender_create_shadow (xrender, surface);
-
-          shadow_region = meta_shadow_xrender_get_region (cw->shadow);
-          XFixesTranslateRegion (xrender->xdisplay,
-                                 shadow_region,
-                                 meta_surface_get_x (surface),
-                                 meta_surface_get_y (surface));
-
-          meta_compositor_add_damage (compositor,
-                                      "meta_compositor_xrender_pre_paint",
-                                      shadow_region);
-
-          XFixesDestroyRegion (xrender->xdisplay, shadow_region);
-          cw->shadow_changed = FALSE;
-        }
-    }
 }
 
 static void
diff --git a/src/compositor/meta-surface-xrender.c b/src/compositor/meta-surface-xrender.c
index 74043052..5047cc34 100644
--- a/src/compositor/meta-surface-xrender.c
+++ b/src/compositor/meta-surface-xrender.c
@@ -25,27 +25,68 @@
 #include "display.h"
 #include "errors.h"
 #include "frame.h"
+#include "meta-compositor-xrender.h"
+#include "meta-shadow-xrender.h"
 #include "window-private.h"
 
 #define OPAQUE 0xffffffff
 
 struct _MetaSurfaceXRender
 {
-  MetaSurface    parent;
+  MetaSurface        parent;
 
-  MetaDisplay   *display;
-  Display       *xdisplay;
+  MetaDisplay       *display;
+  Display           *xdisplay;
 
-  Picture        picture;
+  Picture            picture;
 
-  Pixmap         mask_pixmap;
-  Picture        mask_picture;
+  Pixmap             mask_pixmap;
+  Picture            mask_picture;
 
-  XserverRegion  border_clip;
+  XserverRegion      border_clip;
+
+  MetaShadowXRender *shadow;
+  gboolean           shadow_changed;
 };
 
 G_DEFINE_TYPE (MetaSurfaceXRender, meta_surface_xrender, META_TYPE_SURFACE)
 
+static void
+shadow_changed (MetaSurfaceXRender *self)
+{
+  MetaSurface *surface;
+  MetaCompositor *compositor;
+
+  surface = META_SURFACE (self);
+
+  compositor = meta_surface_get_compositor (surface);
+
+  if (self->shadow != NULL)
+    {
+      int x;
+      int y;
+      XserverRegion shadow_region;
+
+      x = meta_surface_get_x (surface);
+      y = meta_surface_get_y (surface);
+
+      shadow_region = meta_shadow_xrender_get_region (self->shadow);
+      XFixesTranslateRegion (self->xdisplay, shadow_region, x, y);
+
+      meta_compositor_add_damage (compositor, "shadow_changed", shadow_region);
+      XFixesDestroyRegion (self->xdisplay, shadow_region);
+
+      meta_shadow_xrender_free (self->shadow);
+      self->shadow = NULL;
+    }
+  else
+    {
+      meta_compositor_queue_redraw (compositor);
+    }
+
+  self->shadow_changed = TRUE;
+}
+
 static gboolean
 is_argb (MetaSurfaceXRender *self)
 {
@@ -444,6 +485,24 @@ notify_appears_focused_cb (MetaWindow         *window,
 {
   free_mask_pixmap (self);
   free_mask_picture (self);
+
+  shadow_changed (self);
+}
+
+static void
+notify_decorated_cb (MetaWindow         *window,
+                     GParamSpec         *pspec,
+                     MetaSurfaceXRender *self)
+{
+  shadow_changed (self);
+}
+
+static void
+notify_window_type_cb (MetaWindow         *window,
+                       GParamSpec         *pspec,
+                       MetaSurfaceXRender *self)
+{
+  shadow_changed (self);
 }
 
 static void
@@ -464,6 +523,14 @@ meta_surface_xrender_constructed (GObject *object)
   g_signal_connect_object (window, "notify::appears-focused",
                            G_CALLBACK (notify_appears_focused_cb),
                            self, 0);
+
+  g_signal_connect_object (window, "notify::decorated",
+                           G_CALLBACK (notify_decorated_cb),
+                           self, 0);
+
+  g_signal_connect_object (window, "notify::window-type",
+                           G_CALLBACK (notify_window_type_cb),
+                           self, 0);
 }
 
 static void
@@ -484,6 +551,8 @@ meta_surface_xrender_finalize (GObject *object)
       self->border_clip = None;
     }
 
+  shadow_changed (self);
+
   G_OBJECT_CLASS (meta_surface_xrender_parent_class)->finalize (object);
 }
 
@@ -620,6 +689,8 @@ meta_surface_xrender_hide (MetaSurface *surface)
 
   free_picture (self);
   free_mask_picture (self);
+
+  shadow_changed (self);
 }
 
 static void
@@ -631,6 +702,8 @@ meta_surface_xrender_opacity_changed (MetaSurface *surface)
 
   free_mask_pixmap (self);
   free_mask_picture (self);
+
+  shadow_changed (self);
 }
 
 static void
@@ -639,6 +712,33 @@ meta_surface_xrender_sync_geometry (MetaSurface   *surface,
                                     gboolean       position_changed,
                                     gboolean       size_changed)
 {
+  MetaSurfaceXRender *self;
+  MetaCompositor *compositor;
+  XserverRegion region;
+
+  self = META_SURFACE_XRENDER (surface);
+
+  if (self->shadow == NULL)
+    return;
+
+  compositor = meta_surface_get_compositor (surface);
+
+  region = meta_shadow_xrender_get_region (self->shadow);
+  XFixesTranslateRegion (self->xdisplay, region, old_geometry.x, old_geometry.y);
+
+  meta_compositor_add_damage (compositor,
+                              "meta_surface_xrender_sync_geometry",
+                              region);
+
+  XFixesDestroyRegion (self->xdisplay, region);
+
+  if (size_changed)
+    {
+      meta_shadow_xrender_free (self->shadow);
+      self->shadow = NULL;
+
+      self->shadow_changed = TRUE;
+    }
 }
 
 static void
@@ -676,6 +776,29 @@ meta_surface_xrender_pre_paint (MetaSurface   *surface,
 
   if (self->mask_picture == None)
     self->mask_picture = get_window_mask_picture (self);
+
+  if (self->shadow_changed)
+    {
+      if (self->shadow == NULL &&
+          meta_surface_has_shadow (surface))
+        {
+          MetaCompositor *compositor;
+          MetaCompositorXRender *compositor_xrender;
+          XserverRegion shadow_region;
+
+          compositor = meta_surface_get_compositor (surface);
+          compositor_xrender = META_COMPOSITOR_XRENDER (compositor);
+
+          self->shadow = meta_compositor_xrender_create_shadow (compositor_xrender,
+                                                                surface);
+
+          shadow_region = meta_shadow_xrender_get_region (self->shadow);
+          XFixesUnionRegion (self->xdisplay, damage, damage, shadow_region);
+          XFixesDestroyRegion (self->xdisplay, shadow_region);
+        }
+
+      self->shadow_changed = FALSE;
+    }
 }
 
 static void
@@ -703,12 +826,44 @@ meta_surface_xrender_class_init (MetaSurfaceXRenderClass *self_class)
 static void
 meta_surface_xrender_init (MetaSurfaceXRender *self)
 {
+  self->shadow_changed = TRUE;
 }
 
-XserverRegion
-meta_surface_xrender_get_border_clip (MetaSurfaceXRender *self)
+void
+meta_surface_xrender_update_shadow (MetaSurfaceXRender *self)
 {
-  return self->border_clip;
+  shadow_changed (self);
+}
+
+void
+meta_surface_xrender_paint_shadow (MetaSurfaceXRender *self,
+                                   XserverRegion       paint_region,
+                                   Picture             paint_buffer)
+{
+  MetaSurface *surface;
+  XserverRegion shadow_clip;
+
+  surface = META_SURFACE (self);
+
+  if (!meta_surface_is_visible (surface))
+    return;
+
+  if (self->shadow == NULL)
+    return;
+
+  shadow_clip = XFixesCreateRegion (self->xdisplay, NULL, 0);
+  XFixesCopyRegion (self->xdisplay, shadow_clip, self->border_clip);
+
+  if (paint_region != None)
+    XFixesIntersectRegion (self->xdisplay, shadow_clip, shadow_clip, paint_region);
+
+  meta_shadow_xrender_paint (self->shadow,
+                             shadow_clip,
+                             paint_buffer,
+                             meta_surface_get_x (surface),
+                             meta_surface_get_y (surface));
+
+  XFixesDestroyRegion (self->xdisplay, shadow_clip);
 }
 
 void
diff --git a/src/compositor/meta-surface-xrender.h b/src/compositor/meta-surface-xrender.h
index 93db5367..b4fb259f 100644
--- a/src/compositor/meta-surface-xrender.h
+++ b/src/compositor/meta-surface-xrender.h
@@ -27,12 +27,16 @@ G_BEGIN_DECLS
 G_DECLARE_FINAL_TYPE (MetaSurfaceXRender, meta_surface_xrender,
                       META, SURFACE_XRENDER, MetaSurface)
 
-XserverRegion meta_surface_xrender_get_border_clip (MetaSurfaceXRender *self);
+void meta_surface_xrender_update_shadow (MetaSurfaceXRender *self);
 
-void          meta_surface_xrender_paint           (MetaSurfaceXRender *self,
-                                                    XserverRegion       paint_region,
-                                                    Picture             paint_buffer,
-                                                    gboolean            opaque);
+void meta_surface_xrender_paint_shadow  (MetaSurfaceXRender *self,
+                                         XserverRegion       paint_region,
+                                         Picture             paint_buffer);
+
+void meta_surface_xrender_paint         (MetaSurfaceXRender *self,
+                                         XserverRegion       paint_region,
+                                         Picture             paint_buffer,
+                                         gboolean            opaque);
 
 G_END_DECLS
 


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