Track owners of reservations in the pool

This commit is contained in:
Steve Streeting 2021-10-05 14:30:40 +01:00
parent 0a49f5cf74
commit 642c8d2781
3 changed files with 53 additions and 24 deletions

View File

@ -254,13 +254,13 @@ FStevesTextureRenderTargetPoolPtr UStevesGameSubsystem::GetTextureRenderTargetPo
// On the assumption there won't be *loads* of pools, not worth a map, just iterate // On the assumption there won't be *loads* of pools, not worth a map, just iterate
for (auto Tex : TextureRenderTargetPools) for (auto Tex : TextureRenderTargetPools)
{ {
if (Tex->GetPoolName() == Name) if (Tex->GetName() == Name)
return Tex; return Tex;
} }
if (bAutoCreate) if (bAutoCreate)
{ {
FStevesTextureRenderTargetPoolPtr Pool = MakeShared<FStevesTextureRenderTargetPool>(Name); FStevesTextureRenderTargetPoolPtr Pool = MakeShared<FStevesTextureRenderTargetPool>(Name, this);
TextureRenderTargetPools.Add(Pool); TextureRenderTargetPools.Add(Pool);
return Pool; return Pool;
} }

View File

@ -2,9 +2,10 @@
FStevesTextureRenderTargetReservation::~FStevesTextureRenderTargetReservation() FStevesTextureRenderTargetReservation::~FStevesTextureRenderTargetReservation()
{ {
if (Owner.IsValid() && Texture.IsValid()) UE_LOG(LogTemp, Warning, TEXT("Releasing texture reservation"));
if (ParentPool.IsValid() && Texture.IsValid())
{ {
Owner.Pin()->ReleaseTextureReservation(Texture.Get()); ParentPool.Pin()->ReleaseTextureReservation(Texture.Get());
Texture = nullptr; Texture = nullptr;
} }
} }
@ -15,18 +16,18 @@ void FStevesTextureRenderTargetPool::ReleaseTextureReservation(UTextureRenderTar
} }
FStevesTextureRenderTargetReservationPtr FStevesTextureRenderTargetPool::ReserveTexture(FIntPoint Size, FStevesTextureRenderTargetReservationPtr FStevesTextureRenderTargetPool::ReserveTexture(FIntPoint Size,
ETextureRenderTargetFormat Format) ETextureRenderTargetFormat Format, const UObject* Owner)
{ {
// TODO // TODO
return MakeShared<FStevesTextureRenderTargetReservation>(nullptr, this->AsShared()); return MakeShared<FStevesTextureRenderTargetReservation>(nullptr, this->AsShared());
} }
void FStevesTextureRenderTargetPool::RevokeAllReservations() void FStevesTextureRenderTargetPool::RevokeReservations(const UObject* ForOwner)
{ {
// TODO // TODO
} }
void FStevesTextureRenderTargetPool::DrainPool(bool bRevokeReservations) void FStevesTextureRenderTargetPool::DrainPool(bool bForceAndRevokeReservations)
{ {
// TODO // TODO
} }

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Chaos/AABB.h"
#include "Chaos/AABB.h"
#include "Engine/TextureRenderTarget2D.h" #include "Engine/TextureRenderTarget2D.h"
typedef TSharedPtr<struct FStevesTextureRenderTargetReservation> FStevesTextureRenderTargetReservationPtr; typedef TSharedPtr<struct FStevesTextureRenderTargetReservation> FStevesTextureRenderTargetReservationPtr;
@ -16,14 +18,18 @@ struct STEVESUEHELPERS_API FStevesTextureRenderTargetReservation
public: public:
/// The texture. May be null if the pool has forcibly reclaimed the texture prematurely /// The texture. May be null if the pool has forcibly reclaimed the texture prematurely
TWeakObjectPtr<UTextureRenderTarget2D> Texture; TWeakObjectPtr<UTextureRenderTarget2D> Texture;
TWeakPtr<struct FStevesTextureRenderTargetPool> Owner; TWeakPtr<struct FStevesTextureRenderTargetPool> ParentPool;
TWeakObjectPtr<const UObject> CurrentOwner;
FStevesTextureRenderTargetReservation() = default; FStevesTextureRenderTargetReservation() = default;
FStevesTextureRenderTargetReservation(UTextureRenderTarget2D* InTexture, FStevesTextureRenderTargetReservation(UTextureRenderTarget2D* InTexture,
FStevesTextureRenderTargetPoolPtr InOwner) FStevesTextureRenderTargetPoolPtr InParent,
const UObject* InOwner)
: Texture(InTexture), : Texture(InTexture),
Owner(InOwner) ParentPool(InParent),
CurrentOwner(InOwner)
{ {
} }
@ -34,13 +40,15 @@ public:
/** /**
* A pool of render target textures. To save pre-creating render textures as assets, and to control the re-use of * A pool of render target textures. To save pre-creating render textures as assets, and to control the re-use of
* these textures at runtime. * these textures at runtime.
* A pool needs to be owned by a UObject, which will in turn own the textures and so will ultimately control the
* ultimate lifecycle of textures if not released specifically.
*/ */
struct STEVESUEHELPERS_API FStevesTextureRenderTargetPool : public TSharedFromThis<FStevesTextureRenderTargetPool> struct STEVESUEHELPERS_API FStevesTextureRenderTargetPool : public TSharedFromThis<FStevesTextureRenderTargetPool>
{ {
protected: protected:
/// The name of the pool. It's possible to have more than one texture pool. /// The name of the pool. It's possible to have more than one texture pool.
FName PoolName; FName Name;
struct FTextureKey struct FTextureKey
{ {
@ -65,8 +73,24 @@ protected:
}; };
TMultiMap<FTextureKey, TSharedPtr<UTextureRenderTarget2D>> UnreservedTextures; TWeakObjectPtr<UObject> PoolOwner;
TArray<TSharedPtr<UTextureRenderTarget2D>> ReservedTextures; TMultiMap<FTextureKey, UTextureRenderTarget2D*> UnreservedTextures;
/// Weak reverse tracking of reservations, mostly for debugging
struct FReservationInfo
{
FTextureKey Key;
TWeakObjectPtr<const UObject> Owner;
TWeakObjectPtr<UTextureRenderTarget2D> Texture;
FReservationInfo(const FTextureKey& InKey, const UObject* InOwner, UTextureRenderTarget2D* InTexture)
: Key(InKey),
Owner(InOwner),
Texture(InTexture)
{
}
};
TArray<FReservationInfo> Reservations;
friend struct FStevesTextureRenderTargetReservation; friend struct FStevesTextureRenderTargetReservation;
@ -75,36 +99,40 @@ protected:
void ReleaseTextureReservation(UTextureRenderTarget2D* Tex); void ReleaseTextureReservation(UTextureRenderTarget2D* Tex);
public: public:
FStevesTextureRenderTargetPool() = default;
explicit FStevesTextureRenderTargetPool(const FName& PoolName) explicit FStevesTextureRenderTargetPool(const FName& InName, UObject* InOwner)
: PoolName(PoolName) : Name(InName), PoolOwner(InOwner)
{ {
} }
const FName& GetPoolName() const { return PoolName; } const FName& GetName() const { return Name; }
/** /**
* Reserve a texture for use as a render target. This will create a new texture target if needed. * Reserve a texture for use as a render target. This will create a new texture target if needed.
* @param Size The dimensions of the texture * @param Size The dimensions of the texture
* @param Format Format of the texture * @param Format Format of the texture
* @param Owner The UObject which will temporarily own this texture (mostly for debugging, this object won't in fact "own" it
* as per garbage collection rules, the reference is weak
* @return A shared pointer to a structure which holds the reservation for this texture. When that structure is * @return A shared pointer to a structure which holds the reservation for this texture. When that structure is
* destroyed, it will release the texture back to the pool. * destroyed, it will release the texture back to the pool.
*/ */
FStevesTextureRenderTargetReservationPtr ReserveTexture(FIntPoint Size, ETextureRenderTargetFormat Format); FStevesTextureRenderTargetReservationPtr ReserveTexture(FIntPoint Size, ETextureRenderTargetFormat Format, const UObject* Owner);
/** /**
* Forcibly revoke all reservations in this pool. Reservations which have been made will have their weak texture * Forcibly revoke reservations in this pool, either for all owners or for a specific owner.
* pointers invalidated. * Reservations which are revoked will have their weak texture pointers invalidated.
* @param ForOwner If null, revoke all reservations for any owner, or if provided, just for a specific owner.
*/ */
void RevokeAllReservations(); void RevokeReservations(const UObject* ForOwner = nullptr);
/** /**
*
* Destroy previously created textures and free the memory. * Destroy previously created textures and free the memory.
* @param bRevokeReservations If false, only destroys unreserved textures. If true, destroys reserved textures * @param bForceAndRevokeReservations If false, only destroys unreserved textures. If true, destroys reserved textures
* as well (the weak pointer on their reservations will cease to be valid) * as well (the weak pointer on their reservations will cease to be valid)
*/ */
void DrainPool(bool bRevokeReservations = false); void DrainPool(bool bForceAndRevokeReservations = false);
}; };