[macOS] Add support for OpenGLES3 video driver.

This commit is contained in:
bruvzg 2021-11-02 12:27:38 +02:00
parent 87727f70ed
commit 1ad14eb14b
8 changed files with 373 additions and 244 deletions

View File

@ -132,6 +132,7 @@ opts.Add(BoolVariable("deprecated", "Enable deprecated features", True))
opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True)) opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True))
opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False)) opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False))
opts.Add(BoolVariable("vulkan", "Enable the vulkan video driver", True)) opts.Add(BoolVariable("vulkan", "Enable the vulkan video driver", True))
opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 video driver", True))
opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "") opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True)) opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True))
opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True)) opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True))

View File

@ -13,7 +13,7 @@ files = [
"dir_access_osx.mm", "dir_access_osx.mm",
"joypad_osx.cpp", "joypad_osx.cpp",
"vulkan_context_osx.mm", "vulkan_context_osx.mm",
"context_gl_osx.mm", "gl_manager_osx.mm",
] ]
prog = env.add_program("#bin/godot", files) prog = env.add_program("#bin/godot", files)

View File

@ -1,161 +0,0 @@
/*************************************************************************/
/* context_gl_osx.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "context_gl_osx.h"
#if defined(GLES3_ENABLED) || defined(GLES_ENABLED)
void ContextGL_OSX::release_current() {
[NSOpenGLContext clearCurrentContext];
}
void ContextGL_OSX::make_current() {
[context makeCurrentContext];
}
void ContextGL_OSX::update() {
[context update];
}
void ContextGL_OSX::set_opacity(GLint p_opacity) {
[context setValues:&p_opacity forParameter:NSOpenGLCPSurfaceOpacity];
}
int ContextGL_OSX::get_window_width() {
return OS::get_singleton()->get_video_mode().width;
}
int ContextGL_OSX::get_window_height() {
return OS::get_singleton()->get_video_mode().height;
}
void ContextGL_OSX::swap_buffers() {
[context flushBuffer];
}
void ContextGL_OSX::set_use_vsync(bool p_use) {
CGLContextObj ctx = CGLGetCurrentContext();
if (ctx) {
GLint swapInterval = p_use ? 1 : 0;
CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
use_vsync = p_use;
}
}
bool ContextGL_OSX::is_using_vsync() const {
return use_vsync;
}
Error ContextGL_OSX::initialize() {
framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
ERR_FAIL_COND_V(!framework, ERR_CANT_CREATE);
unsigned int attributeCount = 0;
// OS X needs non-zero color size, so set reasonable values
int colorBits = 32;
// Fail if a robustness strategy was requested
#define ADD_ATTR(x) \
{ attributes[attributeCount++] = x; }
#define ADD_ATTR2(x, y) \
{ \
ADD_ATTR(x); \
ADD_ATTR(y); \
}
// Arbitrary array size here
NSOpenGLPixelFormatAttribute attributes[40];
ADD_ATTR(NSOpenGLPFADoubleBuffer);
ADD_ATTR(NSOpenGLPFAClosestPolicy);
if (!gles3_context) {
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy);
} else {
//we now need OpenGL 3 or better, maybe even change this to 3_3Core ?
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
}
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
/*
if (fbconfig->alphaBits > 0)
ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
*/
ADD_ATTR2(NSOpenGLPFADepthSize, 24);
ADD_ATTR2(NSOpenGLPFAStencilSize, 8);
/*
if (fbconfig->stereo)
ADD_ATTR(NSOpenGLPFAStereo);
*/
/*
if (fbconfig->samples > 0) {
ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
}
*/
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// framebuffer, so there's no need (and no way) to request it
ADD_ATTR(0);
#undef ADD_ATTR
#undef ADD_ATTR2
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
ERR_FAIL_COND_V(pixelFormat == nil, ERR_CANT_CREATE);
context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
ERR_FAIL_COND_V(context == nil, ERR_CANT_CREATE);
[context setView:window_view];
[context makeCurrentContext];
return OK;
}
ContextGL_OSX::ContextGL_OSX(id p_view, bool p_gles3_context) {
gles3_context = p_gles3_context;
window_view = p_view;
use_vsync = false;
}
ContextGL_OSX::~ContextGL_OSX() {}
#endif

View File

@ -183,10 +183,13 @@ def configure(env):
) )
env.Append(LIBS=["pthread", "z"]) env.Append(LIBS=["pthread", "z"])
if env["opengl3"]:
env.Append(CPPDEFINES=["GLES_ENABLED", "GLES3_ENABLED"])
env.Append(CCFLAGS=["-Wno-deprecated-declarations"]) # Disable deprecation warnings
env.Append(LINKFLAGS=["-framework", "OpenGL"])
if env["vulkan"]: if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"]) env.Append(CPPDEFINES=["VULKAN_ENABLED"])
env.Append(LINKFLAGS=["-framework", "Metal", "-framework", "QuartzCore", "-framework", "IOSurface"]) env.Append(LINKFLAGS=["-framework", "Metal", "-framework", "QuartzCore", "-framework", "IOSurface"])
if not env["use_volk"]: if not env["use_volk"]:
env.Append(LINKFLAGS=["-L$VULKAN_SDK_PATH/MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/", "-lMoltenVK"]) env.Append(LINKFLAGS=["-L$VULKAN_SDK_PATH/MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/", "-lMoltenVK"])
# env.Append(CPPDEFINES=['GLES_ENABLED', 'GLES3_ENABLED'])

View File

@ -37,8 +37,7 @@
#include "servers/display_server.h" #include "servers/display_server.h"
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
#include "context_gl_osx.h" #include "gl_manager_osx.h"
//TODO - reimplement OpenGLES
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
@ -65,11 +64,11 @@ public:
void _menu_callback(id p_sender); void _menu_callback(id p_sender);
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
ContextGL_OSX *context_gles2; GLManager_OSX *gl_manager = nullptr;
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
VulkanContextOSX *context_vulkan; VulkanContextOSX *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan; RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif #endif
const NSMenu *_get_menu_root(const String &p_menu_root) const; const NSMenu *_get_menu_root(const String &p_menu_root) const;
@ -109,9 +108,6 @@ public:
Vector<Vector2> mpath; Vector<Vector2> mpath;
#if defined(GLES3_ENABLED)
ContextGL_OSX *context_gles2 = nullptr;
#endif
Point2i mouse_pos; Point2i mouse_pos;
Size2i min_size; Size2i min_size;
@ -287,6 +283,7 @@ public:
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override; virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void gl_window_make_current(DisplayServer::WindowID p_window_id) override;
virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override; virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;

View File

@ -46,7 +46,7 @@
#include <IOKit/hid/IOHIDLib.h> #include <IOKit/hid/IOHIDLib.h>
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
//TODO - reimplement OpenGLES #include "drivers/gles3/rasterizer_gles3.h"
#import <AppKit/NSOpenGLView.h> #import <AppKit/NSOpenGLView.h>
#endif #endif
@ -167,8 +167,8 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
} }
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (DS_OSX->rendering_driver == "opengl_es") { if (DS_OSX->rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES DS_OSX->gl_manager->window_destroy(window_id);
} }
#endif #endif
#ifdef VULKAN_ENABLED #ifdef VULKAN_ENABLED
@ -272,8 +272,8 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
} }
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (DS_OSX->rendering_driver == "opengl_es") { if (DS_OSX->rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES DS_OSX->gl_manager->window_resize(window_id, wd.size.width, wd.size.height);
} }
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
@ -377,7 +377,12 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
/* GodotContentView */ /* GodotContentView */
/*************************************************************************/ /*************************************************************************/
#if defined(GLES3_ENABLED)
@interface GodotContentView : NSOpenGLView <NSTextInputClient> {
#else
@interface GodotContentView : NSView <NSTextInputClient> { @interface GodotContentView : NSView <NSTextInputClient> {
#endif
DisplayServerOSX::WindowID window_id; DisplayServerOSX::WindowID window_id;
NSTrackingArea *trackingArea; NSTrackingArea *trackingArea;
NSMutableAttributedString *markedText; NSMutableAttributedString *markedText;
@ -405,12 +410,6 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
} }
- (CALayer *)makeBackingLayer { - (CALayer *)makeBackingLayer {
#if defined(GLES3_ENABLED)
if (DS_OSX->rendering_driver == "opengl_es") {
CALayer *layer = [[NSOpenGLLayer class] layer];
return layer;
}
#endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
if (DS_OSX->rendering_driver == "vulkan") { if (DS_OSX->rendering_driver == "vulkan") {
CALayer *layer = [[CAMetalLayer class] layer]; CALayer *layer = [[CAMetalLayer class] layer];
@ -422,9 +421,8 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
- (void)updateLayer { - (void)updateLayer {
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (DS_OSX->rendering_driver == "opengl_es") { if (DS_OSX->rendering_driver == "opengl3") {
[super updateLayer]; DS_OSX->gl_manager->window_update(window_id);
//TODO - reimplement OpenGLES
} }
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
@ -2587,7 +2585,7 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
} }
#endif #endif
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (rendering_driver == "opengl_es") { if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES //TODO - reimplement OpenGLES
} }
#endif #endif
@ -2606,14 +2604,14 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
} }
#endif #endif
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (rendering_driver == "opengl_es") { if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES //TODO - reimplement OpenGLES
} }
#endif #endif
wd.layered_window = false; wd.layered_window = false;
} }
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (rendering_driver == "opengl_es") { if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES //TODO - reimplement OpenGLES
} }
#endif #endif
@ -3455,18 +3453,31 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) {
void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
gl_manager->swap_buffers();
}
#endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
context_vulkan->set_vsync_mode(p_window, p_vsync_mode); if (rendering_driver == "vulkan") {
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
}
#endif #endif
} }
DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const { DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED) #if defined(GLES3_ENABLED)
return context_vulkan->get_vsync_mode(p_window); if (rendering_driver == "opengl3") {
#else return (gl_manager->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED);
return DisplayServer::VSYNC_ENABLED; }
#endif #endif
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
return context_vulkan->get_vsync_mode(p_window);
}
#endif
return DisplayServer::VSYNC_ENABLED;
} }
Vector<String> DisplayServerOSX::get_rendering_drivers_func() { Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
@ -3476,12 +3487,18 @@ Vector<String> DisplayServerOSX::get_rendering_drivers_func() {
drivers.push_back("vulkan"); drivers.push_back("vulkan");
#endif #endif
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
drivers.push_back("opengl_es"); drivers.push_back("opengl3");
#endif #endif
return drivers; return drivers;
} }
void DisplayServerOSX::gl_window_make_current(DisplayServer::WindowID p_window_id) {
#if defined(GLES3_ENABLED)
gl_manager->window_make_current(p_window_id);
#endif
}
Point2i DisplayServerOSX::ime_get_selection() const { Point2i DisplayServerOSX::ime_get_selection() const {
return im_selection; return im_selection;
} }
@ -3522,7 +3539,7 @@ ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) co
DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) { if (r_error != OK) {
OS::get_singleton()->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver"); OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.", "Unable to initialize Video driver");
} }
return ds; return ds;
} }
@ -3580,8 +3597,11 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V
} }
#endif #endif
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (rendering_driver == "opengl_es") { if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES if (gl_manager) {
Error err = gl_manager->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context");
}
} }
#endif #endif
id = window_id_counter++; id = window_id_counter++;
@ -3601,8 +3621,8 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V
} }
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (rendering_driver == "opengl_es") { if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES gl_manager->window_resize(id, wd.size.width, wd.size.height);
} }
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
@ -3654,15 +3674,15 @@ void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) {
} }
void DisplayServerOSX::release_rendering_thread() { void DisplayServerOSX::release_rendering_thread() {
//TODO - reimplement OpenGLES
} }
void DisplayServerOSX::make_rendering_thread() { void DisplayServerOSX::make_rendering_thread() {
//TODO - reimplement OpenGLES
} }
void DisplayServerOSX::swap_buffers() { void DisplayServerOSX::swap_buffers() {
//TODO - reimplement OpenGLES #if defined(GLES3_ENABLED)
gl_manager->swap_buffers();
#endif
} }
void DisplayServerOSX::console_set_visible(bool p_enabled) { void DisplayServerOSX::console_set_visible(bool p_enabled) {
@ -3753,14 +3773,17 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
//TODO - do Vulkan and OpenGL support checks, driver selection and fallback //TODO - do Vulkan and OpenGL support checks, driver selection and fallback
rendering_driver = p_rendering_driver; rendering_driver = p_rendering_driver;
#ifndef _MSC_VER
#warning Forcing vulkan rendering driver because OpenGL not implemented yet
#endif
rendering_driver = "vulkan";
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (rendering_driver == "opengl_es") { if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES GLManager_OSX::ContextType opengl_api_type = GLManager_OSX::GLES_3_0_COMPATIBLE;
gl_manager = memnew(GLManager_OSX(opengl_api_type));
if (gl_manager->initialize() != OK) {
memdelete(gl_manager);
gl_manager = nullptr;
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Could not initialize OpenGL");
return;
}
} }
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
@ -3788,8 +3811,8 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
show_window(MAIN_WINDOW_ID); show_window(MAIN_WINDOW_ID);
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (rendering_driver == "opengl_es") { if (rendering_driver == "opengl3") {
//TODO - reimplement OpenGLES RasterizerGLES3::make_current();
} }
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
@ -3821,20 +3844,21 @@ DisplayServerOSX::~DisplayServerOSX() {
//destroy drivers //destroy drivers
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (rendering_driver == "opengl_es") { if (gl_manager) {
//TODO - reimplement OpenGLES memdelete(gl_manager);
gl_manager = nullptr;
} }
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") { if (rendering_device_vulkan) {
if (rendering_device_vulkan) { rendering_device_vulkan->finalize();
rendering_device_vulkan->finalize(); memdelete(rendering_device_vulkan);
memdelete(rendering_device_vulkan); rendering_device_vulkan = nullptr;
} }
if (context_vulkan) { if (context_vulkan) {
memdelete(context_vulkan); memdelete(context_vulkan);
} context_vulkan = nullptr;
} }
#endif #endif

View File

@ -1,5 +1,5 @@
/*************************************************************************/ /*************************************************************************/
/* context_gl_osx.h */ /* gl_manager_osx.h */
/*************************************************************************/ /*************************************************************************/
/* This file is part of: */ /* This file is part of: */
/* GODOT ENGINE */ /* GODOT ENGINE */
@ -28,47 +28,79 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#ifndef CONTEXT_GL_OSX_H #ifndef GL_MANAGER_OSX_H
#define CONTEXT_GL_OSX_H #define GL_MANAGER_OSX_H
#if defined(GLES3_ENABLED) || defined(GLES_ENABLED) #if defined(OSX_ENABLED) && defined(GLES3_ENABLED)
#include "core/error/error_list.h" #include "core/error/error_list.h"
#include "core/os/os.h" #include "core/os/os.h"
#include "core/templates/local_vector.h"
#include "servers/display_server.h"
#include <AppKit/AppKit.h> #include <AppKit/AppKit.h>
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.h>
#include <CoreVideo/CoreVideo.h> #include <CoreVideo/CoreVideo.h>
class ContextGL_OSX { class GLManager_OSX {
bool gles3_context; public:
bool use_vsync; enum ContextType {
GLES_3_0_COMPATIBLE,
};
void *framework; private:
id window_view; struct GLWindow {
NSOpenGLPixelFormat *pixelFormat; GLWindow() { in_use = false; }
NSOpenGLContext *context; bool in_use;
DisplayServer::WindowID window_id;
int width;
int height;
id window_view;
NSOpenGLContext *context;
};
LocalVector<GLWindow> _windows;
NSOpenGLContext *_shared_context = nullptr;
GLWindow *_current_window;
Error _create_context(GLWindow &win);
void _internal_set_current_window(GLWindow *p_win);
GLWindow &get_window(unsigned int id) { return _windows[id]; }
const GLWindow &get_window(unsigned int id) const { return _windows[id]; }
bool use_vsync;
ContextType context_type;
public: public:
Error window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height);
void window_destroy(DisplayServer::WindowID p_window_id);
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
// get directly from the cached GLWindow
int window_get_width(DisplayServer::WindowID p_window_id = 0);
int window_get_height(DisplayServer::WindowID p_window_id = 0);
void release_current(); void release_current();
void make_current(); void make_current();
void update();
void set_opacity(GLint p_opacity);
int get_window_width();
int get_window_height();
void swap_buffers(); void swap_buffers();
void window_make_current(DisplayServer::WindowID p_window_id);
void window_update(DisplayServer::WindowID p_window_id);
Error initialize(); Error initialize();
void set_use_vsync(bool p_use); void set_use_vsync(bool p_use);
bool is_using_vsync() const; bool is_using_vsync() const;
ContextGL_OSX(id p_view, bool p_gles3_context); GLManager_OSX(ContextType p_context_type);
~ContextGL_OSX(); ~GLManager_OSX();
}; };
#endif #endif // defined(OSX_ENABLED) && defined(GLES3_ENABLED)
#endif
#endif // GL_MANAGER_OSX_H

View File

@ -0,0 +1,233 @@
/*************************************************************************/
/* gl_manager_osx.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "gl_manager_osx.h"
#ifdef OSX_ENABLED
#ifdef GLES3_ENABLED
#include <stdio.h>
#include <stdlib.h>
Error GLManager_OSX::_create_context(GLWindow &win) {
NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAClosestPolicy,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAColorSize, 32,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAStencilSize, 8,
0
};
NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
ERR_FAIL_COND_V(pixel_format == nil, ERR_CANT_CREATE);
win.context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:_shared_context];
ERR_FAIL_COND_V(win.context == nil, ERR_CANT_CREATE);
if (_shared_context == nullptr) {
_shared_context = win.context;
}
[win.context setView:win.window_view];
[win.context makeCurrentContext];
return OK;
}
Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) {
if (p_window_id >= (int)_windows.size()) {
_windows.resize(p_window_id + 1);
}
GLWindow &win = _windows[p_window_id];
win.in_use = true;
win.window_id = p_window_id;
win.width = p_width;
win.height = p_height;
win.window_view = p_view;
if (_create_context(win) != OK) {
_windows.remove(_windows.size() - 1);
return FAILED;
}
window_make_current(_windows.size() - 1);
return OK;
}
void GLManager_OSX::_internal_set_current_window(GLWindow *p_win) {
_current_window = p_win;
}
void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
if (p_window_id == -1) {
return;
}
GLWindow &win = _windows[p_window_id];
if (!win.in_use) {
return;
}
win.width = p_width;
win.height = p_height;
GLint dim[2];
dim[0] = p_width;
dim[1] = p_height;
CGLSetParameter((CGLContextObj)[win.context CGLContextObj], kCGLCPSurfaceBackingSize, &dim[0]);
CGLEnable((CGLContextObj)[win.context CGLContextObj], kCGLCESurfaceBackingSize);
if (OS::get_singleton()->is_hidpi_allowed()) {
[win.window_view setWantsBestResolutionOpenGLSurface:YES];
} else {
[win.window_view setWantsBestResolutionOpenGLSurface:NO];
}
[win.context update];
}
int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) {
return get_window(p_window_id).width;
}
int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) {
return get_window(p_window_id).height;
}
void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) {
GLWindow &win = get_window(p_window_id);
win.in_use = false;
if (_current_window == &win) {
_current_window = nullptr;
}
}
void GLManager_OSX::release_current() {
if (!_current_window) {
return;
}
[NSOpenGLContext clearCurrentContext];
}
void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) {
if (p_window_id == -1) {
return;
}
GLWindow &win = _windows[p_window_id];
if (!win.in_use) {
return;
}
if (&win == _current_window) {
return;
}
[win.context makeCurrentContext];
_internal_set_current_window(&win);
}
void GLManager_OSX::make_current() {
if (!_current_window) {
return;
}
if (!_current_window->in_use) {
WARN_PRINT("current window not in use!");
return;
}
[_current_window->context makeCurrentContext];
}
void GLManager_OSX::swap_buffers() {
// NO NEED TO CALL SWAP BUFFERS for each window...
// see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXSwapBuffers.xml
if (!_current_window) {
return;
}
if (!_current_window->in_use) {
WARN_PRINT("current window not in use!");
return;
}
[_current_window->context flushBuffer];
}
void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) {
if (p_window_id == -1) {
return;
}
GLWindow &win = _windows[p_window_id];
if (!win.in_use) {
return;
}
if (&win == _current_window) {
return;
}
[win.context update];
}
Error GLManager_OSX::initialize() {
return OK;
}
void GLManager_OSX::set_use_vsync(bool p_use) {
use_vsync = p_use;
CGLContextObj ctx = CGLGetCurrentContext();
if (ctx) {
GLint swapInterval = p_use ? 1 : 0;
CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
use_vsync = p_use;
}
}
bool GLManager_OSX::is_using_vsync() const {
return use_vsync;
}
GLManager_OSX::GLManager_OSX(ContextType p_context_type) {
context_type = p_context_type;
use_vsync = false;
_current_window = nullptr;
}
GLManager_OSX::~GLManager_OSX() {
release_current();
}
#endif // GLES3_ENABLED
#endif // OSX