Fixed cached resource handles getting invalid after reloading texture resources.

This commit is contained in:
Sebastian 2021-04-15 21:30:53 -04:00
parent 9f41d0906e
commit e00a133617
3 changed files with 24 additions and 11 deletions

View File

@ -8,6 +8,7 @@ Change History
Version: 1.22 (2021/04) Version: 1.22 (2021/04)
- Fixed potential for initialization fiasco when using delegates container. - Fixed potential for initialization fiasco when using delegates container.
- Fixed bug in code protecting redirecting handles from self-referencing. - Fixed bug in code protecting redirecting handles from self-referencing.
- Fixed cached resource handles getting invalid after reloading texture resources.
Version: 1.21 (2020/07-09) Version: 1.21 (2020/07-09)
Improving stability Improving stability

View File

@ -125,7 +125,7 @@ FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* I
// Create brush and resource handle for input texture. // Create brush and resource handle for input texture.
Brush.SetResourceObject(InTexture); Brush.SetResourceObject(InTexture);
ResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush); CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
} }
FTextureManager::FTextureEntry::~FTextureEntry() FTextureManager::FTextureEntry::~FTextureEntry()
@ -142,7 +142,7 @@ FTextureManager::FTextureEntry& FTextureManager::FTextureEntry::operator=(FTextu
Name = MoveTemp(Other.Name); Name = MoveTemp(Other.Name);
Texture = MoveTemp(Other.Texture); Texture = MoveTemp(Other.Texture);
Brush = MoveTemp(Other.Brush); Brush = MoveTemp(Other.Brush);
ResourceHandle = MoveTemp(Other.ResourceHandle); CachedResourceHandle = MoveTemp(Other.CachedResourceHandle);
// Reset the other entry (without releasing resources which are already moved to this instance) to remove tracks // Reset the other entry (without releasing resources which are already moved to this instance) to remove tracks
// of ownership and mark it as empty/reusable. // of ownership and mark it as empty/reusable.
@ -151,6 +151,15 @@ FTextureManager::FTextureEntry& FTextureManager::FTextureEntry::operator=(FTextu
return *this; return *this;
} }
const FSlateResourceHandle& FTextureManager::FTextureEntry::GetResourceHandle() const
{
if (!CachedResourceHandle.IsValid() && Brush.HasUObject())
{
CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
}
return CachedResourceHandle;
}
void FTextureManager::FTextureEntry::Reset(bool bReleaseResources) void FTextureManager::FTextureEntry::Reset(bool bReleaseResources)
{ {
if (bReleaseResources) if (bReleaseResources)
@ -175,5 +184,5 @@ void FTextureManager::FTextureEntry::Reset(bool bReleaseResources)
// Clean fields to make sure that we don't reference released or moved resources. // Clean fields to make sure that we don't reference released or moved resources.
Texture.Reset(); Texture.Reset();
Brush = FSlateNoResource(); Brush = FSlateNoResource();
ResourceHandle = FSlateResourceHandle(); CachedResourceHandle = FSlateResourceHandle();
} }

View File

@ -41,7 +41,7 @@ public:
// @returns The index of a texture with given name or INDEX_NONE if there is no such texture // @returns The index of a texture with given name or INDEX_NONE if there is no such texture
TextureIndex FindTextureIndex(const FName& Name) const TextureIndex FindTextureIndex(const FName& Name) const
{ {
return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.Name == Name; }); return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.GetName() == Name; });
} }
// Get the name of a texture at given index. Returns NAME_None, if index is out of range. // Get the name of a texture at given index. Returns NAME_None, if index is out of range.
@ -49,7 +49,7 @@ public:
// @returns The name of a texture at given index or NAME_None if index is out of range. // @returns The name of a texture at given index or NAME_None if index is out of range.
FName GetTextureName(TextureIndex Index) const FName GetTextureName(TextureIndex Index) const
{ {
return IsInRange(Index) ? TextureResources[Index].Name : NAME_None; return IsInRange(Index) ? TextureResources[Index].GetName() : NAME_None;
} }
// Get the Slate Resource Handle to a texture at given index. If index is out of range or resources are not valid // Get the Slate Resource Handle to a texture at given index. If index is out of range or resources are not valid
@ -59,7 +59,7 @@ public:
// found at given index // found at given index
const FSlateResourceHandle& GetTextureHandle(TextureIndex Index) const const FSlateResourceHandle& GetTextureHandle(TextureIndex Index) const
{ {
return IsValidTexture(Index) ? TextureResources[Index].ResourceHandle : ErrorTexture.ResourceHandle; return IsValidTexture(Index) ? TextureResources[Index].GetResourceHandle() : ErrorTexture.GetResourceHandle();
} }
// Create a texture from raw data. // Create a texture from raw data.
@ -118,7 +118,7 @@ private:
// Check whether index is in range and whether texture resources are valid (using NAME_None sentinel). // Check whether index is in range and whether texture resources are valid (using NAME_None sentinel).
FORCEINLINE bool IsValidTexture(TextureIndex Index) const FORCEINLINE bool IsValidTexture(TextureIndex Index) const
{ {
return IsInRange(Index) && TextureResources[Index].Name != NAME_None; return IsInRange(Index) && TextureResources[Index].GetName() != NAME_None;
} }
// Entry for texture resources. Only supports explicit construction. // Entry for texture resources. Only supports explicit construction.
@ -137,14 +137,17 @@ private:
// ... but we need move assignment to support reusing entries. // ... but we need move assignment to support reusing entries.
FTextureEntry& operator=(FTextureEntry&& Other); FTextureEntry& operator=(FTextureEntry&& Other);
FName Name = NAME_None; const FName& GetName() const { return Name; }
TWeakObjectPtr<UTexture2D> Texture; const FSlateResourceHandle& GetResourceHandle() const;
FSlateBrush Brush;
FSlateResourceHandle ResourceHandle;
private: private:
void Reset(bool bReleaseResources); void Reset(bool bReleaseResources);
FName Name = NAME_None;
mutable FSlateResourceHandle CachedResourceHandle;
TWeakObjectPtr<UTexture2D> Texture;
FSlateBrush Brush;
}; };
TArray<FTextureEntry> TextureResources; TArray<FTextureEntry> TextureResources;