xlib/shm: Limit use of the impromptu fallback pixmap for uploads

We want to avoid unnecessary readback and so only want to use the
ShmPixmap when uploading the complete surface.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2012-08-17 20:57:04 +01:00
parent 4af7a1c863
commit bc38108947
5 changed files with 47 additions and 10 deletions

View file

@ -74,10 +74,14 @@ _cairo_xlib_shm_compositor_paint (const cairo_compositor_t *_compositor,
cairo_xlib_surface_t *xlib = (cairo_xlib_surface_t *)extents->surface;
cairo_int_status_t status;
cairo_surface_t *shm;
cairo_bool_t overwrite;
TRACE ((stderr, "%s\n", __FUNCTION__));
shm = _cairo_xlib_surface_get_shm (xlib);
overwrite =
extents->op <= CAIRO_OPERATOR_SOURCE && unclipped (xlib, extents->clip);
shm = _cairo_xlib_surface_get_shm (xlib, overwrite);
if (shm == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -105,7 +109,7 @@ _cairo_xlib_shm_compositor_mask (const cairo_compositor_t *_compositor,
TRACE ((stderr, "%s\n", __FUNCTION__));
shm = _cairo_xlib_surface_get_shm (xlib);
shm = _cairo_xlib_surface_get_shm (xlib, FALSE);
if (shm == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -139,7 +143,7 @@ _cairo_xlib_shm_compositor_stroke (const cairo_compositor_t *_compositor,
TRACE ((stderr, "%s\n", __FUNCTION__));
shm = _cairo_xlib_surface_get_shm (xlib);
shm = _cairo_xlib_surface_get_shm (xlib, FALSE);
if (shm == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -174,7 +178,7 @@ _cairo_xlib_shm_compositor_fill (const cairo_compositor_t *_compositor,
TRACE ((stderr, "%s\n", __FUNCTION__));
shm = _cairo_xlib_surface_get_shm (xlib);
shm = _cairo_xlib_surface_get_shm (xlib, FALSE);
if (shm == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -207,7 +211,7 @@ _cairo_xlib_shm_compositor_glyphs (const cairo_compositor_t *_compositor,
TRACE ((stderr, "%s\n", __FUNCTION__));
shm = _cairo_xlib_surface_get_shm (xlib);
shm = _cairo_xlib_surface_get_shm (xlib, FALSE);
if (shm == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;

View file

@ -404,7 +404,8 @@ _cairo_xlib_surface_create_similar_shm (void *surface,
int width, int height);
cairo_private cairo_surface_t *
_cairo_xlib_surface_get_shm (cairo_xlib_surface_t *surface);
_cairo_xlib_surface_get_shm (cairo_xlib_surface_t *surface,
cairo_bool_t overwrite);
cairo_private cairo_int_status_t
_cairo_xlib_surface_put_shm (cairo_xlib_surface_t *surface);

View file

@ -205,6 +205,28 @@ copy_image_boxes (void *_dst,
return CAIRO_STATUS_SUCCESS;
}
static cairo_bool_t
boxes_cover_surface (cairo_boxes_t *boxes,
cairo_xlib_surface_t *surface)
{
cairo_box_t *b;
if (boxes->num_boxes != 1)
return FALSE;
b = &boxes->chunks.base[0];
if (_cairo_fixed_integer_part (b->p1.x) > 0 ||
_cairo_fixed_integer_part (b->p1.y) > 0)
return FALSE;
if (_cairo_fixed_integer_part (b->p2.x) < surface->width ||
_cairo_fixed_integer_part (b->p2.y) < surface->height)
return FALSE;
return TRUE;
}
static cairo_int_status_t
draw_image_boxes (void *_dst,
cairo_image_surface_t *image,
@ -220,7 +242,11 @@ draw_image_boxes (void *_dst,
_cairo_xlib_shm_surface_get_pixmap (&image->base))
return copy_image_boxes (dst, image, boxes, dx, dy);
shm = (cairo_image_surface_t *) _cairo_xlib_surface_get_shm (dst);
shm = NULL;
if (boxes_cover_surface (boxes, dst))
shm = (cairo_image_surface_t *) _cairo_xlib_surface_get_shm (dst, TRUE);
if (shm == NULL && dst->shm)
shm = (cairo_image_surface_t *) _cairo_xlib_surface_get_shm (dst, FALSE);
if (shm) {
for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {

View file

@ -791,7 +791,8 @@ static void dec_idle (cairo_surface_t *surface)
}
cairo_surface_t *
_cairo_xlib_surface_get_shm (cairo_xlib_surface_t *surface)
_cairo_xlib_surface_get_shm (cairo_xlib_surface_t *surface,
cairo_bool_t overwrite)
{
if (surface->fallback) {
assert (surface->base.damage);
@ -836,6 +837,11 @@ _cairo_xlib_surface_get_shm (cairo_xlib_surface_t *surface)
surface->shm->damage = _cairo_damage_create ();
}
if (overwrite) {
_cairo_damage_destroy (surface->base.damage);
surface->base.damage = _cairo_damage_create ();
}
if (!surface->base.is_clear && surface->base.damage->dirty)
_cairo_xlib_surface_update_shm (surface);

View file

@ -1317,7 +1317,7 @@ _cairo_xlib_surface_acquire_source_image (void *abstract_surf
*image_extra = NULL;
*image_out = (cairo_image_surface_t *)
_cairo_xlib_surface_get_shm (abstract_surface);
_cairo_xlib_surface_get_shm (abstract_surface, FALSE);
if (*image_out)
return (*image_out)->base.status;
@ -1363,7 +1363,7 @@ _cairo_xlib_surface_map_to_image (void *abstract_surface,
cairo_xlib_surface_t *surface = abstract_surface;
cairo_surface_t *image;
image = _cairo_xlib_surface_get_shm (abstract_surface);
image = _cairo_xlib_surface_get_shm (abstract_surface, FALSE);
if (image) {
assert (surface->base.damage);
surface->fallback++;