mirror of
https://github.com/brl/mutter.git
synced 2025-02-19 14:44:10 +00:00
window-actor: Use MetaRegionBuilder when scanning the visible region
This gives a pretty solid performance improvement when resizing windows.
This commit is contained in:
parent
1e9268045d
commit
865b9df9a9
@ -26,6 +26,7 @@
|
|||||||
#include "meta-shadow-factory-private.h"
|
#include "meta-shadow-factory-private.h"
|
||||||
#include "meta-window-actor-private.h"
|
#include "meta-window-actor-private.h"
|
||||||
#include "meta-texture-rectangle.h"
|
#include "meta-texture-rectangle.h"
|
||||||
|
#include "region-utils.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
POSITION_CHANGED,
|
POSITION_CHANGED,
|
||||||
@ -2006,14 +2007,15 @@ meta_window_actor_sync_visibility (MetaWindowActor *self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static cairo_region_t *
|
||||||
scan_visible_region (guchar *mask_data,
|
scan_visible_region (guchar *mask_data,
|
||||||
int stride,
|
int stride,
|
||||||
cairo_region_t *scan_area,
|
cairo_region_t *scan_area)
|
||||||
cairo_region_t *union_against)
|
|
||||||
{
|
{
|
||||||
int i, n_rects;
|
int i, n_rects = cairo_region_num_rectangles (scan_area);
|
||||||
n_rects = cairo_region_num_rectangles (scan_area);
|
MetaRegionBuilder builder;
|
||||||
|
|
||||||
|
meta_region_builder_init (&builder);
|
||||||
|
|
||||||
for (i = 0; i < n_rects; i++)
|
for (i = 0; i < n_rects; i++)
|
||||||
{
|
{
|
||||||
@ -2032,13 +2034,14 @@ scan_visible_region (guchar *mask_data,
|
|||||||
|
|
||||||
if (w > 0)
|
if (w > 0)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t tmp = { x, y, w - x, 1 };
|
meta_region_builder_add_rectangle (&builder, x, y, w - x, 1);
|
||||||
cairo_region_union_rectangle (union_against, &tmp);
|
|
||||||
x = w;
|
x = w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return meta_region_builder_finish (&builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2078,7 +2081,7 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
|||||||
|
|
||||||
if (priv->window->frame != NULL)
|
if (priv->window->frame != NULL)
|
||||||
{
|
{
|
||||||
cairo_region_t *frame_paint_region;
|
cairo_region_t *frame_paint_region, *scanned_region;
|
||||||
cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
|
cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
|
||||||
|
|
||||||
/* Make sure we don't paint the frame over the client window. */
|
/* Make sure we don't paint the frame over the client window. */
|
||||||
@ -2099,7 +2102,9 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
|||||||
cairo_paint (cr);
|
cairo_paint (cr);
|
||||||
|
|
||||||
cairo_surface_flush (surface);
|
cairo_surface_flush (surface);
|
||||||
scan_visible_region (mask_data, stride, frame_paint_region, shape_region);
|
scanned_region = scan_visible_region (mask_data, stride, frame_paint_region);
|
||||||
|
cairo_region_union (shape_region, scanned_region);
|
||||||
|
cairo_region_destroy (scanned_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
|
@ -43,25 +43,10 @@
|
|||||||
/* Optimium performance seems to be with MAX_CHUNK_RECTANGLES=4; 8 is about 10% slower.
|
/* Optimium performance seems to be with MAX_CHUNK_RECTANGLES=4; 8 is about 10% slower.
|
||||||
* But using 8 may be more robust to systems with slow malloc(). */
|
* But using 8 may be more robust to systems with slow malloc(). */
|
||||||
#define MAX_CHUNK_RECTANGLES 8
|
#define MAX_CHUNK_RECTANGLES 8
|
||||||
|
/* XXX: keep in sync with region-utils.h */
|
||||||
#define MAX_LEVELS 16
|
#define MAX_LEVELS 16
|
||||||
|
|
||||||
typedef struct
|
void
|
||||||
{
|
|
||||||
/* To merge regions in binary tree order, we need to keep track of
|
|
||||||
* the regions that we've already merged together at different
|
|
||||||
* levels of the tree. We fill in an array in the pattern:
|
|
||||||
*
|
|
||||||
* |a |
|
|
||||||
* |b |a |
|
|
||||||
* |c | |ab |
|
|
||||||
* |d |c |ab |
|
|
||||||
* |e | | |abcd|
|
|
||||||
*/
|
|
||||||
cairo_region_t *levels[MAX_LEVELS];
|
|
||||||
int n_levels;
|
|
||||||
} MetaRegionBuilder;
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_region_builder_init (MetaRegionBuilder *builder)
|
meta_region_builder_init (MetaRegionBuilder *builder)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -70,7 +55,7 @@ meta_region_builder_init (MetaRegionBuilder *builder)
|
|||||||
builder->n_levels = 1;
|
builder->n_levels = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
|
meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
@ -115,7 +100,7 @@ meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_region_t *
|
cairo_region_t *
|
||||||
meta_region_builder_finish (MetaRegionBuilder *builder)
|
meta_region_builder_finish (MetaRegionBuilder *builder)
|
||||||
{
|
{
|
||||||
cairo_region_t *result = NULL;
|
cairo_region_t *result = NULL;
|
||||||
|
@ -63,6 +63,34 @@ struct _MetaRegionIterator {
|
|||||||
cairo_rectangle_int_t next_rectangle;
|
cairo_rectangle_int_t next_rectangle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _MetaRegionBuilder MetaRegionBuilder;
|
||||||
|
|
||||||
|
/* XXX: keep in sync with region-utils.c */
|
||||||
|
#define MAX_LEVELS 16
|
||||||
|
struct _MetaRegionBuilder {
|
||||||
|
/* To merge regions in binary tree order, we need to keep track of
|
||||||
|
* the regions that we've already merged together at different
|
||||||
|
* levels of the tree. We fill in an array in the pattern:
|
||||||
|
*
|
||||||
|
* |a |
|
||||||
|
* |b |a |
|
||||||
|
* |c | |ab |
|
||||||
|
* |d |c |ab |
|
||||||
|
* |e | | |abcd|
|
||||||
|
*/
|
||||||
|
cairo_region_t *levels[MAX_LEVELS];
|
||||||
|
int n_levels;
|
||||||
|
};
|
||||||
|
#undef MAX_LEVELS
|
||||||
|
|
||||||
|
void meta_region_builder_init (MetaRegionBuilder *builder);
|
||||||
|
void meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
cairo_region_t * meta_region_builder_finish (MetaRegionBuilder *builder);
|
||||||
|
|
||||||
void meta_region_iterator_init (MetaRegionIterator *iter,
|
void meta_region_iterator_init (MetaRegionIterator *iter,
|
||||||
cairo_region_t *region);
|
cairo_region_t *region);
|
||||||
gboolean meta_region_iterator_at_end (MetaRegionIterator *iter);
|
gboolean meta_region_iterator_at_end (MetaRegionIterator *iter);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user