Sfoglia il codice sorgente

Merge pull request #61901 from bruvzg/macos_live_resize_fix_4

Rémi Verschelde 2 anni fa
parent
commit
240fb8666a

+ 1 - 0
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;
 	}

+ 10 - 0
platform/macos/godot_content_view.h

@@ -45,6 +45,14 @@
 
 #import <QuartzCore/CAMetalLayer.h>
 
+@interface GodotContentLayerDelegate : NSObject <CALayerDelegate> {
+	DisplayServer::WindowID window_id;
+}
+
+- (void)setWindowID:(DisplayServer::WindowID)wid;
+
+@end
+
 @interface GodotContentView : RootView <NSTextInputClient> {
 	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

+ 41 - 0
platform/macos/godot_content_view.mm

@@ -32,11 +32,48 @@
 
 #include "display_server_macos.h"
 #include "key_mapping_macos.h"
+#include "main/main.h"
+
+@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;
@@ -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

+ 3 - 2
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();