Explorar el Código

WIP: macOS port
- Basic start-up working

Marko Pintera hace 7 años
padre
commit
c77edc8161

+ 4 - 11
Source/BansheeCore/Managers/BsRenderWindowManager.cpp

@@ -253,16 +253,6 @@ namespace bs
 		mNextWindowId = 0;
 	}
 
-	SPtr<RenderWindow> RenderWindowManager::create(RENDER_WINDOW_DESC& desc)
-	{
-		UINT32 id = mNextWindowId.fetch_add(1, std::memory_order_relaxed);
-
-		SPtr<RenderWindow> renderWindow = createInternal(desc, id);
-		renderWindow->initialize();
-
-		return renderWindow;
-	}
-
 	void RenderWindowManager::_update()
 	{
 		Lock lock(mWindowMutex);
@@ -273,11 +263,14 @@ namespace bs
 		mDirtyProperties.clear();
 	}
 
-	void RenderWindowManager::windowCreated(RenderWindow* window)
+	UINT32 RenderWindowManager::windowCreated(RenderWindow* window)
 	{
+		UINT32 id = mNextWindowId.fetch_add(1, std::memory_order_relaxed);
 		Lock lock(mWindowMutex);
 
 		mCreatedWindows.push_back(window);
+
+		return id;
 	}
 
 	void RenderWindowManager::windowDestroyed(RenderWindow* window)

+ 1 - 7
Source/BansheeCore/Managers/BsRenderWindowManager.h

@@ -106,9 +106,6 @@ namespace bs
 	public:
 		RenderWindowManager();
 
-		/** Creates a new render window using the specified options. */
-		SPtr<RenderWindow> create(RENDER_WINDOW_DESC& desc);
-
 		/** Called once per frame. Dispatches events. */
 		void _update();
 
@@ -123,11 +120,8 @@ namespace bs
 		friend class bs::RenderWindow;
 		friend class bs::RenderWindowManager;
 
-		/** @copydoc create */
-		virtual SPtr<RenderWindow> createInternal(RENDER_WINDOW_DESC& desc, UINT32 windowId) = 0;
-
 		/**	Called whenever a window is created. */
-		void windowCreated(RenderWindow* window);
+		UINT32 windowCreated(RenderWindow* window);
 
 		/**	Called by the core thread when window is destroyed. */
 		void windowDestroyed(RenderWindow* window);

+ 6 - 1
Source/BansheeCore/Private/MacOS/BsMacOSInput.cpp

@@ -700,8 +700,13 @@ namespace bs
 					}
 				}
 
+				static int dbgi = 0;
 				if(relX != 0 || relY != 0 || relZ != 0)
+				{
+					LOGWRN("Mouse move " + toString(relX) + " " + toString(relY) + " " + toString(relZ) + " " +
+						toString(dbgi++));
 					mData.owner->_notifyMouseMoved(relX, relY, relZ);
+				}
 
 				for(UINT32 i = 0; i < 24; i++)
 				{
@@ -806,7 +811,7 @@ namespace bs
 					// Usage -1 and 1 are special signals that happen along with every button press/release and should be
 					// ignored
 					if(usage != -1 && usage != 1)
-						button = scanCodeToKeyCode((UINT32)value);
+						button = scanCodeToKeyCode((UINT32)usage);
 				}
 
 				if(button != BC_UNASSIGNED)

+ 17 - 0
Source/BansheeCore/Private/MacOS/BsMacOSPlatform.h

@@ -3,6 +3,7 @@
 #pragma once
 
 #include "Platform/BsPlatform.h"
+#include "RenderAPI/BsRenderWindow.h"
 
 // Don't include macOS frameworks when generating script bindings, as it can't find them
 #ifndef BS_SBGEN
@@ -37,6 +38,22 @@ namespace bs
 		/** Notifies the system that a window is about to be destroyed. */
 		static void unregisterWindow(CocoaWindow* window);
 
+		/**
+		 * Locks the access to the list of CocoaWindows ensuring no new windows can be created or destroyed. This must be
+		 * called any time CocoaWindow is being used outside of the main thread to ensure the window doesn't get destroyed
+		 * while being in use. Needs to be followed by unlockWindows().
+		 */
+		static void lockWindows();
+
+		/** Releases the lock acquires by lockWindows(). */
+		static void unlockWindows();
+
+		/**
+		 *  Returns a window based on its ID. Returns null if window cannot be found. Expects the caller to lock windows
+		 *  using lockWindows() in case this is called from non-main thread.
+		 */
+		static CocoaWindow* getWindow(UINT32 windowId);
+
 		/** Generates a Cocoa image from the provided pixel data. */
 		static NSImage* createNSImage(const PixelData& data);
 

+ 53 - 14
Source/BansheeCore/Private/MacOS/BsMacOSPlatform.mm

@@ -67,6 +67,8 @@ namespace bs
 	struct Platform::Pimpl
 	{
 		BSAppDelegate* appDelegate = nil;
+
+		Mutex windowMutex;
 		CocoaWindow* mainWindow = nullptr;
 		UnorderedMap<UINT32, CocoaWindow*> allWindows;
 		Vector<ModalWindowInfo> modalWindows;
@@ -262,7 +264,7 @@ namespace bs
 @interface BSPlatform : NSObject
 -(BSPlatform*) initWithPlatformData:(bs::Platform::Pimpl*)platformData;
 -(void) setCaptionNonClientAreas:(NSArray*) params;
--(void) resetNonClientAreas:(NSValue*) windowValue;
+-(void) resetNonClientAreas:(NSValue*) windowIdValue;
 -(void) openFolder:(NSURL*) url;
 -(void) setClipboardText:(NSString*) text;
 -(NSString*) getClipboardText;
@@ -284,8 +286,16 @@ namespace bs
 
 - (void)setCaptionNonClientAreas:(NSArray*)params
 {
-	NSValue* windowValue = params[0];
-	bs::CocoaWindow* window = (bs::CocoaWindow*)[windowValue pointerValue];
+	NSValue* windowIdValue = params[0];
+
+	bs::UINT32 windowId;
+	[windowIdValue getValue:&windowId];
+
+	auto iterFind = mPlatformData->allWindows.find(windowId);
+	if(iterFind == mPlatformData->allWindows.end())
+		return;
+
+	bs::CocoaWindow* window = iterFind->second;
 
 	NSUInteger numEntries = [params count] - 1;
 
@@ -303,10 +313,16 @@ namespace bs
 	window->_setDragZones(areas);
 }
 
-- (void)resetNonClientAreas:(NSValue*) windowValue
+- (void)resetNonClientAreas:(NSValue*) windowIdValue
 {
-	bs::CocoaWindow* window = (bs::CocoaWindow*)[windowValue pointerValue];
+	bs::UINT32 windowId;
+	[windowIdValue getValue:&windowId];
+
+	auto iterFind = mPlatformData->allWindows.find(windowId);
+	if(iterFind == mPlatformData->allWindows.end())
+		return;
 
+	bs::CocoaWindow* window = iterFind->second;
 	window->_setDragZones({});
 }
 
@@ -510,7 +526,7 @@ namespace bs
 
 		if(!mData->cursorIsHidden)
 		{
-			[NSCursor performSelectorOnMainThread:@selector(unhide) withObject:nil waitUntilDone:NO];
+			[NSCursor performSelectorOnMainThread:@selector(hide) withObject:nil waitUntilDone:NO];
 			mData->cursorIsHidden = true;
 		}
 	}
@@ -521,7 +537,7 @@ namespace bs
 
 		if(mData->cursorIsHidden)
 		{
-			[NSCursor performSelectorOnMainThread:@selector(hide) withObject:nil waitUntilDone:NO];
+			[NSCursor performSelectorOnMainThread:@selector(unhide) withObject:nil waitUntilDone:NO];
 			mData->cursorIsHidden = false;
 		}
 	}
@@ -583,10 +599,12 @@ namespace bs
 	{ @autoreleasepool {
 		NSMutableArray* params = [[NSMutableArray alloc] init];
 
-		CocoaWindow* cocoaWindow;
-		window.getCustomAttribute("COCOA_WINDOW", &cocoaWindow);
+		UINT32 windowId;
+		window.getCustomAttribute("WINDOW_ID", &windowId);
 
-		[params addObject:[NSValue valueWithPointer:cocoaWindow]];
+		NSValue* windowIdValue = [NSValue valueWithBytes:&windowId objCType:@encode(UINT32)];
+
+		[params addObject:windowIdValue];
 		for(auto& entry : nonClientAreas)
 			[params addObject:[NSValue value:&entry withObjCType:@encode(bs::Rect2I)]];
 
@@ -603,14 +621,14 @@ namespace bs
 
 	void Platform::resetNonClientAreas(const ct::RenderWindow& window)
 	{
-		CocoaWindow* cocoaWindow;
-		window.getCustomAttribute("COCOA_WINDOW", &cocoaWindow);
+		UINT32 windowId;
+		window.getCustomAttribute("WINDOW_ID", &windowId);
 
-		NSValue* windowValue = [NSValue valueWithPointer:cocoaWindow];
+		NSValue* windowIdValue = [NSValue valueWithBytes:&windowId objCType:@encode(UINT32)];
 
 		[mData->platformManager
 			performSelectorOnMainThread:@selector(resetNonClientAreas:)
-			withObject:windowValue
+			withObject:windowIdValue
 			waitUntilDone:NO];
 	}
 
@@ -766,6 +784,7 @@ namespace bs
 			mData->modalWindows.push_back(info);
 		}
 
+		Lock lock(mData->windowMutex);
 		mData->allWindows[window->_getWindowId()] = window;
 	}
 
@@ -785,6 +804,7 @@ namespace bs
 				mData->modalWindows.erase(iterFind);
 		}
 
+		Lock lock(mData->windowMutex);
 		mData->allWindows.erase(window->_getWindowId());
 
 		[mData->cursorManager unregisterWindow:windowData->window];
@@ -797,6 +817,25 @@ namespace bs
 		}
 	}
 
+	void MacOSPlatform::lockWindows()
+	{
+		mData->windowMutex.lock();
+	}
+
+	void MacOSPlatform::unlockWindows()
+	{
+		mData->windowMutex.unlock();
+	}
+
+	CocoaWindow* MacOSPlatform::getWindow(UINT32 windowId)
+	{
+		auto iterFind = mData->allWindows.find(windowId);
+		if(iterFind == mData->allWindows.end())
+			return nullptr;
+
+		return iterFind->second;
+	}
+
 	NSImage* MacOSPlatform::createNSImage(const PixelData& data)
 	{
 		// Premultiply alpha

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

@@ -356,10 +356,12 @@ enum class MouseEventType
 		bs::MacOSPlatform::sendInputCommandEvent(ict);
 	else
 	{
-		bs::String utf8String = [string UTF8String];
+		const char* chars = [string UTF8String];
+
+		bs::String utf8String(chars);
 		bs::U32String utf32String = bs::UTF8::toUTF32(utf8String);
 
-		for(size_t i = 0; utf32String.length(); i++)
+		for(size_t i = 0; i < utf32String.length(); i++)
 			bs::MacOSPlatform::sendCharInputEvent(utf32String[i]);
 	}
 }

+ 3 - 9
Source/BansheeCore/RenderAPI/BsRenderWindow.cpp

@@ -210,12 +210,6 @@ namespace bs
 		return std::static_pointer_cast<ct::RenderWindow>(mCoreSpecific);
 	}
 
-	SPtr<ct::CoreObject> RenderWindow::createCore() const
-	{
-		RENDER_WINDOW_DESC desc = mDesc;
-		return ct::RenderWindowManager::instance().createInternal(desc, mWindowId);
-	}
-
 	SPtr<RenderWindow> RenderWindow::create(RENDER_WINDOW_DESC& desc, SPtr<RenderWindow> parentWindow)
 	{
 		return RenderWindowManager::instance().create(desc, parentWindow);
@@ -338,10 +332,10 @@ namespace bs
 
 	namespace ct
 	{
-	RenderWindow::RenderWindow(const RENDER_WINDOW_DESC& desc, UINT32 windowId)
-		:mDesc(desc), mWindowId(windowId)
+	RenderWindow::RenderWindow(const RENDER_WINDOW_DESC& desc)
+		:mDesc(desc), mWindowId(0)
 	{
-
+		mWindowId = RenderWindowManager::instance().windowCreated(this);
 	}
 
 	RenderWindow::~RenderWindow()

+ 1 - 4
Source/BansheeCore/RenderAPI/BsRenderWindow.h

@@ -232,9 +232,6 @@ namespace bs
 		/** Returns render window properties that may be edited. */
 		RenderWindowProperties& getMutableProperties();
 
-		/** @copydoc RenderTarget::createCore */
-		SPtr<ct::CoreObject> createCore() const override;
-
 		/**	Updates window properties from the synced property data. */
 		virtual void syncProperties() = 0;
 
@@ -255,7 +252,7 @@ namespace bs
 	class BS_CORE_EXPORT RenderWindow : public RenderTarget
 	{
 	public:
-		RenderWindow(const RENDER_WINDOW_DESC& desc, UINT32 windowId);
+		RenderWindow(const RENDER_WINDOW_DESC& desc);
 		virtual ~RenderWindow();
 
 		/** 

+ 1 - 1
Source/BansheeGLRenderAPI/BsGLRenderAPI.cpp

@@ -134,7 +134,7 @@ namespace bs { namespace ct
 
 		CommandBufferManager::startUp<GLCommandBufferManager>();
 		bs::RenderWindowManager::startUp<bs::GLRenderWindowManager>(this);
-		RenderWindowManager::startUp<GLRenderWindowManager>(this);
+		RenderWindowManager::startUp();
 
 		RenderStateManager::startUp();
 

+ 0 - 22
Source/BansheeGLRenderAPI/BsGLRenderWindowManager.cpp

@@ -21,26 +21,4 @@ namespace bs
 		// Create the window
 		return glSupport->newWindow(desc, windowId, parentWindow);
 	}
-
-	namespace ct
-	{
-	GLRenderWindowManager::GLRenderWindowManager(GLRenderAPI* renderSystem)
-		:mRenderSystem(renderSystem)
-	{
-		assert(mRenderSystem != nullptr);
-	}
-
-	SPtr<RenderWindow> GLRenderWindowManager::createInternal(RENDER_WINDOW_DESC& desc, UINT32 windowId)
-	{
-		GLSupport* glSupport = mRenderSystem->getGLSupport();
-
-		// Create the window
-		SPtr<RenderWindow> window = glSupport->newWindowCore(desc, windowId);
-		window->_setThisPtr(window);
-
-		windowCreated(window.get());
-
-		return window;
-	}
-	}
 }

+ 0 - 17
Source/BansheeGLRenderAPI/BsGLRenderWindowManager.h

@@ -25,22 +25,5 @@ namespace bs
 		ct::GLRenderAPI* mRenderSystem;
 	};
 
-	namespace ct
-	{
-	/**	Manager that handles window creation for OpenGL. */
-	class GLRenderWindowManager : public RenderWindowManager
-	{
-	public:
-		GLRenderWindowManager(GLRenderAPI* renderSystem);
-
-	protected:
-		/** @copydoc RenderWindowManager::createInternal */
-		SPtr<RenderWindow> createInternal(RENDER_WINDOW_DESC& desc, UINT32 windowId) override;
-
-	private:
-		GLRenderAPI* mRenderSystem;
-	};
-	}
-
 	/** @} */
 }

+ 0 - 9
Source/BansheeGLRenderAPI/BsGLSupport.h

@@ -33,15 +33,6 @@ namespace bs { namespace ct
 		 */
 		virtual SPtr<bs::RenderWindow> newWindow(RENDER_WINDOW_DESC& desc, UINT32 windowId, SPtr<bs::RenderWindow> parentWindow) = 0;
 
-		/**
-		 * Creates a new render window using the specified descriptor.
-		 *
-		 * @param[in]	desc			Description of a render window to create.
-		 * @param[in]	windowId		Window ID provided by the render window manager.
-		 * @return						Returns newly created window.
-		 */
-		virtual SPtr<RenderWindow> newWindowCore(RENDER_WINDOW_DESC& desc, UINT32 windowId) = 0;
-
 		/**	Called when OpenGL is being initialized. */
 		virtual void start() = 0;
 

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

@@ -4,6 +4,7 @@
 #include "MacOS/BsMacOSGLSupport.h"
 #define BS_COCOA_INTERNALS
 #include "Private/MacOS/BsMacOSWindow.h"
+#include "Private/MacOS/BsMacOSPlatform.h"
 #import <AppKit/AppKit.h>
 
 namespace bs::ct
@@ -71,8 +72,14 @@ namespace bs::ct
 
 	void MacOSContext::setCurrent(const RenderWindow& renderWindow)
 	{
-		CocoaWindow* window;
-		renderWindow.getCustomAttribute("COCOA_WINDOW", &window);
+		UINT32 windowId;
+		renderWindow.getCustomAttribute("WINDOW_ID", &windowId);
+
+		MacOSPlatform::lockWindows();
+
+		CocoaWindow* window = MacOSPlatform::getWindow(windowId);
+		if(!window)
+			return;
 
 		NSWindow* nsWindow = window->_getPrivateData()->window;
 
@@ -81,6 +88,8 @@ namespace bs::ct
 		[m->context update];
 
 		m->dirty = false;
+
+		MacOSPlatform::unlockWindows();
 	}
 
 	void MacOSContext::endCurrent()

+ 0 - 7
Source/BansheeGLRenderAPI/MacOS/BsMacOSGLSupport.cpp

@@ -18,13 +18,6 @@ namespace bs::ct
 		return SPtr<bs::RenderWindow>(window, &bs::CoreObject::_delete<bs::MacOSRenderWindow, GenAlloc>);
 	}
 
-	SPtr<RenderWindow> MacOSGLSupport::newWindowCore(RENDER_WINDOW_DESC& desc, UINT32 windowId)
-	{
-		MacOSRenderWindow* window = new (bs_alloc<MacOSRenderWindow>()) MacOSRenderWindow(desc, windowId, *this);
-
-		return bs_shared_ptr<MacOSRenderWindow>(window);
-	}
-
 	void MacOSGLSupport::start()
 	{
 		// Do nothing

+ 0 - 3
Source/BansheeGLRenderAPI/MacOS/BsMacOSGLSupport.h

@@ -21,9 +21,6 @@ namespace bs::ct
 		/** @copydoc GLSupport::newWindow */
 		SPtr<bs::RenderWindow> newWindow(RENDER_WINDOW_DESC& desc, UINT32 windowId, SPtr<bs::RenderWindow> parentWindow) override;
 
-		/** @copydoc GLSupport::newWindowCore */
-		SPtr<RenderWindow> newWindowCore(RENDER_WINDOW_DESC& desc, UINT32 windowId) override;
-
 		/** @copydoc GLSupport::start */
 		void start() override;
 

+ 12 - 3
Source/BansheeGLRenderAPI/MacOS/BsMacOSRenderWindow.h

@@ -97,8 +97,12 @@ namespace bs
 		/** @copydoc CoreObject::destroy() */
 		void destroy() override;
 
+		/** @copydoc RenderTarget::createCore */
+		SPtr<ct::CoreObject> createCore() const override;
+
 	private:
 		CocoaWindow* mWindow = nullptr;
+		SPtr<ct::MacOSContext> mContext;
 		bool mIsChild = false;
 
 		RenderWindowProperties mProperties;
@@ -115,7 +119,7 @@ namespace bs
 		class MacOSRenderWindow : public RenderWindow
 		{
 		public:
-			MacOSRenderWindow(const RENDER_WINDOW_DESC& desc, UINT32 windowId, MacOSGLSupport& glSupport);
+			MacOSRenderWindow(const RENDER_WINDOW_DESC& desc, UINT32 cocoaWindowId, const SPtr<MacOSContext>& context);
 
 			/** @copydoc RenderWindow::move */
 			void move(INT32 left, INT32 top) override;
@@ -132,6 +136,7 @@ namespace bs
 			 * @param[out]	dst		Previously allocated buffer to read the contents into. Must be of valid size.
 			 * @param[in]	buffer	Frame buffer to read the contents from.
 			 *
+			 */
 			void copyToMemory(PixelData& dst, FrameBuffer buffer);
 
 			/** @copydoc RenderWindow::swapBuffers */
@@ -155,14 +160,18 @@ namespace bs
 			/** @copydoc RenderWindow::syncProperties */
 			void syncProperties() override;
 
+			/** @copydoc RenderWindow::initialize */
+			void initialize() override;
+
 		protected:
 			friend class bs::MacOSRenderWindow;
 
 			SPtr<MacOSContext> mContext;
-			ct::MacOSGLSupport& mGLSupport;
+			bool mShowOnSwap;
+			UINT32 mCocoaWindowId;
+
 			RenderWindowProperties mProperties;
 			RenderWindowProperties mSyncedProperties;
-			bool mShowOnSwap;
 		};
 	}
 

+ 23 - 18
Source/BansheeGLRenderAPI/MacOS/BsMacOSRenderWindow.mm

@@ -39,7 +39,6 @@ namespace bs
 
 		props.isFullScreen = mDesc.fullscreen && !mIsChild;
 
-		mShowOnSwap = mDesc.hideUntilSwap;
 		props.isHidden = mDesc.hideUntilSwap || mDesc.hidden;
 
 		mWindow = bs_new<CocoaWindow>(windowDesc);
@@ -59,9 +58,6 @@ namespace bs
 		if(mDesc.fullscreen && !mIsChild)
 			setFullscreen(mDesc.videoMode);
 
-		if(mDesc.vsync && mDesc.vsyncInterval > 0)
-			setVSync(true, mDesc.vsyncInterval);
-
 		RenderWindow::initialize();
 
 		{
@@ -85,6 +81,12 @@ namespace bs
 		}
 	}
 
+	SPtr<ct::CoreObject> MacOSRenderWindow::createCore() const
+	{
+		RENDER_WINDOW_DESC desc = mDesc;
+		return bs_shared_ptr_new<ct::MacOSRenderWindow>(desc, mWindow->_getWindowId(), mContext);
+	}
+
 	void MacOSRenderWindow::resize(UINT32 width, UINT32 height)
 	{
 		RenderWindowProperties& props = mProperties;
@@ -354,10 +356,10 @@ namespace bs
 
 	void MacOSRenderWindow::getCustomAttribute(const String& name, void* data) const
 	{
-		if(name == "WINDOW" || name == "COCOA_WINDOW")
+		if(name == "COCOA_WINDOW")
 		{
-			blockUntilCoreInitialized();
-			getCore()->getCustomAttribute(name, data);
+			CocoaWindow** window = (CocoaWindow**)data;
+			*window = mWindow;
 			return;
 		}
 	}
@@ -412,10 +414,19 @@ namespace bs
 
 	namespace ct
 	{
-		MacOSRenderWindow::MacOSRenderWindow(const RENDER_WINDOW_DESC& desc, UINT32 windowId, MacOSGLSupport& glsupport)
-			: RenderWindow(desc, windowId), mWindow(nullptr), mContext(nullptr), mGLSupport(glsupport), mProperties(desc)
-			, mSyncedProperties(desc), mShowOnSwap(false)
-		{ }
+		MacOSRenderWindow::MacOSRenderWindow(const RENDER_WINDOW_DESC& desc, UINT32 cocoaWindowId,
+			const SPtr<MacOSContext>& context)
+			: RenderWindow(desc), mShowOnSwap(desc.hideUntilSwap), mCocoaWindowId(cocoaWindowId), mProperties(desc)
+			, mSyncedProperties(desc)
+		{
+			mContext = context;
+		}
+
+		void MacOSRenderWindow::initialize()
+		{
+			if(mDesc.vsync && mDesc.vsyncInterval > 0)
+				setVSync(true, mDesc.vsyncInterval);
+		}
 
 		void MacOSRenderWindow::move(INT32 left, INT32 top)
 		{
@@ -520,16 +531,10 @@ namespace bs
 				*contextPtr = mContext;
 				return;
 			}
-			else if(name == "COCOA_WINDOW")
-			{
-				CocoaWindow** window = (CocoaWindow**)data;
-				*window = mWindow;
-				return;
-			}
 			else if(name == "WINDOW_ID")
 			{
 				UINT32* windowId = (UINT32*)data;
-				*windowId = mWindow->_getWindowId();
+				*windowId = mCocoaWindowId;
 			}
 		}