Explorar el Código

WIP: macOS port
- Fixed a rendering issue with multiple windows sharing a single OpenGL context
- Fixed an issue where modal windows would completely block the event loop
- Fixed a crash with file dialogs using no filters
- Fixed window move operation for windows with no titlebar, using manual drag zones

Marko Pintera hace 7 años
padre
commit
22f5e36c95

+ 5 - 4
Source/BansheeCore/Private/MacOS/BsMacOSPlatform.mm

@@ -302,7 +302,7 @@ namespace bs
 	bs::Vector<bs::Rect2I> areas;
 	bs::Vector<bs::Rect2I> areas;
 	for(NSUInteger i = 0; i < numEntries; i++)
 	for(NSUInteger i = 0; i < numEntries; i++)
 	{
 	{
-		NSValue* value = params[i];
+		NSValue* value = params[i + 1];
 
 
 		bs::Rect2I area;
 		bs::Rect2I area;
 		[value getValue:&area];
 		[value getValue:&area];
@@ -500,9 +500,10 @@ namespace bs
 			CFNumberGetValue(layerRef, kCFNumberIntType, &layer);
 			CFNumberGetValue(layerRef, kCFNumberIntType, &layer);
 
 
 			// Layer 0 appear to be normal windows
 			// Layer 0 appear to be normal windows
+			// Layer 8 appear to be modal windows
 			// Layer 25 appear to be fullscreen windows
 			// Layer 25 appear to be fullscreen windows
 			// Note: This is based on experimentation, as no documentation about it exists
 			// Note: This is based on experimentation, as no documentation about it exists
-			if(layer != 0 && layer != 25)
+			if(layer != 0 && layer != 8 && layer != 25)
 				continue;
 				continue;
 
 
 			CFDictionaryRef boundsRef = (CFDictionaryRef)CFDictionaryGetValue(dict, kCGWindowBounds);
 			CFDictionaryRef boundsRef = (CFDictionaryRef)CFDictionaryGetValue(dict, kCGWindowBounds);
@@ -759,8 +760,8 @@ namespace bs
 			if(!mData->modalWindows.empty())
 			if(!mData->modalWindows.empty())
 			{
 			{
 				NSModalSession session = mData->modalWindows.back().session;
 				NSModalSession session = mData->modalWindows.back().session;
-				if([NSApp runModalSession:session] != NSModalResponseContinue)
-					break;
+				[NSApp runModalSession:session];
+				break;
 			}
 			}
 			else
 			else
 			{
 			{

+ 2 - 9
Source/BansheeCore/Private/MacOS/BsMacOSWindow.mm

@@ -232,19 +232,12 @@ enum class MouseEventType
 	{
 	{
 		NSPoint point = [event locationInWindow];
 		NSPoint point = [event locationInWindow];
 		NSWindow* window = [event window];
 		NSWindow* window = [event window];
-		NSScreen* screen = nil;
+
 		if(window)
 		if(window)
 		{
 		{
 			NSRect windowFrame = [window frame];
 			NSRect windowFrame = [window frame];
-			point.x += windowFrame.origin.x;
-			point.y += windowFrame.origin.y;
-
-			screen = [window screen];
+			point.y = windowFrame.size.height - point.y;
 		}
 		}
-		else
-			screen = NSScreen.mainScreen;
-
-		bs::flipY(screen, point);
 
 
 		for (NSUInteger i = 0; i < [dragAreas count]; i++)
 		for (NSUInteger i = 0; i < [dragAreas count]; i++)
 		{
 		{

+ 10 - 8
Source/BansheeEditor/MacOS/BsMacOSBrowseDialogs.mm

@@ -43,7 +43,7 @@ namespace bs
 			bool save = ((UINT32) type & (UINT32) FileDialogType::Save) != 0;
 			bool save = ((UINT32) type & (UINT32) FileDialogType::Save) != 0;
 			String path = defaultPath.toString();
 			String path = defaultPath.toString();
 
 
-			if (save)
+			if (!save)
 			{
 			{
 				bool file = ((UINT32) type & (UINT32) FileDialogType::OpenFile) != 0;
 				bool file = ((UINT32) type & (UINT32) FileDialogType::OpenFile) != 0;
 				bool folder = ((UINT32) type & (UINT32) FileDialogType::OpenFolder) != 0;
 				bool folder = ((UINT32) type & (UINT32) FileDialogType::OpenFolder) != 0;
@@ -65,7 +65,8 @@ namespace bs
 					[fileTypes addObject:extensionString];
 					[fileTypes addObject:extensionString];
 				}
 				}
 
 
-				[openDlg setAllowedFileTypes:fileTypes];
+				if(fileTypes.count > 0)
+					[openDlg setAllowedFileTypes:fileTypes];
 
 
 				if ([openDlg runModal] == NSModalResponseOK)
 				if ([openDlg runModal] == NSModalResponseOK)
 				{
 				{
@@ -82,12 +83,12 @@ namespace bs
 			}
 			}
 			else
 			else
 			{
 			{
-				NSSavePanel* openDlg = [NSSavePanel savePanel];
+				NSSavePanel* saveDlg = [NSSavePanel savePanel];
 
 
-				[openDlg setCanCreateDirectories:YES];
+				[saveDlg setCanCreateDirectories:YES];
 
 
 				NSString* pathString = [[NSString stringWithUTF8String:path.c_str()] stringByResolvingSymlinksInPath];
 				NSString* pathString = [[NSString stringWithUTF8String:path.c_str()] stringByResolvingSymlinksInPath];
-				[openDlg setDirectoryURL:[NSURL fileURLWithPath:pathString]];
+				[saveDlg setDirectoryURL:[NSURL fileURLWithPath:pathString]];
 
 
 				NSMutableArray* fileTypes = [[NSMutableArray alloc] init];
 				NSMutableArray* fileTypes = [[NSMutableArray alloc] init];
 				for(UINT32 i = 0; i < (UINT32)extensions.size(); i++)
 				for(UINT32 i = 0; i < (UINT32)extensions.size(); i++)
@@ -96,11 +97,12 @@ namespace bs
 					[fileTypes addObject:extensionString];
 					[fileTypes addObject:extensionString];
 				}
 				}
 
 
-				[openDlg setAllowedFileTypes:fileTypes];
+				if(fileTypes.count > 0)
+					[saveDlg setAllowedFileTypes:fileTypes];
 
 
-				if([openDlg runModal] == NSModalResponseOK)
+				if([saveDlg runModal] == NSModalResponseOK)
 				{
 				{
-					NSURL* file = [openDlg URL];
+					NSURL* file = [saveDlg URL];
 
 
 					String fileStr = String([[file path] cStringUsingEncoding:kCFStringEncodingUTF8]);
 					String fileStr = String([[file path] cStringUsingEncoding:kCFStringEncodingUTF8]);
 					paths.push_back(fileStr);
 					paths.push_back(fileStr);

+ 9 - 0
Source/BansheeGLRenderAPI/MacOS/BsMacOSContext.h

@@ -46,6 +46,15 @@ namespace bs::ct
 		/** Swaps the framebuffer currently attached to this context. */
 		/** Swaps the framebuffer currently attached to this context. */
 		void swapBuffers();
 		void swapBuffers();
 
 
+		/**
+		 * Locks the context so it can safely be used across threads. Should be called before performing any OpenGL
+		 * action or direct operation on the context. When done unlock it via unlock().
+		 */
+		void lock();
+
+		/** Unlocks the context locked via lock(). */
+		void unlock();
+
 	private:
 	private:
 		Pimpl* m;
 		Pimpl* m;
 	};
 	};

+ 11 - 1
Source/BansheeGLRenderAPI/MacOS/BsMacOSContext.mm

@@ -81,7 +81,7 @@ namespace bs::ct
 		[m->context makeCurrentContext];
 		[m->context makeCurrentContext];
 		[m->context update];
 		[m->context update];
 
 
-		m->dirty = false;
+		updateIfDirty();
 
 
 		MacOSPlatform::unlockWindows();
 		MacOSPlatform::unlockWindows();
 	}
 	}
@@ -127,5 +127,15 @@ namespace bs::ct
 
 
 		updateIfDirty();
 		updateIfDirty();
 	}
 	}
+
+	void MacOSContext::lock()
+	{
+		CGLLockContext(m->context.CGLContextObj);
+	}
+
+	void MacOSContext::unlock()
+	{
+		CGLUnlockContext(m->context.CGLContextObj);
+	}
 }
 }
 
 

+ 9 - 14
Source/RenderBeast/BsRenderBeast.cpp

@@ -299,10 +299,13 @@ namespace bs { namespace ct
 		// Make sure any renderer tasks finish first, as rendering might depend on them
 		// Make sure any renderer tasks finish first, as rendering might depend on them
 		processTasks(false);
 		processTasks(false);
 
 
+		// Update reflection probe array if required
+		updateReflProbeArray();
+
 		// Gather all views
 		// Gather all views
-		Vector<RendererView*> views;
 		for (auto& rtInfo : sceneInfo.renderTargets)
 		for (auto& rtInfo : sceneInfo.renderTargets)
 		{
 		{
+			Vector<RendererView*> views;
 			SPtr<RenderTarget> target = rtInfo.target;
 			SPtr<RenderTarget> target = rtInfo.target;
 			const Vector<Camera*>& cameras = rtInfo.cameras;
 			const Vector<Camera*>& cameras = rtInfo.cameras;
 
 
@@ -313,26 +316,18 @@ namespace bs { namespace ct
 				RendererView* viewInfo = sceneInfo.views[viewIdx];
 				RendererView* viewInfo = sceneInfo.views[viewIdx];
 				views.push_back(viewInfo);
 				views.push_back(viewInfo);
 			}
 			}
-		}
-
-		mMainViewGroup->setViews(views.data(), (UINT32)views.size());
-		mMainViewGroup->determineVisibility(sceneInfo);
-
-		// Update reflection probe array if required
-		updateReflProbeArray();
 
 
-		// Render everything
-		renderViews(*mMainViewGroup, frameInfo);
+			mMainViewGroup->setViews(views.data(), (UINT32)views.size());
+			mMainViewGroup->determineVisibility(sceneInfo);
 
 
-		gProfilerGPU().endFrame();
+			// Render everything
+			renderViews(*mMainViewGroup, frameInfo);
 
 
-		// Present render targets with back buffers
-		for (auto& rtInfo : sceneInfo.renderTargets)
-		{
 			if(rtInfo.target->getProperties().isWindow)
 			if(rtInfo.target->getProperties().isWindow)
 				RenderAPI::instance().swapBuffers(rtInfo.target);
 				RenderAPI::instance().swapBuffers(rtInfo.target);
 		}
 		}
 
 
+		gProfilerGPU().endFrame();
 		gProfilerCPU().endSample("renderAllCore");
 		gProfilerCPU().endSample("renderAllCore");
 	}
 	}