From 6a77f96642b201f614ce7eb67f3b6ec4e1e8c181 Mon Sep 17 00:00:00 2001
From: David Robillard <d@drobilla.net>
Date: Fri, 26 Jul 2019 23:46:29 +0200
Subject: Make enterContext take a drawing parameter like leaveContext

These need to be symmetric because sometimes different things need to happen in
either situation when entering the context as well.
---
 pugl/pugl.h                | 21 ++++++++++++++-------
 pugl/pugl_internal.h       |  4 ++--
 pugl/pugl_internal_types.h |  6 +++---
 pugl/pugl_osx.m            | 12 ++++++------
 pugl/pugl_win.c            | 20 ++++++++++++--------
 pugl/pugl_x11.c            | 19 ++++++++++---------
 pugl/pugl_x11_cairo.c      |  4 ++--
 pugl/pugl_x11_gl.c         |  8 ++++----
 test/pugl_test.c           |  2 +-
 9 files changed, 54 insertions(+), 42 deletions(-)

diff --git a/pugl/pugl.h b/pugl/pugl.h
index 3e0578e..f34b4de 100644
--- a/pugl/pugl.h
+++ b/pugl/pugl.h
@@ -572,21 +572,28 @@ puglGetContext(PuglView* view);
 /**
    Enter the drawing context.
 
-   This must be called before any code that accesses the drawing context,
-   including any GL functions.  This is only necessary for code that does so
-   outside the usual draw callback or handling of an expose event.
+   Note that pugl automatically enters and leaves the drawing context during
+   configure and expose events, so it is not normally necessary to call this.
+   However, it can be used to enter the drawing context elsewhere, for example
+   to call any GL functions during setup.
+
+   @param view The view being entered.
+   @param drawing If true, prepare for drawing.
 */
 PUGL_API void
-puglEnterContext(PuglView* view);
+puglEnterContext(PuglView* view, bool drawing);
 
 /**
    Leave the drawing context.
 
-   This must be called after puglEnterContext and applies the results of the
-   drawing code (for example, by swapping buffers).
+   This must be called after puglEnterContext() with a matching `drawing`
+   parameter.
+
+   @param view The view being left.
+   @param drawing If true, finish drawing, for example by swapping buffers.
 */
 PUGL_API void
-puglLeaveContext(PuglView* view, bool flush);
+puglLeaveContext(PuglView* view, bool drawing);
 
 /**
    @}
diff --git a/pugl/pugl_internal.h b/pugl/pugl_internal.h
index 57b026f..ac31b65 100644
--- a/pugl/pugl_internal.h
+++ b/pugl/pugl_internal.h
@@ -252,13 +252,13 @@ puglDispatchEvent(PuglView* view, const PuglEvent* event)
 	case PUGL_CONFIGURE:
 		view->width  = (int)event->configure.width;
 		view->height = (int)event->configure.height;
-		puglEnterContext(view);
+		puglEnterContext(view, false);
 		view->eventFunc(view, event);
 		puglLeaveContext(view, false);
 		break;
 	case PUGL_EXPOSE:
 		if (event->expose.count == 0) {
-			puglEnterContext(view);
+			puglEnterContext(view, true);
 			view->eventFunc(view, event);
 			puglLeaveContext(view, true);
 		}
diff --git a/pugl/pugl_internal_types.h b/pugl/pugl_internal_types.h
index fad1b2d..7dcfc9f 100644
--- a/pugl/pugl_internal_types.h
+++ b/pugl/pugl_internal_types.h
@@ -90,10 +90,10 @@ typedef struct {
 	/** Destroy surface and drawing context. */
 	int (*destroy)(PuglView*);
 
-	/** Enter drawing context. */
-	int (*enter)(PuglView*);
+	/** Enter drawing context, for drawing if parameter is true. */
+	int (*enter)(PuglView*, bool);
 
-	/** Leave drawing context, explicitly flushing if parameter is true. */
+	/** Leave drawing context, after drawing if parameter is true. */
 	int (*leave)(PuglView*, bool);
 
 	/** Resize drawing context to the given width and height. */
diff --git a/pugl/pugl_osx.m b/pugl/pugl_osx.m
index c5a94f8..82bc9a6 100644
--- a/pugl/pugl_osx.m
+++ b/pugl/pugl_osx.m
@@ -740,21 +740,21 @@ puglInitInternals(void)
 }
 
 void
-puglEnterContext(PuglView* view)
+puglEnterContext(PuglView* view, bool PUGL_UNUSED(drawing))
 {
 	[[view->impl->glview openGLContext] makeCurrentContext];
 }
 
 void
-puglLeaveContext(PuglView* view, bool flush)
+puglLeaveContext(PuglView* view, bool drawing)
 {
+	if (drawing) {
 #ifdef PUGL_HAVE_CAIRO
-	if (view->ctx_type & PUGL_CAIRO) {
-		pugl_cairo_gl_draw(&view->impl->cairo_gl, view->width, view->height);
-	}
+		if (view->ctx_type & PUGL_CAIRO) {
+			pugl_cairo_gl_draw(&view->impl->cairo_gl, view->width, view->height);
+		}
 #endif
 
-	if (flush) {
 		[[view->impl->glview openGLContext] flushBuffer];
 	}
 
diff --git a/pugl/pugl_win.c b/pugl/pugl_win.c
index 747a1f4..d9cdf7d 100644
--- a/pugl/pugl_win.c
+++ b/pugl/pugl_win.c
@@ -115,7 +115,7 @@ puglInitInternals(void)
 }
 
 void
-puglEnterContext(PuglView* view)
+puglEnterContext(PuglView* view, bool drawing)
 {
 #ifdef PUGL_HAVE_GL
 	if (view->ctx_type == PUGL_GL) {
@@ -123,19 +123,23 @@ puglEnterContext(PuglView* view)
 	}
 #endif
 
-	PAINTSTRUCT ps;
-	BeginPaint(view->impl->hwnd, &ps);
+	if (drawing) {
+		PAINTSTRUCT ps;
+		BeginPaint(view->impl->hwnd, &ps);
+	}
 }
 
 void
-puglLeaveContext(PuglView* view, bool flush)
+puglLeaveContext(PuglView* view, bool drawing)
 {
-	PAINTSTRUCT ps;
-	EndPaint(view->impl->hwnd, &ps);
+	if (drawing) {
+		PAINTSTRUCT ps;
+		EndPaint(view->impl->hwnd, &ps);
 
 #ifdef PUGL_HAVE_GL
-	if (view->ctx_type == PUGL_GL && flush) {
-		SwapBuffers(view->impl->hdc);
+		if (view->ctx_type == PUGL_GL) {
+			SwapBuffers(view->impl->hdc);
+		}
 	}
 #endif
 
diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c
index ff44aef..3a0f4c2 100644
--- a/pugl/pugl_x11.c
+++ b/pugl/pugl_x11.c
@@ -68,15 +68,15 @@ puglInitInternals(void)
 }
 
 void
-puglEnterContext(PuglView* view)
+puglEnterContext(PuglView* view, bool drawing)
 {
-	view->impl->backend->enter(view);
+	view->impl->backend->enter(view, drawing);
 }
 
 void
-puglLeaveContext(PuglView* view, bool flush)
+puglLeaveContext(PuglView* view, bool drawing)
 {
-	view->impl->backend->leave(view, flush);
+	view->impl->backend->leave(view, drawing);
 }
 
 int
@@ -559,7 +559,9 @@ puglProcessEvents(PuglView* view)
 	}
 
 	if (config_event.type || expose_event.type) {
-		puglEnterContext(view);
+		const bool draw = expose_event.type && expose_event.expose.count == 0;
+
+		puglEnterContext(view, draw);
 
 		if (config_event.type) {
 			view->width  = (int)config_event.configure.width;
@@ -568,12 +570,11 @@ puglProcessEvents(PuglView* view)
 			view->eventFunc(view, (const PuglEvent*)&config_event);
 		}
 
-		if (expose_event.type && expose_event.expose.count == 0) {
+		if (draw) {
 			view->eventFunc(view, (const PuglEvent*)&expose_event);
-			puglLeaveContext(view, true);
-		} else {
-			puglLeaveContext(view, false);
 		}
+
+		puglLeaveContext(view, draw);
 	}
 
 	return PUGL_SUCCESS;
diff --git a/pugl/pugl_x11_cairo.c b/pugl/pugl_x11_cairo.c
index a0a0789..c52b875 100644
--- a/pugl/pugl_x11_cairo.c
+++ b/pugl/pugl_x11_cairo.c
@@ -87,13 +87,13 @@ puglX11CairoDestroy(PuglView* view)
 }
 
 static int
-puglX11CairoEnter(PuglView* PUGL_UNUSED(view))
+puglX11CairoEnter(PuglView* PUGL_UNUSED(view), bool PUGL_UNUSED(drawing))
 {
 	return 0;
 }
 
 static int
-puglX11CairoLeave(PuglView* PUGL_UNUSED(view), bool PUGL_UNUSED(flush))
+puglX11CairoLeave(PuglView* PUGL_UNUSED(view), bool PUGL_UNUSED(drawing))
 {
 	return 0;
 }
diff --git a/pugl/pugl_x11_gl.c b/pugl/pugl_x11_gl.c
index 46caaa0..1277404 100644
--- a/pugl/pugl_x11_gl.c
+++ b/pugl/pugl_x11_gl.c
@@ -150,7 +150,7 @@ puglX11GlDestroy(PuglView* view)
 }
 
 static int
-puglX11GlEnter(PuglView* view)
+puglX11GlEnter(PuglView* view, bool PUGL_UNUSED(drawing))
 {
 	PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
 	glXMakeCurrent(view->impl->display, view->impl->win, surface->ctx);
@@ -158,13 +158,13 @@ puglX11GlEnter(PuglView* view)
 }
 
 static int
-puglX11GlLeave(PuglView* view, bool flush)
+puglX11GlLeave(PuglView* view, bool drawing)
 {
 	PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
 
-	if (flush && surface->double_buffered) {
+	if (drawing && surface->double_buffered) {
 		glXSwapBuffers(view->impl->display, view->impl->win);
-	} else if (flush) {
+	} else if (drawing) {
 		glFlush();
 	}
 
diff --git a/test/pugl_test.c b/test/pugl_test.c
index f011962..fe1cc29 100644
--- a/test/pugl_test.c
+++ b/test/pugl_test.c
@@ -183,7 +183,7 @@ main(int argc, char** argv)
 		return 1;
 	}
 
-	puglEnterContext(view);
+	puglEnterContext(view, false);
 	glEnable(GL_DEPTH_TEST);
 	glDepthFunc(GL_LESS);
 	glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
-- 
cgit v1.2.3