aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-03-14 17:14:00 +0100
committerDavid Robillard <d@drobilla.net>2020-03-15 10:24:47 +0100
commit919dd0200074cbaac655ee2cb3f8767592f80514 (patch)
tree949dc55a9cd981c87a55c53a6e49d1bb977d931f
parent1450f08a3d9f961bdc9cf9014553492bf986cf72 (diff)
Windows: Use ephemeral Cairo surface for drawing
-rw-r--r--pugl/detail/win_cairo.c75
1 files changed, 37 insertions, 38 deletions
diff --git a/pugl/detail/win_cairo.c b/pugl/detail/win_cairo.c
index be0e1d1..4e37f0f 100644
--- a/pugl/detail/win_cairo.c
+++ b/pugl/detail/win_cairo.c
@@ -1,5 +1,5 @@
/*
- Copyright 2012-2019 David Robillard <http://drobilla.net>
+ Copyright 2012-2020 David Robillard <http://drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -21,6 +21,7 @@
#include "pugl/detail/types.h"
#include "pugl/detail/win.h"
#include "pugl/pugl_cairo.h"
+#include "pugl/pugl_stub.h"
#include <cairo-win32.h>
#include <cairo.h>
@@ -46,15 +47,6 @@ puglWinCairoCreateDrawContext(PuglView* view)
DeleteObject(SelectObject(surface->drawDc, surface->drawBitmap));
- cairo_status_t st = CAIRO_STATUS_SUCCESS;
- if (!(surface->surface = cairo_win32_surface_create(surface->drawDc)) ||
- (st = cairo_surface_status(surface->surface)) ||
- !(surface->cr = cairo_create(surface->surface)) ||
- (st = cairo_status(surface->cr))) {
- return PUGL_CREATE_CONTEXT_FAILED;
- }
-
- cairo_save(surface->cr);
return PUGL_SUCCESS;
}
@@ -66,11 +58,7 @@ puglWinCairoDestroyDrawContext(PuglView* view)
DeleteDC(surface->drawDc);
DeleteObject(surface->drawBitmap);
- cairo_destroy(surface->cr);
- cairo_surface_destroy(surface->surface);
- surface->surface = NULL;
- surface->cr = NULL;
surface->drawDc = NULL;
surface->drawBitmap = NULL;
@@ -90,10 +78,32 @@ puglWinCairoConfigure(PuglView* view)
return st;
}
+static void
+puglWinCairoClose(PuglView* view)
+{
+ PuglInternals* const impl = view->impl;
+ PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+
+ cairo_surface_destroy(surface->surface);
+
+ surface->surface = NULL;
+}
+
static PuglStatus
-puglWinCairoCreate(PuglView* view)
+puglWinCairoOpen(PuglView* view)
{
- return puglWinCairoCreateDrawContext(view);
+ PuglInternals* const impl = view->impl;
+ PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+
+ cairo_status_t st = CAIRO_STATUS_SUCCESS;
+ if (!(surface->surface = cairo_win32_surface_create(surface->drawDc)) ||
+ (st = cairo_surface_status(surface->surface)) ||
+ !(surface->cr = cairo_create(surface->surface)) ||
+ (st = cairo_status(surface->cr))) {
+ return PUGL_CREATE_CONTEXT_FAILED;
+ }
+
+ return PUGL_SUCCESS;
}
static PuglStatus
@@ -102,6 +112,7 @@ puglWinCairoDestroy(PuglView* view)
PuglInternals* const impl = view->impl;
PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+ puglWinCairoClose(view);
puglWinCairoDestroyDrawContext(view);
free(surface);
impl->surface = NULL;
@@ -112,16 +123,16 @@ puglWinCairoDestroy(PuglView* view)
static PuglStatus
puglWinCairoEnter(PuglView* view, const PuglEventExpose* expose)
{
- PuglInternals* const impl = view->impl;
- PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+ PuglStatus st = PUGL_SUCCESS;
- if (expose) {
+ if (expose &&
+ !(st = puglWinCairoCreateDrawContext(view)) &&
+ !(st = puglWinCairoOpen(view))) {
PAINTSTRUCT ps;
BeginPaint(view->impl->hwnd, &ps);
- cairo_save(surface->cr);
}
- return PUGL_SUCCESS;
+ return st;
}
static PuglStatus
@@ -131,12 +142,14 @@ puglWinCairoLeave(PuglView* view, const PuglEventExpose* expose)
PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
if (expose) {
- cairo_restore(surface->cr);
cairo_surface_flush(surface->surface);
BitBlt(impl->hdc,
0, 0, (int)view->frame.width, (int)view->frame.height,
surface->drawDc, 0, 0, SRCCOPY);
+ puglWinCairoClose(view);
+ puglWinCairoDestroyDrawContext(view);
+
PAINTSTRUCT ps;
EndPaint(view->impl->hwnd, &ps);
SwapBuffers(view->impl->hdc);
@@ -145,20 +158,6 @@ puglWinCairoLeave(PuglView* view, const PuglEventExpose* expose)
return PUGL_SUCCESS;
}
-static PuglStatus
-puglWinCairoResize(PuglView* view,
- int PUGL_UNUSED(width),
- int PUGL_UNUSED(height))
-{
- PuglStatus st = PUGL_SUCCESS;
- if ((st = puglWinCairoDestroyDrawContext(view)) ||
- (st = puglWinCairoCreateDrawContext(view))) {
- return st;
- }
-
- return PUGL_SUCCESS;
-}
-
static void*
puglWinCairoGetContext(PuglView* view)
{
@@ -169,11 +168,11 @@ const PuglBackend*
puglCairoBackend()
{
static const PuglBackend backend = {puglWinCairoConfigure,
- puglWinCairoCreate,
+ puglStubCreate,
puglWinCairoDestroy,
puglWinCairoEnter,
puglWinCairoLeave,
- puglWinCairoResize,
+ puglStubResize,
puglWinCairoGetContext};
return &backend;