Quellcode durchsuchen

Add core object dependencies
Fixing material loading

Marko Pintera vor 11 Jahren
Ursprung
Commit
2026432fe7

+ 5 - 0
BansheeCore/Include/BsCoreObject.h

@@ -230,6 +230,11 @@ namespace BansheeEngine
 		 */
 		virtual void syncFromCore(const CoreSyncData& data) { }
 
+		/**
+		 * @brief	Populates the provided array with all core objects that this core object depends upon.
+		 */
+		virtual void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies) { }
+
 	protected:
 		SPtr<CoreObjectCore> mCoreSpecific;
 	};

+ 5 - 0
BansheeCore/Include/BsFont.h

@@ -84,6 +84,11 @@ namespace BansheeEngine
 
 		Font();
 
+		/**
+		 * @copydoc	CoreObject::getCoreDependencies
+		 */
+		void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
+
 	private:
 		Map<UINT32, FontData> mFontDataPerSize;
 

+ 35 - 11
BansheeCore/Include/BsMaterial.h

@@ -169,17 +169,7 @@ namespace BansheeEngine
 		typedef typename TTechniqueType<Core>::Type TechniqueType;
 		typedef typename TShaderType<Core>::Type ShaderType;
 
-		/**
-		 * @brief	Sets a shader that will be used by the material. Best technique within the
-		 * 			provided shader will be used for the material.
-		 *
-		 * @note	Shader must be set before doing any other operations with the material.
-		 * 			
-		 * 			After setting the shader if change any systems that a shader technique is 
-		 * 			dependent upon (render system, renderer, etc), you will need to call this 
-		 * 			method again on all your Materials to make sure technique used is updated.
-		 */
-		void setShader(ShaderType shader);
+		virtual ~TMaterial() { }
 
 		/**
 		 * @brief	Returns the currently active shader.
@@ -581,6 +571,11 @@ namespace BansheeEngine
 	public:
 		~MaterialCore() { }
 
+		/**
+		 * @copydoc	Material::setShader
+		 */
+		void setShader(const SPtr<ShaderCore>& shader);
+
 		/**
 		 * @brief	Creates a new material with the specified shader.
 		 */
@@ -609,6 +604,18 @@ namespace BansheeEngine
 	public:
 		~Material() { }
 
+		/**
+		 * @brief	Sets a shader that will be used by the material. Best technique within the
+		 * 			provided shader will be used for the material.
+		 *
+		 * @note	Shader must be set before doing any other operations with the material.
+		 * 			
+		 * 			After setting the shader if change any systems that a shader technique is 
+		 * 			dependent upon (render system, renderer, etc), you will need to call this 
+		 * 			method again on all your Materials to make sure technique used is updated.
+		 */
+		void setShader(const HShader& shader);
+
 		/**
 		 * @brief	Retrieves an implementation of a material usable only from the
 		 *			core thread.
@@ -648,6 +655,11 @@ namespace BansheeEngine
 		 */
 		CoreSyncData syncToCore(FrameAlloc* allocator);
 
+		/**
+		 * @copydoc	CoreObject::getCoreDependencies
+		 */
+		void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
+
 		/**
 		 * @copydoc	CoreObject::markCoreDirty
 		 */
@@ -678,6 +690,18 @@ namespace BansheeEngine
 		 */
 		void notifyResourceChanged(const HResource& resource);
 
+		/**
+		 * @brief	Checks if all resources needed for initialization have been loaded.
+		 */
+		bool checkIfDependenciesLoaded() const;
+
+		/**
+		 * @brief	Performs material initialization when all resources are ready.
+		 */
+		void initializeIfLoaded();
+
+		UINT32 mLoadFlags;
+
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/************************************************************************/

+ 5 - 0
BansheeCore/Include/BsPass.h

@@ -225,6 +225,11 @@ namespace BansheeEngine
 		 */
 		SPtr<CoreObjectCore> createCore() const;
 
+		/**
+		 * @copydoc	CoreObject::syncToCore
+		 */
+		void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
+
 		/**
 		 * @copydoc	CoreObject::initialize
 		 */

+ 1 - 0
BansheeCore/Include/BsResources.h

@@ -25,6 +25,7 @@ namespace BansheeEngine
 			HResource resource;
 			ResourcePtr loadedData;
 			UINT32 remainingDependencies;
+			bool notifyImmediately;
 		};
 
 	public:

+ 5 - 0
BansheeCore/Include/BsShader.h

@@ -309,6 +309,11 @@ namespace BansheeEngine
 	private:
 		Shader(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
 
+		/**
+		 * @copydoc	CoreObject::getCoreDependencies
+		 */
+		void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
+
 		/**
 		 * @copydoc	CoreObject::createCore
 		 */

+ 5 - 0
BansheeCore/Include/BsTechnique.h

@@ -110,6 +110,11 @@ namespace BansheeEngine
 		 */
 		SPtr<CoreObjectCore> createCore() const;
 
+		/**
+		 * @copydoc	CoreObject::getCoreDependencies
+		 */
+		void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
+
 		/**
 		 * @brief	Creates a new technique but doesn't initialize it.
 		 */

+ 5 - 0
BansheeCore/Include/BsViewport.h

@@ -257,6 +257,11 @@ namespace BansheeEngine
 		 */
 		CoreSyncData syncToCore(FrameAlloc* allocator);
 
+		/**
+		 * @copydoc	CoreObject::getCoreDependencies
+		 */
+		void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
+
 		/**
 		 * @copydoc	CoreObject::createCore
 		 */

+ 12 - 0
BansheeCore/Source/BsFont.cpp

@@ -83,6 +83,18 @@ namespace BansheeEngine
 		return bestSize;
 	}
 
+	void Font::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
+	{
+		for (auto& fontDataEntry : mFontDataPerSize)
+		{
+			for (auto& texture : fontDataEntry.second.texturePages)
+			{
+				if (texture.isLoaded())
+					dependencies.push_back(texture.getInternalPtr());
+			}
+		}
+	}
+
 	HFont Font::create(const Vector<FontData>& fontData)
 	{
 		FontPtr newFont = _createPtr(fontData);

+ 176 - 46
BansheeCore/Source/BsMaterial.cpp

@@ -24,6 +24,13 @@ namespace BansheeEngine
 		bool create;
 	};
 
+	enum MaterialLoadFlags
+	{
+		Load_None	= 0,
+		Load_Shader	= 1,
+		Load_All	= 2
+	};
+
 	SPtr<PassParametersCore> convertParamsToCore(const SPtr<PassParameters>& passParams)
 	{
 		SPtr<PassParametersCore> passParameters = bs_shared_ptr<PassParametersCore>();
@@ -441,39 +448,6 @@ namespace BansheeEngine
 		return allParamDescs;
 	}
 
-	template<>
-	void TMaterial<true>::setShader(ShaderType shader)
-	{
-		mShader = shader;
-
-		initBestTechnique();
-
-		_markCoreDirty();
-	}
-
-	template<>
-	void TMaterial<false>::setShader(ShaderType shader)
-	{
-		mShader = shader;
-		mBestTechnique = nullptr;
-		_markResourcesDirty();
-
-		if (mShader)
-		{
-			if (!mShader.isLoaded())
-			{
-				LOGWRN("Initializing a material with shader that is not yet loaded. Waiting until load is complete. This will result in a performance hit.");
-				mShader.blockUntilLoaded();
-
-				return; // Return because we rely on the resource listener to trigger initialization after load, so we don't do it twice
-			}
-		}
-
-		initBestTechnique();
-		_markCoreDirty();
-	}
-
-
 	template<bool Core>
 	UINT32 TMaterial<Core>::getNumPasses() const
 	{
@@ -854,6 +828,15 @@ namespace BansheeEngine
 		mParametersPerPass = passParams;
 	}
 
+	void MaterialCore::setShader(const SPtr<ShaderCore>& shader)
+	{
+		mShader = shader;
+
+		initBestTechnique();
+
+		_markCoreDirty();
+	}
+
 	void MaterialCore::syncToCore(const CoreSyncData& data)
 	{
 		char* dataPtr = (char*)data.getBuffer();
@@ -900,9 +883,11 @@ namespace BansheeEngine
 	}
 
 	Material::Material()
+		:mLoadFlags(Load_None)
 	{ }
 
 	Material::Material(const HShader& shader)
+		:mLoadFlags(Load_None)
 	{
 		mShader = shader;
 	}
@@ -914,6 +899,16 @@ namespace BansheeEngine
 		Resource::initialize();
 	}
 
+	void Material::setShader(const HShader& shader)
+	{
+		mShader = shader;
+		mBestTechnique = nullptr;
+		mLoadFlags = Load_None;
+		_markResourcesDirty();
+
+		initializeIfLoaded();
+	}
+
 	void Material::_markCoreDirty()
 	{
 		markCoreDirty();
@@ -1000,37 +995,172 @@ namespace BansheeEngine
 		return CoreSyncData(buffer, size);
 	}
 
+	void Material::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
+	{
+		if (mShader.isLoaded())
+			dependencies.push_back(mShader.getInternalPtr());
+
+		for (auto& params : mParametersPerPass)
+		{
+			UINT32 numParams = params->getNumParams();
+			for (UINT32 i = 0; i < numParams; i++)
+			{
+				GpuParamsPtr gpuParams = params->getParamByIdx(i);
+				if (gpuParams != nullptr)
+					dependencies.push_back(gpuParams);
+			}
+		}
+	}
+
 	void Material::getResourceDependencies(Vector<HResource>& resources)
 	{
 		if (mShader != nullptr)
+		{
 			resources.push_back(mShader);
+
+			if (mShader.isLoaded())
+			{
+				TechniquePtr bestTechnique = mShader->getBestTechnique();
+				if (bestTechnique != nullptr)
+				{
+					UINT32 numPasses = bestTechnique->getNumPasses();
+					for (UINT32 i = 0; i < numPasses; i++)
+					{
+						PassPtr pass = bestTechnique->getPass(i);
+
+						HGpuProgram vertProg = pass->getVertexProgram();
+						if (vertProg != nullptr)
+							resources.push_back(vertProg);
+
+						HGpuProgram fragProg = pass->getFragmentProgram();
+						if (fragProg != nullptr)
+							resources.push_back(fragProg);
+
+						HGpuProgram geomProg = pass->getGeometryProgram();
+						if (geomProg != nullptr)
+							resources.push_back(geomProg);
+
+						HGpuProgram domProg = pass->getDomainProgram();
+						if (domProg != nullptr)
+							resources.push_back(domProg);
+
+						HGpuProgram hullProg = pass->getHullProgram();
+						if (hullProg != nullptr)
+							resources.push_back(hullProg);
+
+						HGpuProgram computeProg = pass->getComputeProgram();
+						if (computeProg != nullptr)
+							resources.push_back(computeProg);
+
+						HBlendState blendState = pass->getBlendState();
+						if (blendState != nullptr)
+							resources.push_back(blendState);
+
+						HRasterizerState rasterizerState = pass->getRasterizerState();
+						if (rasterizerState != nullptr)
+							resources.push_back(rasterizerState);
+
+						HDepthStencilState depthStencilState = pass->getDepthStencilState();
+						if (depthStencilState != nullptr)
+							resources.push_back(depthStencilState);
+					}
+				}
+			}
+		}
 	}
 
-	void Material::notifyResourceLoaded(const HResource& resource)
+	bool Material::checkIfDependenciesLoaded() const
 	{
-		if (mBestTechnique == nullptr)
+		if (mShader == nullptr) // No shader, so everything is technically loaded
+			return true;
+
+		if (!mShader.isLoaded())
+			return false;
+
+		TechniquePtr bestTechnique = mShader->getBestTechnique();
+		if (bestTechnique == nullptr) // No valid technique, so everything is technically loaded
+			return true;
+
+		UINT32 numPasses = bestTechnique->getNumPasses();
+		for (UINT32 i = 0; i < numPasses; i++)
 		{
-			initBestTechnique();
-			markCoreDirty();
+			PassPtr pass = bestTechnique->getPass(i);
+
+			HGpuProgram vertProg = pass->getVertexProgram();
+			if (vertProg != nullptr && !vertProg.isLoaded())
+				return false;
+
+			HGpuProgram fragProg = pass->getFragmentProgram();
+			if (fragProg != nullptr && !fragProg.isLoaded())
+				return false;
+
+			HGpuProgram geomProg = pass->getGeometryProgram();
+			if (geomProg != nullptr && !geomProg.isLoaded())
+				return false;
+
+			HGpuProgram domProg = pass->getDomainProgram();
+			if (domProg != nullptr && !domProg.isLoaded())
+				return false;
+
+			HGpuProgram hullProg = pass->getHullProgram();
+			if (hullProg != nullptr && !hullProg.isLoaded())
+				return false;
+
+			HGpuProgram computeProg = pass->getComputeProgram();
+			if (computeProg != nullptr && !computeProg.isLoaded())
+				return false;
+
+			HBlendState blendState = pass->getBlendState();
+			if (blendState != nullptr && !blendState.isLoaded())
+				return false;
+
+			HRasterizerState rasterizerState = pass->getRasterizerState();
+			if (rasterizerState != nullptr && !rasterizerState.isLoaded())
+				return false;
+
+			HDepthStencilState depthStencilState = pass->getDepthStencilState();
+			if (depthStencilState != nullptr && !depthStencilState.isLoaded())
+				return false;
 		}
+
+		return true;
 	}
 
-	void Material::notifyResourceDestroyed(const HResource& resource)
+	void Material::initializeIfLoaded()
 	{
-		if (mBestTechnique == nullptr)
+		if (checkIfDependenciesLoaded())
+		{
+			if (mLoadFlags != Load_All)
+			{
+				mLoadFlags = Load_All;
+
+				initBestTechnique();
+				markCoreDirty();
+			}
+		}
+		else
 		{
-			initBestTechnique();
-			markCoreDirty();
+			if (mShader.isLoaded() && mLoadFlags == Load_None)
+			{
+				mLoadFlags = Load_Shader;
+				markResourcesDirty(); // Need to register resources dependent on shader now
+			}
 		}
 	}
 
+	void Material::notifyResourceLoaded(const HResource& resource)
+	{
+		initializeIfLoaded();
+	}
+
+	void Material::notifyResourceDestroyed(const HResource& resource)
+	{
+		initializeIfLoaded();
+	}
+
 	void Material::notifyResourceChanged(const HResource& resource)
 	{
-		if (mBestTechnique == nullptr)
-		{
-			initBestTechnique();
-			markCoreDirty();
-		}
+		initializeIfLoaded();
 	}
 
 	HMaterial Material::create()

+ 30 - 0
BansheeCore/Source/BsPass.cpp

@@ -136,6 +136,36 @@ namespace BansheeEngine
 		markResourcesDirty();
 	}
 
+	void Pass::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
+	{
+		if (mData.blendState.isLoaded())
+			dependencies.push_back(mData.blendState.getInternalPtr());
+
+		if (mData.rasterizerState.isLoaded())
+			dependencies.push_back(mData.rasterizerState.getInternalPtr());
+
+		if (mData.depthStencilState.isLoaded())
+			dependencies.push_back(mData.depthStencilState.getInternalPtr());
+
+		if (mData.vertexProgram.isLoaded())
+			dependencies.push_back(mData.vertexProgram.getInternalPtr());
+
+		if (mData.fragmentProgram.isLoaded())
+			dependencies.push_back(mData.fragmentProgram.getInternalPtr());
+
+		if (mData.geometryProgram.isLoaded())
+			dependencies.push_back(mData.geometryProgram.getInternalPtr());
+
+		if (mData.hullProgram.isLoaded())
+			dependencies.push_back(mData.hullProgram.getInternalPtr());
+
+		if (mData.domainProgram.isLoaded())
+			dependencies.push_back(mData.domainProgram.getInternalPtr());
+
+		if (mData.computeProgram.isLoaded())
+			dependencies.push_back(mData.computeProgram.getInternalPtr());
+	}
+
 	void Pass::getResourceDependencies(Vector<HResource>& resources)
 	{
 		if (mData.blendState != nullptr)

+ 9 - 4
BansheeCore/Source/BsResources.cpp

@@ -10,6 +10,7 @@
 #include "BsDebug.h"
 #include "BsUtility.h"
 #include "BsSavedResourceData.h"
+#include "BsResourceListenerManager.h"
 
 namespace BansheeEngine
 {
@@ -143,6 +144,7 @@ namespace BansheeEngine
 			mInProgressResources[uuid] = loadData;
 			loadData->resource = outputResource;
 			loadData->remainingDependencies = 1;
+			loadData->notifyImmediately = synchronous; // Make resource listener trigger before exit if loading synchronously
 
 			for (auto& dependency : savedResourceData->getDependencies())
 			{
@@ -212,7 +214,7 @@ namespace BansheeEngine
 			resource.blockUntilLoaded();
 		}
 
-		Vector<ResourceDependency> dependencies = Utility::findResourceDependencies(*resource.get(), false);
+		Vector<ResourceDependency> dependencies = Utility::findResourceDependencies(*resource.get());
 
 		// Call this before we actually destroy it
 		onResourceDestroyed(resource);
@@ -280,7 +282,7 @@ namespace BansheeEngine
 
 		mDefaultResourceManifest->registerResource(resource.getUUID(), filePath);
 
-		Vector<ResourceDependency> dependencyList = Utility::findResourceDependencies(*resource.get(), false);
+		Vector<ResourceDependency> dependencyList = Utility::findResourceDependencies(*resource.get());
 
 		Vector<String> dependencyUUIDs(dependencyList.size());
 		for (UINT32 i = 0; i < (UINT32)dependencyList.size(); i++)
@@ -398,12 +400,15 @@ namespace BansheeEngine
 		{
 			{
 				BS_LOCK_MUTEX(mLoadedResourceMutex);
-				mLoadedResources[resource.getUUID()] = resource;
+				mLoadedResources[uuid] = resource;
 			}
 
-			resource._setHandleData(myLoadData->loadedData, resource.getUUID());
+			resource._setHandleData(myLoadData->loadedData, uuid);
 			onResourceLoaded(resource);
 
+			if (myLoadData->notifyImmediately)
+				ResourceListenerManager::instance().notifyListeners(uuid);
+
 			bs_delete(myLoadData);
 		}
 

+ 6 - 0
BansheeCore/Source/BsShader.cpp

@@ -198,6 +198,12 @@ namespace BansheeEngine
 		return shaderCorePtr;
 	}
 
+	void Shader::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
+	{
+		for (auto& technique : mTechniques)
+			dependencies.push_back(technique);
+	}
+
 	bool Shader::isSampler(GpuParamObjectType type)
 	{
 		switch(type)

+ 6 - 0
BansheeCore/Source/BsTechnique.cpp

@@ -89,6 +89,12 @@ namespace BansheeEngine
 		return techniquePtr;
 	}
 
+	void Technique::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
+	{
+		for (auto& pass : mPasses)
+			dependencies.push_back(pass);
+	}
+
 	TechniquePtr Technique::create(const String& renderSystem, const String& renderer, const Vector<SPtr<Pass>>& passes)
 	{
 		Technique* technique = new (bs_alloc<Technique>()) Technique(renderSystem, renderer, passes);

+ 6 - 0
BansheeCore/Source/BsViewport.cpp

@@ -200,6 +200,12 @@ namespace BansheeEngine
 		return CoreSyncData(buffer, size);
 	}
 
+	void Viewport::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
+	{
+		if (mTarget != nullptr)
+			dependencies.push_back(mTarget);
+	}
+
 	ViewportPtr Viewport::create(const RenderTargetPtr& target, float x, float y, float width, float height)
 	{
 		Viewport* viewport = new (bs_alloc<Viewport>()) Viewport(target, x, y, width, height);

+ 5 - 0
BansheeEngine/Include/BsCameraHandler.h

@@ -576,6 +576,11 @@ namespace BansheeEngine
 		 */
 		CoreSyncData syncToCore(FrameAlloc* allocator);
 
+		/**
+		 * @copydoc	CoreObject::getCoreDependencies
+		 */
+		void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
+
 		/**
 		 * @brief	Creates a new camera without initializing it.
 		 */

+ 5 - 0
BansheeEngine/Include/BsRenderableHandler.h

@@ -228,6 +228,11 @@ namespace BansheeEngine
 		 */
 		CoreSyncData syncToCore(FrameAlloc* allocator);
 
+		/**
+		 * @copydoc	CoreObject::getCoreDependencies
+		 */
+		void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
+
 		/**
 		 * @copydoc	IResourceListener::getResourceDependencies
 		 */

+ 5 - 0
BansheeEngine/Include/BsSpriteTexture.h

@@ -64,6 +64,11 @@ namespace BansheeEngine
 		 */
 		SpriteTexture(const Vector2& uvOffset, const Vector2& uvScale, const HTexture& texture);
 
+		/**
+		 * @copydoc	CoreObject::getCoreDependencies
+		 */
+		void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
+
 		HTexture mAtlasTexture;
 		Vector2 mUVOffset;
 		Vector2 mUVScale;

+ 5 - 0
BansheeEngine/Source/BsCameraHandler.cpp

@@ -816,6 +816,11 @@ namespace BansheeEngine
 		return CoreSyncData(buffer, size);
 	}
 
+	void CameraHandler::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
+	{
+		dependencies.push_back(mViewport);
+	}
+
 	void CameraHandler::_markCoreDirty()
 	{
 		markCoreDirty();

+ 12 - 0
BansheeEngine/Source/BsRenderableHandler.cpp

@@ -263,6 +263,18 @@ namespace BansheeEngine
 		return CoreSyncData(data, size);
 	}
 
+	void RenderableHandler::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
+	{
+		if (mMesh.isLoaded())
+			dependencies.push_back(mMesh.getInternalPtr());
+
+		for (auto& material : mMaterials)
+		{
+			if (material.isLoaded())
+				dependencies.push_back(material.getInternalPtr());
+		}
+	}
+
 	void RenderableHandler::getResourceDependencies(Vector<HResource>& resources)
 	{
 		if (mMesh != nullptr)

+ 6 - 0
BansheeEngine/Source/BsSpriteTexture.cpp

@@ -43,6 +43,12 @@ namespace BansheeEngine
 		return Math::roundToInt(mAtlasTexture->getProperties().getHeight() * mUVScale.y);
 	}
 
+	void SpriteTexture::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
+	{
+		if (mAtlasTexture.isLoaded())
+			dependencies.push_back(mAtlasTexture.getInternalPtr());
+	}
+
 	HSpriteTexture SpriteTexture::create(const HTexture& texture)
 	{
 		SpriteTexturePtr texturePtr = bs_core_ptr<SpriteTexture, PoolAlloc>

+ 12 - 7
TODO.txt

@@ -7,13 +7,18 @@ ManagedSerializeArray::deserializeManagedInstance were reported as ManagedSerial
 It's inconsistent to reproduce but started happening after I have modified managed object serialization to be on-demand. It's possibly
 related to lambdas not capturing types as I expect them to. It always happens in the same place.
 
-TODO - Material waits to Shader to be loaded but doesn't wait for shader GpuPrograms or state objects.
- - What's the best way to ensure initialization is done when all these are loaded?
-
-TODO - Material loading issue. Deserializing a material will still call initialize() which will block until shader is loaded.
- - I should instead wait until everything is loaded before initializing the material. (e.g. when I want to load the material async
-   I shouldn't be blocking.)
-   - Remove call to initialize() in MaterialRTTI and instead add ResourceListener call to Resources?
+Keep the sync internal to CoreObjectManager
+Add a new public syncToCore method that accepts a core accessor (possibly make it part of CoreObjectManager, to keep things consistent with method described below)
+ - It only syncs that specific object and all the children
+ - getCoreDependencies to get children
+Rename syncUpload, syncDownload to syncToCore
+ - It will sync all objects as it does now, no change
+Add syncToCore for GpuParams when binding them from sim thread
+Possibly remove syncFromCore and replace it with custom managers
+ - Remove mesh bounds sync completely
+ - Remove render target sync (priority and active state)
+   - Remove RenderTargetCore::setPriority and make active state window only
+ - Move anything render target related to RenderWindowManager
 
 I can get mono errors by checking g_print calls in goutput.c
  - Calling thunks incorrectly can cause those weird errors with no real callstack