[Feat] (iOS): support MobileGL builds and Metal surfaces

This commit is contained in:
2026-06-30 07:25:20 +08:00
parent cca4df17d9
commit 2f1949e093
6 changed files with 68 additions and 13 deletions
+31 -3
View File
@@ -7,7 +7,9 @@ option(MOBILEGL_BUILD_BENCHMARK "Build MobileGL benchmarks"
option(MOBILEGL_FORCE_RELEASE_OPT "Enable Release optimization flags in Debug build" ON )
option(MOBILEGL_ENABLE_TRACY "Enable tracy for profiling" OFF)
option(MOBILEGL_BUILD_TRACE_REPLAY "Build desktop apitrace replay runner" OFF)
option(MOBILEGL_IOS "Build MobileGL for iOS instead of macOS when APPLE is set" OFF)
set(MOBILEGL_LOG_ACTIVE_LEVEL "MOBILEGL_LOG_LEVEL_INFO" CACHE STRING "MobileGL active log level macro")
set(MOBILEGL_VULKAN_LIBRARY "" CACHE FILEPATH "Vulkan loader/MoltenVK library to link for iOS builds")
if (ANDROID)
set(MOBILEGL_BUILD_TEST OFF CACHE BOOL "Build MobileGL tests" FORCE)
@@ -273,7 +275,7 @@ set(SOURCE_FILES
MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.cpp
)
if (APPLE)
if (APPLE AND NOT MOBILEGL_IOS)
list(APPEND SOURCE_FILES
MobileGL/MG_Impl/CGLImpl/CGLImpl.cpp
MobileGL/MG_Impl/CGLImpl/Exporting/Definitions.cpp
@@ -393,7 +395,7 @@ if (ANDROID)
)
endif()
if (APPLE)
if (APPLE AND NOT MOBILEGL_IOS)
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC
"-framework Cocoa"
"-framework QuartzCore"
@@ -410,7 +412,31 @@ if (APPLE)
endif()
endif()
if (NOT ANDROID)
if (APPLE AND MOBILEGL_IOS)
target_compile_definitions(${CMAKE_PROJECT_NAME} PUBLIC MOBILEGL_IOS=1 _LIBCPP_DISABLE_AVAILABILITY)
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC
"-framework CoreGraphics"
"-framework Foundation"
"-framework QuartzCore"
objc)
if (MOBILEGL_VULKAN_LIBRARY)
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC "${MOBILEGL_VULKAN_LIBRARY}")
endif()
if(TARGET ${CMAKE_PROJECT_NAME}_s)
target_compile_definitions(${CMAKE_PROJECT_NAME}_s PUBLIC MOBILEGL_IOS=1 _LIBCPP_DISABLE_AVAILABILITY)
target_link_libraries(${CMAKE_PROJECT_NAME}_s PUBLIC
"-framework CoreGraphics"
"-framework Foundation"
"-framework QuartzCore"
objc)
if (MOBILEGL_VULKAN_LIBRARY)
target_link_libraries(${CMAKE_PROJECT_NAME}_s PUBLIC "${MOBILEGL_VULKAN_LIBRARY}")
endif()
endif()
endif()
if (NOT ANDROID AND NOT MOBILEGL_IOS)
find_package(Vulkan)
if (Vulkan_FOUND)
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Vulkan::Vulkan Vulkan::Headers)
@@ -418,7 +444,9 @@ if (NOT ANDROID)
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${Vulkan_INCLUDE_DIR})
target_include_directories(${CMAKE_PROJECT_NAME}_s PUBLIC ${Vulkan_INCLUDE_DIR})
endif ()
endif ()
if (NOT ANDROID)
if (MOBILEGL_BUILD_TEST)
add_subdirectory(MobileGL/MG_Test)
endif()
@@ -666,8 +666,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
return false;
}
if ((handle.Backend != WindowBackend::Android && handle.Backend != WindowBackend::X11) || !handle.Handle) {
MGLOG_E("DirectGLES backend only supports Android and X11 native windows");
if ((handle.Backend != WindowBackend::Android &&
handle.Backend != WindowBackend::X11 &&
handle.Backend != WindowBackend::MetalLayer) ||
!handle.Handle) {
MGLOG_E("DirectGLES backend only supports Android, X11, and CAMetalLayer native windows");
return false;
}
@@ -5476,15 +5476,28 @@ void main() {
} // TODO: support more platforms
#if defined(VK_USE_PLATFORM_METAL_EXT)
exts.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
instanceInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
if (IsExtensionSupported(m_extensions, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) {
exts.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
instanceInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
} else {
MGLOG_I("Optional Vulkan instance extension not supported: %s",
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
}
#endif
if (m_validationLayersEnabled) {
exts.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}
MGLOG_I("Enabling %d Vulkan instance extensions:", exts.size());
for (const char* ext : exts) {
MGLOG_I(" %s", ext);
}
for (const char* ext : exts) {
if (!IsExtensionSupported(m_extensions, ext)) {
MGLOG_E("Required Vulkan instance extension not found: %s", ext);
}
MOBILEGL_ASSERT(IsExtensionSupported(m_extensions, ext), "Required Vulkan instance extension not found: %s",
ext);
}
+2 -2
View File
@@ -7,7 +7,7 @@
// End of Source File Header
#include "GetProcAddress.h"
#if defined(__APPLE__)
#if defined(__APPLE__) && !defined(MOBILEGL_IOS)
#ifndef GL_SILENCE_DEPRECATION
#define GL_SILENCE_DEPRECATION
#endif
@@ -67,7 +67,7 @@ namespace MobileGL::MG_Impl {
GETPROC(eglCreatePlatformPixmapSurface, name);
GETPROC(eglWaitSync, name);
#if defined(__APPLE__)
#if defined(__APPLE__) && !defined(MOBILEGL_IOS)
GETPROC(CGLChoosePixelFormat, name);
GETPROC(CGLDestroyPixelFormat, name);
GETPROC(CGLDescribePixelFormat, name);
+2 -2
View File
@@ -10,7 +10,7 @@
#include "GLImpl/Texture/ProxyTexture.h"
#include "GLImpl/Framebuffer/GL_Framebuffer.h"
#if defined(__APPLE__)
#if defined(__APPLE__) && !defined(MOBILEGL_IOS)
#include "NSOpenGLImpl/NSOpenGLImpl.h"
#endif
@@ -48,7 +48,7 @@ namespace MobileGL::MG_Impl {
MakeUnique<GLImpl::FramebufferImpl::DefaultFramebufferInfo>(fbo0, colorTex, depthTex, stencilTex);
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).Bind(fbo0);
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).Bind(fbo0);
#if defined(__APPLE__)
#if defined(__APPLE__) && !defined(MOBILEGL_IOS)
NSOpenGLImpl::InstallHooks();
#endif
}
@@ -8,6 +8,9 @@
#include "Loader.h"
#include "MG_Util/Types.h"
#if defined(MOBILEGL_IOS)
#include <dlfcn.h>
#endif
namespace MobileGL::MG_Util::BackendLoader {
static Bool UseRetraceAngle() {
@@ -29,10 +32,14 @@ namespace MobileGL::MG_Util::BackendLoader {
}
static void* OpenLib(const Vector<String>& names) {
#if !defined(__WIN32) && !defined(_WIN32) && !defined(__APPLE__)
#if !defined(__WIN32) && !defined(_WIN32) && (!defined(__APPLE__) || defined(MOBILEGL_IOS))
static const String LibPathPrefixes[] = {
#if defined(MOBILEGL_IOS)
"@rpath/", "@executable_path/Frameworks/", "@loader_path/Frameworks/",
#else
"/opt/vc/lib/", "/usr/local/lib/", "/usr/lib/", "/usr/lib/x86_64-linux-gnu/",
"/usr/lib64/", "/lib64/",
#endif
"" // We should put this to the end of the list to avoid breaking `LD_LIBRARY_PATH` usage
};
@@ -53,7 +60,7 @@ namespace MobileGL::MG_Util::BackendLoader {
}
inline void* ProcAddress(void* lib, const char* name) {
#if !defined(__WIN32) && !defined(_WIN32) && !defined(__APPLE__)
#if !defined(__WIN32) && !defined(_WIN32) && (!defined(__APPLE__) || defined(MOBILEGL_IOS))
return dlsym(lib, name);
#else
return nullptr;
@@ -465,7 +472,11 @@ namespace MobileGL::MG_Util::BackendLoader {
return;
}
} else {
#if defined(MOBILEGL_IOS)
eglLib = OpenLib({"libtinygl4angle.dylib"});
#else
eglLib = OpenLib({"libEGL.so"});
#endif
}
if (!eglLib) {