From 919dd0200074cbaac655ee2cb3f8767592f80514 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 14 Mar 2020 17:14:00 +0100 Subject: Windows: Use ephemeral Cairo surface for drawing --- pugl/detail/win_cairo.c | 75 ++++++++++++++++++++++++------------------------- 1 file 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 + Copyright 2012-2020 David Robillard 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 #include @@ -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; -- cgit v1.2.1