Skip to content

Commit

Permalink
clip: Report the surface offset when retrieving the clip mask
Browse files Browse the repository at this point in the history
Stop the callers from guessing the origin of the clip surface by
reporting it explicitly! This enables the clip to bypass any rectangles
overlaid on top of the clip surface, which is common when the backends
limit the clip to the extents of the operation -- but irrelevant to the
actual content of the clip mask
  • Loading branch information
Chris Wilson committed Apr 25, 2010
1 parent 241ce93 commit 4d36327
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 59 deletions.
2 changes: 1 addition & 1 deletion src/cairo-clip-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ cairo_private const cairo_rectangle_int_t *
_cairo_clip_get_extents (const cairo_clip_t *clip);

cairo_private cairo_surface_t *
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst);
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty);

cairo_private cairo_status_t
_cairo_clip_combine_with_surface (cairo_clip_t *clip,
Expand Down
26 changes: 20 additions & 6 deletions src/cairo-clip.c
Original file line number Diff line number Diff line change
Expand Up @@ -942,17 +942,28 @@ _cairo_clip_path_to_boxes (cairo_clip_path_t *clip_path,

static cairo_surface_t *
_cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
cairo_surface_t *target)
cairo_surface_t *target,
int *tx, int *ty)
{
const cairo_rectangle_int_t *clip_extents = &clip_path->extents;
cairo_bool_t need_translate;
cairo_surface_t *surface;
cairo_clip_path_t *prev;
cairo_status_t status;

while (clip_path->prev != NULL &&
clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
clip_path->path.maybe_fill_region)
{
clip_path = clip_path->prev;
}

clip_extents = &clip_path->extents;
if (clip_path->surface != NULL &&
clip_path->surface->backend == target->backend)
{
*tx = clip_extents->x;
*ty = clip_extents->y;
return clip_path->surface;
}

Expand Down Expand Up @@ -1046,16 +1057,17 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
{
cairo_surface_pattern_t pattern;
cairo_surface_t *prev_surface;
int prev_tx, prev_ty;

prev_surface = _cairo_clip_path_get_surface (prev, target);
prev_surface = _cairo_clip_path_get_surface (prev, target, &prev_tx, &prev_ty);
if (unlikely (prev_surface->status))
goto BAIL;

_cairo_pattern_init_for_surface (&pattern, prev_surface);
pattern.base.filter = CAIRO_FILTER_NEAREST;
cairo_matrix_init_translate (&pattern.base.matrix,
clip_extents->x - prev->extents.x,
clip_extents->y - prev->extents.y);
clip_extents->x - prev_tx,
clip_extents->y - prev_ty);
status = _cairo_surface_paint (surface,
CAIRO_OPERATOR_IN,
&pattern.base,
Expand All @@ -1071,6 +1083,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
prev = prev->prev;
}

*tx = clip_extents->x;
*ty = clip_extents->y;
cairo_surface_destroy (clip_path->surface);
return clip_path->surface = surface;

Expand Down Expand Up @@ -1158,11 +1172,11 @@ _cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
}

cairo_surface_t *
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target)
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target, int *tx, int *ty)
{
/* XXX is_clear -> all_clipped */
assert (clip->path != NULL);
return _cairo_clip_path_get_surface (clip->path, target);
return _cairo_clip_path_get_surface (clip->path, target, tx, ty);
}

cairo_status_t
Expand Down
39 changes: 21 additions & 18 deletions src/cairo-image-surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -1481,13 +1481,14 @@ _cairo_image_surface_fixup_unbounded (cairo_image_surface_t *dst,

if (clip != NULL) {
cairo_surface_t *clip_surface;
int clip_x, clip_y;

clip_surface = _cairo_clip_get_surface (clip, &dst->base);
clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
assert (clip_surface->status == CAIRO_STATUS_SUCCESS);

mask = ((cairo_image_surface_t *) clip_surface)->pixman_image;
mask_x = -clip->path->extents.x;
mask_y = -clip->path->extents.y;
mask_x = -clip_x;
mask_y = -clip_y;
} else {
if (rects->bounded.width == rects->unbounded.width &&
rects->bounded.height == rects->unbounded.height)
Expand Down Expand Up @@ -1852,6 +1853,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
{
pixman_image_t *tmp;
cairo_surface_t *clip_surface;
int clip_x, clip_y;
cairo_status_t status;

tmp = pixman_image_create_bits (dst->pixman_format,
Expand Down Expand Up @@ -1887,7 +1889,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
goto CLEANUP_SURFACE;

assert (clip->path != NULL);
clip_surface = _cairo_clip_get_surface (clip, &dst->base);
clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
goto CLEANUP_SURFACE;

Expand All @@ -1898,17 +1900,17 @@ _clip_and_composite_combine (cairo_clip_t *clip,
((cairo_image_surface_t *) clip_surface)->pixman_image,
dst->pixman_image,
0, 0,
extents->x - clip->path->extents.x,
extents->y - clip->path->extents.y,
extents->x - clip_x,
extents->y - clip_y,
extents->x, extents->y,
extents->width, extents->height);
#else
/* Punch the clip out of the destination */
pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE,
((cairo_image_surface_t *) clip_surface)->pixman_image,
NULL, dst->pixman_image,
extents->x - clip->path->extents.x,
extents->y - clip->path->extents.y,
extents->x - clip_x,
extents->y - clip_y,
0, 0,
extents->x, extents->y,
extents->width, extents->height);
Expand All @@ -1919,8 +1921,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
((cairo_image_surface_t *) clip_surface)->pixman_image,
dst->pixman_image,
0, 0,
extents->x - clip->path->extents.x,
extents->y - clip->path->extents.y,
extents->x - clip_x,
extents->y - clip_y,
extents->x, extents->y,
extents->width, extents->height);
#endif
Expand All @@ -1930,8 +1932,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
((cairo_image_surface_t *) clip_surface)->pixman_image,
dst->pixman_image,
0, 0,
extents->x - clip->path->extents.x,
extents->y - clip->path->extents.y,
extents->x - clip_x,
extents->y - clip_y,
extents->x, extents->y,
extents->width, extents->height);
}
Expand Down Expand Up @@ -2741,13 +2743,14 @@ _composite_boxes (cairo_image_surface_t *dst,

if (need_clip_mask) {
cairo_surface_t *clip_surface;
int clip_x, clip_y;

clip_surface = _cairo_clip_get_surface (clip, &dst->base);
clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
return clip_surface->status;

mask_x = -clip->path->extents.x;
mask_y = -clip->path->extents.y;
mask_x = -clip_x;
mask_y = -clip_y;

if (op == CAIRO_OPERATOR_CLEAR) {
pattern = NULL;
Expand Down Expand Up @@ -2831,9 +2834,9 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst,
info.num_traps = traps.num_traps;
info.traps = traps.traps;
info.antialias = antialias;
status = _clip_and_composite (dst, op, src,
_composite_traps, &info,
extents, clip);
status = _clip_and_composite (dst, op, src,
_composite_traps, &info,
extents, clip);

_cairo_traps_fini (&traps);
return status;
Expand Down
20 changes: 10 additions & 10 deletions src/cairo-surface-fallback.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
cairo_surface_pattern_t pattern;
cairo_surface_pattern_t clip_pattern;
cairo_surface_t *clip_surface;
int clip_x, clip_y;
cairo_status_t status;

/* We'd be better off here creating a surface identical in format
Expand Down Expand Up @@ -266,7 +267,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
goto CLEANUP_SURFACE;

assert (clip->path != NULL);
clip_surface = _cairo_clip_get_surface (clip, dst);
clip_surface = _cairo_clip_get_surface (clip, dst, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
goto CLEANUP_SURFACE;

Expand All @@ -275,8 +276,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
/* Combine that with the clip */
status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_IN,
&clip_pattern.base, NULL, intermediate,
extents->x - clip->path->extents.x,
extents->y - clip->path->extents.y,
extents->x - clip_x,
extents->y - clip_y,
0, 0,
0, 0,
extents->width, extents->height,
Expand All @@ -287,8 +288,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
/* Punch the clip out of the destination */
status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_OUT,
&clip_pattern.base, NULL, dst,
extents->x - clip->path->extents.x,
extents->y - clip->path->extents.y,
extents->x - clip_x,
extents->y - clip_y,
0, 0,
extents->x, extents->y,
extents->width, extents->height,
Expand Down Expand Up @@ -477,9 +478,9 @@ _composite_trap_region (cairo_clip_t *clip,

if (clip != NULL) {
cairo_surface_t *clip_surface = NULL;
const cairo_rectangle_int_t *clip_extents;
int clip_x, clip_y;

clip_surface = _cairo_clip_get_surface (clip, dst);
clip_surface = _cairo_clip_get_surface (clip, dst, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
return clip_surface->status;

Expand All @@ -489,9 +490,8 @@ _composite_trap_region (cairo_clip_t *clip,
}

_cairo_pattern_init_for_surface (&mask_pattern, clip_surface);
clip_extents = _cairo_clip_get_extents (clip);
mask_x = extents->x - clip_extents->x;
mask_y = extents->y - clip_extents->y;
mask_x = extents->x - clip_x;
mask_y = extents->y - clip_y;
mask = &mask_pattern.base;
}

Expand Down
31 changes: 15 additions & 16 deletions src/cairo-xcb-surface-render.c
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
{
cairo_xcb_surface_t *tmp;
cairo_surface_t *clip_surface;
int clip_x, clip_y;
xcb_render_picture_t clip_picture;
cairo_status_t status;

Expand Down Expand Up @@ -1952,7 +1953,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
if (unlikely (status))
goto CLEANUP_SURFACE;

clip_surface = _cairo_clip_get_surface (clip, &dst->base);
clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
goto CLEANUP_SURFACE;

Expand All @@ -1972,8 +1973,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
clip_picture, XCB_NONE, dst->picture,
extents->x - clip->path->extents.x,
extents->y - clip->path->extents.y,
extents->x - clip_x,
extents->y - clip_y,
0, 0,
extents->x, extents->y,
extents->width, extents->height);
Expand All @@ -1983,8 +1984,8 @@ _clip_and_composite_combine (cairo_clip_t *clip,
XCB_RENDER_PICT_OP_ADD,
tmp->picture, clip_picture, dst->picture,
0, 0,
extents->x - clip->path->extents.x,
extents->y - clip->path->extents.y,
extents->x - clip_x,
extents->y - clip_y,
extents->x, extents->y,
extents->width, extents->height);
}
Expand Down Expand Up @@ -2182,13 +2183,10 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
cairo_xcb_surface_t *mask;
int mask_x, mask_y;

mask = (cairo_xcb_surface_t *) _cairo_clip_get_surface (clip, &dst->base);
mask = (cairo_xcb_surface_t *) _cairo_clip_get_surface (clip, &dst->base, &mask_x, &mask_y);
if (unlikely (mask->base.status))
return mask->base.status;

mask_x = - clip->path->extents.x;
mask_y = - clip->path->extents.y;

/* top */
if (rects->bounded.y != rects->unbounded.y) {
int x = rects->unbounded.x;
Expand All @@ -2199,7 +2197,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
mask->picture, XCB_NONE, dst->picture,
x + mask_x, y + mask_y,
x - mask_x, y - mask_y,
0, 0,
x, y,
width, height);
Expand All @@ -2215,7 +2213,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
mask->picture, XCB_NONE, dst->picture,
x + mask_x, y + mask_y,
x - mask_x, y - mask_y,
0, 0,
x, y,
width, height);
Expand All @@ -2231,7 +2229,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
mask->picture, XCB_NONE, dst->picture,
x + mask_x, y + mask_y,
x - mask_x, y - mask_y,
0, 0,
x, y,
width, height);
Expand All @@ -2247,7 +2245,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
_cairo_xcb_connection_render_composite (dst->connection,
XCB_RENDER_PICT_OP_OUT_REVERSE,
mask->picture, XCB_NONE, dst->picture,
x + mask_x, y + mask_y,
x - mask_x, y - mask_y,
0, 0,
x, y,
width, height);
Expand Down Expand Up @@ -2541,16 +2539,17 @@ _composite_boxes (cairo_xcb_surface_t *dst,

if (need_clip_mask) {
cairo_surface_t *clip_surface;
int clip_x, clip_y;

clip_surface = _cairo_clip_get_surface (clip, &dst->base);
clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
if (unlikely (clip_surface->status))
return clip_surface->status;

_cairo_pattern_init_for_surface (&mask, clip_surface);
mask.base.filter = CAIRO_FILTER_NEAREST;
cairo_matrix_init_translate (&mask.base.matrix,
-clip->path->extents.x,
-clip->path->extents.y);
-clip_x,
-clip_y);

if (op == CAIRO_OPERATOR_CLEAR) {
src = NULL;
Expand Down
9 changes: 4 additions & 5 deletions src/drm/cairo-drm-i915-shader.c
Original file line number Diff line number Diff line change
Expand Up @@ -2403,11 +2403,11 @@ i915_shader_set_clip (i915_shader_t *shader,
cairo_clip_t *clip)
{
cairo_surface_t *clip_surface;
const cairo_rectangle_int_t *clip_extents;
int clip_x, clip_y;
union i915_shader_channel *channel;
i915_surface_t *s;

clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base);
clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base, &clip_x, &clip_y);
assert (clip_surface->status == CAIRO_STATUS_SUCCESS);
assert (clip_surface->type == CAIRO_SURFACE_TYPE_DRM);

Expand All @@ -2434,13 +2434,12 @@ i915_shader_set_clip (i915_shader_t *shader,
SS3_NORMALIZED_COORDS |
i915_texture_extend (CAIRO_EXTEND_NONE);

clip_extents = _cairo_clip_get_extents (clip);
cairo_matrix_init_scale (&shader->clip.base.matrix,
1. / s->intel.drm.width,
1. / s->intel.drm.height);
cairo_matrix_translate (&shader->clip.base.matrix,
NEAREST_BIAS - clip_extents->x,
NEAREST_BIAS - clip_extents->y);
NEAREST_BIAS - clip_x,
NEAREST_BIAS - clip_y);
}

static cairo_status_t
Expand Down
Loading

0 comments on commit 4d36327

Please sign in to comment.