diff --git a/Source/Engine/Content/AssetReference.h b/Source/Engine/Content/AssetReference.h index 6aee12246..b9d54f30a 100644 --- a/Source/Engine/Content/AssetReference.h +++ b/Source/Engine/Content/AssetReference.h @@ -9,9 +9,6 @@ /// class FLAXENGINE_API AssetReferenceBase { -public: - typedef Delegate<> EventType; - protected: Asset* _asset = nullptr; @@ -19,17 +16,17 @@ public: /// /// The asset loaded event (fired when asset gets loaded or is already loaded after change). /// - EventType Loaded; + Action Loaded; /// /// The asset unloading event (should cleanup refs to it). /// - EventType Unload; + Action Unload; /// /// Action fired when field gets changed (link a new asset or change to the another value). /// - EventType Changed; + Action Changed; public: NON_COPYABLE(AssetReferenceBase); diff --git a/Source/Engine/Graphics/Async/Tasks/GPUCopyResourceTask.h b/Source/Engine/Graphics/Async/Tasks/GPUCopyResourceTask.h index 86c723530..f57327fa4 100644 --- a/Source/Engine/Graphics/Async/Tasks/GPUCopyResourceTask.h +++ b/Source/Engine/Graphics/Async/Tasks/GPUCopyResourceTask.h @@ -26,12 +26,12 @@ public: , _srcResource(src) , _dstResource(dst) { - _srcResource.OnUnload.Bind(this); - _dstResource.OnUnload.Bind(this); + _srcResource.Released.Bind(this); + _dstResource.Released.Bind(this); } private: - void OnResourceUnload(GPUResourceReference* ref) + void OnResourceReleased() { Cancel(); } @@ -47,14 +47,11 @@ protected: // [GPUTask] Result run(GPUTasksContext* context) override { - if (_srcResource.IsMissing() || _dstResource.IsMissing()) + if (!_srcResource || !_dstResource) return Result::MissingResources; - context->GPU->CopyResource(_dstResource, _srcResource); - return Result::Ok; } - void OnEnd() override { _srcResource.Unlink(); diff --git a/Source/Engine/Graphics/Async/Tasks/GPUCopySubresourceTask.h b/Source/Engine/Graphics/Async/Tasks/GPUCopySubresourceTask.h index ab8f1ffad..193eb965d 100644 --- a/Source/Engine/Graphics/Async/Tasks/GPUCopySubresourceTask.h +++ b/Source/Engine/Graphics/Async/Tasks/GPUCopySubresourceTask.h @@ -31,12 +31,12 @@ public: , _srcSubresource(srcSubresource) , _dstSubresource(dstSubresource) { - _srcResource.OnUnload.Bind(this); - _dstResource.OnUnload.Bind(this); + _srcResource.Released.Bind(this); + _dstResource.Released.Bind(this); } private: - void OnResourceUnload(GPUResourceReference* ref) + void OnResourceReleased() { Cancel(); } @@ -52,14 +52,11 @@ protected: // [GPUTask] Result run(GPUTasksContext* context) override { - if (_srcResource.IsMissing() || _dstResource.IsMissing()) + if (!_srcResource || !_dstResource) return Result::MissingResources; - context->GPU->CopySubresource(_dstResource, _dstSubresource, _srcResource, _srcSubresource); - return Result::Ok; } - void OnEnd() override { _srcResource.Unlink(); diff --git a/Source/Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h b/Source/Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h index d2f20449c..3d38ce58b 100644 --- a/Source/Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h +++ b/Source/Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h @@ -31,7 +31,7 @@ public: , _buffer(buffer) , _offset(offset) { - _buffer.OnUnload.Bind(this); + _buffer.Released.Bind(this); if (copyData) _data.Copy(data); @@ -40,7 +40,7 @@ public: } private: - void OnResourceUnload(BufferReference* ref) + void OnResourceReleased() { Cancel(); } @@ -56,14 +56,11 @@ protected: // [GPUTask] Result run(GPUTasksContext* context) override { - if (_buffer.IsMissing()) + if (!_buffer) return Result::MissingResources; - context->GPU->UpdateBuffer(_buffer, _data.Get(), _data.Length(), _offset); - return Result::Ok; } - void OnEnd() override { _buffer.Unlink(); diff --git a/Source/Engine/Graphics/Async/Tasks/GPUUploadTextureMipTask.h b/Source/Engine/Graphics/Async/Tasks/GPUUploadTextureMipTask.h index 6e9cca7fd..2aff3511b 100644 --- a/Source/Engine/Graphics/Async/Tasks/GPUUploadTextureMipTask.h +++ b/Source/Engine/Graphics/Async/Tasks/GPUUploadTextureMipTask.h @@ -35,7 +35,7 @@ public: , _rowPitch(rowPitch) , _slicePitch(slicePitch) { - _texture.OnUnload.Bind(this); + _texture.Released.Bind(this); if (copyData) _data.Copy(data); @@ -44,7 +44,7 @@ public: } private: - void OnResourceUnload(GPUTextureReference* ref) + void OnResourceReleased() { Cancel(); } diff --git a/Source/Engine/Graphics/GPUDevice.cpp b/Source/Engine/Graphics/GPUDevice.cpp index f0056e26c..2a54c7c4d 100644 --- a/Source/Engine/Graphics/GPUDevice.cpp +++ b/Source/Engine/Graphics/GPUDevice.cpp @@ -3,6 +3,7 @@ #include "GPUDevice.h" #include "RenderTargetPool.h" #include "GPUPipelineState.h" +#include "GPUResourceProperty.h" #include "GPUSwapChain.h" #include "RenderTask.h" #include "RenderTools.h" @@ -25,6 +26,39 @@ #include "Engine/Renderer/RenderList.h" #include "Engine/Scripting/Enums.h" +GPUResourcePropertyBase::~GPUResourcePropertyBase() +{ + const auto e = _resource; + if (e) + { + _resource = nullptr; + e->Releasing.Unbind(this); + } +} + +void GPUResourcePropertyBase::OnSet(GPUResource* resource) +{ + auto e = _resource; + if (e != resource) + { + if (e) + e->Releasing.Unbind(this); + _resource = e = resource; + if (e) + e->Releasing.Bind(this); + } +} + +void GPUResourcePropertyBase::OnReleased() +{ + auto e = _resource; + if (e) + { + _resource = nullptr; + e->Releasing.Unbind(this); + } +} + GPUPipelineState* GPUPipelineState::Spawn(const SpawnParams& params) { return GPUDevice::Instance->CreatePipelineState(); diff --git a/Source/Engine/Graphics/GPUResourceProperty.h b/Source/Engine/Graphics/GPUResourceProperty.h index b3c56007d..0b5d73c40 100644 --- a/Source/Engine/Graphics/GPUResourceProperty.h +++ b/Source/Engine/Graphics/GPUResourceProperty.h @@ -8,28 +8,39 @@ /// /// GPU Resource container utility object. /// -template -class GPUResourceProperty +class FLAXENGINE_API GPUResourcePropertyBase { -private: - T* _resource; +protected: + GPUResource* _resource = nullptr; -private: - // Disable copy actions - GPUResourceProperty(const GPUResourceProperty& other) = delete; +public: + NON_COPYABLE(GPUResourcePropertyBase); + + GPUResourcePropertyBase() = default; + ~GPUResourcePropertyBase(); public: /// - /// Action fired when resource gets unloaded (reference gets cleared bu async tasks should stop execution). + /// Action fired when resource gets released (reference gets cleared bu async tasks should stop execution). /// - Delegate OnUnload; + Action Released; +protected: + void OnSet(GPUResource* resource); + void OnReleased(); +}; + +/// +/// GPU Resource container utility object. +/// +template +class GPUResourceProperty : public GPUResourcePropertyBase +{ public: /// /// Initializes a new instance of the class. /// GPUResourceProperty() - : _resource(nullptr) { } @@ -38,9 +49,37 @@ public: /// /// The resource. GPUResourceProperty(T* resource) - : _resource(nullptr) { - Set(resource); + OnSet(resource); + } + + /// + /// Initializes a new instance of the class. + /// + /// The other value. + GPUResourceProperty(const GPUResourceProperty& other) + { + OnSet(other.Get()); + } + + /// + /// Initializes a new instance of the class. + /// + /// The other value. + GPUResourceProperty(GPUResourceProperty&& other) + { + OnSet(other.Get()); + other.OnSet(nullptr); + } + + GPUResourceProperty& operator=(GPUResourceProperty&& other) + { + if (&other != this) + { + OnSet(other._resource); + other.OnSet(nullptr); + } + return *this; } /// @@ -48,13 +87,6 @@ public: /// ~GPUResourceProperty() { - // Check if object has been binded - if (_resource) - { - // Unlink - _resource->Releasing.template Unbind(this); - _resource = nullptr; - } } public: @@ -63,43 +95,34 @@ public: return Get() == other; } - FORCE_INLINE bool operator==(GPUResourceProperty& other) const + FORCE_INLINE bool operator==(const GPUResourceProperty& other) const { return Get() == other.Get(); } - GPUResourceProperty& operator=(const GPUResourceProperty& other) - { - if (this != &other) - Set(other.Get()); - return *this; - } - FORCE_INLINE GPUResourceProperty& operator=(T& other) { - Set(&other); + OnSet(&other); return *this; } FORCE_INLINE GPUResourceProperty& operator=(T* other) { - Set(other); + OnSet(other); return *this; } /// /// Implicit conversion to GPU Resource /// - /// Resource FORCE_INLINE operator T*() const { - return _resource; + return (T*)_resource; } /// /// Implicit conversion to resource /// - /// True if resource has been binded, otherwise false FORCE_INLINE operator bool() const { return _resource != nullptr; @@ -108,37 +131,17 @@ public: /// /// Implicit conversion to resource /// - /// Resource FORCE_INLINE T* operator->() const { - return _resource; + return (T*)_resource; } /// /// Gets linked resource /// - /// Resource FORCE_INLINE T* Get() const { - return _resource; - } - - /// - /// Checks if resource has been binded - /// - /// True if resource has been binded, otherwise false - FORCE_INLINE bool IsBinded() const - { - return _resource != nullptr; - } - - /// - /// Checks if resource is missing - /// - /// True if resource is missing, otherwise false - FORCE_INLINE bool IsMissing() const - { - return _resource == nullptr; + return (T*)_resource; } public: @@ -148,19 +151,7 @@ public: /// Value to assign void Set(T* value) { - if (_resource != value) - { - // Remove reference from the old one - if (_resource) - _resource->Releasing.template Unbind(this); - - // Change referenced object - _resource = value; - - // Add reference to the new one - if (_resource) - _resource->Releasing.template Bind(this); - } + OnSet(value); } /// @@ -168,22 +159,7 @@ public: /// void Unlink() { - if (_resource) - { - // Remove reference from the old one - _resource->Releasing.template Unbind(this); - _resource = nullptr; - } - } - -private: - void onResourceUnload() - { - if (_resource) - { - _resource = nullptr; - OnUnload(this); - } + OnSet(nullptr); } }; diff --git a/Source/Engine/Graphics/Textures/StreamingTexture.cpp b/Source/Engine/Graphics/Textures/StreamingTexture.cpp index e1be01252..173b0ef85 100644 --- a/Source/Engine/Graphics/Textures/StreamingTexture.cpp +++ b/Source/Engine/Graphics/Textures/StreamingTexture.cpp @@ -329,11 +329,11 @@ public: , _dataLock(_streamingTexture->GetOwner()->LockData()) { _streamingTexture->_streamingTasks.Add(this); - _texture.OnUnload.Bind(this); + _texture.Released.Bind(this); } private: - void onResourceUnload2(GPUTextureReference* ref) + void OnResourceReleased2() { // Unlink texture if (_streamingTexture)