forked from AuroraMiddleware/gtk
gdkinternals: Document our drawing and painting process better
This commit is contained in:
parent
c01e37a9a5
commit
10a7a89311
@ -216,15 +216,82 @@ struct _GdkWindow
|
||||
|
||||
cairo_pattern_t *background;
|
||||
|
||||
/* The paint logic here is a bit complex because of our intermingling of
|
||||
* cairo and GL. Let's first go over the cairo-alone case:
|
||||
*
|
||||
* 1) gdk_window_begin_paint_region() is called with an update region. If
|
||||
* the backend wants it, we redirect drawing to a temporary surface
|
||||
* sized the same as the update region and set `surface_needs_composite`
|
||||
* to TRUE. Otherwise, we paint directly onto the real server-side window.
|
||||
*
|
||||
* 2) Things paint with cairo using gdk_cairo_create().
|
||||
*
|
||||
* 3) When everything is painted, the user calls gdk_window_end_paint().
|
||||
* If there was a temporary surface, this is composited back onto the
|
||||
* real backing surface in the appropriate places.
|
||||
*
|
||||
* This is similar to double buffering, except we only have partial surfaces
|
||||
* of undefined contents, and instead of swapping between two buffers, we
|
||||
* create a new temporary buffer every time.
|
||||
*
|
||||
* When we add GL to the mix, we have this instead:
|
||||
*
|
||||
* 1) gdk_window_begin_paint_region() is called with an update region like
|
||||
* before. We always redirect cairo drawing to a temporary surface when
|
||||
* GL is enabled.
|
||||
*
|
||||
* 2) Things paint with cairo using gdk_cairo_create(). Whenever
|
||||
* something paints, it calls gdk_window_mark_paint_from_clip() to mark
|
||||
* which regions it has painted in software. We'll learn what this does
|
||||
* soon.
|
||||
*
|
||||
* 3) Something paints with GL and uses gdk_cairo_draw_from_gl() to
|
||||
* composite back into the scene. We paint this onto the backing
|
||||
* store for the window *immediately* by using GL, rather than
|
||||
* painting to the temporary surface, and keep track of the area that
|
||||
* we've painted in `flushed_region`.
|
||||
*
|
||||
* 4) Something paints using software again. It calls
|
||||
* gdk_window_mark_paint_from_clip(), which subtracts the region it
|
||||
* has painted from `flushed_region` and adds the region to
|
||||
* `needs_blended_region`.
|
||||
*
|
||||
* 5) Something paints using GL again, using gdk_cairo_draw_from_gl().
|
||||
* It paints directly to the backing store, removes the region it
|
||||
* painted from `needs_blended_region`, and adds to `flushed_region`.
|
||||
*
|
||||
* 6) gdk_window_end_paint() is called. It composites the temporary surface
|
||||
* back to the window, using GL, except it doesn't bother copying
|
||||
* `flushed_region`, and when it paints `needs_blended_region`, it also
|
||||
* turns on GL blending.
|
||||
*
|
||||
* That means that at any point in time, we have three regions:
|
||||
*
|
||||
* * `region` - This is the original invalidated region and is never
|
||||
* touched.
|
||||
*
|
||||
* * `flushed_region` - This is the portion of `region` that has GL
|
||||
* contents that have been painted directly to the window, and
|
||||
* doesn't have any cairo drawing painted over it.
|
||||
*
|
||||
* * `needs_blended_region` - This is the portion of `region` that
|
||||
* GL contents that have part cairo drawing painted over it.
|
||||
* gdk_window_end_paint() will draw this region using blending.
|
||||
*
|
||||
* `flushed_region` and `needs_blended_region` never intersect, and the
|
||||
* rest of `region` that isn't covered by either is the "opaque region",
|
||||
* which is any area of cairo drawing that didn't ever intersect with GL.
|
||||
* We can paint these from GL without turning on blending.
|
||||
**/
|
||||
|
||||
struct {
|
||||
cairo_region_t *region;
|
||||
/* The temporary surface that we're painting to. This will be composited
|
||||
* back into the window when we call end_paint. This is our poor-man's
|
||||
* way of doing double buffering. */
|
||||
cairo_surface_t *surface;
|
||||
|
||||
/* Areas of region that have been copied to the back buffer already */
|
||||
cairo_region_t *region;
|
||||
cairo_region_t *flushed_region;
|
||||
/* Areas of region that have been copied to the back buffer but
|
||||
needs furter blending of surface data. These two regions are
|
||||
always non-intersecting. */
|
||||
cairo_region_t *need_blend_region;
|
||||
|
||||
gboolean surface_needs_composite;
|
||||
|
Loading…
Reference in New Issue
Block a user