[cairo] Problem in cairo + xcb where alpha blending is cumulative (becoming more opaque with each render)
ryan.flannery at gmail.com
Thu Sep 27 04:28:08 UTC 2018
>From what I can see, my issue boils down to CAIRO_OPERATOR_SOURCE not
behaving as I would expect, with the use of an xcb backed surface.
Namely, after doing a cairo_pop_group_to_source(), if I
CAIRO_OPERATOR_SOURCE), based on the docs I would expect the alpha channel
to be copied from the intermediate pattern/surface as-is to the
destination, with no blending. I actually observe this when the destination
is *not* an xcb derived surface (I'm playing with a png one now, using the
sample program I included).
With an xcb backed surface like in my original program, setting the
operator to CAIRO_OPERATOR_SOURCE results in a solid black background.
Specifically, my case is this:
// BEGIN render loop
cairo_set_source_rgba(cairo, 0.8, 0, 0, 0.1);
// draw (lots of) stuff
// END render loop
// reset operator to CAIRO_OPERATOR_OVER
I've been looking into cairo-xcb / xcb specifics regarding this, but any
cluesticks that could be provided would be appreciated.
> I've recently been using cairo + xcb to build a new application. I've hit
> a problem supporting transparency / alpha-blending, where I want to allow
> users to set the background window with an alpha value and have the root
> x11 window show through that. The raw transparency piece works fine and is
> easy in cairo + xcb, but I'm struggling with my main render loop -- it
> seems to add / accumulate the alpha values with each render, and doesn't
> remove previously drawn content with alpha values. I have more details
> below including a fully functioning prototype with my layout setup (also
> below and in a gist), but here's what I've been trying after much
> google'ing and searching the archives:
> My main render loop looks roughly like this (and I understand why this
> would accumulate opaqueness over time):
> // BEGIN render loop
> // draw (lots of) stuff
> // END render loop
> where clear_background() is:
> cairo_set_source_rgba(cairo, 0.8, 0, 0, 0.1);
> With that loop, as-is, I can see why the alpha values are accumulating
> with each render.
> To compensate, I've tried the following based on the cairo site's
> documentation, and browsing the archives, but with no success:
> 1. cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); (and subsequent
> resets to *_OVER)
> I've tried this before the cairo_paint() at the END of the loop, as
> well as in the BEGIN loop (both before and after the cairo_push_group()).
> My understanding is that this copies the alpha from SOURCE as-is,
> with no blending, but I'm not observing that in the results, regardless of
> where I place it (and tweak the timing to confirm each step).
> Use of it *always* results in a black background, which makes me
> think I have something larger out-of-whack.
> 2. I've looked at other operators, but none seem applicable (and I've
> tested most in various setups like the above).
> 3. Using cairo_mask() / cairo_mask_surface() when using
> cairo_pop_group() (the raw one, returning a cairo_pattern_t) to render
> after the pop, but that also fails.
> My ultimate goals are basically these:
> 1. Have the window always reset to a consistent background of rgba =
> 2. Don't 'accumulate' alpha artifacts from the widgets drawn in the
> loop each time
> My sample code below illustrates what I'm trying and my setup.
> It draws a 200 x 200 pixel window (at x,y = 200,200).
> It has an initial background of rgba = 0.8/0/0/0.1,
> and a 50x50 pixel green square in the top left (rgba=0/1/0/0.5).
> Every second it redraws, and moves the square towards the bottom right.
> 1. The background is *always* rgba = 0.8/0/0/0.1
> 2. Only one square (the most recent) is shown with rgba = 0/1/0/0.5
> BUT what I observe (trying lots of variants):
> 1. The background gets more opaque with each render, eventually
> becoming solid
> 2. The previous renders of the green square persist and aren't cleared
> The code is below, along with build instructions, and available at:
> Note the example includes a great deal of XCB setup, including logic to
> handle tiling window managers (my use case). I doubt that's of interest
> here, but I'm including it for completeness (but below the main cairo
> Any feedback appreciated (on this or other conventions I have!)
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the cairo