diff options
-rw-r--r-- | src/compositor/meta-compositor-xrender.c | 123 | ||||
-rw-r--r-- | src/compositor/meta-surface-xrender.c | 106 | ||||
-rw-r--r-- | src/compositor/meta-surface-xrender.h | 4 |
3 files changed, 126 insertions, 107 deletions
diff --git a/src/compositor/meta-compositor-xrender.c b/src/compositor/meta-compositor-xrender.c index ebd40aa5..586f7c3c 100644 --- a/src/compositor/meta-compositor-xrender.c +++ b/src/compositor/meta-compositor-xrender.c @@ -92,16 +92,12 @@ typedef struct _MetaCompWindow MetaRectangle rect; - Pixmap mask_pixmap; - int mode; gboolean damaged; XserverRegion shape_region; - Picture mask; - gboolean needs_shadow; MetaShadowType shadow_type; @@ -1157,34 +1153,6 @@ get_visible_region (MetaDisplay *display, return region; } -static Picture -get_window_mask (MetaSurface *surface) -{ - MetaCompWindow *cw; - MetaDisplay *display; - Display *xdisplay; - XRenderPictFormat *format; - Picture picture; - - cw = g_object_get_data (G_OBJECT (surface), "cw"); - - if (cw->mask_pixmap == None) - cw->mask_pixmap = meta_surface_xrender_create_mask_pixmap (META_SURFACE_XRENDER (surface), TRUE); - - if (cw->mask_pixmap == None) - return None; - - display = meta_window_get_display (cw->window); - xdisplay = meta_display_get_xdisplay (display); - format = XRenderFindStandardFormat (xdisplay, PictStandardA8); - - meta_error_trap_push (display); - picture = XRenderCreatePicture (xdisplay, cw->mask_pixmap, format, 0, NULL); - meta_error_trap_pop (display); - - return picture; -} - static void paint_dock_shadows (MetaCompositorXRender *xrender, GList *surfaces, @@ -1282,9 +1250,6 @@ paint_windows (MetaCompositorXRender *xrender, picture = meta_surface_xrender_get_picture (META_SURFACE_XRENDER (surface)); - if (cw->mask == None) - cw->mask = get_window_mask (surface); - if (cw->window_region == None) cw->window_region = get_window_region (display, cw); @@ -1360,11 +1325,13 @@ paint_windows (MetaCompositorXRender *xrender, { MetaSurface *surface; Picture picture; + Picture mask; surface = META_SURFACE (index->data); cw = g_object_get_data (G_OBJECT (surface), "cw"); picture = meta_surface_xrender_get_picture (META_SURFACE_XRENDER (surface)); + mask = meta_surface_xrender_get_mask_picture (META_SURFACE_XRENDER (surface)); if (picture) { @@ -1399,16 +1366,16 @@ paint_windows (MetaCompositorXRender *xrender, XFixesSetPictureClipRegion (xdisplay, root_buffer, 0, 0, cw->border_clip); - if (cw->mode == WINDOW_SOLID && cw->mask != None) + if (cw->mode == WINDOW_SOLID && mask != None) { XRenderComposite (xdisplay, PictOpOver, picture, - cw->mask, root_buffer, 0, 0, 0, 0, + mask, root_buffer, 0, 0, 0, 0, x, y, wid, hei); } else if (cw->mode == WINDOW_ARGB) { XRenderComposite (xdisplay, PictOpOver, picture, - cw->mask, root_buffer, 0, 0, 0, 0, + mask, root_buffer, 0, 0, 0, 0, x, y, wid, hei); } } @@ -1504,24 +1471,12 @@ free_win (MetaCompWindow *cw, /* See comment in map_win */ - if (cw->mask_pixmap && destroy) - { - XFreePixmap (xdisplay, cw->mask_pixmap); - cw->mask_pixmap = None; - } - if (cw->shape_region) { XFixesDestroyRegion (xdisplay, cw->shape_region); cw->shape_region = None; } - if (cw->mask) - { - XRenderFreePicture (xdisplay, cw->mask); - cw->mask = None; - } - if (cw->shadow) { XRenderFreePicture (xdisplay, cw->shadow); @@ -1592,12 +1547,6 @@ map_win (MetaCompositorXRender *xrender, is so that we will still have a valid pixmap for whenever the window is unmapped */ - if (cw->mask_pixmap) - { - XFreePixmap (xdisplay, cw->mask_pixmap); - cw->mask_pixmap = None; - } - if (cw->client_region) { XFixesDestroyRegion (xdisplay, cw->client_region); @@ -1645,12 +1594,6 @@ notify_appears_focused_cb (MetaWindow *window, else cw->shadow_type = META_SHADOW_MEDIUM; - if (cw->mask) - { - XRenderFreePicture (xdisplay, cw->mask); - cw->mask = None; - } - if (cw->shadow) { XRenderFreePicture (xdisplay, cw->shadow); @@ -1690,24 +1633,12 @@ notify_decorated_cb (MetaWindow *window, meta_error_trap_push (window->display); - if (cw->mask_pixmap != None) - { - XFreePixmap (xrender->xdisplay, cw->mask_pixmap); - cw->mask_pixmap = None; - } - if (cw->shape_region != None) { XFixesDestroyRegion (xrender->xdisplay, cw->shape_region); cw->shape_region = None; } - if (cw->mask != None) - { - XRenderFreePicture (xrender->xdisplay, cw->mask); - cw->mask = None; - } - if (cw->window_region != None) { XFixesDestroyRegion (xrender->xdisplay, cw->window_region); @@ -1764,6 +1695,7 @@ get_window_surface (MetaSurface *surface) Display *xdisplay; Pixmap back_pixmap; Pixmap mask_pixmap; + gboolean free_pixmap; cairo_surface_t *back_surface; cairo_surface_t *window_surface; cairo_t *cr; @@ -1778,9 +1710,14 @@ get_window_surface (MetaSurface *surface) if (back_pixmap == None) return NULL; - mask_pixmap = None; + mask_pixmap = meta_surface_xrender_get_mask_pixmap (META_SURFACE_XRENDER (surface)); + free_pixmap = FALSE; + if (cw->window->opacity != (guint) OPAQUE) - mask_pixmap = meta_surface_xrender_create_mask_pixmap (META_SURFACE_XRENDER (surface), FALSE); + { + mask_pixmap = meta_surface_xrender_create_mask_pixmap (META_SURFACE_XRENDER (surface), FALSE); + free_pixmap = TRUE; + } back_surface = cairo_xlib_surface_create (xdisplay, back_pixmap, get_toplevel_xvisual (cw->window), @@ -1795,9 +1732,8 @@ get_window_surface (MetaSurface *surface) cairo_set_source_surface (cr, back_surface, 0, 0); cairo_surface_destroy (back_surface); - if (mask_pixmap != None || cw->mask_pixmap != None) + if (mask_pixmap != None) { - Pixmap pixmap; Screen *xscreen; XRenderPictFormat *format; int width; @@ -1805,7 +1741,6 @@ get_window_surface (MetaSurface *surface) cairo_surface_t *mask; cairo_pattern_t *pattern; - pixmap = mask_pixmap != None ? mask_pixmap : cw->mask_pixmap; xscreen = DefaultScreenOfDisplay (xdisplay); format = XRenderFindStandardFormat (xdisplay, PictStandardA8); @@ -1813,7 +1748,7 @@ get_window_surface (MetaSurface *surface) height = frame != NULL ? cw->rect.height : 1; mask = cairo_xlib_surface_create_with_xrender_format (xdisplay, - pixmap, + mask_pixmap, xscreen, format, width, @@ -1837,7 +1772,7 @@ get_window_surface (MetaSurface *surface) cairo_destroy (cr); - if (mask_pixmap != None) + if (free_pixmap && mask_pixmap != None) XFreePixmap (xdisplay, mask_pixmap); return window_surface; @@ -2181,8 +2116,6 @@ meta_compositor_xrender_add_window (MetaCompositor *compositor, G_CALLBACK (notify_shaded_cb), surface, 0); - cw->mask_pixmap = None; - cw->damaged = FALSE; cw->shape_region = cairo_region_to_xserver_region (xrender->xdisplay, @@ -2308,18 +2241,6 @@ meta_compositor_xrender_window_opacity_changed (MetaCompositor *compositor, determine_mode (xrender, cw); cw->needs_shadow = window_has_shadow (xrender, cw); - if (cw->mask_pixmap != None) - { - XFreePixmap (xrender->xdisplay, cw->mask_pixmap); - cw->mask_pixmap = None; - } - - if (cw->mask != None) - { - XRenderFreePicture (xrender->xdisplay, cw->mask); - cw->mask = None; - } - if (cw->shadow) { XRenderFreePicture (xrender->xdisplay, cw->shadow); @@ -2526,18 +2447,6 @@ meta_compositor_xrender_sync_window_geometry (MetaCompositor *compositor, if (cw->rect.width != old_rect.width || cw->rect.height != old_rect.height) { - if (cw->mask_pixmap != None) - { - XFreePixmap (xrender->xdisplay, cw->mask_pixmap); - cw->mask_pixmap = None; - } - - if (cw->mask != None) - { - XRenderFreePicture (xrender->xdisplay, cw->mask); - cw->mask = None; - } - if (cw->shadow != None) { XRenderFreePicture (xrender->xdisplay, cw->shadow); diff --git a/src/compositor/meta-surface-xrender.c b/src/compositor/meta-surface-xrender.c index b7bc7b84..254fea67 100644 --- a/src/compositor/meta-surface-xrender.c +++ b/src/compositor/meta-surface-xrender.c @@ -33,6 +33,9 @@ struct _MetaSurfaceXRender MetaSurface parent; Picture picture; + + Pixmap mask_pixmap; + Picture mask_picture; }; G_DEFINE_TYPE (MetaSurfaceXRender, meta_surface_xrender, META_TYPE_SURFACE) @@ -56,6 +59,44 @@ free_picture (MetaSurfaceXRender *self) self->picture = None; } +static void +free_mask_pixmap (MetaSurfaceXRender *self) +{ + MetaWindow *window; + MetaDisplay *display; + Display *xdisplay; + + if (self->mask_pixmap == None) + return; + + window = meta_surface_get_window (META_SURFACE (self)); + + display = meta_window_get_display (window); + xdisplay = meta_display_get_xdisplay (display); + + XFreePixmap (xdisplay, self->mask_pixmap); + self->mask_pixmap = None; +} + +static void +free_mask_picture (MetaSurfaceXRender *self) +{ + MetaWindow *window; + MetaDisplay *display; + Display *xdisplay; + + if (self->mask_picture == None) + return; + + window = meta_surface_get_window (META_SURFACE (self)); + + display = meta_window_get_display (window); + xdisplay = meta_display_get_xdisplay (display); + + XRenderFreePicture (xdisplay, self->mask_picture); + self->mask_picture = None; +} + static Picture get_window_picture (MetaSurfaceXRender *self) { @@ -103,6 +144,32 @@ get_window_picture (MetaSurfaceXRender *self) return picture; } +static Picture +get_window_mask_picture (MetaSurfaceXRender *self) +{ + MetaWindow *window; + MetaDisplay *display; + Display *xdisplay; + XRenderPictFormat *format; + Picture picture; + + if (self->mask_pixmap == None) + return None; + + window = meta_surface_get_window (META_SURFACE (self)); + + display = meta_window_get_display (window); + xdisplay = meta_display_get_xdisplay (display); + + format = XRenderFindStandardFormat (xdisplay, PictStandardA8); + + meta_error_trap_push (display); + picture = XRenderCreatePicture (xdisplay, self->mask_pixmap, format, 0, NULL); + meta_error_trap_pop (display); + + return picture; +} + static void meta_surface_xrender_finalize (GObject *object) { @@ -112,12 +179,23 @@ meta_surface_xrender_finalize (GObject *object) free_picture (self); + free_mask_pixmap (self); + free_mask_picture (self); + G_OBJECT_CLASS (meta_surface_xrender_parent_class)->finalize (object); } static void meta_surface_xrender_show (MetaSurface *surface) { + MetaSurfaceXRender *self; + + self = META_SURFACE_XRENDER (surface); + + /* The reason we free pixmap here is so that we will still have + * a valid pixmap when the window is unmapped. + */ + free_mask_pixmap (self); } static void @@ -128,11 +206,18 @@ meta_surface_xrender_hide (MetaSurface *surface) self = META_SURFACE_XRENDER (surface); free_picture (self); + free_mask_picture (self); } static void meta_surface_xrender_opacity_changed (MetaSurface *surface) { + MetaSurfaceXRender *self; + + self = META_SURFACE_XRENDER (surface); + + free_mask_pixmap (self); + free_mask_picture (self); } static void @@ -143,6 +228,9 @@ meta_surface_xrender_free_pixmap (MetaSurface *surface) self = META_SURFACE_XRENDER (surface); free_picture (self); + + free_mask_pixmap (self); + free_mask_picture (self); } static void @@ -160,6 +248,12 @@ meta_surface_xrender_pre_paint (MetaSurface *surface) if (self->picture == None) self->picture = get_window_picture (self); + + if (self->mask_pixmap == None) + self->mask_pixmap = meta_surface_xrender_create_mask_pixmap (self, TRUE); + + if (self->mask_picture == None) + self->mask_picture = get_window_mask_picture (self); } static void @@ -301,3 +395,15 @@ meta_surface_xrender_get_picture (MetaSurfaceXRender *self) { return self->picture; } + +Pixmap +meta_surface_xrender_get_mask_pixmap (MetaSurfaceXRender *self) +{ + return self->mask_pixmap; +} + +Picture +meta_surface_xrender_get_mask_picture (MetaSurfaceXRender *self) +{ + return self->mask_picture; +} diff --git a/src/compositor/meta-surface-xrender.h b/src/compositor/meta-surface-xrender.h index ba7c0e04..ea0b1987 100644 --- a/src/compositor/meta-surface-xrender.h +++ b/src/compositor/meta-surface-xrender.h @@ -32,6 +32,10 @@ Pixmap meta_surface_xrender_create_mask_pixmap (MetaSurfaceXRender *self, Picture meta_surface_xrender_get_picture (MetaSurfaceXRender *self); +Pixmap meta_surface_xrender_get_mask_pixmap (MetaSurfaceXRender *self); + +Picture meta_surface_xrender_get_mask_picture (MetaSurfaceXRender *self); + G_END_DECLS #endif |