// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #pragma once #include "GPUTexture.h" #include "ITextureOwner.h" #include "Engine/Streaming/StreamableResource.h" #include "Types.h" /// /// GPU texture object which can change it's resolution (quality) at runtime /// class FLAXENGINE_API StreamingTexture : public Object, public StreamableResource { friend class StreamTextureMipTask; friend class StreamTextureResizeTask; protected: ITextureOwner* _owner; GPUTexture* _texture; TextureHeader _header; volatile mutable int64 _streamingTasksCount; bool _isBlockCompressed; public: /// /// Init /// /// Parent object /// Texture object name StreamingTexture(ITextureOwner* owner, const String& name); /// /// Destructor /// ~StreamingTexture(); public: /// /// Gets the owner. /// /// The owner. FORCE_INLINE ITextureOwner* GetOwner() const { return _owner; } /// /// Gets texture object handle /// /// Texture object FORCE_INLINE GPUTexture* GetTexture() const { return _texture; } /// /// Gets texture size of Vector2::Zero if not loaded /// /// Texture size FORCE_INLINE Vector2 Size() const { return _texture->Size(); } public: /// /// Gets a value indicating whether this instance is initialized. /// FORCE_INLINE bool IsInitialized() const { return _header.MipLevels > 0; } /// /// Gets total texture width (in texels) /// /// Texture width FORCE_INLINE int32 TotalWidth() const { return _header.Width; } /// /// Gets total texture height (in texels) /// /// Texture width FORCE_INLINE int32 TotalHeight() const { return _header.Height; } /// /// Gets total texture array size /// /// Texture array size FORCE_INLINE int32 TotalArraySize() const { return IsCubeMap() ? 6 : 1; } /// /// Gets total texture mip levels count /// /// Texture mip levels FORCE_INLINE int32 TotalMipLevels() const { return _header.MipLevels; } /// /// Returns texture format type /// /// Texture format type FORCE_INLINE TextureFormatType GetFormatType() const { return _header.Type; } /// /// Returns true if it's a cube map texture /// /// True if i's a cubemap FORCE_INLINE bool IsCubeMap() const { return _header.IsCubeMap; } /// /// Returns true if texture cannot be used during GPU resources streaming system /// /// True if texture cannot be used during GPU resources streaming system FORCE_INLINE bool NeverStream() const { return _header.NeverStream; } /// /// Gets the texture header. /// /// Header FORCE_INLINE const TextureHeader* GetHeader() const { return &_header; } /// /// Gets a boolean indicating whether this is a using a block compress format (BC1, BC2, BC3, BC4, BC5, BC6H, BC7). /// FORCE_INLINE bool IsBlockCompressed() const { return _isBlockCompressed; } public: /// /// Converts allocated texture mip index to the absolute mip map index. /// /// Index of the texture mip. /// The index of the mip map. FORCE_INLINE int32 TextureMipIndexToTotalIndex(int32 textureMipIndex) const { const int32 missingMips = TotalMipLevels() - _texture->MipLevels(); return textureMipIndex + missingMips; } /// /// Converts absolute mip map index to the allocated texture mip index. /// /// Index of the texture mip. /// The index of the mip map. FORCE_INLINE int32 TotalIndexToTextureMipIndex(int32 mipIndex) const { const int32 missingMips = TotalMipLevels() - _texture->MipLevels(); return mipIndex - missingMips; } public: /// /// Creates new texture /// /// Texture header /// True if cannot create texture, otherwise false bool Create(const TextureHeader& header); /// /// Release texture /// void UnloadTexture(); /// /// Gets the total memory usage that texture may have in use (if loaded to the maximum quality). /// Exact value may differ due to memory alignment and resource allocation policy. /// /// The amount of bytes. uint64 GetTotalMemoryUsage() const; public: FORCE_INLINE GPUTexture* operator->() const { return _texture; } public: // [Object] String ToString() const override { return _texture->ToString(); } // [StreamableResource] int32 GetMaxResidency() const override { return _header.MipLevels; } int32 GetCurrentResidency() const override { return _texture->ResidentMipLevels(); } int32 GetAllocatedResidency() const override { return _texture->MipLevels(); } bool CanBeUpdated() const override; Task* UpdateAllocation(int32 residency) override; Task* CreateStreamingTask(int32 residency) override; };