Browse Source

[macOS] Add support for OpenGLES3 video driver.

bruvzg 3 years ago
parent
commit
1ad14eb14b

+ 1 - 0
SConstruct

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

+ 1 - 1
platform/osx/SCsub

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

+ 0 - 161
platform/osx/context_gl_osx.mm

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

+ 5 - 2
platform/osx/detect.py

@@ -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'])

+ 5 - 8
platform/osx/display_server_osx.h

@@ -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"
-//TODO - reimplement OpenGLES
+#include "gl_manager_osx.h"
 #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;
-	RenderingDeviceVulkan *rendering_device_vulkan;
+	VulkanContextOSX *context_vulkan = nullptr;
+	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;

+ 73 - 49
platform/osx/display_server_osx.mm

@@ -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") {
-		//TODO - reimplement OpenGLES
+	if (DS_OSX->rendering_driver == "opengl3") {
+		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") {
-		//TODO - reimplement OpenGLES
+	if (DS_OSX->rendering_driver == "opengl3") {
+		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") {
-		[super updateLayer];
-		//TODO - reimplement OpenGLES
+	if (DS_OSX->rendering_driver == "opengl3") {
+		DS_OSX->gl_manager->window_update(window_id);
 	}
 	}
 #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(GLES3_ENABLED)
+	if (rendering_driver == "opengl3") {
+		return (gl_manager->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED);
+	}
+#endif
 #if defined(VULKAN_ENABLED)
 #if defined(VULKAN_ENABLED)
-	return context_vulkan->get_vsync_mode(p_window);
-#else
-	return DisplayServer::VSYNC_ENABLED;
+	if (rendering_driver == "vulkan") {
+		return context_vulkan->get_vsync_mode(p_window);
+	}
 #endif
 #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") {
-			//TODO - reimplement OpenGLES
+		if (rendering_driver == "opengl3") {
+			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") {
-		//TODO - reimplement OpenGLES
+	if (rendering_driver == "opengl3") {
+		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") {
-		//TODO - reimplement OpenGLES
+	if (rendering_driver == "opengl3") {
+		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") {
-		//TODO - reimplement OpenGLES
+	if (rendering_driver == "opengl3") {
+		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") {
-		//TODO - reimplement OpenGLES
+	if (gl_manager) {
+		memdelete(gl_manager);
+		gl_manager = nullptr;
 	}
 	}
 #endif
 #endif
 #if defined(VULKAN_ENABLED)
 #if defined(VULKAN_ENABLED)
-	if (rendering_driver == "vulkan") {
-		if (rendering_device_vulkan) {
-			rendering_device_vulkan->finalize();
-			memdelete(rendering_device_vulkan);
-		}
+	if (rendering_device_vulkan) {
+		rendering_device_vulkan->finalize();
+		memdelete(rendering_device_vulkan);
+		rendering_device_vulkan = nullptr;
+	}
 
 
-		if (context_vulkan) {
-			memdelete(context_vulkan);
-		}
+	if (context_vulkan) {
+		memdelete(context_vulkan);
+		context_vulkan = nullptr;
 	}
 	}
 #endif
 #endif
 
 

+ 53 - 21
platform/osx/context_gl_osx.h → platform/osx/gl_manager_osx.h

@@ -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
-#define CONTEXT_GL_OSX_H
+#ifndef GL_MANAGER_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 {
-	bool gles3_context;
-	bool use_vsync;
+class GLManager_OSX {
+public:
+	enum ContextType {
+		GLES_3_0_COMPATIBLE,
+	};
+
+private:
+	struct GLWindow {
+		GLWindow() { in_use = false; }
+		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);
 
 
-	void *framework;
-	id window_view;
-	NSOpenGLPixelFormat *pixelFormat;
-	NSOpenGLContext *context;
+	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:
-	void release_current();
+	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 make_current();
 	void make_current();
-	void update();
+	void swap_buffers();
 
 
-	void set_opacity(GLint p_opacity);
+	void window_make_current(DisplayServer::WindowID p_window_id);
 
 
-	int get_window_width();
-	int get_window_height();
-	void swap_buffers();
+	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);
-	~ContextGL_OSX();
+	GLManager_OSX(ContextType p_context_type);
+	~GLManager_OSX();
 };
 };
 
 
-#endif
-#endif
+#endif // defined(OSX_ENABLED) && defined(GLES3_ENABLED)
+
+#endif // GL_MANAGER_OSX_H

+ 233 - 0
platform/osx/gl_manager_osx.mm

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