From d46bc8f4ac90a130d2c0f385fbaca4b6e9390ac2 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 10 Jun 2022 14:02:51 +0300 Subject: [PATCH] [macOS, 4.0] Fix unresponsive redraw during live resizing. --- platform/macos/display_server_macos.mm | 1 + platform/macos/godot_content_view.h | 10 ++++++ platform/macos/godot_content_view.mm | 43 +++++++++++++++++++++++++- platform/macos/os_macos.mm | 5 +-- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index b009007d733..91c6da5d13e 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -166,6 +166,7 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context"); } #endif + [wd.window_view updateLayerDelegate]; id = window_id_counter++; windows[id] = wd; } diff --git a/platform/macos/godot_content_view.h b/platform/macos/godot_content_view.h index 353305aec19..a6318ab9030 100644 --- a/platform/macos/godot_content_view.h +++ b/platform/macos/godot_content_view.h @@ -45,6 +45,14 @@ #import +@interface GodotContentLayerDelegate : NSObject { + DisplayServer::WindowID window_id; +} + +- (void)setWindowID:(DisplayServer::WindowID)wid; + +@end + @interface GodotContentView : RootView { DisplayServer::WindowID window_id; NSTrackingArea *tracking_area; @@ -53,12 +61,14 @@ bool mouse_down_control; bool ignore_momentum_scroll; bool last_pen_inverted; + id layer_delegate; } - (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor; - (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy; - (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed; - (void)setWindowID:(DisplayServer::WindowID)wid; +- (void)updateLayerDelegate; - (void)cancelComposition; @end diff --git a/platform/macos/godot_content_view.mm b/platform/macos/godot_content_view.mm index dbed9699012..f93ef48f6c8 100644 --- a/platform/macos/godot_content_view.mm +++ b/platform/macos/godot_content_view.mm @@ -32,12 +32,49 @@ #include "display_server_macos.h" #include "key_mapping_macos.h" +#include "main/main.h" -@implementation GodotContentView +@implementation GodotContentLayerDelegate - (id)init { self = [super init]; window_id = DisplayServer::INVALID_WINDOW_ID; + return self; +} + +- (void)setWindowID:(DisplayServerMacOS::WindowID)wid { + window_id = wid; +} + +- (void)displayLayer:(CALayer *)layer { + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); + if (OS::get_singleton()->get_main_loop() && ds->get_is_resizing()) { + Main::force_redraw(); + if (!Main::is_iterating()) { // Avoid cyclic loop. + Main::iteration(); + } + } +} + +@end + +@implementation GodotContentView + +- (void)setFrameSize:(NSSize)newSize { + [super setFrameSize:newSize]; + [self.layer setNeedsDisplay]; // Force "drawRect" call. +} + +- (void)updateLayerDelegate { + self.layer.delegate = layer_delegate; + self.layer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable; + self.layer.needsDisplayOnBoundsChange = YES; +} + +- (id)init { + self = [super init]; + layer_delegate = [[GodotContentLayerDelegate alloc] init]; + window_id = DisplayServer::INVALID_WINDOW_ID; tracking_area = nil; ime_input_event_in_progress = false; mouse_down_control = false; @@ -45,6 +82,9 @@ last_pen_inverted = false; [self updateTrackingAreas]; + self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize; + self.layerContentsPlacement = NSViewLayerContentsPlacementTopLeft; + if (@available(macOS 10.13, *)) { [self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeFileURL]]; #if !defined(__aarch64__) // Do not build deprectead 10.13 code on ARM. @@ -58,6 +98,7 @@ - (void)setWindowID:(DisplayServerMacOS::WindowID)wid { window_id = wid; + [layer_delegate setWindowID:window_id]; } // MARK: Backing Layer diff --git a/platform/macos/os_macos.mm b/platform/macos/os_macos.mm index 35c4e4b03db..c250a9d71af 100644 --- a/platform/macos/os_macos.mm +++ b/platform/macos/os_macos.mm @@ -56,10 +56,11 @@ _FORCE_INLINE_ String OS_MacOS::get_framework_executable(const String &p_path) { } void OS_MacOS::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) { - // Prevent main loop from sleeping and redraw window during resize / modal popups. + // Prevent main loop from sleeping and redraw window during modal popup display. + // Do not redraw when rendering is done from the separate thread, it will conflict with the OpenGL context updates. DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); - if (get_singleton()->get_main_loop() && ds && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD || !ds->get_is_resizing())) { + if (get_singleton()->get_main_loop() && ds && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD) && !ds->get_is_resizing()) { Main::force_redraw(); if (!Main::is_iterating()) { // Avoid cyclic loop. Main::iteration();