aboutsummaryrefslogtreecommitdiffstats
path: root/pugl/detail
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-02-17 19:48:03 +0100
committerDavid Robillard <d@drobilla.net>2020-02-18 23:19:42 +0100
commit73b8c91e71676a66ef27b981da147fdf5344fded (patch)
treebbd2857e3354b8908f0470c645ca36744a252a6f /pugl/detail
parent5dc5a5737d6708fd352367f1dbe2a198e841604a (diff)
downloadpugl-73b8c91e71676a66ef27b981da147fdf5344fded.tar.gz
pugl-73b8c91e71676a66ef27b981da147fdf5344fded.tar.bz2
pugl-73b8c91e71676a66ef27b981da147fdf5344fded.zip
X11: Use a single Cairo context
Cairo has a built-in cache that makes this fast enough to not matter, and it removes some state which is always good.
Diffstat (limited to 'pugl/detail')
-rw-r--r--pugl/detail/x11_cairo.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/pugl/detail/x11_cairo.c b/pugl/detail/x11_cairo.c
index 523a569..9d3ec16 100644
--- a/pugl/detail/x11_cairo.c
+++ b/pugl/detail/x11_cairo.c
@@ -33,9 +33,8 @@
typedef struct {
cairo_surface_t* back;
- cairo_t* backCr;
cairo_surface_t* front;
- cairo_t* frontCr;
+ cairo_t* cr;
} PuglX11CairoSurface;
static PuglStatus
@@ -50,18 +49,11 @@ puglX11CairoCreate(PuglView* view)
impl->display, impl->win, impl->vi->visual, width, height);
surface.front = cairo_surface_create_similar(
surface.back, CAIRO_CONTENT_COLOR, width, height);
- surface.backCr = cairo_create(surface.back);
- surface.frontCr = cairo_create(surface.front);
cairo_status_t st = CAIRO_STATUS_SUCCESS;
- if (!surface.back || !surface.backCr ||
- !surface.front || !surface.frontCr ||
+ if (!surface.back || !surface.front ||
(st = cairo_surface_status(surface.back)) ||
- (st = cairo_surface_status(surface.front)) ||
- (st = cairo_status(surface.backCr)) ||
- (st = cairo_status(surface.frontCr))) {
- cairo_destroy(surface.frontCr);
- cairo_destroy(surface.backCr);
+ (st = cairo_surface_status(surface.front))) {
cairo_surface_destroy(surface.front);
cairo_surface_destroy(surface.back);
return PUGL_CREATE_CONTEXT_FAILED;
@@ -79,8 +71,6 @@ puglX11CairoDestroy(PuglView* view)
PuglInternals* const impl = view->impl;
PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
- cairo_destroy(surface->frontCr);
- cairo_destroy(surface->backCr);
cairo_surface_destroy(surface->front);
cairo_surface_destroy(surface->back);
free(surface);
@@ -95,7 +85,10 @@ puglX11CairoEnter(PuglView* view, bool drawing)
PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
if (drawing) {
- cairo_save(surface->frontCr);
+ surface->cr = cairo_create(surface->front);
+ if (!surface->cr || cairo_status(surface->cr)) {
+ return PUGL_CREATE_CONTEXT_FAILED;
+ }
}
return PUGL_SUCCESS;
@@ -108,9 +101,18 @@ puglX11CairoLeave(PuglView* view, bool drawing)
PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
if (drawing) {
- cairo_set_source_surface(surface->backCr, surface->front, 0, 0);
- cairo_paint(surface->backCr);
- cairo_restore(surface->frontCr);
+ // Destroy front context that was used by the user for drawing
+ cairo_destroy(surface->cr);
+
+ // Create a new context for the back and paint the front onto it
+ surface->cr = cairo_create(surface->back);
+ cairo_set_source_surface(surface->cr, surface->front, 0, 0);
+ cairo_paint(surface->cr);
+ cairo_destroy(surface->cr);
+ surface->cr = NULL;
+
+ // Flush back to X
+ cairo_surface_flush(surface->back);
}
return PUGL_SUCCESS;
@@ -124,16 +126,12 @@ puglX11CairoResize(PuglView* view, int width, int height)
cairo_xlib_surface_set_size(surface->back, width, height);
- cairo_destroy(surface->frontCr);
cairo_surface_destroy(surface->front);
if (!(surface->front = cairo_surface_create_similar(
surface->back, CAIRO_CONTENT_COLOR, width, height))) {
return PUGL_CREATE_CONTEXT_FAILED;
}
- surface->frontCr = cairo_create(surface->front);
- cairo_save(surface->frontCr);
-
return PUGL_SUCCESS;
}
@@ -143,7 +141,7 @@ puglX11CairoGetContext(PuglView* view)
PuglInternals* const impl = view->impl;
PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
- return surface->frontCr;
+ return surface->cr;
}
const PuglBackend*