Vulkan/SwapChain: Fix crash on fullscreen with MoltenVK
This commit is contained in:
parent
093979a65a
commit
b581cc4777
|
@ -18,10 +18,35 @@ Log_SetChannel(Vulkan::SwapChain);
|
|||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <objc/message.h>
|
||||
|
||||
static bool IsMainThread()
|
||||
{
|
||||
Class clsNSThread = objc_getClass("NSThread");
|
||||
if (!clsNSThread)
|
||||
return false;
|
||||
|
||||
return reinterpret_cast<BOOL (*)(Class, SEL)>(objc_msgSend)(clsNSThread, sel_getUid("isMainThread"));
|
||||
}
|
||||
|
||||
static bool CreateMetalLayer(WindowInfo* wi)
|
||||
{
|
||||
if (!IsMainThread())
|
||||
{
|
||||
struct MainThreadParams
|
||||
{
|
||||
WindowInfo* wi;
|
||||
bool result;
|
||||
};
|
||||
MainThreadParams params = {wi, false};
|
||||
dispatch_sync_f(dispatch_get_main_queue(), ¶ms, [](void* vparams) {
|
||||
MainThreadParams* params = static_cast<MainThreadParams*>(vparams);
|
||||
params->result = CreateMetalLayer(params->wi);
|
||||
});
|
||||
return params.result;
|
||||
}
|
||||
|
||||
id view = reinterpret_cast<id>(wi->window_handle);
|
||||
|
||||
Class clsCAMetalLayer = objc_getClass("CAMetalLayer");
|
||||
|
@ -32,7 +57,7 @@ static bool CreateMetalLayer(WindowInfo* wi)
|
|||
}
|
||||
|
||||
// [CAMetalLayer layer]
|
||||
id layer = reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(objc_getClass("CAMetalLayer"), sel_getUid("layer"));
|
||||
id layer = reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(clsCAMetalLayer, sel_getUid("layer"));
|
||||
if (!layer)
|
||||
{
|
||||
Log_ErrorPrint("Failed to create Metal layer.");
|
||||
|
@ -61,6 +86,12 @@ static bool CreateMetalLayer(WindowInfo* wi)
|
|||
|
||||
static void DestroyMetalLayer(WindowInfo* wi)
|
||||
{
|
||||
if (!IsMainThread())
|
||||
{
|
||||
dispatch_sync_f(dispatch_get_main_queue(), wi, [](void* wi) { DestroyMetalLayer(static_cast<WindowInfo*>(wi)); });
|
||||
return;
|
||||
}
|
||||
|
||||
id view = reinterpret_cast<id>(wi->window_handle);
|
||||
id layer = reinterpret_cast<id>(wi->surface_handle);
|
||||
if (layer == nil)
|
||||
|
@ -68,7 +99,6 @@ static void DestroyMetalLayer(WindowInfo* wi)
|
|||
|
||||
reinterpret_cast<void (*)(id, SEL, id)>(objc_msgSend)(view, sel_getUid("setLayer:"), nil);
|
||||
reinterpret_cast<void (*)(id, SEL, BOOL)>(objc_msgSend)(view, sel_getUid("setWantsLayer:"), NO);
|
||||
reinterpret_cast<void (*)(id, SEL)>(objc_msgSend)(layer, sel_getUid("release"));
|
||||
wi->surface_handle = nullptr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue