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

This commit is contained in:
Martin Fouilleul 2023-06-23 15:32:32 +02:00
parent 83f128fb55
commit 18c793dbb4
5 changed files with 36 additions and 0 deletions

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;