shaped-texture: Remove the cairo overlay (and rounded corners)

As we want GTK+ to paint the mask on an A8, we can't simply use a cairo
path. A later commit will make this into a simple masked texture, and
meta-window-actor will be in control of the mask.

https://bugzilla.gnome.org/show_bug.cgi?id=676052
This commit is contained in:
Jasper St. Pierre 2012-04-26 23:06:19 -04:00
parent 9ca00d5cce
commit 4de492eb20
3 changed files with 4 additions and 233 deletions

View File

@ -77,9 +77,6 @@ struct _MetaShapedTexturePrivate
cairo_region_t *clip_region; cairo_region_t *clip_region;
cairo_region_t *shape_region; cairo_region_t *shape_region;
cairo_region_t *overlay_region;
cairo_path_t *overlay_path;
guint tex_width, tex_height; guint tex_width, tex_height;
guint mask_width, mask_height; guint mask_width, mask_height;
@ -111,8 +108,6 @@ meta_shaped_texture_init (MetaShapedTexture *self)
priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self); priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
priv->shape_region = NULL; priv->shape_region = NULL;
priv->overlay_path = NULL;
priv->overlay_region = NULL;
priv->paint_tower = meta_texture_tower_new (); priv->paint_tower = meta_texture_tower_new ();
priv->texture = COGL_INVALID_HANDLE; priv->texture = COGL_INVALID_HANDLE;
priv->mask_texture = COGL_INVALID_HANDLE; priv->mask_texture = COGL_INVALID_HANDLE;
@ -149,7 +144,6 @@ meta_shaped_texture_dispose (GObject *object)
meta_shaped_texture_set_shape_region (self, NULL); meta_shaped_texture_set_shape_region (self, NULL);
meta_shaped_texture_set_clip_region (self, NULL); meta_shaped_texture_set_clip_region (self, NULL);
meta_shaped_texture_set_overlay_path (self, NULL, NULL);
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object); G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
} }
@ -169,59 +163,6 @@ meta_shaped_texture_dirty_mask (MetaShapedTexture *stex)
cogl_material_set_layer (priv->material, 1, COGL_INVALID_HANDLE); cogl_material_set_layer (priv->material, 1, COGL_INVALID_HANDLE);
} }
static void
install_overlay_path (MetaShapedTexture *stex,
guchar *mask_data,
int tex_width,
int tex_height,
int stride)
{
MetaShapedTexturePrivate *priv = stex->priv;
int i, n_rects;
cairo_t *cr;
cairo_rectangle_int_t rect;
cairo_surface_t *surface;
if (priv->overlay_region == NULL)
return;
surface = cairo_image_surface_create_for_data (mask_data,
CAIRO_FORMAT_A8,
tex_width,
tex_height,
stride);
cr = cairo_create (surface);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
n_rects = cairo_region_num_rectangles (priv->overlay_region);
for (i = 0; i < n_rects; i++)
{
cairo_region_get_rectangle (priv->overlay_region, i, &rect);
cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
}
cairo_fill_preserve (cr);
if (priv->overlay_path == NULL)
{
/* If we have an overlay region but not an overlay path, then we
* just need to clear the rectangles in the overlay region. */
goto out;
}
cairo_clip (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba (cr, 1, 1, 1, 1);
cairo_append_path (cr, priv->overlay_path);
cairo_fill (cr);
out:
cairo_destroy (cr);
cairo_surface_destroy (surface);
}
static void static void
meta_shaped_texture_ensure_mask (MetaShapedTexture *stex) meta_shaped_texture_ensure_mask (MetaShapedTexture *stex)
{ {
@ -251,14 +192,10 @@ meta_shaped_texture_ensure_mask (MetaShapedTexture *stex)
int n_rects; int n_rects;
int stride; int stride;
/* If we have no shape region and no (or an empty) overlay region, we /* If we have no shape region, we don't need to create
* don't need to create a full mask texture, so quit early. */ * a full mask texture, so quit early. */
if (priv->shape_region == NULL && if (priv->shape_region == NULL)
(priv->overlay_region == NULL || return;
cairo_region_num_rectangles (priv->overlay_region) == 0))
{
return;
}
stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, tex_width); stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, tex_width);
@ -290,8 +227,6 @@ meta_shaped_texture_ensure_mask (MetaShapedTexture *stex)
memset (p, 255, x2 - x1); memset (p, 255, x2 - x1);
} }
install_overlay_path (stex, mask_data, tex_width, tex_height, stride);
if (meta_texture_rectangle_check (paint_tex)) if (meta_texture_rectangle_check (paint_tex))
priv->mask_texture = meta_texture_rectangle_new (tex_width, tex_height, priv->mask_texture = meta_texture_rectangle_new (tex_width, tex_height,
COGL_PIXEL_FORMAT_A_8, COGL_PIXEL_FORMAT_A_8,
@ -727,48 +662,6 @@ meta_shaped_texture_get_texture (MetaShapedTexture *stex)
return stex->priv->texture; return stex->priv->texture;
} }
/**
* meta_shaped_texture_set_overlay_path:
* @stex: a #MetaShapedTexture
* @overlay_region: A region containing the parts of the mask to overlay.
* All rectangles in this region are wiped clear to full transparency,
* and the overlay path is clipped to this region.
* @overlay_path: (transfer full): This path will be painted onto the mask
* texture with a fully opaque source. Due to the lack of refcounting
* in #cairo_path_t, ownership of the path is assumed.
*/
void
meta_shaped_texture_set_overlay_path (MetaShapedTexture *stex,
cairo_region_t *overlay_region,
cairo_path_t *overlay_path)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
if (priv->overlay_region != NULL)
{
cairo_region_destroy (priv->overlay_region);
priv->overlay_region = NULL;
}
if (priv->overlay_path != NULL)
{
cairo_path_destroy (priv->overlay_path);
priv->overlay_path = NULL;
}
cairo_region_reference (overlay_region);
priv->overlay_region = overlay_region;
/* cairo_path_t does not have refcounting. */
priv->overlay_path = overlay_path;
meta_shaped_texture_dirty_mask (stex);
}
/** /**
* meta_shaped_texture_set_clip_region: * meta_shaped_texture_set_clip_region:
* @stex: a #MetaShapedTexture * @stex: a #MetaShapedTexture

View File

@ -1989,123 +1989,6 @@ meta_window_actor_sync_visibility (MetaWindowActor *self)
} }
} }
static inline void
set_integral_bounding_rect (cairo_rectangle_int_t *rect,
double x, double y,
double width, double height)
{
rect->x = floor(x);
rect->y = floor(y);
rect->width = ceil(x + width) - rect->x;
rect->height = ceil(y + height) - rect->y;
}
static void
update_corners (MetaWindowActor *self,
MetaFrameBorders *borders)
{
MetaWindowActorPrivate *priv = self->priv;
MetaRectangle outer;
cairo_rectangle_int_t corner_rects[4];
cairo_region_t *corner_region;
cairo_path_t *corner_path;
float top_left, top_right, bottom_left, bottom_right;
float x, y;
/* need these to build a path */
cairo_t *cr;
cairo_surface_t *surface;
if (!priv->window->frame)
{
meta_shaped_texture_set_overlay_path (META_SHAPED_TEXTURE (priv->actor),
NULL, NULL);
return;
}
meta_window_get_outer_rect (priv->window, &outer);
meta_frame_get_corner_radiuses (priv->window->frame,
&top_left,
&top_right,
&bottom_left,
&bottom_right);
/* Unfortunately, cairo does not allow us to create a context
* without a surface. Create a 0x0 image surface to "paint to"
* so we can get the path. */
surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
0, 0);
cr = cairo_create (surface);
/* top left */
x = borders->invisible.left;
y = borders->invisible.top;
set_integral_bounding_rect (&corner_rects[0],
x, y, top_left, top_left);
cairo_arc (cr,
x + top_left,
y + top_left,
top_left,
0, M_PI*2);
/* top right */
x = borders->invisible.left + outer.width - top_right;
y = borders->invisible.top;
set_integral_bounding_rect (&corner_rects[1],
x, y, top_right, top_right);
cairo_arc (cr,
x,
y + top_right,
top_right,
0, M_PI*2);
/* bottom right */
x = borders->invisible.left + outer.width - bottom_right;
y = borders->invisible.top + outer.height - bottom_right;
set_integral_bounding_rect (&corner_rects[2],
x, y, bottom_right, bottom_right);
cairo_arc (cr,
x,
y,
bottom_right,
0, M_PI*2);
/* bottom left */
x = borders->invisible.left;
y = borders->invisible.top + outer.height - bottom_left;
set_integral_bounding_rect (&corner_rects[3],
x, y, bottom_left, bottom_left);
cairo_arc (cr,
x + bottom_left,
y,
bottom_left,
0, M_PI*2);
corner_path = cairo_copy_path (cr);
cairo_surface_destroy (surface);
cairo_destroy (cr);
corner_region = cairo_region_create_rectangles (corner_rects, 4);
meta_shaped_texture_set_overlay_path (META_SHAPED_TEXTURE (priv->actor),
corner_region, corner_path);
cairo_region_destroy (corner_region);
}
static void static void
check_needs_reshape (MetaWindowActor *self) check_needs_reshape (MetaWindowActor *self)
{ {
@ -2184,8 +2067,6 @@ check_needs_reshape (MetaWindowActor *self)
cairo_region_destroy (region); cairo_region_destroy (region);
update_corners (self, &borders);
priv->needs_reshape = FALSE; priv->needs_reshape = FALSE;
meta_window_actor_invalidate_shadow (self); meta_window_actor_invalidate_shadow (self);
} }

View File

@ -75,9 +75,6 @@ CoglHandle meta_shaped_texture_get_texture (MetaShapedTexture *stex);
void meta_shaped_texture_set_shape_region (MetaShapedTexture *stex, void meta_shaped_texture_set_shape_region (MetaShapedTexture *stex,
cairo_region_t *region); cairo_region_t *region);
void meta_shaped_texture_set_overlay_path (MetaShapedTexture *stex,
cairo_region_t *overlay_region,
cairo_path_t *overlay_path);
/* Assumes ownership of clip_region */ /* Assumes ownership of clip_region */
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,