summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/osx/detect.py2
-rw-r--r--platform/osx/os_osx.h9
-rw-r--r--platform/osx/os_osx.mm64
-rw-r--r--scene/gui/color_picker.cpp25
4 files changed, 68 insertions, 32 deletions
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 31fcbc0427..36a753e683 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -126,7 +126,7 @@ def configure(env):
env.Append(CPPPATH=['#platform/osx'])
env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED', '-DCOREMIDI_ENABLED'])
- env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
+ env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'CoreVideo'])
env.Append(LIBS=['pthread'])
env.Append(CPPFLAGS=['-mmacosx-version-min=10.9'])
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 262079fa89..927c8c9b00 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -43,8 +43,10 @@
#include "servers/visual/rasterizer.h"
#include "servers/visual/visual_server_wrap_mt.h"
#include "servers/visual_server.h"
+#include <AppKit/AppKit.h>
#include <AppKit/NSCursor.h>
#include <ApplicationServices/ApplicationServices.h>
+#include <CoreVideo/CoreVideo.h>
#undef CursorShape
/**
@@ -102,10 +104,13 @@ public:
id window_view;
id autoreleasePool;
id cursor;
- id pixelFormat;
- id context;
+ NSOpenGLPixelFormat *pixelFormat;
+ NSOpenGLContext *context;
bool layered_window;
+ bool waiting_for_vsync;
+ NSCondition *vsync_condition;
+ CVDisplayLinkRef displayLink;
CursorShape cursor_shape;
NSCursor *cursors[CURSOR_MAX];
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 760858b2e5..3f80d19fa1 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -117,6 +117,21 @@ static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFacto
return Vector2(mouse_x, mouse_y);
}
+// 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) {
+ OS_OSX *os = (OS_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
+ [os->vsync_condition lock];
+ os->waiting_for_vsync = false;
+ [os->vsync_condition signal];
+ [os->vsync_condition unlock];
+
+ return kCVReturnSuccess;
+}
+
@interface GodotApplication : NSApplication
@end
@@ -1366,6 +1381,15 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
[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];
+
set_use_vsync(p_desired.use_vsync);
[NSApp activateIgnoringOtherApps:YES];
@@ -1453,6 +1477,11 @@ void OS_OSX::finalize() {
midi_driver.close();
#endif
+ if (displayLink) {
+ CVDisplayLinkRelease(displayLink);
+ }
+ [vsync_condition release];
+
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL);
CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL);
@@ -1967,6 +1996,17 @@ String OS_OSX::get_locale() const {
}
void OS_OSX::swap_buffers() {
+ if (is_vsync_enabled()) {
+ // 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];
}
@@ -2633,22 +2673,22 @@ Error OS_OSX::move_to_trash(const String &p_path) {
}
void OS_OSX::_set_use_vsync(bool p_enable) {
- CGLContextObj ctx = CGLGetCurrentContext();
+ // 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.
+
+ /* CGLContextObj ctx = CGLGetCurrentContext();
if (ctx) {
GLint swapInterval = p_enable ? 1 : 0;
CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
- }
-}
-/*
-bool OS_OSX::is_vsync_enabled() const {
- GLint swapInterval = 0;
- CGLContextObj ctx = CGLGetCurrentContext();
- if (ctx) {
- CGLGetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
- }
- return swapInterval ? true : false;
+ }*/
+
+ ///TODO Maybe pause/unpause display link?
+ waiting_for_vsync = p_enable;
}
-*/
+
OS_OSX *OS_OSX::singleton = NULL;
OS_OSX::OS_OSX() {
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 307a421016..4b1c7b3db7 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -82,11 +82,8 @@ void ColorPicker::_notification(int p_what) {
} break;
case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: {
- if (screen != NULL) {
- if (screen->is_visible()) {
- screen->hide();
- }
- }
+ if (screen != NULL && screen->is_visible())
+ screen->hide();
} break;
}
}
@@ -500,21 +497,17 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) {
void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> bev = p_event;
-
- if (bev.is_valid()) {
-
- if (bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) {
- emit_signal("color_changed", color);
- screen->hide();
- }
+ if (bev.is_valid() && bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) {
+ emit_signal("color_changed", color);
+ screen->hide();
}
Ref<InputEventMouseMotion> mev = p_event;
-
if (mev.is_valid()) {
Viewport *r = get_tree()->get_root();
if (!r->get_visible_rect().has_point(Point2(mev->get_global_position().x, mev->get_global_position().y)))
return;
+
Ref<Image> img = r->get_texture()->get_data();
if (img.is_valid() && !img->empty()) {
img->lock();
@@ -540,6 +533,8 @@ void ColorPicker::_screen_pick_pressed() {
screen->set_anchors_and_margins_preset(Control::PRESET_WIDE);
screen->set_default_cursor_shape(CURSOR_POINTING_HAND);
screen->connect("gui_input", this, "_screen_input");
+ // It immediately toggles off in the first press otherwise.
+ screen->call_deferred("connect", "hide", btn_pick, "set_pressed", varray(false));
}
screen->raise();
screen->show_modal();
@@ -830,8 +825,6 @@ void ColorPickerButton::_update_picker() {
add_child(popup);
picker->connect("color_changed", this, "_color_changed");
popup->connect("modal_closed", this, "_modal_closed");
- popup->connect("about_to_show", this, "set_pressed", varray(true));
- popup->connect("popup_hide", this, "set_pressed", varray(false));
picker->set_pick_color(color);
picker->set_edit_alpha(edit_alpha);
}
@@ -862,6 +855,4 @@ ColorPickerButton::ColorPickerButton() {
picker = NULL;
popup = NULL;
edit_alpha = true;
-
- set_toggle_mode(true);
}