You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
@@ -43,9 +43,15 @@ struct DisplayServerEmbeddedState {
|
|||||||
/// Default to a scale of 2.0, which is the most common.
|
/// Default to a scale of 2.0, which is the most common.
|
||||||
float screen_max_scale = 2.0f;
|
float screen_max_scale = 2.0f;
|
||||||
float screen_dpi = 96.0f;
|
float screen_dpi = 96.0f;
|
||||||
|
/// The display ID of the window which is displaying the the embedded process content.
|
||||||
|
uint32_t display_id = -1;
|
||||||
|
|
||||||
void serialize(PackedByteArray &r_data);
|
void serialize(PackedByteArray &r_data);
|
||||||
Error deserialize(const PackedByteArray &p_data);
|
Error deserialize(const PackedByteArray &p_data);
|
||||||
|
|
||||||
|
_FORCE_INLINE_ bool operator==(const DisplayServerEmbeddedState &p_other) const {
|
||||||
|
return screen_max_scale == p_other.screen_max_scale && screen_dpi == p_other.screen_dpi && display_id == p_other.display_id;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DisplayServerEmbedded : public DisplayServer {
|
class DisplayServerEmbedded : public DisplayServer {
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ DisplayServerEmbedded::DisplayServerEmbedded(const String &p_rendering_driver, W
|
|||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
ERR_FAIL_MSG("Could not create OpenGL context.");
|
ERR_FAIL_MSG("Could not create OpenGL context.");
|
||||||
}
|
}
|
||||||
|
gl_manager->set_vsync_enabled(p_vsync_mode != DisplayServer::VSYNC_DISABLED);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -708,15 +709,44 @@ void DisplayServerEmbedded::window_set_ime_position(const Point2i &p_pos, Window
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerEmbedded::set_state(const DisplayServerEmbeddedState &p_state) {
|
void DisplayServerEmbedded::set_state(const DisplayServerEmbeddedState &p_state) {
|
||||||
|
if (state == p_state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t old_display_id = state.display_id;
|
||||||
|
|
||||||
state = p_state;
|
state = p_state;
|
||||||
|
|
||||||
|
if (state.display_id != old_display_id) {
|
||||||
|
#if defined(GLES3_ENABLED)
|
||||||
|
if (gl_manager) {
|
||||||
|
gl_manager->set_display_id(state.display_id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerEmbedded::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
void DisplayServerEmbedded::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
||||||
// Not supported
|
#if defined(GLES3_ENABLED)
|
||||||
|
if (gl_manager) {
|
||||||
|
gl_manager->set_vsync_enabled(p_vsync_mode != DisplayServer::VSYNC_DISABLED);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
rendering_context->window_set_vsync_mode(p_window, p_vsync_mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayServer::VSyncMode DisplayServerEmbedded::window_get_vsync_mode(WindowID p_window) const {
|
DisplayServer::VSyncMode DisplayServerEmbedded::window_get_vsync_mode(WindowID p_window) const {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
#if defined(GLES3_ENABLED)
|
||||||
|
if (gl_manager) {
|
||||||
|
return (gl_manager->is_vsync_enabled() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(RD_ENABLED)
|
#if defined(RD_ENABLED)
|
||||||
if (rendering_context) {
|
if (rendering_context) {
|
||||||
return rendering_context->window_get_vsync_mode(p_window);
|
return rendering_context->window_get_vsync_mode(p_window);
|
||||||
@@ -762,14 +792,15 @@ void DisplayServerEmbedded::swap_buffers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerEmbeddedState::serialize(PackedByteArray &r_data) {
|
void DisplayServerEmbeddedState::serialize(PackedByteArray &r_data) {
|
||||||
r_data.resize(8);
|
r_data.resize(12);
|
||||||
|
|
||||||
uint8_t *data = r_data.ptrw();
|
uint8_t *data = r_data.ptrw();
|
||||||
data += encode_float(screen_max_scale, data);
|
data += encode_float(screen_max_scale, data);
|
||||||
data += encode_float(screen_dpi, data);
|
data += encode_float(screen_dpi, data);
|
||||||
|
data += encode_uint32(display_id, data);
|
||||||
|
|
||||||
// Assert we had enough space.
|
// Assert we had enough space.
|
||||||
DEV_ASSERT(data - r_data.ptrw() >= r_data.size());
|
DEV_ASSERT((data - r_data.ptrw()) >= r_data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Error DisplayServerEmbeddedState::deserialize(const PackedByteArray &p_data) {
|
Error DisplayServerEmbeddedState::deserialize(const PackedByteArray &p_data) {
|
||||||
@@ -778,6 +809,8 @@ Error DisplayServerEmbeddedState::deserialize(const PackedByteArray &p_data) {
|
|||||||
screen_max_scale = decode_float(data);
|
screen_max_scale = decode_float(data);
|
||||||
data += sizeof(float);
|
data += sizeof(float);
|
||||||
screen_dpi = decode_float(data);
|
screen_dpi = decode_float(data);
|
||||||
|
data += sizeof(float);
|
||||||
|
display_id = decode_uint32(data);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ public:
|
|||||||
|
|
||||||
Vector<Vector2> mpath;
|
Vector<Vector2> mpath;
|
||||||
|
|
||||||
|
CGDirectDisplayID display_id = -1;
|
||||||
|
|
||||||
Point2i mouse_pos;
|
Point2i mouse_pos;
|
||||||
WindowResizeEdge edge = WINDOW_EDGE_MAX;
|
WindowResizeEdge edge = WINDOW_EDGE_MAX;
|
||||||
|
|
||||||
@@ -253,10 +255,12 @@ private:
|
|||||||
void initialize_tts() const;
|
void initialize_tts() const;
|
||||||
|
|
||||||
struct EmbeddedProcessData {
|
struct EmbeddedProcessData {
|
||||||
const EmbeddedProcessMacOS *process;
|
EmbeddedProcessMacOS *process;
|
||||||
|
WindowData *wd = nullptr;
|
||||||
CALayer *layer_host = nil;
|
CALayer *layer_host = nil;
|
||||||
};
|
};
|
||||||
HashMap<OS::ProcessID, EmbeddedProcessData> embedded_processes;
|
HashMap<OS::ProcessID, EmbeddedProcessData> embedded_processes;
|
||||||
|
void _window_update_display_id(WindowData *p_wd);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void menu_callback(id p_sender);
|
void menu_callback(id p_sender);
|
||||||
@@ -294,6 +298,10 @@ public:
|
|||||||
|
|
||||||
bool is_always_on_top_recursive(WindowID p_window) const;
|
bool is_always_on_top_recursive(WindowID p_window) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the display ID of a window.
|
||||||
|
*/
|
||||||
|
uint32_t window_get_display_id(WindowID p_window) const;
|
||||||
void window_destroy(WindowID p_window);
|
void window_destroy(WindowID p_window);
|
||||||
void window_resize(WindowID p_window, int p_width, int p_height);
|
void window_resize(WindowID p_window, int p_width, int p_height);
|
||||||
void window_set_custom_window_buttons(WindowData &p_wd, bool p_enabled);
|
void window_set_custom_window_buttons(WindowData &p_wd, bool p_enabled);
|
||||||
@@ -461,7 +469,7 @@ public:
|
|||||||
|
|
||||||
virtual void enable_for_stealing_focus(OS::ProcessID pid) override;
|
virtual void enable_for_stealing_focus(OS::ProcessID pid) override;
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
Error embed_process_update(WindowID p_window, const EmbeddedProcessMacOS *p_process);
|
Error embed_process_update(WindowID p_window, EmbeddedProcessMacOS *p_process);
|
||||||
#endif
|
#endif
|
||||||
virtual Error request_close_embedded_process(OS::ProcessID p_pid) override;
|
virtual Error request_close_embedded_process(OS::ProcessID p_pid) override;
|
||||||
virtual Error remove_embedded_process(OS::ProcessID p_pid) override;
|
virtual Error remove_embedded_process(OS::ProcessID p_pid) override;
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#include "scene/resources/image_texture.h"
|
#include "scene/resources/image_texture.h"
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
#import "display_server_embedded.h"
|
||||||
#import "editor/embedded_process_macos.h"
|
#import "editor/embedded_process_macos.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod
|
|||||||
{
|
{
|
||||||
WindowData &wd = windows[id];
|
WindowData &wd = windows[id];
|
||||||
|
|
||||||
wd.window_delegate = [[GodotWindowDelegate alloc] init];
|
wd.window_delegate = [[GodotWindowDelegate alloc] initWithDisplayServer:this];
|
||||||
ERR_FAIL_NULL_V_MSG(wd.window_delegate, INVALID_WINDOW_ID, "Can't create a window delegate");
|
ERR_FAIL_NULL_V_MSG(wd.window_delegate, INVALID_WINDOW_ID, "Can't create a window delegate");
|
||||||
[wd.window_delegate setWindowID:id];
|
[wd.window_delegate setWindowID:id];
|
||||||
|
|
||||||
@@ -2196,6 +2197,8 @@ void DisplayServerMacOS::reparent_check(WindowID p_window) {
|
|||||||
WindowData &wd = windows[p_window];
|
WindowData &wd = windows[p_window];
|
||||||
NSScreen *screen = [wd.window_object screen];
|
NSScreen *screen = [wd.window_object screen];
|
||||||
|
|
||||||
|
_window_update_display_id(&wd);
|
||||||
|
|
||||||
if (wd.transient_parent != INVALID_WINDOW_ID) {
|
if (wd.transient_parent != INVALID_WINDOW_ID) {
|
||||||
WindowData &wd_parent = windows[wd.transient_parent];
|
WindowData &wd_parent = windows[wd.transient_parent];
|
||||||
NSScreen *parent_screen = [wd_parent.window_object screen];
|
NSScreen *parent_screen = [wd_parent.window_object screen];
|
||||||
@@ -3284,9 +3287,34 @@ void DisplayServerMacOS::enable_for_stealing_focus(OS::ProcessID pid) {
|
|||||||
ERR_FAIL_V(m_retval); \
|
ERR_FAIL_V(m_retval); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t DisplayServerMacOS::window_get_display_id(WindowID p_window) const {
|
||||||
|
const WindowData *wd;
|
||||||
|
GET_OR_FAIL_V(wd, windows, p_window, -1);
|
||||||
|
return wd->display_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerMacOS::_window_update_display_id(WindowData *p_wd) {
|
||||||
|
NSScreen *screen = [p_wd->window_object screen];
|
||||||
|
CGDirectDisplayID display_id = [[screen deviceDescription][@"NSScreenNumber"] unsignedIntValue];
|
||||||
|
if (p_wd->display_id == display_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_wd->display_id = display_id;
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
// Notify any embedded processes of the new display ID, so that they can potentially update their vsync.
|
||||||
|
for (KeyValue<OS::ProcessID, EmbeddedProcessData> &E : embedded_processes) {
|
||||||
|
if (E.value.wd == p_wd) {
|
||||||
|
E.value.process->display_state_changed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
|
||||||
Error DisplayServerMacOS::embed_process_update(WindowID p_window, const EmbeddedProcessMacOS *p_process) {
|
Error DisplayServerMacOS::embed_process_update(WindowID p_window, EmbeddedProcessMacOS *p_process) {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
WindowData *wd;
|
WindowData *wd;
|
||||||
@@ -3303,6 +3331,7 @@ Error DisplayServerMacOS::embed_process_update(WindowID p_window, const Embedded
|
|||||||
ed = &embedded_processes.insert(p_pid, EmbeddedProcessData())->value;
|
ed = &embedded_processes.insert(p_pid, EmbeddedProcessData())->value;
|
||||||
|
|
||||||
ed->process = p_process;
|
ed->process = p_process;
|
||||||
|
ed->wd = wd;
|
||||||
|
|
||||||
CALayerHost *host = [CALayerHost new];
|
CALayerHost *host = [CALayerHost new];
|
||||||
uint32_t p_context_id = p_process->get_context_id();
|
uint32_t p_context_id = p_process->get_context_id();
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ class EmbeddedProcessMacOS final : public EmbeddedProcessBase {
|
|||||||
// Helper functions.
|
// Helper functions.
|
||||||
|
|
||||||
void _try_embed_process();
|
void _try_embed_process();
|
||||||
void update_embedded_process() const;
|
void update_embedded_process();
|
||||||
void _joy_connection_changed(int p_index, bool p_connected) const;
|
void _joy_connection_changed(int p_index, bool p_connected) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -113,6 +113,8 @@ public:
|
|||||||
|
|
||||||
_FORCE_INLINE_ LayerHost *get_layer_host() const { return layer_host; }
|
_FORCE_INLINE_ LayerHost *get_layer_host() const { return layer_host; }
|
||||||
|
|
||||||
|
void display_state_changed();
|
||||||
|
|
||||||
// MARK: - Embedded process state
|
// MARK: - Embedded process state
|
||||||
_FORCE_INLINE_ DisplayServer::MouseMode get_mouse_mode() const { return mouse_mode; }
|
_FORCE_INLINE_ DisplayServer::MouseMode get_mouse_mode() const { return mouse_mode; }
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ void EmbeddedProcessMacOS::_notification(int p_what) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmbeddedProcessMacOS::update_embedded_process() const {
|
void EmbeddedProcessMacOS::update_embedded_process() {
|
||||||
layer_host->set_rect(get_adjusted_embedded_window_rect(get_rect()));
|
layer_host->set_rect(get_adjusted_embedded_window_rect(get_rect()));
|
||||||
if (is_embedding_completed()) {
|
if (is_embedding_completed()) {
|
||||||
ds->embed_process_update(window->get_window_id(), this);
|
ds->embed_process_update(window->get_window_id(), this);
|
||||||
@@ -130,24 +130,28 @@ void EmbeddedProcessMacOS::request_close() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmbeddedProcessMacOS::display_state_changed() {
|
||||||
|
DisplayServerEmbeddedState state;
|
||||||
|
state.screen_max_scale = ds->screen_get_max_scale();
|
||||||
|
state.screen_dpi = ds->screen_get_dpi();
|
||||||
|
state.display_id = ds->window_get_display_id(window->get_window_id());
|
||||||
|
PackedByteArray data;
|
||||||
|
state.serialize(data);
|
||||||
|
script_debugger->send_message("embed:ds_state", { data });
|
||||||
|
}
|
||||||
|
|
||||||
void EmbeddedProcessMacOS::_try_embed_process() {
|
void EmbeddedProcessMacOS::_try_embed_process() {
|
||||||
if (current_process_id == 0 || script_debugger == nullptr || context_id == 0) {
|
if (current_process_id == 0 || script_debugger == nullptr || context_id == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error err = ds->embed_process_update(window->get_window_id(), this);
|
DisplayServer::WindowID wid = window->get_window_id();
|
||||||
|
Error err = ds->embed_process_update(wid, this);
|
||||||
if (err == OK) {
|
if (err == OK) {
|
||||||
layer_host->set_rect(get_adjusted_embedded_window_rect(get_rect()));
|
layer_host->set_rect(get_adjusted_embedded_window_rect(get_rect()));
|
||||||
|
|
||||||
// Replicate some of the DisplayServer state.
|
// Replicate important DisplayServer state.
|
||||||
{
|
display_state_changed();
|
||||||
DisplayServerEmbeddedState state;
|
|
||||||
state.screen_max_scale = ds->screen_get_max_scale();
|
|
||||||
state.screen_dpi = ds->screen_get_dpi();
|
|
||||||
PackedByteArray data;
|
|
||||||
state.serialize(data);
|
|
||||||
script_debugger->send_message("embed:ds_state", { data });
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect2i rect = get_screen_embedded_window_rect();
|
Rect2i rect = get_screen_embedded_window_rect();
|
||||||
script_debugger->send_message("embed:window_size", { rect.size });
|
script_debugger->send_message("embed:window_size", { rect.size });
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ class GLManagerEmbedded {
|
|||||||
/// Triple-buffering is used to avoid stuttering.
|
/// Triple-buffering is used to avoid stuttering.
|
||||||
static constexpr uint32_t BUFFER_COUNT = 3;
|
static constexpr uint32_t BUFFER_COUNT = 3;
|
||||||
|
|
||||||
|
// The display ID for which vsync is used. If this value is -1, vsync is disabled.
|
||||||
|
constexpr static uint32_t INVALID_DISPLAY_ID = static_cast<uint32_t>(-1);
|
||||||
|
|
||||||
struct FrameBuffer {
|
struct FrameBuffer {
|
||||||
IOSurfaceRef surface = nullptr;
|
IOSurfaceRef surface = nullptr;
|
||||||
unsigned int tex = 0;
|
unsigned int tex = 0;
|
||||||
@@ -86,12 +89,25 @@ class GLManagerEmbedded {
|
|||||||
CGLTexImageIOSurface2DPtr CGLTexImageIOSurface2D = nullptr;
|
CGLTexImageIOSurface2DPtr CGLTexImageIOSurface2D = nullptr;
|
||||||
CGLErrorStringPtr CGLErrorString = nullptr;
|
CGLErrorStringPtr CGLErrorString = nullptr;
|
||||||
|
|
||||||
|
uint32_t display_id = INVALID_DISPLAY_ID;
|
||||||
|
CVDisplayLinkRef display_link;
|
||||||
|
bool vsync_enabled = false;
|
||||||
|
bool display_link_running = false;
|
||||||
|
dispatch_semaphore_t display_semaphore = nullptr;
|
||||||
|
|
||||||
|
void create_display_link();
|
||||||
|
void release_display_link();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Error window_create(DisplayServer::WindowID p_window_id, CALayer *p_layer, int p_width, int p_height);
|
Error window_create(DisplayServer::WindowID p_window_id, CALayer *p_layer, int p_width, int p_height);
|
||||||
void window_destroy(DisplayServer::WindowID p_window_id);
|
void window_destroy(DisplayServer::WindowID p_window_id);
|
||||||
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
|
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
|
||||||
Size2i window_get_size(DisplayServer::WindowID p_window_id) const;
|
Size2i window_get_size(DisplayServer::WindowID p_window_id) const;
|
||||||
|
|
||||||
|
void set_display_id(uint32_t p_display_id);
|
||||||
|
void set_vsync_enabled(bool p_enabled);
|
||||||
|
bool is_vsync_enabled() const { return vsync_enabled; }
|
||||||
|
|
||||||
void release_current();
|
void release_current();
|
||||||
void swap_buffers();
|
void swap_buffers();
|
||||||
|
|
||||||
|
|||||||
@@ -237,6 +237,10 @@ void GLManagerEmbedded::swap_buffers() {
|
|||||||
}
|
}
|
||||||
last_valid = true;
|
last_valid = true;
|
||||||
|
|
||||||
|
if (display_link_running) {
|
||||||
|
dispatch_semaphore_wait(display_semaphore, DISPATCH_TIME_FOREVER);
|
||||||
|
}
|
||||||
|
|
||||||
[CATransaction begin];
|
[CATransaction begin];
|
||||||
[CATransaction setDisableActions:YES];
|
[CATransaction setDisableActions:YES];
|
||||||
win.layer.contents = (__bridge id)win.framebuffers[win.current_fb].surface;
|
win.layer.contents = (__bridge id)win.framebuffers[win.current_fb].surface;
|
||||||
@@ -249,7 +253,65 @@ Error GLManagerEmbedded::initialize() {
|
|||||||
return framework_loaded ? OK : ERR_CANT_CREATE;
|
return framework_loaded ? OK : ERR_CANT_CREATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLManagerEmbedded::create_display_link() {
|
||||||
|
DEV_ASSERT(display_link == nullptr);
|
||||||
|
|
||||||
|
CVReturn err = CVDisplayLinkCreateWithCGDisplay(CGMainDisplayID(), &display_link);
|
||||||
|
ERR_FAIL_COND_MSG(err != kCVReturnSuccess, "Failed to create display link.");
|
||||||
|
|
||||||
|
__block dispatch_semaphore_t local_semaphore = display_semaphore;
|
||||||
|
|
||||||
|
CVDisplayLinkSetOutputHandler(display_link, ^CVReturn(CVDisplayLinkRef p_display_link, const CVTimeStamp *p_now, const CVTimeStamp *p_output_time, CVOptionFlags p_flags, CVOptionFlags *p_flags_out) {
|
||||||
|
dispatch_semaphore_signal(local_semaphore);
|
||||||
|
return kCVReturnSuccess;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLManagerEmbedded::release_display_link() {
|
||||||
|
DEV_ASSERT(display_link != nullptr);
|
||||||
|
if (CVDisplayLinkIsRunning(display_link)) {
|
||||||
|
CVDisplayLinkStop(display_link);
|
||||||
|
}
|
||||||
|
CVDisplayLinkRelease(display_link);
|
||||||
|
display_link = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLManagerEmbedded::set_display_id(uint32_t p_display_id) {
|
||||||
|
if (display_id == p_display_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVReturn err = CVDisplayLinkSetCurrentCGDisplay(display_link, static_cast<CGDirectDisplayID>(p_display_id));
|
||||||
|
ERR_FAIL_COND_MSG(err != kCVReturnSuccess, "Failed to set display ID for display link.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLManagerEmbedded::set_vsync_enabled(bool p_enabled) {
|
||||||
|
if (p_enabled == vsync_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vsync_enabled = p_enabled;
|
||||||
|
|
||||||
|
if (vsync_enabled) {
|
||||||
|
if (!CVDisplayLinkIsRunning(display_link)) {
|
||||||
|
CVReturn err = CVDisplayLinkStart(display_link);
|
||||||
|
ERR_FAIL_COND_MSG(err != kCVReturnSuccess, "Failed to start display link.");
|
||||||
|
display_link_running = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (CVDisplayLinkIsRunning(display_link)) {
|
||||||
|
CVReturn err = CVDisplayLinkStop(display_link);
|
||||||
|
ERR_FAIL_COND_MSG(err != kCVReturnSuccess, "Failed to stop display link.");
|
||||||
|
display_link_running = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GLManagerEmbedded::GLManagerEmbedded() {
|
GLManagerEmbedded::GLManagerEmbedded() {
|
||||||
|
display_semaphore = dispatch_semaphore_create(BUFFER_COUNT);
|
||||||
|
|
||||||
|
create_display_link();
|
||||||
|
|
||||||
NSBundle *framework = [NSBundle bundleWithIdentifier:@"com.apple.opengl"];
|
NSBundle *framework = [NSBundle bundleWithIdentifier:@"com.apple.opengl"];
|
||||||
if ([framework load]) {
|
if ([framework load]) {
|
||||||
void *library_handle = dlopen([framework.executablePath UTF8String], RTLD_NOW);
|
void *library_handle = dlopen([framework.executablePath UTF8String], RTLD_NOW);
|
||||||
@@ -263,6 +325,7 @@ GLManagerEmbedded::GLManagerEmbedded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLManagerEmbedded::~GLManagerEmbedded() {
|
GLManagerEmbedded::~GLManagerEmbedded() {
|
||||||
|
release_display_link();
|
||||||
release_current();
|
release_current();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,10 +35,12 @@
|
|||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
@interface GodotWindowDelegate : NSObject <NSWindowDelegate> {
|
class DisplayServerMacOS;
|
||||||
DisplayServer::WindowID window_id;
|
|
||||||
}
|
@interface GodotWindowDelegate : NSObject <NSWindowDelegate>
|
||||||
|
|
||||||
- (void)setWindowID:(DisplayServer::WindowID)wid;
|
- (void)setWindowID:(DisplayServer::WindowID)wid;
|
||||||
|
|
||||||
|
- (instancetype)initWithDisplayServer:(DisplayServerMacOS *)p_ds;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -35,15 +35,25 @@
|
|||||||
#import "godot_content_view.h"
|
#import "godot_content_view.h"
|
||||||
#import "godot_window.h"
|
#import "godot_window.h"
|
||||||
|
|
||||||
@implementation GodotWindowDelegate
|
@implementation GodotWindowDelegate {
|
||||||
|
DisplayServer::WindowID window_id;
|
||||||
|
DisplayServerMacOS *ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithDisplayServer:(DisplayServerMacOS *)p_ds {
|
||||||
|
if (self = [super init]) {
|
||||||
|
ds = p_ds;
|
||||||
|
window_id = DisplayServerMacOS::INVALID_WINDOW_ID;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setWindowID:(DisplayServer::WindowID)wid {
|
- (void)setWindowID:(DisplayServer::WindowID)wid {
|
||||||
window_id = wid;
|
window_id = wid;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)windowShouldClose:(id)sender {
|
- (BOOL)windowShouldClose:(id)sender {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,8 +62,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowWillClose:(NSNotification *)notification {
|
- (void)windowWillClose:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,8 +82,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
|
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,8 +99,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidFailToEnterFullScreen:(NSWindow *)window {
|
- (void)windowDidFailToEnterFullScreen:(NSWindow *)window {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,8 +108,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
|
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,8 +132,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowWillExitFullScreen:(NSNotification *)notification {
|
- (void)windowWillExitFullScreen:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,8 +148,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidFailToExitFullScreen:(NSWindow *)window {
|
- (void)windowDidFailToExitFullScreen:(NSWindow *)window {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,8 +163,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidExitFullScreen:(NSNotification *)notification {
|
- (void)windowDidExitFullScreen:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,8 +209,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
|
- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,8 +239,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowWillStartLiveResize:(NSNotification *)notification {
|
- (void)windowWillStartLiveResize:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (ds->has_window(window_id)) {
|
||||||
if (ds && ds->has_window(window_id)) {
|
|
||||||
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
|
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
|
||||||
wd.last_frame_rect = [wd.window_object frame];
|
wd.last_frame_rect = [wd.window_object frame];
|
||||||
ds->set_is_resizing(true);
|
ds->set_is_resizing(true);
|
||||||
@@ -246,15 +247,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidEndLiveResize:(NSNotification *)notification {
|
- (void)windowDidEndLiveResize:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
ds->set_is_resizing(false);
|
||||||
if (ds) {
|
|
||||||
ds->set_is_resizing(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidResize:(NSNotification *)notification {
|
- (void)windowDidResize:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,8 +274,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidChangeScreen:(NSNotification *)notification {
|
- (void)windowDidChangeScreen:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,8 +282,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidMove:(NSNotification *)notification {
|
- (void)windowDidMove:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,8 +295,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidBecomeKey:(NSNotification *)notification {
|
- (void)windowDidBecomeKey:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,8 +326,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidResignKey:(NSNotification *)notification {
|
- (void)windowDidResignKey:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,8 +345,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidMiniaturize:(NSNotification *)notification {
|
- (void)windowDidMiniaturize:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,8 +360,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidDeminiaturize:(NSNotification *)notification {
|
- (void)windowDidDeminiaturize:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,8 +377,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidChangeOcclusionState:(NSNotification *)notification {
|
- (void)windowDidChangeOcclusionState:(NSNotification *)notification {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
if (!ds->has_window(window_id)) {
|
||||||
if (!ds || !ds->has_window(window_id)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
|
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user