Explorar el Código

Added RenderTargetManager and fixed up render target core/sim syncing

Marko Pintera hace 11 años
padre
commit
f2ab5fb8dd

+ 2 - 0
BansheeCore/BansheeCore.vcxproj

@@ -307,6 +307,7 @@
     <ClInclude Include="Include\BsPlatform.h" />
     <ClInclude Include="Include\BsProfilingManager.h" />
     <ClInclude Include="Include\BsQueryManager.h" />
+    <ClInclude Include="Include\BsRenderTargetManager.h" />
     <ClInclude Include="Include\BsResourceManifest.h" />
     <ClInclude Include="Include\BsResourceManifestRTTI.h" />
     <ClInclude Include="Include\BsResourceMetaData.h" />
@@ -471,6 +472,7 @@
     <ClCompile Include="Source\BsProfilingManager.cpp" />
     <ClCompile Include="Source\BsQueryManager.cpp" />
     <ClCompile Include="Source\BsRenderer.cpp" />
+    <ClCompile Include="Source\BsRenderTargetManager.cpp" />
     <ClCompile Include="Source\BsResourceManifest.cpp" />
     <ClCompile Include="Source\BsResourceMetaData.cpp" />
     <ClCompile Include="Source\BsTextureImportOptions.cpp" />

+ 6 - 0
BansheeCore/BansheeCore.vcxproj.filters

@@ -528,6 +528,9 @@
     <ClInclude Include="Include\BsResourceMetaDataRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsRenderTargetManager.h">
+      <Filter>Header Files\RenderSystem</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsCoreApplication.cpp">
@@ -827,5 +830,8 @@
     <ClCompile Include="Source\BsResourceMetaData.cpp">
       <Filter>Source Files\Resources</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsRenderTargetManager.cpp">
+      <Filter>Source Files\RenderSystem</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 0
BansheeCore/Include/BsCorePrerequisites.h

@@ -82,6 +82,7 @@ namespace BansheeEngine
 	class MultiRenderTexture;
     class RenderWindow;
 	class RenderWindowCore;
+	class RenderTargetProperties;
     struct RenderOpMesh;
     class StringInterface;
     class SamplerState;

+ 2 - 0
BansheeCore/Include/BsRenderTarget.h

@@ -269,6 +269,8 @@ namespace BansheeEngine
 		mutable Event<void()> onResized;
 
     protected:
+		friend class RenderTargetManager;
+
 		RenderTarget();
 
 		/**

+ 59 - 0
BansheeCore/Include/BsRenderTargetManager.h

@@ -0,0 +1,59 @@
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Handles render target updates, usually cross-thread updates triggered
+	 *			by render targets getting modified on the core thread.
+	 *
+	 * @note	Internal class.
+	 */
+	class BS_CORE_EXPORT RenderTargetManager : public Module<RenderTargetManager>
+	{
+		struct RenderTargetData
+		{
+			RenderTargetProperties* properties;
+			bool dirty;
+		};
+
+	public:
+		~RenderTargetManager();
+
+		/**
+		 * @brief	Registers a new render target with the manager.
+		 *			Should be called when RT is initialized on the core thread.
+		 *
+		 * @note	Core thread only.
+		 */
+		void registerRenderTarget(RenderTarget* rt);
+
+		/**
+		 * @brief	Unregisters a render target from the manager.
+		 *			Should be called when RT is getting destroyed on the core thread.
+		 *
+		 * @note	Core thread only.
+		 */
+		void unregisterRenderTarget(RenderTarget* rt);
+
+		/**
+		 * @brief	Called once per frame on the core thread. Should be called at the end of
+		 *			the frame once all render target related methods have completed.
+		 *
+		 * @note	Core thread only.
+		 */
+		void updateCore();
+
+		/**
+		 * @brief	Called once per frame on the sim thread. Should be called at the beginning
+		 *			of the frame before the code can access render targets.
+		 */
+		void update();
+
+	private:
+		UnorderedMap<RenderTarget*, RenderTargetData> mRenderTargets;
+		BS_MUTEX(mMutex);
+	};
+}

+ 3 - 3
BansheeCore/Include/BsRenderWindowManager.h

@@ -18,9 +18,9 @@ namespace BansheeEngine
 		RenderWindowManager();
 
 		/**
-		* @brief	Creates a new render window using the specified options. Optionally
-		*			makes the created window a child of another window.
-		*/
+		 * @brief	Creates a new render window using the specified options. Optionally
+		 *			makes the created window a child of another window.
+		 */
 		RenderWindowPtr create(RENDER_WINDOW_DESC& desc, RenderWindowPtr parentWindow);
 
 		/**

+ 5 - 0
BansheeCore/Source/BsCoreApplication.cpp

@@ -26,6 +26,7 @@
 #include "BsMaterialManager.h"
 #include "BsFontManager.h"
 #include "BsRenderWindowManager.h"
+#include "BsRenderTargetManager.h"
 #include "BsRenderer.h"
 #include "BsDeferredCallManager.h"
 #include "BsCoreThread.h"
@@ -66,6 +67,7 @@ namespace BansheeEngine
 		Platform::_startUp();
 		MemStack::beginThread();
 
+		RenderTargetManager::startUp();
 		UUIDGenerator::startUp();
 		ProfilerCPU::startUp();
 		ProfilingManager::startUp();
@@ -149,6 +151,7 @@ namespace BansheeEngine
 		ProfilingManager::shutDown();
 		ProfilerCPU::shutDown();
 		UUIDGenerator::shutDown();
+		RenderTargetManager::shutDown();
 
 		MemStack::endThread();
 		Platform::_shutDown();
@@ -163,6 +166,7 @@ namespace BansheeEngine
 			gProfilerCPU().beginThread("Sim");
 
 			gCoreThread().update();
+			RenderTargetManager::instance().update();
 			Platform::_update();
 			DeferredCallManager::instance()._update();
 			RenderWindowManager::instance()._update();
@@ -201,6 +205,7 @@ namespace BansheeEngine
 
 			gCoreThread().queueCommand(&Platform::_coreUpdate);
 			gCoreThread().submitAccessors();
+			gCoreThread().queueCommand(std::bind(&RenderTargetManager::updateCore, RenderTargetManager::instancePtr()));
 			gCoreThread().queueCommand(std::bind(&CoreApplication::endCoreProfiling, this));
 			gCoreThread().queueCommand(std::bind(&CoreApplication::frameRenderingFinishedCallback, this));
 

+ 5 - 4
BansheeCore/Source/BsRenderTarget.cpp

@@ -3,6 +3,7 @@
 #include "BsException.h"
 #include "BsRenderSystem.h"
 #include "BsCoreThread.h"
+#include "BsRenderTargetManager.h"
 
 namespace BansheeEngine 
 {
@@ -43,10 +44,6 @@ namespace BansheeEngine
 	{
 		THROW_IF_CORE_THREAD;
 
-		// DEBUG ONLY
-		if (mCore != nullptr)
-			*mProperties = *mCore->mProperties;
-
 		return *mProperties;
 	}
 
@@ -60,10 +57,14 @@ namespace BansheeEngine
 		CoreObject::initialize_internal();
 
 		mCore = createCore();
+
+		RenderTargetManager::instance().registerRenderTarget(this);
 	}
 
 	void RenderTarget::destroy_internal()
 	{
+		RenderTargetManager::instance().unregisterRenderTarget(this);
+
 		bs_delete(mCore);
 		mCore = nullptr;
 

+ 72 - 0
BansheeCore/Source/BsRenderTargetManager.cpp

@@ -0,0 +1,72 @@
+#include "BsRenderTargetManager.h"
+#include "BsRenderTarget.h"
+
+namespace BansheeEngine
+{
+	RenderTargetManager::~RenderTargetManager()
+	{
+		assert(mRenderTargets.size() == 0 && "All render targets must be released before render target manager can be shut down.");
+	}
+
+	void RenderTargetManager::registerRenderTarget(RenderTarget* rt)
+	{
+		BS_LOCK_MUTEX(mMutex);
+
+		RenderTargetData rtData;
+		rtData.properties = rt->createProperties();
+		rtData.dirty = true;
+
+		mRenderTargets.insert(std::make_pair(rt, rtData));
+	}
+
+	void RenderTargetManager::unregisterRenderTarget(RenderTarget* rt)
+	{
+		BS_LOCK_MUTEX(mMutex);
+
+		auto findIter = mRenderTargets.find(rt);
+		if (findIter == mRenderTargets.end())
+			return;
+
+		RenderTargetData& rtData = findIter->second;
+		bs_delete(rtData.properties);
+
+		mRenderTargets.erase(findIter);
+	}
+
+	void RenderTargetManager::updateCore()
+	{
+		BS_LOCK_MUTEX(mMutex);
+
+		for (auto& rtPair : mRenderTargets)
+		{
+			RenderTarget* rt = rtPair.first;
+			RenderTargetData& rtData = rtPair.second;
+
+			if (rt->getCore()->_isCoreDirty())
+			{
+				*rtData.properties = rt->getCore()->getProperties();
+				rtData.dirty = true;
+
+				rt->getCore()->_markCoreClean();
+			}
+		}
+	}
+
+	void RenderTargetManager::update()
+	{
+		BS_LOCK_MUTEX(mMutex);
+
+		for (auto& rtPair : mRenderTargets)
+		{
+			RenderTarget* rt = rtPair.first;
+			RenderTargetData& rtData = rtPair.second;
+
+			if (rtData.dirty)
+			{
+				*rt->mProperties = *rtData.properties;
+
+				rtData.dirty = false;
+			}
+		}
+	}
+}

+ 0 - 1
SceneView.txt

@@ -95,7 +95,6 @@ RenderTarget (and in turn, Viewport) make data available to sim thread, even tho
 
 TODO:
  - Core thread gets stuck on shutdown when OpenGL is used...Somewhere in kernel
- - DX9 doesn't render anything in viewport (shader issue?)
  - getProperties on non-core should just make a copy of core for now to check if everything works
  - Remove the debug stuff in RenderTarget when done testing