From 18c793dbb4fac59facc1877fbb04ea889ef2b895 Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Fri, 23 Jun 2023 15:32:32 +0200 Subject: [PATCH] When we call mg_surface_prepare() on a surface, select it in a per-thread handle. Automatically call deselect on the selected handle when preparing another surface. Also have a way to deselect whichever surface is currently selected. This is needed for some backend that explicitly need to be 'unbound' before using them from another thread --- src/graphics.h | 3 +++ src/graphics_surface.c | 25 +++++++++++++++++++++++++ src/graphics_surface.h | 2 ++ src/mtl_surface.m | 1 + src/wgl_surface.c | 5 +++++ 5 files changed, 36 insertions(+) diff --git a/src/graphics.h b/src/graphics.h index c13805f..fd9f0b2 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -99,8 +99,11 @@ MP_API bool mg_surface_is_nil(mg_surface surface); MP_API mg_surface mg_surface_create_for_window(mp_window window, mg_surface_api api); MP_API void mg_surface_destroy(mg_surface surface); + MP_API void mg_surface_prepare(mg_surface surface); MP_API void mg_surface_present(mg_surface surface); +MP_API void mg_surface_deselect(void); + MP_API void mg_surface_swap_interval(mg_surface surface, int swap); MP_API vec2 mg_surface_contents_scaling(mg_surface surface); MP_API mp_rect mg_surface_get_frame(mg_surface surface); diff --git a/src/graphics_surface.c b/src/graphics_surface.c index 20eec15..fb8a9cf 100644 --- a/src/graphics_surface.c +++ b/src/graphics_surface.c @@ -8,6 +8,12 @@ #include"graphics_surface.h" +//--------------------------------------------------------------- +// per-thread selected surface +//--------------------------------------------------------------- + +mp_thread_local mg_surface __mgSelectedSurface = {0}; + //--------------------------------------------------------------- // typed handles functions //--------------------------------------------------------------- @@ -208,13 +214,32 @@ void mg_surface_destroy(mg_surface handle) } } +void mg_surface_deselect() +{ + DEBUG_ASSERT(__mgData.init); + + mg_surface_data* prevSurface = mg_surface_data_from_handle(__mgSelectedSurface); + if(prevSurface && prevSurface->deselect) + { + prevSurface->deselect(prevSurface); + } + __mgSelectedSurface = mg_surface_nil(); +} + void mg_surface_prepare(mg_surface surface) { DEBUG_ASSERT(__mgData.init); + + if(surface.h != __mgSelectedSurface.h) + { + mg_surface_deselect(); + } + mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); if(surfaceData && surfaceData->prepare) { surfaceData->prepare(surfaceData); + __mgSelectedSurface = surface; } } diff --git a/src/graphics_surface.h b/src/graphics_surface.h index 89e1e5c..fed7d6c 100644 --- a/src/graphics_surface.h +++ b/src/graphics_surface.h @@ -23,6 +23,7 @@ typedef struct mg_canvas_backend mg_canvas_backend; typedef void (*mg_surface_destroy_proc)(mg_surface_data* surface); typedef void (*mg_surface_prepare_proc)(mg_surface_data* surface); +typedef void (*mg_surface_deselect_proc)(mg_surface_data* surface); typedef void (*mg_surface_present_proc)(mg_surface_data* surface); typedef void (*mg_surface_swap_interval_proc)(mg_surface_data* surface, int swap); typedef vec2 (*mg_surface_contents_scaling_proc)(mg_surface_data* surface); @@ -42,6 +43,7 @@ typedef struct mg_surface_data mg_surface_destroy_proc destroy; mg_surface_prepare_proc prepare; mg_surface_present_proc present; + mg_surface_deselect_proc deselect; mg_surface_swap_interval_proc swapInterval; mg_surface_contents_scaling_proc contentsScaling; mg_surface_get_frame_proc getFrame; diff --git a/src/mtl_surface.m b/src/mtl_surface.m index cd9354b..bba001c 100644 --- a/src/mtl_surface.m +++ b/src/mtl_surface.m @@ -158,6 +158,7 @@ mg_surface_data* mg_mtl_surface_create_for_window(mp_window window) surface->interface.api = MG_METAL; surface->interface.destroy = mg_mtl_surface_destroy; surface->interface.prepare = mg_mtl_surface_prepare; + surface->interface.deselect = 0; surface->interface.present = mg_mtl_surface_present; surface->interface.swapInterval = mg_mtl_surface_swap_interval; diff --git a/src/wgl_surface.c b/src/wgl_surface.c index 406ebc4..70fdebe 100644 --- a/src/wgl_surface.c +++ b/src/wgl_surface.c @@ -153,6 +153,11 @@ void mg_wgl_surface_present(mg_surface_data* interface) SwapBuffers(surface->hDC); } +void mg_wgl_surface_deselect(mg_surface_data* interface) +{ + wglMakeCurrent(NULL, NULL); +} + void mg_wgl_surface_swap_interval(mg_surface_data* interface, int swap) { mg_wgl_surface* surface = (mg_wgl_surface*)interface;