Files
2025-05-18 13:04:45 +08:00

201 lines
8.7 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "RawBuffer.h"
#include "Device/DeviceBuffer.h"
#include "BlobRef.h"
#include "Helper/DataUtil.h"
#include "2D/TextureHelper.h"
class Device;
class RawBuffer;
class BlobTransform;
class Blobber;
struct ResourceBindInfo;
typedef TUniqueFunction<void(const Blob*)> BlobReadyCallback;
typedef cti::continuable<const Blob*> AsyncBlobResultPtr;
typedef std::shared_ptr<Blob> BlobPtr;
typedef std::unique_ptr<Blob> BlobUPtr;
typedef std::weak_ptr<Blob> BlobPtrW;
typedef std::vector<BlobPtr> BlobPtrVec;
typedef std::vector<BlobPtrW> BlobPtrWVec;
#if DEBUG_BLOB_REF_KEEPING == 1
struct DebugBlobLock
{
public:
DebugBlobLock();
~DebugBlobLock();
};
#endif
class TEXTUREGRAPHENGINE_API Blob : public std::enable_shared_from_this<Blob>
{
friend class Blobber;
friend class TiledBlob;
friend class TiledBlob_Promise;
public:
static const char* LODTransformName;
typedef std::vector<BlobPtrW> OwnerList;
typedef std::vector<std::weak_ptr<Blob>> LinkedBlobsVec;
protected:
DeviceBufferRef Buffer; /// Device buffer that is attached to this blob
bool bIsFinalised = false; /// Whether the promise has been finalised or not
int32 ReplayCount = 0; /// For debug purpose, Incremented when replaying a job and regenerating the content of the blob.
FDateTime FinaliseTS = FDateTime::Now(); /// Time when the blob was finalised
BlobPtrWVec LODLevels; /// The mip chain for this blob (for textures). Can also be Mesh data with fewer triangles etc. Doesn't matter to us
BlobPtr MinMax; /// The blob that's used for calculating min/max
std::shared_ptr<float> MinValue; /// Extracted min value (this is not always present)
std::shared_ptr<float> MaxValue; /// Extracted min value (this is not always present)
BlobPtr Histogram; /// The blob that's used for storing histogram data. not always have a histogram only created when required.
BlobPtrW LODParent; /// The parent of this blob. Essentially the blob that was used to generate THIS lod Level
BlobPtrW LODSource; /// The original source of this blob, the mip Level 0
bool bIsLODLevel = false; /// Whether this blob already represents an LOD'd blob
LinkedBlobsVec LinkedBlobs; /// Blobs that are linked to this tiled blob. These are objects that are
/// uniquely created within the system but eventually resolve to the same
/// tiled blob. We need to ensure that these are resolved correctly
/// so that if some object is holding a pointer to a particular TiledBlob_Promise
/// it gets the same view upon the completion.
/// This is usually very uncommon with Blobs but more of a possibility with TiledBlob_Promise
/// but we need to ensure that it works correctly for all blobs
#if DEBUG_BLOB_REF_KEEPING == 1
OwnerList _owners; /// The TiledBlobs that contain this blob as a tile
virtual void AddTiledOwner(BlobPtrW owner);
#endif
Blob();
virtual void OnFinaliseInternal(BlobReadyCallback callback) const;
virtual void ResetBuffer();
virtual void Touch(uint64 BatchId);
virtual void UpdateAccessInfo(uint64 batchId);
virtual void SetHash(CHashPtr Hash);
virtual void UpdateLinkedBlobs(bool bDoFinalise);
virtual void AddLinkedBlob(BlobPtr LinkedBlob);
virtual void FinaliseFrom(Blob* RHS);
virtual void SyncWith(Blob* RHS);
public:
Blob(DeviceBufferRef InBuffer);
Blob(const BufferDescriptor& InDesc, CHashPtr InHash);
Blob(const Blob& InBlob) = delete; /// non-copyable
virtual ~Blob();
virtual AsyncBufferResultPtr Bind(const BlobTransform* Transform, const ResourceBindInfo& BindInfo);
virtual AsyncBufferResultPtr Unbind(const BlobTransform* Transform, const ResourceBindInfo& BindInfo);
virtual bool IsValid() const;
virtual bool IsNull() const;
virtual CHashPtr Hash() const;
//virtual void SetHash(CHashPtr hash);
virtual AsyncBufferResultPtr Flush(const ResourceBindInfo& BindInfo);
virtual AsyncPrepareResult PrepareForWrite(const ResourceBindInfo& BindInfo);
#if 0 /// TODO /// Do we really need this?
virtual AsyncBufferResultPtr PrepareForWrite(const ResourceBindInfo& BindInfo);
#endif
virtual FString DisplayName() const;
virtual bool IsFinalised() const { return bIsFinalised; }
virtual bool IsTiled() const { return false; }
virtual bool CanCalculateHash() const { return IsFinalised(); }
virtual void FinaliseNow(bool bNoCalcHash, CHashPtr FixedHash);
virtual AsyncBufferResultPtr Finalise(bool bNoCalcHash, CHashPtr FixedHash);
virtual AsyncRawBufferPtr Raw(); /// SLOW: Read doc for DeviceBuffer::Raw() in DeviceBuffer.h
virtual AscynCHashPtr CalcHash(); /// SLOW: Because calls Raw() underneath. Don't use directly
virtual FString& Name() { check(Buffer); return Buffer->GetName(); }
virtual const FString& Name() const { check(Buffer); return Buffer->GetName(); }
virtual const BufferDescriptor& GetDescriptor() const { /*check(_buffer);*/ return Buffer->Descriptor(); }
virtual AsyncBlobResultPtr OnFinalise() const;
virtual AsyncDeviceBufferRef TransferTo(Device* TargetDevice);
virtual DeviceBufferRef GetBufferRef() const;
//////////////////////////////////////////////////////////////////////////
/// Min/Max related
//////////////////////////////////////////////////////////////////////////
virtual BlobPtr GetMinMaxBlob();
virtual void SetMinMax(BlobPtr InMinMax);
virtual float GetMinValue() const;
virtual float GetMaxValue() const;
virtual bool HasMinMax() const;
//////////////////////////////////////////////////////////////////////////
/// LOD/MipMaps related
//////////////////////////////////////////////////////////////////////////
virtual BlobPtrW GetLODLevel(int32 Level);
virtual bool HasLODLevels() const;
virtual bool HasLODLevel(int32 Index) const;
virtual int32 NumLODLevels() const;
virtual void SetLODLevel(int32 Level, BlobPtr LODBlob, BlobPtrW LODParentBlob, BlobPtrW LODSourceBlob, bool bAddToBlobber);
BlobPtr GetHistogram() const;
//////////////////////////////////////////////////////////////////////////
/// Ownership related
//////////////////////////////////////////////////////////////////////////
#if DEBUG_BLOB_REF_KEEPING == 1
virtual void AddOwner(BlobPtrW owner);
virtual void RemoveOwner(BlobPtrW owner);
void RemoveOwner(Blob* owner);
virtual bool HasOwner(BlobPtrW owner);
bool HasOwner(Blob* owner);
virtual OwnerList::iterator FindOwner(BlobPtrW owner);
OwnerList::iterator FindOwner(Blob* owner);
virtual bool HasBlobAsTile(Blob* blob) const { return false; };
#endif
//////////////////////////////////////////////////////////////////////////
/// Inline function
//////////////////////////////////////////////////////////////////////////
FORCEINLINE uint32 GetWidth() const { return GetDescriptor().Width; }
FORCEINLINE uint32 GetHeight() const { return GetDescriptor().Height; }
FORCEINLINE bool IsWellDefined() { return !IsLateBound() && GetWidth() > 0 && GetHeight() > 0; }
//FORCEINLINE const DeviceBufferRef& Buffer() const { return _buffer; }
FORCEINLINE DeviceType GetDeviceType() const { return Buffer.GetDeviceType(); }
FORCEINLINE int32 GetReplayCount() const { return ReplayCount; } /// For debug purpose, report the replay number
FORCEINLINE const FDateTime& FinaliseTimestamp() const { return FinaliseTS; }
FORCEINLINE bool IsLateBound() const { return GetDescriptor().Format == BufferFormat::LateBound; }
FORCEINLINE BlobPtrW GetLODParent() const { return LODParent; }
FORCEINLINE BlobPtrW GetLODSource() const { return LODSource; }
FORCEINLINE bool IsLODLevel() const { return bIsLODLevel; }
FORCEINLINE bool IsTransient() const
{
bool TransientBuffer = false;
if (Buffer && !Buffer.IsValid())
TransientBuffer = Buffer->IsTransient();
return TransientBuffer || GetDescriptor().bIsTransient;
}
//Sets the histogram of the blob
FORCEINLINE void SetHistogram(BlobPtr InHistogram) { check(!Histogram); Histogram = InHistogram; }
//Check if blob already has a histogram
FORCEINLINE bool HasHistogram() const { return Histogram != nullptr; }
//////////////////////////////////////////////////////////////////////////
/// Static functions
//////////////////////////////////////////////////////////////////////////
static CHashPtr CalculateMipHash(CHashPtr MainHash, int32 Level);
static CHashPtrVec CalculateMipHashes(CHashPtr MainHash, CHashPtr ParentHash, int32 Level);
};
typedef T_BlobRef<Blob> BlobRef;
typedef T_Tiles<BlobPtr> BlobPtrTiles;