[cairo] XCopyArea and Cairo - trying to implement scrolling

Chris Wilson chris at chris-wilson.co.uk
Fri May 15 01:47:20 PDT 2015


On Thu, May 14, 2015 at 08:34:00PM -0700, Richard Billington wrote:
> I'm trying to translate a backend from using Xlib calls to using
> Cairo, where reasonable. The drawing operations I'm doing (text and
> graphics) are ignoring the xlib gcontext, and instead using the
> cairo context. However, when I try to use my cairo implementation of
> an xcopyarea-like function, I get some kind of event generated which
> I don't know how to handle. If I try to use xcopyarea (the xlib
> implementation), it "works" except that the background is always
> black, not the background it ought to be.
> 
> I can go into more specifics, but I'm just wondering if there's any
> standard way of doing this. I found an archived discussion from many
> years ago about this subject, but I can't tell if there were
> patches/reimplementations done to better accommodate this nor if
> there's a standard approach.

Sure, the crux of the issue is that the self-copy case remains undefined
(it more or less boils down to not all hardware truly supports it). The
easiest no-nonsense definition would be that the source is treated as
static from the instance of being bound to the context (that is if it
maps to the cairo_get_target, then we immediately take a copy[-on-write?]).
That is overkill and prevents some optimisations for e.g. converting a
	cairo_set_source_surface(cairo_get_target(), 10, 10);
	cairo_rectangle();
	cairo_fill();
into a XCopyArea, so finding the right balance is hard (but I think that
is the right definition for the API!).

On the other hand, with the hypothetical cairo-surface API you would be
able to do the transformation into XCopyArea easily (since the definition
there would be an implicit copy-on-write for the source being passed
into the operation, and not at the context).

However, that all has to be compared to

expose-event (or preferrably repaint function after accumulating
exposures):
	/* use double buffering */
	cairo_create(xlib_surface);
	cairo_rectangle(redraw_x, redraw_y, redraw_w, redraw_h);
	cairo_clip();
	cairo_push_group_with_context(CAIRO_CONTENT_COLOR);
	.... bunch of rendering ...
	cairo_pop_group_to_source();
	cairo_paint();
	cairo_destroy();

	cairo_surface_flush(xlib_surface);

and now in your scroll function you are free to use XCopyArea on the
underlying drawable. For completeness after using XCopyArea, call
cairo_surface_mark_dirty().
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the cairo mailing list