mirror of https://github.com/PCSX2/pcsx2.git
Common: Move ObjC methods to CocoaTools
This commit is contained in:
parent
dbfb93a50f
commit
beab9870cf
|
@ -229,3 +229,20 @@ function(find_optional_system_library library bundled_path)
|
|||
set(${library}_TYPE "Bundled" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(fixup_file_properties target)
|
||||
get_target_property(SOURCES ${target} SOURCES)
|
||||
if(APPLE)
|
||||
foreach(source IN LISTS SOURCES)
|
||||
# Set the right file types for .inl files in Xcode
|
||||
if("${source}" MATCHES "\\.(inl|h)$")
|
||||
set_source_files_properties("${source}" PROPERTIES XCODE_EXPLICIT_FILE_TYPE sourcecode.cpp.h)
|
||||
endif()
|
||||
# CMake makefile and ninja generators will attempt to share one PCH for both cpp and mm files
|
||||
# That's not actually OK
|
||||
if("${source}" MATCHES "\\.mm$")
|
||||
set_source_files_properties("${source}" PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
|
|
@ -191,6 +191,15 @@ if(WIN32)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
target_sources(common PRIVATE
|
||||
CocoaTools.mm
|
||||
CocoaTools.h
|
||||
)
|
||||
target_compile_options(common PRIVATE -fobjc-arc)
|
||||
target_link_options(common PRIVATE -fobjc-link-runtime)
|
||||
endif()
|
||||
|
||||
if(USE_OPENGL)
|
||||
if(WIN32)
|
||||
target_sources(common PRIVATE
|
||||
|
@ -203,9 +212,6 @@ if(USE_OPENGL)
|
|||
GL/ContextAGL.mm
|
||||
GL/ContextAGL.h
|
||||
)
|
||||
set_source_files_properties(GL/ContextAGL.mm PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
|
||||
target_compile_options(common PRIVATE -fobjc-arc)
|
||||
target_link_options(common PRIVATE -fobjc-link-runtime)
|
||||
else()
|
||||
if(X11_API OR WAYLAND_API)
|
||||
target_sources(common PRIVATE
|
||||
|
@ -263,6 +269,7 @@ target_link_libraries(common PUBLIC
|
|||
fmt::fmt
|
||||
)
|
||||
|
||||
fixup_file_properties(common)
|
||||
target_compile_features(common PUBLIC cxx_std_17)
|
||||
target_include_directories(common PUBLIC ../3rdparty/include ../)
|
||||
target_compile_definitions(common PUBLIC "${PCSX2_DEFS}")
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
struct WindowInfo;
|
||||
|
||||
/// Helper functions for things that need Objective-C
|
||||
namespace CocoaTools
|
||||
{
|
||||
bool CreateMetalLayer(WindowInfo* wi);
|
||||
void DestroyMetalLayer(WindowInfo* wi);
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
|
@ -0,0 +1,66 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#error "Compile this with -fobjc-arc"
|
||||
#endif
|
||||
|
||||
#include "CocoaTools.h"
|
||||
#include "Console.h"
|
||||
#include "WindowInfo.h"
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
bool CocoaTools::CreateMetalLayer(WindowInfo* wi)
|
||||
{
|
||||
if (![NSThread isMainThread])
|
||||
{
|
||||
bool ret;
|
||||
dispatch_sync(dispatch_get_main_queue(), [&ret, wi]{ ret = CreateMetalLayer(wi); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAMetalLayer* layer = [CAMetalLayer layer];
|
||||
if (!layer)
|
||||
{
|
||||
Console.Error("Failed to create Metal layer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
NSView* view = (__bridge NSView*)wi->window_handle;
|
||||
[view setWantsLayer:YES];
|
||||
[view setLayer:layer];
|
||||
[layer setContentsScale:[[[view window] screen] backingScaleFactor]];
|
||||
// Store the layer pointer, that way MoltenVK doesn't call [NSView layer] outside the main thread.
|
||||
wi->surface_handle = (__bridge_retained void*)layer;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CocoaTools::DestroyMetalLayer(WindowInfo* wi)
|
||||
{
|
||||
if (![NSThread isMainThread])
|
||||
{
|
||||
dispatch_sync_f(dispatch_get_main_queue(), wi, [](void* ctx){ DestroyMetalLayer(static_cast<WindowInfo*>(ctx)); });
|
||||
return;
|
||||
}
|
||||
|
||||
NSView* view = (__bridge NSView*)wi->window_handle;
|
||||
CAMetalLayer* layer = (__bridge_transfer CAMetalLayer*)wi->surface_handle;
|
||||
if (!layer)
|
||||
return;
|
||||
wi->surface_handle = nullptr;
|
||||
[view setLayer:nil];
|
||||
[view setWantsLayer:NO];
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "common/Vulkan/SwapChain.h"
|
||||
#include "common/Assertions.h"
|
||||
#include "common/CocoaTools.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/Vulkan/Context.h"
|
||||
#include "common/Vulkan/Util.h"
|
||||
|
@ -26,96 +27,6 @@
|
|||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <objc/message.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
#ifdef __i386__
|
||||
typedef float CGFloat;
|
||||
#else
|
||||
typedef double CGFloat;
|
||||
#endif
|
||||
|
||||
template <typename Ret, typename Self, typename... Args>
|
||||
Ret msgsend(Self self, const char* sel, Args... args)
|
||||
{
|
||||
void (*fn)(void) = objc_msgSend;
|
||||
#ifdef __i386__
|
||||
if (std::is_same<Ret, float>::value || std::is_same<Ret, double>::value || std::is_same<Ret, long double>::value)
|
||||
fn = objc_msgSend_fpret;
|
||||
#endif
|
||||
#ifdef __x86_64__
|
||||
if (std::is_same<Ret, long double>::value)
|
||||
fn = objc_msgSend_fpret;
|
||||
#endif
|
||||
return reinterpret_cast<Ret(*)(Self, SEL, Args...)>(fn)(self, sel_getUid(sel), args...);
|
||||
}
|
||||
|
||||
static bool CreateMetalLayer(WindowInfo* wi)
|
||||
{
|
||||
// if (![NSThread isMainThread])
|
||||
if (!msgsend<BOOL, Class>(objc_getClass("NSThread"), "isMainThread"))
|
||||
{
|
||||
__block bool ret;
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{ ret = CreateMetalLayer(wi); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
id view = reinterpret_cast<id>(wi->window_handle);
|
||||
|
||||
Class clsCAMetalLayer = objc_getClass("CAMetalLayer");
|
||||
if (!clsCAMetalLayer)
|
||||
{
|
||||
Console.Error("Failed to get CAMetalLayer class.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// [CAMetalLayer layer]
|
||||
id layer = msgsend<id, Class>(clsCAMetalLayer, "layer");
|
||||
if (!layer)
|
||||
{
|
||||
Console.Error("Failed to create Metal layer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// This needs to be retained, otherwise we double release below.
|
||||
msgsend<void, id>(layer, "retain");
|
||||
|
||||
// [view setWantsLayer:YES]
|
||||
msgsend<void, id, BOOL>(view, "setWantsLayer:", YES);
|
||||
|
||||
// [view setLayer:layer]
|
||||
msgsend<void, id, id>(view, "setLayer:", layer);
|
||||
|
||||
// NSScreen* screen = [NSScreen mainScreen]
|
||||
id screen = msgsend<id, Class>(objc_getClass("NSScreen"), "mainScreen");
|
||||
|
||||
// CGFloat factor = [screen backingScaleFactor]
|
||||
CGFloat factor = msgsend<CGFloat, id>(screen, "backingScaleFactor");
|
||||
|
||||
// layer.contentsScale = factor
|
||||
msgsend<void, id, CGFloat>(layer, "setContentsScale:", factor);
|
||||
|
||||
// Store the layer pointer, that way MoltenVK doesn't call [NSView layer] outside the main thread.
|
||||
wi->surface_handle = layer;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DestroyMetalLayer(WindowInfo* wi)
|
||||
{
|
||||
id view = reinterpret_cast<id>(wi->window_handle);
|
||||
id layer = reinterpret_cast<id>(wi->surface_handle);
|
||||
if (layer == nil)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace Vulkan
|
||||
{
|
||||
SwapChain::SwapChain(const WindowInfo& wi, VkSurfaceKHR surface, VkPresentModeKHR preferred_present_mode)
|
||||
|
@ -435,7 +346,7 @@ namespace Vulkan
|
|||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
if (wi->type == WindowInfo::Type::MacOS)
|
||||
{
|
||||
if (!wi->surface_handle && !CreateMetalLayer(wi))
|
||||
if (!wi->surface_handle && !CocoaTools::CreateMetalLayer(wi))
|
||||
return VK_NULL_HANDLE;
|
||||
|
||||
VkMetalSurfaceCreateInfoEXT surface_create_info = {VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT, nullptr,
|
||||
|
@ -483,7 +394,7 @@ namespace Vulkan
|
|||
|
||||
#if defined(__APPLE__)
|
||||
if (wi->type == WindowInfo::Type::MacOS && wi->surface_handle)
|
||||
DestroyMetalLayer(wi);
|
||||
CocoaTools::DestroyMetalLayer(wi);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1749,6 +1749,8 @@ if(GETTEXT_FOUND AND NOT NO_TRANSLATION AND NOT PCSX2_CORE)
|
|||
GETTEXT_CREATE_TRANSLATIONS_PCSX2(${CMAKE_SOURCE_DIR}/locales/templates/pcsx2_Main.pot ${PO_MAIN_FILES})
|
||||
endif()
|
||||
|
||||
fixup_file_properties(PCSX2)
|
||||
|
||||
if (APPLE)
|
||||
find_library(METAL_LIBRARY Metal)
|
||||
find_library(QUARTZCORE_LIBRARY QuartzCore)
|
||||
|
@ -1758,19 +1760,6 @@ if (APPLE)
|
|||
# We have a bunch of page-sized arrays in bss that we use for jit
|
||||
# Obviously not being able to make those arrays executable would be a problem
|
||||
target_link_options(PCSX2_FLAGS INTERFACE -Wl,-segprot,__DATA,rwx,rw)
|
||||
|
||||
get_target_property(PCSX2_SOURCES PCSX2 SOURCES)
|
||||
foreach(source IN LISTS PCSX2_SOURCES)
|
||||
# Set the right file types for .inl files in Xcode
|
||||
if("${source}" MATCHES "\\.(inl|h)$")
|
||||
set_source_files_properties("${source}" PROPERTIES XCODE_EXPLICIT_FILE_TYPE sourcecode.cpp.h)
|
||||
endif()
|
||||
# CMake makefile and ninja generators will attempt to share one PCH for both cpp and mm files
|
||||
# That's not actually OK
|
||||
if("${source}" MATCHES "\\.mm$")
|
||||
set_source_files_properties("${source}" PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL PROPERTY PCSX2_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
|
Loading…
Reference in New Issue