diff options
Diffstat (limited to 'platform/osx')
-rw-r--r-- | platform/osx/SCsub | 5 | ||||
-rw-r--r-- | platform/osx/context_gl_osx.h | 79 | ||||
-rw-r--r-- | platform/osx/context_gl_osx.mm | 216 | ||||
-rw-r--r-- | platform/osx/detect.py | 30 | ||||
-rw-r--r-- | platform/osx/os_osx.h | 10 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 337 |
6 files changed, 444 insertions, 233 deletions
diff --git a/platform/osx/SCsub b/platform/osx/SCsub index 2632c4f032..09f213cb0e 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -13,11 +13,10 @@ files = [ 'dir_access_osx.mm', 'joypad_osx.cpp', 'power_osx.cpp', + 'vulkan_context_osx.mm', + 'context_gl_osx.mm' ] -if (env["renderer"] == "vulkan"): - files += ['vulkan_context_osx.mm'] - prog = env.add_program('#bin/godot', files) if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: diff --git a/platform/osx/context_gl_osx.h b/platform/osx/context_gl_osx.h new file mode 100644 index 0000000000..831a813fe9 --- /dev/null +++ b/platform/osx/context_gl_osx.h @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* context_gl_osx.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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. */ +/*************************************************************************/ + +#ifndef CONTEXT_GL_OSX_H +#define CONTEXT_GL_OSX_H + +#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) + +#include "core/error_list.h" +#include "core/os/os.h" + +#include <AppKit/AppKit.h> +#include <ApplicationServices/ApplicationServices.h> +#include <CoreVideo/CoreVideo.h> + +class ContextGL_OSX { + + bool opengl_3_context; + bool use_vsync; + + void *framework; + id window_view; + NSOpenGLPixelFormat *pixelFormat; + NSOpenGLContext *context; + +public: + bool waiting_for_vsync; + NSCondition *vsync_condition; + CVDisplayLinkRef displayLink; + + void release_current(); + + void make_current(); + void update(); + + void set_opacity(GLint p_opacity); + + int get_window_width(); + int get_window_height(); + void swap_buffers(); + + Error initialize(); + + void set_use_vsync(bool p_use); + bool is_using_vsync() const; + + ContextGL_OSX(id p_view, bool p_opengl_3_context); + ~ContextGL_OSX(); +}; + +#endif +#endif
\ No newline at end of file diff --git a/platform/osx/context_gl_osx.mm b/platform/osx/context_gl_osx.mm new file mode 100644 index 0000000000..425c9b0ac4 --- /dev/null +++ b/platform/osx/context_gl_osx.mm @@ -0,0 +1,216 @@ +/*************************************************************************/ +/* context_gl_osx.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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(OPENGL_ENABLED) || defined(GLES_ENABLED) + +// DisplayLinkCallback is called from our DisplayLink OS thread informing us right before +// a screen update is required. We can use it to work around the broken vsync. +static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now, const CVTimeStamp *outputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) { + ContextGL_OSX *gl_ctx = (ContextGL_OSX *)displayLinkContext; + + // Set flag so we know we can output our next frame and signal our conditional lock + // if we're not doing vsync this will be ignored + [gl_ctx->vsync_condition lock]; + gl_ctx->waiting_for_vsync = false; + [gl_ctx->vsync_condition signal]; + [gl_ctx->vsync_condition unlock]; + + return kCVReturnSuccess; +} + +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() { + + if (use_vsync) { + // Wait until our DisplayLink callback unsets our flag... + [vsync_condition lock]; + while (waiting_for_vsync) + [vsync_condition wait]; + + // Make sure we wait again next frame around + waiting_for_vsync = true; + + [vsync_condition unlock]; + } + + [context flushBuffer]; +} + +void ContextGL_OSX::set_use_vsync(bool p_use) { + // CGLCPSwapInterval broke in OSX 10.14 and it seems Apple is not interested in fixing + // it as OpenGL is now deprecated and Metal solves this differently. + // Following SDLs example we're working around this using DisplayLink + // When vsync is enabled we set a flag "waiting_for_vsync" to true. + // This flag is set to false when DisplayLink informs us our display is about to refresh. + + ///TODO Maybe pause/unpause display link? + use_vsync = p_use; + waiting_for_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 (!opengl_3_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]; + + // setup our display link, this will inform us when a refresh is needed + CVDisplayLinkCreateWithActiveCGDisplays(&displayLink); + CVDisplayLinkSetOutputCallback(displayLink, &DisplayLinkCallback, this); + CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, context.CGLContextObj, pixelFormat.CGLPixelFormatObj); + CVDisplayLinkStart(displayLink); + + // initialise a conditional lock object + vsync_condition = [[NSCondition alloc] init]; + + return OK; +} + +ContextGL_OSX::ContextGL_OSX(id p_view, bool p_opengl_3_context) { + + opengl_3_context = p_opengl_3_context; + window_view = p_view; + use_vsync = false; +} + +ContextGL_OSX::~ContextGL_OSX() { + + if (displayLink) { + CVDisplayLinkRelease(displayLink); + } + [vsync_condition release]; +} + +#endif diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 989bf6d425..c4e8779523 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -154,20 +154,16 @@ def configure(env): env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'CoreVideo', '-framework', 'AVFoundation', '-framework', 'CoreMedia']) env.Append(LIBS=['pthread', 'z']) - if (env["renderer"] == "vulkan"): - env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) - env.Append(CPPDEFINES=['VULKAN_ENABLED']) - env.Append(LINKFLAGS=['-framework', 'Metal', '-framework', 'QuartzCore', '-framework', 'IOSurface']) - if (env['use_static_mvk']): - env.Append(LINKFLAGS=['-framework', 'MoltenVK']) - elif not env["builtin_vulkan_loader"]: - env.Append(LIBS=['vulkan']) - - env.Append(CCFLAGS=['-mmacosx-version-min=10.11']) - env.Append(LINKFLAGS=['-mmacosx-version-min=10.11']) - else: - env.Append(CPPDEFINES=['GLES_ENABLED']) - env.Append(LINKFLAGS=['-framework', 'OpenGL', '-framework', 'AGL']) - - env.Append(CCFLAGS=['-mmacosx-version-min=10.9']) - env.Append(LINKFLAGS=['-mmacosx-version-min=10.9']) + env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) + env.Append(CPPDEFINES=['VULKAN_ENABLED']) + + #env.Append(CPPDEFINES=['GLES_ENABLED', 'OPENGL_ENABLED']) + + env.Append(LINKFLAGS=['-framework', 'Metal', '-framework', 'QuartzCore', '-framework', 'IOSurface']) + if (env['use_static_mvk']): + env.Append(LINKFLAGS=['-framework', 'MoltenVK']) + elif not env["builtin_vulkan_loader"]: + env.Append(LIBS=['vulkan']) + + env.Append(CCFLAGS=['-mmacosx-version-min=10.11']) + env.Append(LINKFLAGS=['-mmacosx-version-min=10.11']) diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 97da467ce4..00fc56def6 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -46,6 +46,10 @@ #include "servers/visual/visual_server_wrap_mt.h" #include "servers/visual_server.h" +#if defined(OPENGL_ENABLED) +#include "context_gl_osx.h" +#endif + #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" #include "platform/osx/vulkan_context_osx.h" @@ -110,14 +114,12 @@ public: id cursor; #if defined(OPENGL_ENABLED) - void *framework; - NSOpenGLPixelFormat *pixelFormat; - NSOpenGLContext *context; + ContextGL_OSX *context_gles2; #endif #if defined(VULKAN_ENABLED) VulkanContextOSX *context_vulkan; - RenderingDeviceVulkan *rendering_device; + RenderingDeviceVulkan *rendering_device_vulkan; #endif bool layered_window; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 5a64aa5698..5d2bc5172f 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -37,10 +37,10 @@ #if defined(OPENGL_ENABLED) #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" #endif + #if defined(VULKAN_ENABLED) -#include "servers/visual/rasterizer/rasterizer_rd.h" +#include "servers/visual/rasterizer_rd/rasterizer_rd.h" #endif #include "main/main.h" @@ -271,29 +271,6 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { return NSTerminateCancel; } -- (void)applicationDidHide:(NSNotification *)notification { - /* - _Godotwindow* window; - for (window = _Godot.windowListHead; window; window = window->next) - _GodotInputWindowVisibility(window, GL_FALSE); -*/ -} - -- (void)applicationDidUnhide:(NSNotification *)notification { - /* - _Godotwindow* window; - - for (window = _Godot.windowListHead; window; window = window->next) { - if ([window_object isVisible]) - _GodotInputWindowVisibility(window, GL_TRUE); - } -*/ -} - -- (void)applicationDidChangeScreenParameters:(NSNotification *)notification { - //_GodotInputMonitorChange(); -} - - (void)showAbout:(id)sender { if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT); @@ -347,11 +324,14 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { NSWindow *window = (NSWindow *)[notification object]; CGFloat newBackingScaleFactor = [window backingScaleFactor]; CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; + #if defined(OPENGL_ENABLED) - if (OS_OSX::singleton->is_hidpi_allowed()) { - [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; - } else { - [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO]; + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) { + if (OS_OSX::singleton->is_hidpi_allowed()) { + [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; + } else { + [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO]; + } } #endif @@ -374,10 +354,12 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { } - (void)windowDidResize:(NSNotification *)notification { + #if defined(OPENGL_ENABLED) - [OS_OSX::singleton->context update]; + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) { + OS_OSX::singleton->context_gles2->update(); + } #endif - const NSRect contentRect = [OS_OSX::singleton->window_view frame]; const NSRect fbRect = contentRect; @@ -386,9 +368,11 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { OS_OSX::singleton->window_size.height = fbRect.size.height * displayScale; #if defined(VULKAN_ENABLED) - CALayer* layer = [OS_OSX::singleton->window_view layer]; - layer.contentsScale = OS_OSX::singleton->_display_scale(); - OS_OSX::singleton->context_vulkan->window_resize(0, OS_OSX::singleton->window_size.width, OS_OSX::singleton->window_size.height); + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + CALayer* layer = [OS_OSX::singleton->window_view layer]; + layer.contentsScale = OS_OSX::singleton->_display_scale(); + OS_OSX::singleton->context_vulkan->window_resize(0, OS_OSX::singleton->window_size.width, OS_OSX::singleton->window_size.height); + } #endif if (OS_OSX::singleton->main_loop) { @@ -398,15 +382,6 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { Main::iteration(); } } - - /* - _GodotInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); - _GodotInputWindowSize(window, contentRect.size.width, contentRect.size.height); - _GodotInputWindowDamage(window); - - if (window->cursorMode == Godot_CURSOR_DISABLED) - centerCursor(window); -*/ } - (void)windowDidMove:(NSNotification *)notification { @@ -414,17 +389,6 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { if (OS_OSX::singleton->get_main_loop()) { OS_OSX::singleton->input->release_pressed_events(); } - - /* - [window->nsgl.context update]; - - int x, y; - _GodotPlatformGetWindowPos(window, &x, &y); - _GodotInputWindowPos(window, x, y); - - if (window->cursorMode == Godot_CURSOR_DISABLED) - centerCursor(window); -*/ } - (void)windowDidBecomeKey:(NSNotification *)notification { @@ -489,21 +453,25 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { - (CALayer*)makeBackingLayer { #if defined(VULKAN_ENABLED) - CALayer* layer = [[CAMetalLayer class] layer]; - layer.contentsScale = OS_OSX::singleton->_display_scale(); - return layer; + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + CALayer* layer = [[CAMetalLayer class] layer]; + layer.contentsScale = OS_OSX::singleton->_display_scale(); + return layer; + } #endif -#if defined(OPENGL_ENABLED) return [super makeBackingLayer]; -#endif } - (void)updateLayer { -#if defined(OPENGL_ENABLED) - [OS_OSX::singleton->context update]; -#endif #if defined(VULKAN_ENABLED) - [super updateLayer]; + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + [super updateLayer]; + } +#endif +#if defined(OPENGL_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) { + OS_OSX::singleton->context_gles2->update(); + } #endif } @@ -1499,6 +1467,14 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a // Register to be notified on displays arrangement changes CGDisplayRegisterReconfigurationCallback(displays_arrangement_changed, NULL); + //!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO - do Vulkan and GLES2 support checks, driver selection and fallback + video_driver_index = p_video_driver; + print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]"); + //!!!!!!!!!!!!!!!!!!!!!!!!!! + + //Create window + window_delegate = [[GodotWindowDelegate alloc] init]; // Don't use accumulation buffer support; it's not accelerated @@ -1540,15 +1516,15 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a if (displayScale > 1.0) { #if defined(OPENGL_ENABLED) - [window_view setWantsBestResolutionOpenGLSurface:YES]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + [window_view setWantsBestResolutionOpenGLSurface:YES]; + } #endif - //if (current_videomode.resizable) [window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; } else { [window_view setWantsBestResolutionOpenGLSurface:NO]; } - //[window_object setTitle:[NSString stringWithUTF8String:"GodotEnginies"]]; [window_object setContentView:window_view]; [window_object setDelegate:window_delegate]; [window_object setAcceptsMouseMovedEvents:YES]; @@ -1556,80 +1532,50 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a [window_object setRestorable:NO]; + // Init context and rendering device #if defined(OPENGL_ENABLED) - framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); - ERR_FAIL_COND(!framework); + if (video_driver_index == VIDEO_DRIVER_GLES2) { - unsigned int attributeCount = 0; + context_gles2 = memnew(ContextGL_OSX(window_view, false)); - // 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]; + if (context_gles2->initialize() != OK) { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - ADD_ATTR(NSOpenGLPFADoubleBuffer); - ADD_ATTR(NSOpenGLPFAClosestPolicy); + context_gles2->set_use_vsync(p_desired.use_vsync); - if (p_video_driver == VIDEO_DRIVER_GLES2) { - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy); - } else { - //we now need OpenGL 3 or better, maybe even change this to 3_3Core ? - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { - ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); - - /* - if (fbconfig->alphaBits > 0) - ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); -*/ - - ADD_ATTR2(NSOpenGLPFADepthSize, 24); + context_vulkan = memnew(VulkanContextOSX); + if (context_vulkan->initialize() != OK) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + if (context_vulkan->window_create(window_view, get_video_mode().width, get_video_mode().height) == -1) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - ADD_ATTR2(NSOpenGLPFAStencilSize, 8); + rendering_device_vulkan = memnew(RenderingDeviceVulkan); + rendering_device_vulkan->initialize(context_vulkan); - /* - if (fbconfig->stereo) - ADD_ATTR(NSOpenGLPFAStereo); -*/ - - /* - if (fbconfig->samples > 0) { - ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); - ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + RasterizerRD::make_current(); } -*/ - - // 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_UNAVAILABLE); - - context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - - ERR_FAIL_COND_V(context == nil, ERR_UNAVAILABLE); - - [context setView:window_view]; - - [context makeCurrentContext]; - - set_use_vsync(p_desired.use_vsync); #endif [NSApp activateIgnoringOtherApps:YES]; @@ -1641,67 +1587,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a if (p_desired.fullscreen) zoomed = true; - /*** END OSX INITIALIZATION ***/ - -#if defined(OPENGL_ENABLED) - bool gles3 = true; - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gles3 = false; - } - - bool editor = Engine::get_singleton()->is_editor_hint(); - bool gl_initialization_error = false; - - while (true) { - if (gles3) { - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - p_video_driver = VIDEO_DRIVER_GLES2; - gles3 = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } else { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } - } - } - - if (gl_initialization_error) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); - return ERR_UNAVAILABLE; - } - - video_driver_index = p_video_driver; -#endif -#if defined(VULKAN_ENABLED) - video_driver_index = VIDEO_DRIVER_VULKAN; - - context_vulkan = memnew(VulkanContextOSX); - context_vulkan->initialize(); - context_vulkan->window_create(window_view, get_video_mode().width, get_video_mode().height); - - //temporary - rendering_device = memnew(RenderingDeviceVulkan); - rendering_device->initialize(context_vulkan); - RasterizerRD::make_current(); -#endif - visual_server = memnew(VisualServerRaster); if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); @@ -1734,6 +1619,27 @@ void OS_OSX::finalize() { midi_driver.close(); #endif +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + + if (context_gles2) + memdelete(context_gles2); + } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + } + + if (context_vulkan) + memdelete(context_vulkan); + + } +#endif + CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL); CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL); @@ -1745,15 +1651,6 @@ void OS_OSX::finalize() { cursors_cache.clear(); visual_server->finish(); memdelete(visual_server); - -#if defined(VULKAN_ENABLED) - rendering_device->finalize(); - memdelete(rendering_device); - - memdelete(context_vulkan); -#endif - - //memdelete(rasterizer); } void OS_OSX::set_main_loop(MainLoop *p_main_loop) { @@ -2298,13 +2195,17 @@ String OS_OSX::get_clipboard() const { void OS_OSX::release_rendering_thread() { #if defined(OPENGL_ENABLED) - [NSOpenGLContext clearCurrentContext]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->release_current(); + } #endif } void OS_OSX::make_rendering_thread() { #if defined(OPENGL_ENABLED) - [context makeCurrentContext]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->make_current(); + } #endif } @@ -2320,10 +2221,15 @@ String OS_OSX::get_locale() const { } void OS_OSX::swap_buffers() { - [context flushBuffer]; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->swap_buffers(); + } #endif #if defined(VULKAN_ENABLED) - context_vulkan->swap_buffers(); + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->swap_buffers(); + } #endif } @@ -2738,8 +2644,9 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) { [window_object setOpaque:NO]; [window_object setHasShadow:NO]; #if defined(OPENGL_ENABLED) - GLint opacity = 0; - [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->set_opacity(0); + } #endif layered_window = true; } else { @@ -2747,13 +2654,16 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) { [window_object setOpaque:YES]; [window_object setHasShadow:YES]; #if defined(OPENGL_ENABLED) - GLint opacity = 1; - [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->set_opacity(1); + } #endif layered_window = false; } #if defined(OPENGL_ENABLED) - [context update]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->update(); + } #endif NSRect frame = [window_object frame]; [window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES]; @@ -3073,11 +2983,20 @@ Error OS_OSX::move_to_trash(const String &p_path) { } void OS_OSX::_set_use_vsync(bool p_enable) { + // FIXME: Commented out during rebase of vulkan branch on master. + /* CGLContextObj ctx = CGLGetCurrentContext(); if (ctx) { GLint swapInterval = p_enable ? 1 : 0; CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval); } + */ +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (context_gles2) + context_gles2->set_use_vsync(p_enable); + } +#endif } OS_OSX *OS_OSX::singleton = NULL; |