Prechádzať zdrojové kódy

Dock overlay no longer uses the sim thread rendering callback

BearishSun 10 rokov pred
rodič
commit
6c9390b79b

+ 0 - 7
BansheeCore/Include/BsCoreRenderer.h

@@ -153,13 +153,6 @@ namespace BansheeEngine
 		 */
 		static void draw(const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh);
 
-		/**
-		 * @brief	Callback that gets triggered before a viewport gets rendered.
-		 *
-		 * @note	Sim thread.
-		 */
-		Event<void(const Viewport*, DrawList&)> onRenderViewport;
-
 	protected:
 		UnorderedMap<const CameraCore*, Map<UINT32, std::function<void()>>> mRenderCallbacks;
 	};

+ 75 - 26
BansheeEditor/Include/BsDockManager.h

@@ -6,6 +6,8 @@
 
 namespace BansheeEngine
 {
+	class DockOverlayRenderer;
+
 	/**
 	 * @brief	GUI element that allows editor widgets to be docked in it using arbitrary
 	 *			layouts. Docked widgets can be resized, undocked, maximizes or closed as needed.
@@ -228,15 +230,50 @@ namespace BansheeEngine
 		DockManager(EditorWindowBase* parentWindow, const GUIDimensions& dimensions);
 		~DockManager();
 
-		static const Color TINT_COLOR;
-		static const Color HIGHLIGHT_COLOR;
+		/**
+		 * @brief	Updates the dock overlay mesh that is displayed when user is dragging a widget
+		 *			over a certain area.
+		 */
+		void updateDropOverlay(INT32 x, INT32 y, UINT32 width, UINT32 height);
+
+		/**
+		 * @brief	Checks is the provided point inside the provided polygon.
+		 *
+		 * @param	polyPoints	Points of the polygon to test against.
+		 * @param	numPoints	Number of points in "polyPoints".
+		 * @param	point		Point to check if it's in the polygon.
+		 *
+		 * @returns	True if the point is in the polygon.
+		 */
+		bool insidePolygon(Vector2* polyPoints, UINT32 numPoints, Vector2 point) const;
+
+		/**
+		 * @brief	Initializes the renderer used for displaying the dock overlay.
+		 */
+		void initializeOverlayRenderer(const SPtr<MaterialCore>& initData);
+
+		/**
+		 * @brief	Destroys the dock overlay renderer.
+		 */
+		void destroyOverlayRenderer(DockOverlayRenderer* core);
+
+		/**
+		 * @copydoc GUIElementBase::updateClippedBounds
+		 */
+		void updateClippedBounds() override;
+
+		/**
+		 * @copydoc GUIElementBase::_mouseEvent
+		 */
+		bool _mouseEvent(const GUIMouseEvent& event) override;
+
+		std::atomic<DockOverlayRenderer*> mCore;
 
 		EditorWindowBase* mParentWindow;
 		DockContainer mRootContainer;
 		Rect2I mArea;
 
 		HMesh mDropOverlayMesh;
-		HMaterial mDropOverlayMat;
 		Rect2I mLastOverlayBounds;
 
 		DockContainer* mMouseOverContainer;
@@ -246,40 +283,52 @@ namespace BansheeEngine
 		Vector2* mBotDropPolygon;
 		Vector2* mLeftDropPolygon;
 		Vector2* mRightDropPolygon;
+	};
 
-		HEvent mRenderCallback;
-
-		/**
-		 * @brief	Render callback that allows the dock manager to render its overlay when needed.
-		 *			Called once per frame by the renderer.
-		 */
-		void render(const Viewport* viewport, DrawList& renderQueue);
+	/**
+	 * @brief	Handles rendering of the dock overlay, on the core thread.
+	 * 			
+	 * @note	Core thread only.
+	 */
+	class DockOverlayRenderer
+	{
+	public:
+		DockOverlayRenderer();
+		~DockOverlayRenderer();
 
-		/**
-		 * @brief	Updates the dock overlay mesh that is displayed when user is dragging a widget
-		 *			over a certain area.
-		 */
-		void updateDropOverlay(INT32 x, INT32 y, UINT32 width, UINT32 height);
+	private:
+		friend class DockManager;
 
 		/**
-		 * @brief	Checks is the provided point inside the provided polygon.
-		 *
-		 * @param	polyPoints	Points of the polygon to test against.
-		 * @param	numPoints	Number of points in "polyPoints".
-		 * @param	point		Point to check if it's in the polygon.
+		 * @brief	Initializes the object. Must be called right after construction and before any use.
 		 *
-		 * @returns	True if the point is in the polygon.
+		 * @param	material	Material used for drawing the dock overlay.
 		 */
-		bool insidePolygon(Vector2* polyPoints, UINT32 numPoints, Vector2 point) const;
+		void initialize(const SPtr<MaterialCore>& material);
 
 		/**
-		 * @copydoc GUIElementBase::updateClippedBounds
+		 * @brief	Updates the grid mesh to render.
+		 * 			
+		 * @param	camera		Camera to render the dock overlay to.
+		 * @param	mesh		Overlay mesh to render.
+		 * @param	active		Should the overlay be shown or not.
+		 * @param	location	Highlighted location of the overlay.
 		 */
-		void updateClippedBounds() override;
+		void updateData(const SPtr<CameraCore>& camera, const SPtr<MeshCore>& mesh, bool active,
+			DockManager::DockLocation location);
 
 		/**
-		 * @copydoc GUIElementBase::_mouseEvent
+		 * @brief	Callback triggered by the renderer, actually draws the dock overlay.
 		 */
-		bool _mouseEvent(const GUIMouseEvent& event) override;
+		void render();
+		
+		SPtr<CameraCore> mCamera;
+		SPtr<MaterialCore> mMaterial;
+		SPtr<MeshCore> mMesh;
+		DockManager::DockLocation mHighlightedDropLoc;
+		bool mShowOverlay;
+
+		static const Color TINT_COLOR;
+		static const Color HIGHLIGHT_COLOR;
 	};
 }

+ 2 - 2
BansheeEditor/Include/BsSceneGrid.h

@@ -83,7 +83,7 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @brief	Core thread portion of the scene grid. Handles interaction with the renderer.
+	 * @brief	Handles scene grid rendering on the core thread.
 	 */
 	class SceneGridCore
 	{
@@ -106,7 +106,7 @@ namespace BansheeEngine
 		 * @brief	Updates the grid mesh to render.
 		 * 			
 		 * @param	mesh		Grid mesh to render.
-		 * @param	scpacing	Spacing between the grid lines.
+		 * @param	spacing		Spacing between the grid lines.
 		 */
 		void updateData(const SPtr<MeshCore>& mesh, float spacing);
 

+ 109 - 54
BansheeEditor/Source/BsDockManager.cpp

@@ -24,9 +24,10 @@
 #include "BsDockManagerLayout.h"
 #include "BsEditorWindow.h"
 #include "BsGUIPanel.h"
-
+#include "BsCoreThread.h"
 #include "BsGUISkin.h"
 #include "BsGUIButton.h"
+#include <BsSelectionRenderer.h>
 
 using namespace std::placeholders;
 
@@ -35,9 +36,6 @@ namespace BansheeEngine
 	const UINT32 DockManager::DockContainer::SLIDER_SIZE = 4;
 	const UINT32 DockManager::DockContainer::MIN_CHILD_SIZE = 20;
 
-	const Color DockManager::TINT_COLOR = Color(0.44f, 0.44f, 0.44f, 0.22f);
-	const Color DockManager::HIGHLIGHT_COLOR = Color(0.44f, 0.44f, 0.44f, 0.42f);
-
 	DockManager::DockContainer::DockContainer(DockManager* manager)
 		:mIsLeaf(true), mWidgets(nullptr), mSplitPosition(0.5f),
 		mIsHorizontal(false), mParent(nullptr), mSlider(nullptr), mManager(manager)
@@ -443,19 +441,32 @@ namespace BansheeEngine
 		mLeftDropPolygon = bs_newN<Vector2>(4);
 		mRightDropPolygon = bs_newN<Vector2>(4);
 
-		mDropOverlayMat = BuiltinEditorResources::instance().createDockDropOverlayMaterial();
+		HMaterial dropOverlayMat = BuiltinEditorResources::instance().createDockDropOverlayMaterial();
 
-		mRenderCallback = RendererManager::instance().getActive()->onRenderViewport.connect(std::bind(&DockManager::render, this, _1, _2));
+		mCore.store(bs_new<DockOverlayRenderer>(), std::memory_order_release);
+		gCoreAccessor().queueCommand(std::bind(&DockManager::initializeOverlayRenderer, 
+			this, dropOverlayMat->getCore()));
 	}
 
 	DockManager::~DockManager()
 	{
-		mRenderCallback.disconnect();
-
 		bs_deleteN(mTopDropPolygon, 4);
 		bs_deleteN(mBotDropPolygon, 4);
 		bs_deleteN(mLeftDropPolygon, 4);
 		bs_deleteN(mRightDropPolygon, 4);
+
+		gCoreAccessor().queueCommand(std::bind(&DockManager::destroyOverlayRenderer,
+			this, mCore.load(std::memory_order_relaxed)));
+	}
+
+	void DockManager::initializeOverlayRenderer(const SPtr<MaterialCore>& initData)
+	{
+		mCore.load(std::memory_order_acquire)->initialize(initData);
+	}
+
+	void DockManager::destroyOverlayRenderer(DockOverlayRenderer* core)
+	{
+		bs_delete(core);
 	}
 
 	DockManager* DockManager::create(EditorWindowBase* parentWindow)
@@ -472,54 +483,12 @@ namespace BansheeEngine
 		}
 
 		mRootContainer.update();
-	}
 
-	void DockManager::render(const Viewport* viewport, DrawList& drawList)
-	{
-		if (_getParentWidget() == nullptr || _getParentWidget()->getTarget() != viewport)
-			return;
-
-		if(!mShowOverlay)
-			return;
-
-		float invViewportWidth = 1.0f / (viewport->getWidth() * 0.5f);
-		float invViewportHeight = 1.0f / (viewport->getHeight() * 0.5f);
-
-		if(!mDropOverlayMesh.isLoaded())
-			return;
-
-		if(!mDropOverlayMat.isLoaded())
-			return;
+		HCamera camera = mParentWindow->getGUICamera();
 
-		mDropOverlayMat->setFloat("invViewportWidth", invViewportWidth);
-		mDropOverlayMat->setFloat("invViewportHeight", invViewportHeight);
-
-		mDropOverlayMat->setColor("tintColor", TINT_COLOR);
-		mDropOverlayMat->setColor("highlightColor", HIGHLIGHT_COLOR);
-
-		Color highlightColor;
-		switch(mHighlightedDropLoc)
-		{
-		case DockLocation::Top:
-			highlightColor = Color(1.0f, 0.0f, 0.0f, 0.0f);
-			break;
-		case DockLocation::Bottom:
-			highlightColor = Color(0.0f, 1.0f, 0.0f, 0.0f);
-			break;
-		case DockLocation::Left:
-			highlightColor = Color(0.0f, 0.0f, 1.0f, 0.0f);
-			break;
-		case DockLocation::Right:
-			highlightColor = Color(0.0f, 0.0f, 0.0f, 1.0f);
-			break;
-		case DockLocation::None:
-			highlightColor = Color(0.0f, 0.0f, 0.0f, 0.0f);
-			break;
-		}
-
-		mDropOverlayMat->setColor("highlightActive", highlightColor);
-
-		drawList.add(mDropOverlayMat.getInternalPtr(), mDropOverlayMesh.getInternalPtr(), 0, Vector3::ZERO);
+		DockOverlayRenderer* core = mCore.load(std::memory_order_relaxed);
+		gCoreAccessor().queueCommand(std::bind(&DockOverlayRenderer::updateData, core, camera->_getCamera()->getCore(),
+			mDropOverlayMesh->getCore(), mShowOverlay, mHighlightedDropLoc));
 	}
 
 	void DockManager::insert(EditorWidgetContainer* relativeTo, EditorWidgetBase* widgetToInsert, DockLocation location)
@@ -1070,4 +1039,90 @@ namespace BansheeEngine
 
 		return isInside;
 	}
+
+	const Color DockOverlayRenderer::TINT_COLOR = Color(0.44f, 0.44f, 0.44f, 0.22f);
+	const Color DockOverlayRenderer::HIGHLIGHT_COLOR = Color(0.44f, 0.44f, 0.44f, 0.42f);
+
+	DockOverlayRenderer::DockOverlayRenderer()
+		:mShowOverlay(false), mHighlightedDropLoc(DockManager::DockLocation::None)
+	{
+		
+	}
+
+	DockOverlayRenderer::~DockOverlayRenderer()
+	{
+		if (mCamera != nullptr)
+		{
+			CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
+			activeRenderer->_unregisterRenderCallback(mCamera.get(), -20);
+		}
+	}
+
+	void DockOverlayRenderer::initialize(const SPtr<MaterialCore>& material)
+	{
+		mMaterial = material;
+	}
+
+	void DockOverlayRenderer::updateData(const SPtr<CameraCore>& camera, const SPtr<MeshCore>& mesh, bool active, 
+		DockManager::DockLocation location)
+	{
+		if (mCamera != camera)
+		{
+			CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
+			if (mCamera != nullptr)
+				activeRenderer->_unregisterRenderCallback(mCamera.get(), -20);
+
+			if (camera != nullptr)
+				activeRenderer->_registerRenderCallback(camera.get(), -20, std::bind(&DockOverlayRenderer::render, this));
+		}
+
+		mCamera = camera;
+		mMesh = mesh;
+		mShowOverlay = active;
+		mHighlightedDropLoc = location;
+	}
+
+	void DockOverlayRenderer::render()
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		if (!mShowOverlay)
+			return;
+
+		SPtr<ViewportCore> viewport = mCamera->getViewport();
+
+		float invViewportWidth = 1.0f / (viewport->getWidth() * 0.5f);
+		float invViewportHeight = 1.0f / (viewport->getHeight() * 0.5f);
+
+		mMaterial->setFloat("invViewportWidth", invViewportWidth);
+		mMaterial->setFloat("invViewportHeight", invViewportHeight);
+
+		mMaterial->setColor("tintColor", TINT_COLOR);
+		mMaterial->setColor("highlightColor", HIGHLIGHT_COLOR);
+
+		Color highlightColor;
+		switch (mHighlightedDropLoc)
+		{
+		case DockManager::DockLocation::Top:
+			highlightColor = Color(1.0f, 0.0f, 0.0f, 0.0f);
+			break;
+		case DockManager::DockLocation::Bottom:
+			highlightColor = Color(0.0f, 1.0f, 0.0f, 0.0f);
+			break;
+		case DockManager::DockLocation::Left:
+			highlightColor = Color(0.0f, 0.0f, 1.0f, 0.0f);
+			break;
+		case DockManager::DockLocation::Right:
+			highlightColor = Color(0.0f, 0.0f, 0.0f, 1.0f);
+			break;
+		case DockManager::DockLocation::None:
+			highlightColor = Color(0.0f, 0.0f, 0.0f, 0.0f);
+			break;
+		}
+
+		mMaterial->setColor("highlightActive", highlightColor);
+
+		CoreRenderer::setPass(mMaterial, 0);
+		CoreRenderer::draw(mMesh, mMesh->getProperties().getSubMesh(0));
+	}
 }

+ 1 - 1
BansheeEditor/Source/BsSelectionRenderer.cpp

@@ -24,7 +24,7 @@ namespace BansheeEngine
 			
 		mCore.store(bs_new<SelectionRendererCore>(SelectionRendererCore::PrivatelyConstuct()), std::memory_order_release);
 
-		gCoreAccessor().queueCommand(std::bind(&SelectionRenderer::initializeCore, this, selectionMat->getCore()));;
+		gCoreAccessor().queueCommand(std::bind(&SelectionRenderer::initializeCore, this, selectionMat->getCore()));
 	}
 
 	SelectionRenderer::~SelectionRenderer()

+ 2 - 2
BansheeEngine/Include/BsCCamera.h

@@ -273,10 +273,10 @@ namespace BansheeEngine
 		Vector3 unprojectPoint(const Vector3& point) const { return mInternal->unprojectPoint(point); }
 
 		/**
-		 * @brief	Returns the internal camera handler that is used for
+		 * @brief	Returns the internal camera that is used for
 		 *			majority of operations by this component.
 		 */
-		CameraPtr _getHandler() const { updateView(); return mInternal; }
+		CameraPtr _getCamera() const { updateView(); return mInternal; }
 
     protected:
 		/**

+ 2 - 2
BansheeEngine/Include/BsCLight.h

@@ -106,9 +106,9 @@ namespace BansheeEngine
 		Sphere getBounds() const;
 
 	    /**
-		 * @brief	Returns the light internals that this component wraps.
+		 * @brief	Returns the light that this component wraps.
 	     */
-		SPtr<Light> _getInternal() const { return mInternal; }
+		SPtr<Light> _getLight() const { return mInternal; }
 
     protected:
 		mutable SPtr<Light> mInternal;

+ 2 - 2
BansheeEngine/Include/BsCRenderable.h

@@ -56,10 +56,10 @@ namespace BansheeEngine
 		Bounds getBounds() const;
 
 		/**
-		 * @brief	Returns the internal renderable handler that is used for
+		 * @brief	Returns the internal renderable that is used for
 		 *			majority of operations by this component.
 		 */
-		RenderablePtr _getHandler() const { return mInternal; }
+		RenderablePtr _getRenderable() const { return mInternal; }
 
 	private:
 		/**

+ 0 - 4
RenderBeast/Source/BsRenderBeast.cpp

@@ -283,10 +283,6 @@ namespace BansheeEngine
 			// Get overlay render operations
 			OverlayManager::instance().render(viewport, *drawList);
 
-			// Get any operations from hooked up callbacks
-			const Viewport* viewportRawPtr = camera->getViewport().get();
-			onRenderViewport(viewportRawPtr, *drawList);
-
 			RenderQueuePtr renderQueue = bs_shared_ptr_new<RenderQueue>();
 			const Vector<DrawOperation>& drawOps = drawList->getDrawOperations();
 

+ 4 - 0
TODO.txt

@@ -94,6 +94,10 @@ Other polish:
    - This has to work not only when I come back to the object, but whenever inspector rebuilds (e.g. after removing element from array)
    - Consider saving this information with the serialized object
  - Import option inspectors for Texture, Mesh, Font
+ - Drag and drop issue:
+  - Starting a window drag caused a weird crash, likely caused by memory corruption. Cannot reproduce
+  - Starting drag of the hierarchy window will also start selection drag if the project window was docked above it
+  - Attempting to dock a dragged window onto the LibraryWindow causes a managed crash
 
 Stage 2 polish:
  - Inject an icon into an .exe (Win32 specific)