From 29ecb3948a340197fbd25aed2abe128507b99de4 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Mon, 4 Oct 2021 16:23:22 +0100 Subject: [PATCH] Blocking out render texture pool API --- .../Private/StevesGameSubsystem.cpp | 20 +++++ .../Private/StevesTextureRenderTargetPool.cpp | 32 +++++++ .../Public/StevesGameSubsystem.h | 14 ++++ .../Public/StevesTextureRenderTargetPool.h | 83 +++++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 Source/StevesUEHelpers/Private/StevesTextureRenderTargetPool.cpp create mode 100644 Source/StevesUEHelpers/Public/StevesTextureRenderTargetPool.h diff --git a/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp b/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp index a71b48c..9fdaf12 100644 --- a/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp +++ b/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp @@ -249,6 +249,26 @@ void UStevesGameSubsystem::SetBrushFromAtlas(FSlateBrush* Brush, TScriptInterfac } } +FStevesTextureRenderTargetPoolPtr UStevesGameSubsystem::GetTextureRenderTargetPool(FName Name, bool bAutoCreate) +{ + // On the assumption there won't be *loads* of pools, not worth a map, just iterate + for (auto Tex : TextureRenderTargetPools) + { + if (Tex->GetPoolName() == Name) + return Tex; + } + + if (bAutoCreate) + { + FStevesTextureRenderTargetPoolPtr Pool = MakeShared(Name); + TextureRenderTargetPools.Add(Pool); + return Pool; + } + + return nullptr; + +} + bool UStevesGameSubsystem::FInputModeDetector::ShouldProcessInputEvents() const { diff --git a/Source/StevesUEHelpers/Private/StevesTextureRenderTargetPool.cpp b/Source/StevesUEHelpers/Private/StevesTextureRenderTargetPool.cpp new file mode 100644 index 0000000..2b3a0c6 --- /dev/null +++ b/Source/StevesUEHelpers/Private/StevesTextureRenderTargetPool.cpp @@ -0,0 +1,32 @@ +#include "StevesTextureRenderTargetPool.h" + +FStevesTextureRenderTargetReservation::~FStevesTextureRenderTargetReservation() +{ + if (Owner.IsValid() && Texture.IsValid()) + { + Owner.Pin()->ReleaseTextureReservation(Texture.Get()); + Texture = nullptr; + } +} + +void FStevesTextureRenderTargetPool::ReleaseTextureReservation(UTextureRenderTarget2D* Tex) +{ + // TODO +} + +FStevesTextureRenderTargetReservationPtr FStevesTextureRenderTargetPool::ReserveTexture(FIntPoint Size, + ETextureRenderTargetFormat Format) +{ + // TODO + return MakeShared(nullptr, this->AsShared()); +} + +void FStevesTextureRenderTargetPool::RevokeAllReservations() +{ + // TODO +} + +void FStevesTextureRenderTargetPool::DrainPool(bool bRevokeReservations) +{ + // TODO +} diff --git a/Source/StevesUEHelpers/Public/StevesGameSubsystem.h b/Source/StevesUEHelpers/Public/StevesGameSubsystem.h index 5ad56ce..d7df976 100644 --- a/Source/StevesUEHelpers/Public/StevesGameSubsystem.h +++ b/Source/StevesUEHelpers/Public/StevesGameSubsystem.h @@ -6,6 +6,7 @@ #include "PaperSprite.h" #include "Framework/Application/IInputProcessor.h" #include "StevesHelperCommon.h" +#include "StevesTextureRenderTargetPool.h" #include "StevesUI/FocusSystem.h" #include "StevesUI/UiTheme.h" @@ -14,6 +15,7 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnInputModeChanged, int, PlayerIndex, EInputMode, InputMode); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnWindowForegroundChanged, bool, bFocussed); +/// Entry point for all the top-level features of the helper system UCLASS(Config=Game) class STEVESUEHELPERS_API UStevesGameSubsystem : public UGameInstanceSubsystem { @@ -109,6 +111,8 @@ protected: UPROPERTY(BlueprintReadWrite) UUiTheme* DefaultUiTheme; + TArray TextureRenderTargetPools; + void CreateInputDetector(); void DestroyInputDetector(); void InitTheme(); @@ -198,4 +202,14 @@ public: static void SetBrushFromAtlas(FSlateBrush* Brush, TScriptInterface AtlasRegion, bool bMatchSize); + + + /** + * Retrieve a pool of texture render targets. If a pool doesn't exist with the given name, it can be created. + * @param Name Identifier for the pool. + * @param bAutoCreate + * @return The pool, or null if it doesn't exist and bAutoCreate is false + */ + FStevesTextureRenderTargetPoolPtr GetTextureRenderTargetPool(FName Name, bool bAutoCreate = true); + }; diff --git a/Source/StevesUEHelpers/Public/StevesTextureRenderTargetPool.h b/Source/StevesUEHelpers/Public/StevesTextureRenderTargetPool.h new file mode 100644 index 0000000..bf7dd22 --- /dev/null +++ b/Source/StevesUEHelpers/Public/StevesTextureRenderTargetPool.h @@ -0,0 +1,83 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Engine/TextureRenderTarget2D.h" + +typedef TSharedPtr FStevesTextureRenderTargetReservationPtr; +typedef TSharedPtr FStevesTextureRenderTargetPoolPtr; + +/// Holder for an assigned texture. While this structure exists, the texture will be considered assigned +/// and will not be returned from any other request. Once this structure is destroyed the texture will +/// be free for re-use. For that reason, only pass this structure around by SharedRef/SharedPtr. +/// The texture is held by a weak pointer however, the strong pointer is held by the pool. The texture will continue +/// to be available to this reservation except if the pool is told to forcibly release textures. +struct STEVESUEHELPERS_API FStevesTextureRenderTargetReservation +{ +public: + /// The texture. May be null if the pool has forcibly reclaimed the texture prematurely + TWeakObjectPtr Texture; + TWeakPtr Owner; + + FStevesTextureRenderTargetReservation() = default; + + FStevesTextureRenderTargetReservation(UTextureRenderTarget2D* InTexture, + FStevesTextureRenderTargetPoolPtr InOwner) + : Texture(InTexture), + Owner(InOwner) + { + } + + ~FStevesTextureRenderTargetReservation(); +}; + + +/** + * 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. + */ +struct STEVESUEHELPERS_API FStevesTextureRenderTargetPool : public TSharedFromThis +{ + +protected: + /// The name of the pool. It's possible to have more than one texture pool. + FName PoolName; + + friend struct FStevesTextureRenderTargetReservation; + /// Release a reservation on a texture, allowing it back into the pool + /// Protected because only FStevesTextureRenderTargetReservation will need to do this. + void ReleaseTextureReservation(UTextureRenderTarget2D* Tex); + +public: + FStevesTextureRenderTargetPool() = default; + + explicit FStevesTextureRenderTargetPool(const FName& PoolName) + : PoolName(PoolName) + { + } + + const FName& GetPoolName() const { return PoolName; } + + /** + * 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 Format Format of the texture + * @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. + */ + FStevesTextureRenderTargetReservationPtr ReserveTexture(FIntPoint Size, ETextureRenderTargetFormat Format); + + /** + * Forcibly revoke all reservations in this pool. Reservations which have been made will have their weak texture + * pointers invalidated. + */ + void RevokeAllReservations(); + + /** + * Destroy previously created textures and free the memory. + * @param bRevokeReservations If false, only destroys unreserved textures. If true, destroys reserved textures + * as well (the weak pointer on their reservations will cease to be valid) + */ + void DrainPool(bool bRevokeReservations = false); + +}; +