This reduces non-unity build time by ~2% and build size by ~0.5%.
This PR is a 'clean' version of #6199 updated to latest development Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
// AzCore
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/std/parallel/binary_semaphore.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/std/parallel/shared_mutex.h>
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
class any;
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Data
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzCore/std/typetraits/is_base_of.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/IO/IStreamerTypes.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -7,11 +7,61 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetDataStream.h>
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/std/parallel/condition_variable.h>
|
||||
|
||||
namespace AZ::Data
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
struct AssetDataStreamPrivate
|
||||
{
|
||||
//! Optional data buffer that's been directly passed in through Open(), instead of reading data from a file.
|
||||
AZStd::vector<AZ::u8> m_preloadedData;
|
||||
//! The current active streamer read request - tracked in case we need to cancel it prematurely
|
||||
AZ::IO::FileRequestPtr m_curReadRequest{ nullptr };
|
||||
|
||||
//! Synchronization for the read request, so that it's possible to block until completion.
|
||||
AZStd::mutex m_readRequestMutex;
|
||||
AZStd::condition_variable m_readRequestActive;
|
||||
|
||||
void SetReadRequest(AZ::IO::FileRequestPtr&& req)
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::mutex> lock(m_readRequestMutex);
|
||||
// The read request finished, so stop tracking it.
|
||||
m_curReadRequest = AZStd::move(req);
|
||||
}
|
||||
void BlockUntilReadComplete()
|
||||
{
|
||||
AZStd::unique_lock<AZStd::mutex> lock(m_readRequestMutex);
|
||||
m_readRequestActive.wait(
|
||||
lock,
|
||||
[this]
|
||||
{
|
||||
return m_curReadRequest == nullptr;
|
||||
});
|
||||
lock.unlock();
|
||||
}
|
||||
void CancelRequest()
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::mutex> lock(m_readRequestMutex);
|
||||
if (m_curReadRequest)
|
||||
{
|
||||
auto streamer = Interface<IO::IStreamer>::Get();
|
||||
m_curReadRequest = streamer->Cancel(m_curReadRequest);
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Internal
|
||||
AssetDataStream::AssetDataStream(AZ::IO::IStreamerTypes::RequestMemoryAllocator* bufferAllocator)
|
||||
: m_bufferAllocator(bufferAllocator ? bufferAllocator : &m_defaultAllocator)
|
||||
, m_privateData(new Internal::AssetDataStreamPrivate)
|
||||
{
|
||||
ClearInternalStateData();
|
||||
}
|
||||
@@ -22,6 +72,7 @@ namespace AZ::Data
|
||||
{
|
||||
Close();
|
||||
}
|
||||
delete m_privateData;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,9 +104,9 @@ namespace AZ::Data
|
||||
OpenInternal(data.size(), "(mem buffer)");
|
||||
|
||||
// Directly take ownership of the provided buffer
|
||||
m_preloadedData = AZStd::move(data);
|
||||
m_buffer = m_preloadedData.data();
|
||||
m_loadedSize = m_preloadedData.size();
|
||||
m_privateData->m_preloadedData = AZStd::move(data);
|
||||
m_buffer = m_privateData->m_preloadedData.data();
|
||||
m_loadedSize = m_privateData->m_preloadedData.size();
|
||||
}
|
||||
|
||||
void AssetDataStream::Open(const AZStd::string& filePath, size_t fileOffset, size_t assetSize,
|
||||
@@ -65,7 +116,7 @@ namespace AZ::Data
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
|
||||
AZ_Assert(!m_isOpen, "Attempting to open the stream when it is already open.");
|
||||
AZ_Assert(!m_curReadRequest, "Queueing an asset stream load while one is still in progress.");
|
||||
AZ_Assert(!m_privateData->m_curReadRequest, "Queueing an asset stream load while one is still in progress.");
|
||||
AZ_Assert(!filePath.empty(), "AssetDataStream::Open called without a valid file name.");
|
||||
|
||||
// Initialize the state variables and start tracking the overall load timings
|
||||
@@ -97,11 +148,8 @@ namespace AZ::Data
|
||||
"Buffer for %s was expected to be %zu bytes, but is %zu bytes.",
|
||||
m_filePath.c_str(), m_requestedAssetSize, m_loadedSize);
|
||||
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::mutex> lock(m_readRequestMutex);
|
||||
// The read request finished, so stop tracking it.
|
||||
m_curReadRequest = nullptr;
|
||||
}
|
||||
// The read request finished, so stop tracking it.
|
||||
m_privateData->SetReadRequest(nullptr);
|
||||
|
||||
// Call the load callback to start processing the loaded data.
|
||||
if (loadCallback)
|
||||
@@ -115,21 +163,22 @@ namespace AZ::Data
|
||||
}
|
||||
|
||||
// Notify that the load is complete, in case anyone is using BlockUntilLoadComplete to block.
|
||||
m_readRequestActive.notify_one();
|
||||
m_privateData->m_readRequestActive.notify_one();
|
||||
};
|
||||
|
||||
// Queue the raw file load with the file streamer.
|
||||
auto streamer = AZ::Interface<AZ::IO::IStreamer>::Get();
|
||||
m_curReadRequest = streamer->Read(
|
||||
m_privateData->m_curReadRequest =
|
||||
streamer->Read(
|
||||
m_filePath,
|
||||
*m_bufferAllocator,
|
||||
m_requestedAssetSize,
|
||||
deadline, priority, m_fileOffset);
|
||||
m_curDeadline = deadline;
|
||||
m_curPriority = priority;
|
||||
streamer->SetRequestCompleteCallback(m_curReadRequest, streamerCallback);
|
||||
streamer->SetRequestCompleteCallback(m_privateData->m_curReadRequest, streamerCallback);
|
||||
|
||||
streamer->QueueRequest(m_curReadRequest);
|
||||
streamer->QueueRequest(m_privateData->m_curReadRequest);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -139,19 +188,19 @@ namespace AZ::Data
|
||||
loadCallback(AZ::IO::IStreamerTypes::RequestStatus::Completed);
|
||||
}
|
||||
|
||||
m_readRequestActive.notify_one();
|
||||
m_privateData->m_readRequestActive.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetDataStream::Reschedule(AZStd::chrono::milliseconds newDeadline, AZ::IO::IStreamerTypes::Priority newPriority)
|
||||
{
|
||||
if (m_curReadRequest && (newDeadline < m_curDeadline || newPriority > m_curPriority))
|
||||
if (m_privateData->m_curReadRequest && (newDeadline < m_curDeadline || newPriority > m_curPriority))
|
||||
{
|
||||
auto deadline = AZStd::GetMin(m_curDeadline, newDeadline);
|
||||
auto priority = AZStd::GetMax(m_curPriority, newPriority);
|
||||
|
||||
auto streamer = Interface<IO::IStreamer>::Get();
|
||||
m_curReadRequest = streamer->RescheduleRequest(m_curReadRequest, deadline, priority);
|
||||
m_privateData->m_curReadRequest = streamer->RescheduleRequest(m_privateData->m_curReadRequest, deadline, priority);
|
||||
m_curDeadline = deadline;
|
||||
m_curPriority = priority;
|
||||
}
|
||||
@@ -159,15 +208,13 @@ namespace AZ::Data
|
||||
|
||||
void AssetDataStream::BlockUntilLoadComplete()
|
||||
{
|
||||
AZStd::unique_lock<AZStd::mutex> lock(m_readRequestMutex);
|
||||
m_readRequestActive.wait(lock, [this] { return m_curReadRequest == nullptr; });
|
||||
lock.unlock();
|
||||
m_privateData->BlockUntilReadComplete();
|
||||
}
|
||||
|
||||
void AssetDataStream::ClearInternalStateData()
|
||||
{
|
||||
// Clear all our internal state data.
|
||||
m_preloadedData.resize(0);
|
||||
m_privateData->m_preloadedData.resize(0);
|
||||
m_buffer = nullptr;
|
||||
m_loadedSize = 0;
|
||||
m_requestedAssetSize = 0;
|
||||
@@ -204,10 +251,10 @@ namespace AZ::Data
|
||||
void AssetDataStream::Close()
|
||||
{
|
||||
AZ_Assert(m_isOpen, "Attempting to close a stream that hasn't been opened.");
|
||||
AZ_Assert(m_curReadRequest == nullptr, "Attempting to close a stream with a read request in flight.");
|
||||
AZ_Assert(m_privateData->m_curReadRequest == nullptr, "Attempting to close a stream with a read request in flight.");
|
||||
|
||||
// Destroy the asset buffer and unlock the allocator, so the allocator itself knows that it is no longer needed.
|
||||
if (m_buffer != m_preloadedData.data())
|
||||
if (m_buffer != m_privateData->m_preloadedData.data())
|
||||
{
|
||||
m_bufferAllocator->Release(m_buffer);
|
||||
}
|
||||
@@ -221,12 +268,7 @@ namespace AZ::Data
|
||||
|
||||
void AssetDataStream::RequestCancel()
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::mutex> lock(m_readRequestMutex);
|
||||
if (m_curReadRequest)
|
||||
{
|
||||
auto streamer = Interface<IO::IStreamer>::Get();
|
||||
m_curReadRequest = streamer->Cancel(m_curReadRequest);
|
||||
}
|
||||
m_privateData->CancelRequest();
|
||||
}
|
||||
|
||||
void AssetDataStream::Seek(AZ::IO::OffsetType bytes, AZ::IO::GenericStream::SeekMode mode)
|
||||
|
||||
@@ -9,17 +9,26 @@
|
||||
|
||||
#include <AzCore/IO/GenericStreams.h>
|
||||
#include <AzCore/IO/IStreamerTypes.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/parallel/condition_variable.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/std/function/function_template.h>
|
||||
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
template<class T, class Allocator>
|
||||
class vector;
|
||||
}
|
||||
|
||||
namespace AZ::Data
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
struct AssetDataStreamPrivate;
|
||||
}
|
||||
|
||||
class AssetDataStream : public AZ::IO::GenericStream
|
||||
{
|
||||
public:
|
||||
using VectorDataSource = AZStd::vector<AZ::u8, AZStd::allocator>;
|
||||
// The default Generic Stream APIs in this class will only allow for a single sequential pass
|
||||
// through the data, no seeking. Reads will block when pages aren't available yet, and
|
||||
// pages will be marked for recycling once reading has progressed beyond them.
|
||||
@@ -29,10 +38,10 @@ namespace AZ::Data
|
||||
~AssetDataStream() override;
|
||||
|
||||
// Open the AssetDataStream and make a copy of the provided memory buffer.
|
||||
void Open(const AZStd::vector<AZ::u8>& data);
|
||||
void Open(const VectorDataSource& data);
|
||||
|
||||
// Open the AssetDataStream and directly take ownership of a pre-populated memory buffer.
|
||||
void Open(AZStd::vector<AZ::u8>&& data);
|
||||
void Open(VectorDataSource&& data);
|
||||
|
||||
// Open the AssetDataStream and load it via file streaming
|
||||
using OnCompleteCallback = AZStd::function<void(AZ::IO::IStreamerTypes::RequestStatus)>;
|
||||
@@ -91,6 +100,8 @@ namespace AZ::Data
|
||||
|
||||
void ClearInternalStateData();
|
||||
|
||||
Internal::AssetDataStreamPrivate* m_privateData;
|
||||
|
||||
//! The allocator to use for allocating / deallocating asset buffers
|
||||
AZ::IO::IStreamerTypes::RequestMemoryAllocator* m_bufferAllocator{ nullptr };
|
||||
|
||||
@@ -106,9 +117,6 @@ namespace AZ::Data
|
||||
//! The amount of data that's expected to be loaded.
|
||||
size_t m_requestedAssetSize{ 0 };
|
||||
|
||||
//! Optional data buffer that's been directly passed in through Open(), instead of reading data from a file.
|
||||
AZStd::vector<AZ::u8> m_preloadedData;
|
||||
|
||||
//! The buffer that will hold the raw data after it's loaded from the file.
|
||||
void* m_buffer{ nullptr };
|
||||
|
||||
@@ -119,19 +127,12 @@ namespace AZ::Data
|
||||
//! The current offset representing how far we've read into the buffer.
|
||||
size_t m_curOffset{ 0 };
|
||||
|
||||
//! The current active streamer read request - tracked in case we need to cancel it prematurely
|
||||
AZ::IO::FileRequestPtr m_curReadRequest{ nullptr };
|
||||
|
||||
//! The current request deadline. Used to avoid requesting a reschedule to the same (current) deadline.
|
||||
AZStd::chrono::milliseconds m_curDeadline{ AZ::IO::IStreamerTypes::s_noDeadline };
|
||||
|
||||
//! The current request priority. Used to avoid requesting a reschedule to the same (current) priority.
|
||||
AZ::IO::IStreamerTypes::Priority m_curPriority{ AZ::IO::IStreamerTypes::s_priorityMedium };
|
||||
|
||||
//! Synchronization for the read request, so that it's possible to block until completion.
|
||||
AZStd::mutex m_readRequestMutex;
|
||||
AZStd::condition_variable m_readRequestActive;
|
||||
|
||||
//! Track whether or not the stream is currently open
|
||||
bool m_isOpen{ false };
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzCore/Asset/AssetManager_private.h>
|
||||
#include <AzCore/Asset/AssetDataStream.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <AzCore/Asset/AssetContainer.h>
|
||||
#include <AzCore/Asset/AssetDataStream.h>
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h> // used as allocator for most components
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
|
||||
@@ -15,14 +15,18 @@
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzCore/std/any.h>
|
||||
|
||||
// These Streamer includes need to be moved to Streamer internals/implementation,
|
||||
// and pull out only what we need for visibility at IStreamer.h interface declaration.
|
||||
#include <AzCore/IO/Streamer/Statistics.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
class ExternalFileRequest;
|
||||
class FileRequestHandle;
|
||||
|
||||
using FileRequestPtr = AZStd::intrusive_ptr<ExternalFileRequest>;
|
||||
/**
|
||||
* Data Streamer Interface
|
||||
*/
|
||||
|
||||
@@ -137,18 +137,18 @@ namespace AZ::IO
|
||||
AZStd::visit([this, request](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
ReadFile(request, args);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::FlushData>)
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
@@ -166,7 +166,7 @@ namespace AZ::IO
|
||||
{
|
||||
Section& delayed = m_delayedSections.front();
|
||||
AZ_Assert(delayed.m_parent, "Delayed section doesn't have a reference to the original request.");
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&delayed.m_parent->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&delayed.m_parent->GetCommand());
|
||||
AZ_Assert(data, "A request in the delayed queue of the BlockCache didn't have a parent with read data.");
|
||||
// This call can add the same section to the back of the queue if there's not
|
||||
// enough space. Because of this the entry needs to be removed from the delayed
|
||||
@@ -233,7 +233,7 @@ namespace AZ::IO
|
||||
}
|
||||
}
|
||||
|
||||
void BlockCache::ReadFile(FileRequest* request, FileRequest::ReadData& data)
|
||||
void BlockCache::ReadFile(FileRequest* request, Requests::ReadData& data)
|
||||
{
|
||||
if (!m_next)
|
||||
{
|
||||
@@ -250,7 +250,7 @@ namespace AZ::IO
|
||||
m_numMetaDataRetrievalInProgress--;
|
||||
if (fileSizeRequest.GetStatus() == IStreamerTypes::RequestStatus::Completed)
|
||||
{
|
||||
auto& requestInfo = AZStd::get<FileRequest::FileMetaDataRetrievalData>(fileSizeRequest.GetCommand());
|
||||
auto& requestInfo = AZStd::get<Requests::FileMetaDataRetrievalData>(fileSizeRequest.GetCommand());
|
||||
if (requestInfo.m_found)
|
||||
{
|
||||
ContinueReadFile(request, requestInfo.m_fileSize);
|
||||
@@ -272,7 +272,7 @@ namespace AZ::IO
|
||||
Section main;
|
||||
Section epilog;
|
||||
|
||||
auto& data = AZStd::get<FileRequest::ReadData>(request->GetCommand());
|
||||
auto& data = AZStd::get<Requests::ReadData>(request->GetCommand());
|
||||
|
||||
if (!SplitRequest(prolog, main, epilog, data.m_path, fileLength, data.m_offset, data.m_size,
|
||||
reinterpret_cast<u8*>(data.m_output)))
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
class RequestPath;
|
||||
namespace Requests
|
||||
{
|
||||
struct ReadData;
|
||||
}
|
||||
|
||||
struct BlockCacheConfig final :
|
||||
public IStreamerStackConfig
|
||||
{
|
||||
@@ -109,7 +115,7 @@ namespace AZ::IO
|
||||
|
||||
using TimePoint = AZStd::chrono::system_clock::time_point;
|
||||
|
||||
void ReadFile(FileRequest* request, FileRequest::ReadData& data);
|
||||
void ReadFile(FileRequest* request, Requests::ReadData& data);
|
||||
void ContinueReadFile(FileRequest* request, u64 fileLength);
|
||||
CacheResult ReadFromCache(FileRequest* request, Section& section, const RequestPath& filePath);
|
||||
CacheResult ReadFromCache(FileRequest* request, Section& section, u32 cacheBlock);
|
||||
|
||||
@@ -101,12 +101,12 @@ namespace AZ::IO
|
||||
AZStd::visit([this, request](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::CreateDedicatedCacheData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::CreateDedicatedCacheData>)
|
||||
{
|
||||
args.m_range = FileRange::CreateRangeForEntireFile();
|
||||
m_context->PushPreparedRequest(request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::DestroyDedicatedCacheData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::DestroyDedicatedCacheData>)
|
||||
{
|
||||
args.m_range = FileRange::CreateRangeForEntireFile();
|
||||
m_context->PushPreparedRequest(request);
|
||||
@@ -125,28 +125,28 @@ namespace AZ::IO
|
||||
AZStd::visit([this, request](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
ReadFile(request, args);
|
||||
return;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CreateDedicatedCacheData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CreateDedicatedCacheData>)
|
||||
{
|
||||
CreateDedicatedCache(request, args);
|
||||
return;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::DestroyDedicatedCacheData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::DestroyDedicatedCacheData>)
|
||||
{
|
||||
DestroyDedicatedCache(request, args);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::FlushData>)
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
@@ -200,7 +200,7 @@ namespace AZ::IO
|
||||
}
|
||||
}
|
||||
|
||||
void DedicatedCache::ReadFile(FileRequest* request, FileRequest::ReadData& data)
|
||||
void DedicatedCache::ReadFile(FileRequest* request, Requests::ReadData& data)
|
||||
{
|
||||
size_t index = FindCache(data.m_path, data.m_offset);
|
||||
if (index == s_fileNotFound)
|
||||
@@ -255,7 +255,7 @@ namespace AZ::IO
|
||||
StreamStackEntry::CollectStatistics(statistics);
|
||||
}
|
||||
|
||||
void DedicatedCache::CreateDedicatedCache(FileRequest* request, FileRequest::CreateDedicatedCacheData& data)
|
||||
void DedicatedCache::CreateDedicatedCache(FileRequest* request, Requests::CreateDedicatedCacheData& data)
|
||||
{
|
||||
size_t index = FindCache(data.m_path, data.m_range);
|
||||
if (index == s_fileNotFound)
|
||||
@@ -276,7 +276,7 @@ namespace AZ::IO
|
||||
m_context->MarkRequestAsCompleted(request);
|
||||
}
|
||||
|
||||
void DedicatedCache::DestroyDedicatedCache(FileRequest* request, FileRequest::DestroyDedicatedCacheData& data)
|
||||
void DedicatedCache::DestroyDedicatedCache(FileRequest* request, Requests::DestroyDedicatedCacheData& data)
|
||||
{
|
||||
size_t index = FindCache(data.m_path, data.m_range);
|
||||
if (index != s_fileNotFound)
|
||||
|
||||
@@ -11,15 +11,21 @@
|
||||
#include <AzCore/IO/Streamer/BlockCache.h>
|
||||
#include <AzCore/IO/Streamer/FileRange.h>
|
||||
#include <AzCore/IO/Streamer/Statistics.h>
|
||||
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
|
||||
#include <AzCore/IO/Streamer/StreamStackEntry.h>
|
||||
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/limits.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/limits.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
namespace Requests
|
||||
{
|
||||
struct CreateDedicatedCacheData;
|
||||
struct DestroyDedicatedCacheData;
|
||||
} // namespace Requests
|
||||
|
||||
struct DedicatedCacheConfig final :
|
||||
public IStreamerStackConfig
|
||||
{
|
||||
@@ -56,16 +62,19 @@ namespace AZ::IO
|
||||
|
||||
void UpdateStatus(Status& status) const override;
|
||||
|
||||
void UpdateCompletionEstimates(AZStd::chrono::system_clock::time_point now, AZStd::vector<FileRequest*>& internalPending,
|
||||
StreamerContext::PreparedQueue::iterator pendingBegin, StreamerContext::PreparedQueue::iterator pendingEnd) override;
|
||||
void UpdateCompletionEstimates(
|
||||
AZStd::chrono::system_clock::time_point now,
|
||||
AZStd::vector<FileRequest*>& internalPending,
|
||||
StreamerContext::PreparedQueue::iterator pendingBegin,
|
||||
StreamerContext::PreparedQueue::iterator pendingEnd) override;
|
||||
|
||||
void CollectStatistics(AZStd::vector<Statistic>& statistics) const override;
|
||||
|
||||
private:
|
||||
void CreateDedicatedCache(FileRequest* request, FileRequest::CreateDedicatedCacheData& data);
|
||||
void DestroyDedicatedCache(FileRequest* request, FileRequest::DestroyDedicatedCacheData& data);
|
||||
void CreateDedicatedCache(FileRequest* request, Requests::CreateDedicatedCacheData& data);
|
||||
void DestroyDedicatedCache(FileRequest* request, Requests::DestroyDedicatedCacheData& data);
|
||||
|
||||
void ReadFile(FileRequest* request, FileRequest::ReadData& data);
|
||||
void ReadFile(FileRequest* request, AZ::IO::Requests::ReadData& data);
|
||||
size_t FindCache(const RequestPath& filename, FileRange range);
|
||||
size_t FindCache(const RequestPath& filename, u64 offset);
|
||||
|
||||
|
||||
@@ -12,22 +12,30 @@
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/IO/Streamer/StreamerContext.h>
|
||||
|
||||
namespace AZ::IO
|
||||
//
|
||||
// Command structures.
|
||||
//
|
||||
|
||||
namespace AZ::IO::Requests
|
||||
{
|
||||
//
|
||||
// Command structures.
|
||||
//
|
||||
ReadData::ReadData(void* output, u64 outputSize, const RequestPath& path, u64 offset, u64 size, bool sharedRead)
|
||||
: m_path(path)
|
||||
, m_output(output)
|
||||
, m_outputSize(outputSize)
|
||||
, m_offset(offset)
|
||||
, m_size(size)
|
||||
, m_sharedRead(sharedRead)
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::ExternalRequestData::ExternalRequestData(FileRequestPtr&& request)
|
||||
: m_request(AZStd::move(request))
|
||||
{}
|
||||
|
||||
FileRequest::RequestPathStoreData::RequestPathStoreData(RequestPath path)
|
||||
: m_path(AZStd::move(path))
|
||||
{}
|
||||
|
||||
FileRequest::ReadRequestData::ReadRequestData(RequestPath path, void* output, u64 outputSize, u64 offset, u64 size,
|
||||
AZStd::chrono::system_clock::time_point deadline, IStreamerTypes::Priority priority)
|
||||
ReadRequestData::ReadRequestData(
|
||||
RequestPath path,
|
||||
void* output,
|
||||
u64 outputSize,
|
||||
u64 offset,
|
||||
u64 size,
|
||||
AZStd::chrono::system_clock::time_point deadline,
|
||||
IStreamerTypes::Priority priority)
|
||||
: m_path(AZStd::move(path))
|
||||
, m_allocator(nullptr)
|
||||
, m_deadline(deadline)
|
||||
@@ -37,10 +45,16 @@ namespace AZ::IO
|
||||
, m_size(size)
|
||||
, m_priority(priority)
|
||||
, m_memoryType(IStreamerTypes::MemoryType::ReadWrite) // Only generic memory can be assigned externally.
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::ReadRequestData::ReadRequestData(RequestPath path, IStreamerTypes::RequestMemoryAllocator* allocator,
|
||||
u64 offset, u64 size, AZStd::chrono::system_clock::time_point deadline, IStreamerTypes::Priority priority)
|
||||
ReadRequestData::ReadRequestData(
|
||||
RequestPath path,
|
||||
IStreamerTypes::RequestMemoryAllocator* allocator,
|
||||
u64 offset,
|
||||
u64 size,
|
||||
AZStd::chrono::system_clock::time_point deadline,
|
||||
IStreamerTypes::Priority priority)
|
||||
: m_path(AZStd::move(path))
|
||||
, m_allocator(allocator)
|
||||
, m_deadline(deadline)
|
||||
@@ -50,9 +64,10 @@ namespace AZ::IO
|
||||
, m_size(size)
|
||||
, m_priority(priority)
|
||||
, m_memoryType(IStreamerTypes::MemoryType::ReadWrite) // Only generic memory can be assigned externally.
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::ReadRequestData::~ReadRequestData()
|
||||
ReadRequestData::~ReadRequestData()
|
||||
{
|
||||
if (m_allocator != nullptr)
|
||||
{
|
||||
@@ -64,65 +79,81 @@ namespace AZ::IO
|
||||
}
|
||||
}
|
||||
|
||||
FileRequest::ReadData::ReadData(void* output, u64 outputSize, const RequestPath& path, u64 offset, u64 size, bool sharedRead)
|
||||
: m_output(output)
|
||||
, m_outputSize(outputSize)
|
||||
, m_path(path)
|
||||
, m_offset(offset)
|
||||
, m_size(size)
|
||||
, m_sharedRead(sharedRead)
|
||||
{}
|
||||
CreateDedicatedCacheData::CreateDedicatedCacheData(RequestPath path, const FileRange& range)
|
||||
: m_path(AZStd::move(path))
|
||||
, m_range(range)
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::CompressedReadData::CompressedReadData(CompressionInfo&& compressionInfo, void* output, u64 readOffset, u64 readSize)
|
||||
DestroyDedicatedCacheData::DestroyDedicatedCacheData(RequestPath path, const FileRange& range)
|
||||
: m_path(AZStd::move(path))
|
||||
, m_range(range)
|
||||
{
|
||||
}
|
||||
|
||||
ExternalRequestData::ExternalRequestData(FileRequestPtr&& request)
|
||||
: m_request(AZStd::move(request))
|
||||
{
|
||||
}
|
||||
|
||||
RequestPathStoreData::RequestPathStoreData(RequestPath path)
|
||||
: m_path(AZStd::move(path))
|
||||
{
|
||||
}
|
||||
|
||||
CompressedReadData::CompressedReadData(CompressionInfo&& compressionInfo, void* output, u64 readOffset, u64 readSize)
|
||||
: m_compressionInfo(AZStd::move(compressionInfo))
|
||||
, m_output(output)
|
||||
, m_readOffset(readOffset)
|
||||
, m_readSize(readSize)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::FileExistsCheckData::FileExistsCheckData(const RequestPath& path)
|
||||
FileExistsCheckData::FileExistsCheckData(const RequestPath& path)
|
||||
: m_path(path)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::FileMetaDataRetrievalData::FileMetaDataRetrievalData(const RequestPath& path)
|
||||
FileMetaDataRetrievalData::FileMetaDataRetrievalData(const RequestPath& path)
|
||||
: m_path(path)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::CancelData::CancelData(FileRequestPtr target)
|
||||
CancelData::CancelData(FileRequestPtr target)
|
||||
: m_target(AZStd::move(target))
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::FlushData::FlushData(RequestPath path)
|
||||
FlushData::FlushData(RequestPath path)
|
||||
: m_path(AZStd::move(path))
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::RescheduleData::RescheduleData(FileRequestPtr target, AZStd::chrono::system_clock::time_point newDeadline,
|
||||
RescheduleData::RescheduleData(
|
||||
FileRequestPtr target,
|
||||
AZStd::chrono::system_clock::time_point newDeadline,
|
||||
IStreamerTypes::Priority newPriority)
|
||||
: m_target(AZStd::move(target))
|
||||
, m_newDeadline(newDeadline)
|
||||
, m_newPriority(newPriority)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::CreateDedicatedCacheData::CreateDedicatedCacheData(RequestPath path, const FileRange& range)
|
||||
: m_path(AZStd::move(path))
|
||||
, m_range(range)
|
||||
{}
|
||||
|
||||
FileRequest::DestroyDedicatedCacheData::DestroyDedicatedCacheData(RequestPath path, const FileRange& range)
|
||||
: m_path(AZStd::move(path))
|
||||
, m_range(range)
|
||||
{}
|
||||
|
||||
FileRequest::ReportData::ReportData(ReportType reportType)
|
||||
Requests::ReportData::ReportData(ReportType reportType)
|
||||
: m_reportType(reportType)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
FileRequest::CustomData::CustomData(AZStd::any data, bool failWhenUnhandled)
|
||||
CustomData::CustomData(AZStd::any data, bool failWhenUnhandled)
|
||||
: m_data(AZStd::move(data))
|
||||
, m_failWhenUnhandled(failWhenUnhandled)
|
||||
{}
|
||||
|
||||
{
|
||||
}
|
||||
} // namespace AZ::IO::Requests
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
using namespace Requests;
|
||||
//
|
||||
// FileRequest
|
||||
//
|
||||
@@ -263,7 +294,7 @@ namespace AZ::IO
|
||||
SetOptionalParent(parent);
|
||||
}
|
||||
|
||||
void FileRequest::CreateReport(ReportData::ReportType reportType)
|
||||
void FileRequest::CreateReport(Requests::ReportType reportType)
|
||||
{
|
||||
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
|
||||
"Attempting to set FileRequest to 'Report', but another task was already assigned.");
|
||||
@@ -361,7 +392,7 @@ namespace AZ::IO
|
||||
"Request does not contain a valid command. It may have been reset already or was never assigned a command.");
|
||||
return true;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CustomData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CustomData>)
|
||||
{
|
||||
return args.m_failWhenUnhandled;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,252 @@ namespace AZ::IO
|
||||
class ExternalFileRequest;
|
||||
|
||||
using FileRequestPtr = AZStd::intrusive_ptr<ExternalFileRequest>;
|
||||
} // namespace AZ::IO
|
||||
|
||||
namespace AZ::IO::Requests
|
||||
{
|
||||
//! Request to read data. This is a translated request and holds an absolute path and has been
|
||||
//! resolved to the archive file if needed.
|
||||
struct ReadData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
ReadData(void* output, u64 outputSize, const RequestPath& path, u64 offset, u64 size, bool sharedRead);
|
||||
|
||||
const RequestPath& m_path; //!< The path to the file that contains the requested data.
|
||||
void* m_output; //!< Target output to write the read data to.
|
||||
u64 m_outputSize; //!< Size of memory m_output points to. This needs to be at least as big as m_size, but can be bigger.
|
||||
u64 m_offset; //!< The offset in bytes into the file.
|
||||
u64 m_size; //!< The number of bytes to read from the file.
|
||||
bool m_sharedRead; //!< True if other code will be reading from the file or the stack entry can exclusively lock.
|
||||
};
|
||||
|
||||
//! Request to read data. This is an untranslated request and holds a relative path. The Scheduler
|
||||
//! will translate this to the appropriate ReadData or CompressedReadData.
|
||||
struct ReadRequestData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
ReadRequestData(
|
||||
RequestPath path,
|
||||
void* output,
|
||||
u64 outputSize,
|
||||
u64 offset,
|
||||
u64 size,
|
||||
AZStd::chrono::system_clock::time_point deadline,
|
||||
IStreamerTypes::Priority priority);
|
||||
ReadRequestData(
|
||||
RequestPath path,
|
||||
IStreamerTypes::RequestMemoryAllocator* allocator,
|
||||
u64 offset,
|
||||
u64 size,
|
||||
AZStd::chrono::system_clock::time_point deadline,
|
||||
IStreamerTypes::Priority priority);
|
||||
~ReadRequestData();
|
||||
|
||||
RequestPath m_path; //!< Relative path to the target file.
|
||||
IStreamerTypes::RequestMemoryAllocator* m_allocator; //!< Allocator used to manage the memory for this request.
|
||||
AZStd::chrono::system_clock::time_point m_deadline; //!< Time by which this request should have been completed.
|
||||
void* m_output; //!< The memory address assigned (during processing) to store the read data to.
|
||||
u64 m_outputSize; //!< The memory size of the addressed used to store the read data.
|
||||
u64 m_offset; //!< The offset in bytes into the file.
|
||||
u64 m_size; //!< The number of bytes to read from the file.
|
||||
IStreamerTypes::Priority m_priority; //!< Priority used for ordering requests. This is used when requests have the same deadline.
|
||||
IStreamerTypes::MemoryType m_memoryType; //!< The type of memory provided by the allocator if used.
|
||||
};
|
||||
|
||||
//! Creates a cache dedicated to a single file. This is best used for files where blocks are read from
|
||||
//! periodically such as audio banks of video files.
|
||||
struct CreateDedicatedCacheData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
CreateDedicatedCacheData(RequestPath path, const FileRange& range);
|
||||
|
||||
RequestPath m_path;
|
||||
FileRange m_range;
|
||||
};
|
||||
|
||||
//! Destroys a cache dedicated to a single file that was previously created by CreateDedicatedCache
|
||||
struct DestroyDedicatedCacheData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
DestroyDedicatedCacheData(RequestPath path, const FileRange& range);
|
||||
|
||||
RequestPath m_path;
|
||||
FileRange m_range;
|
||||
};
|
||||
|
||||
enum class ReportType : int8_t
|
||||
{
|
||||
FileLocks
|
||||
};
|
||||
|
||||
struct ReportData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityLow;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
explicit ReportData(ReportType reportType);
|
||||
|
||||
ReportType m_reportType;
|
||||
};
|
||||
|
||||
//! Stores a reference to the external request so it stays alive while the request is being processed.
|
||||
//! This is needed because Streamer supports fire-and-forget requests since completion can be handled by
|
||||
//! registering a callback.
|
||||
struct ExternalRequestData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
explicit ExternalRequestData(FileRequestPtr&& request);
|
||||
|
||||
FileRequestPtr m_request; //!< The request that was send to Streamer.
|
||||
};
|
||||
|
||||
//! Stores an instance of a RequestPath. To reduce copying instances of a RequestPath functions that
|
||||
//! need a path take them by reference to the original request. In some cases a path originates from
|
||||
//! within in the stack and temporary storage is needed. This struct allows for that temporary storage
|
||||
//! so it can be safely referenced later.
|
||||
struct RequestPathStoreData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
explicit RequestPathStoreData(RequestPath path);
|
||||
|
||||
RequestPath m_path;
|
||||
};
|
||||
|
||||
//! Request to read and decompress data.
|
||||
struct CompressedReadData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
CompressedReadData(CompressionInfo&& compressionInfo, void* output, u64 readOffset, u64 readSize);
|
||||
|
||||
CompressionInfo m_compressionInfo;
|
||||
void* m_output; //!< Target output to write the read data to.
|
||||
u64 m_readOffset; //!< The offset into the decompressed to start copying from.
|
||||
u64 m_readSize; //!< Number of bytes to read from the decompressed file.
|
||||
};
|
||||
|
||||
//! Holds the progress of an operation chain until this request is explicitly completed.
|
||||
struct WaitData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
};
|
||||
|
||||
//! Checks to see if any node in the stack can find a file at the provided path.
|
||||
struct FileExistsCheckData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
explicit FileExistsCheckData(const RequestPath& path);
|
||||
|
||||
const RequestPath& m_path;
|
||||
bool m_found{ false };
|
||||
};
|
||||
|
||||
//! Searches for a file in the stack and retrieves the meta data. This may be slower than a file exists
|
||||
//! check.
|
||||
struct FileMetaDataRetrievalData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
explicit FileMetaDataRetrievalData(const RequestPath& path);
|
||||
|
||||
const RequestPath& m_path;
|
||||
u64 m_fileSize{ 0 };
|
||||
bool m_found{ false };
|
||||
};
|
||||
|
||||
//! Cancels a request in the stream stack, if possible.
|
||||
struct CancelData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHighest;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
explicit CancelData(FileRequestPtr target);
|
||||
|
||||
FileRequestPtr m_target; //!< The request that will be canceled.
|
||||
};
|
||||
|
||||
//! Updates the priority and deadline of a request that has not been queued yet.
|
||||
struct RescheduleData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
RescheduleData(FileRequestPtr target, AZStd::chrono::system_clock::time_point newDeadline, IStreamerTypes::Priority newPriority);
|
||||
|
||||
FileRequestPtr m_target; //!< The request that will be rescheduled.
|
||||
AZStd::chrono::system_clock::time_point m_newDeadline; //!< The new deadline for the request.
|
||||
IStreamerTypes::Priority m_newPriority; //!< The new priority for the request.
|
||||
};
|
||||
|
||||
//! Flushes all references to the provided file in the streaming stack.
|
||||
struct FlushData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
explicit FlushData(RequestPath path);
|
||||
|
||||
RequestPath m_path;
|
||||
};
|
||||
|
||||
//! Flushes all caches in the streaming stack.
|
||||
struct FlushAllData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
};
|
||||
|
||||
//! Data for a custom command. This can be used by nodes added extensions that need data that can't be stored
|
||||
//! in the already provided data.
|
||||
struct CustomData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
|
||||
CustomData(AZStd::any data, bool failWhenUnhandled);
|
||||
|
||||
AZStd::any m_data; //!< The data for the custom request.
|
||||
bool m_failWhenUnhandled; //!< Whether or not the request is marked as failed or success when no node process it.
|
||||
};
|
||||
using CommandVariant = AZStd::variant<
|
||||
AZStd::monostate,
|
||||
ExternalRequestData,
|
||||
RequestPathStoreData,
|
||||
ReadRequestData,
|
||||
ReadData,
|
||||
CompressedReadData,
|
||||
WaitData,
|
||||
FileExistsCheckData,
|
||||
FileMetaDataRetrievalData,
|
||||
CancelData,
|
||||
RescheduleData,
|
||||
FlushData,
|
||||
FlushAllData,
|
||||
CreateDedicatedCacheData,
|
||||
DestroyDedicatedCacheData,
|
||||
ReportData,
|
||||
CustomData>;
|
||||
|
||||
} // namespace AZ::IO::Requests
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
class FileRequest final
|
||||
{
|
||||
public:
|
||||
@@ -36,218 +281,7 @@ namespace AZ::IO
|
||||
friend class StreamerContext;
|
||||
friend class ExternalFileRequest;
|
||||
|
||||
//! Stores a reference to the external request so it stays alive while the request is being processed.
|
||||
//! This is needed because Streamer supports fire-and-forget requests since completion can be handled by
|
||||
//! registering a callback.
|
||||
struct ExternalRequestData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
explicit ExternalRequestData(FileRequestPtr&& request);
|
||||
|
||||
FileRequestPtr m_request; //!< The request that was send to Streamer.
|
||||
};
|
||||
|
||||
//! Stores an instance of a RequestPath. To reduce copying instances of a RequestPath functions that
|
||||
//! need a path take them by reference to the original request. In some cases a path originates from
|
||||
//! within in the stack and temporary storage is needed. This struct allows for that temporary storage
|
||||
//! so it can be safely referenced later.
|
||||
struct RequestPathStoreData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
explicit RequestPathStoreData(RequestPath path);
|
||||
|
||||
RequestPath m_path;
|
||||
};
|
||||
|
||||
//! Request to read data. This is an untranslated request and holds a relative path. The Scheduler
|
||||
//! will translate this to the appropriate ReadData or CompressedReadData.
|
||||
struct ReadRequestData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
ReadRequestData(RequestPath path, void* output, u64 outputSize, u64 offset, u64 size,
|
||||
AZStd::chrono::system_clock::time_point deadline, IStreamerTypes::Priority priority);
|
||||
ReadRequestData(RequestPath path, IStreamerTypes::RequestMemoryAllocator* allocator, u64 offset, u64 size,
|
||||
AZStd::chrono::system_clock::time_point deadline, IStreamerTypes::Priority priority);
|
||||
~ReadRequestData();
|
||||
|
||||
RequestPath m_path; //!< Relative path to the target file.
|
||||
IStreamerTypes::RequestMemoryAllocator* m_allocator; //!< Allocator used to manage the memory for this request.
|
||||
AZStd::chrono::system_clock::time_point m_deadline; //!< Time by which this request should have been completed.
|
||||
void* m_output; //!< The memory address assigned (during processing) to store the read data to.
|
||||
u64 m_outputSize; //!< The memory size of the addressed used to store the read data.
|
||||
u64 m_offset; //!< The offset in bytes into the file.
|
||||
u64 m_size; //!< The number of bytes to read from the file.
|
||||
IStreamerTypes::Priority m_priority; //!< Priority used for ordering requests. This is used when requests have the same deadline.
|
||||
IStreamerTypes::MemoryType m_memoryType; //!< The type of memory provided by the allocator if used.
|
||||
};
|
||||
|
||||
//! Request to read data. This is a translated request and holds an absolute path and has been
|
||||
//! resolved to the archive file if needed.
|
||||
struct ReadData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
ReadData(void* output, u64 outputSize, const RequestPath& path, u64 offset, u64 size, bool sharedRead);
|
||||
|
||||
const RequestPath& m_path; //!< The path to the file that contains the requested data.
|
||||
void* m_output; //!< Target output to write the read data to.
|
||||
u64 m_outputSize; //!< Size of memory m_output points to. This needs to be at least as big as m_size, but can be bigger.
|
||||
u64 m_offset; //!< The offset in bytes into the file.
|
||||
u64 m_size; //!< The number of bytes to read from the file.
|
||||
bool m_sharedRead; //!< True if other code will be reading from the file or the stack entry can exclusively lock.
|
||||
};
|
||||
|
||||
//! Request to read and decompress data.
|
||||
struct CompressedReadData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
|
||||
CompressedReadData(CompressionInfo&& compressionInfo, void* output, u64 readOffset, u64 readSize);
|
||||
|
||||
CompressionInfo m_compressionInfo;
|
||||
void* m_output; //!< Target output to write the read data to.
|
||||
u64 m_readOffset; //!< The offset into the decompressed to start copying from.
|
||||
u64 m_readSize; //!< Number of bytes to read from the decompressed file.
|
||||
};
|
||||
|
||||
//! Holds the progress of an operation chain until this request is explicitly completed.
|
||||
struct WaitData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
inline constexpr static bool s_failWhenUnhandled = true;
|
||||
};
|
||||
|
||||
//! Checks to see if any node in the stack can find a file at the provided path.
|
||||
struct FileExistsCheckData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
explicit FileExistsCheckData(const RequestPath& path);
|
||||
|
||||
const RequestPath& m_path;
|
||||
bool m_found{ false };
|
||||
};
|
||||
|
||||
//! Searches for a file in the stack and retrieves the meta data. This may be slower than a file exists
|
||||
//! check.
|
||||
struct FileMetaDataRetrievalData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
explicit FileMetaDataRetrievalData(const RequestPath& path);
|
||||
|
||||
const RequestPath& m_path;
|
||||
u64 m_fileSize{ 0 };
|
||||
bool m_found{ false };
|
||||
};
|
||||
|
||||
//! Cancels a request in the stream stack, if possible.
|
||||
struct CancelData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHighest;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
explicit CancelData(FileRequestPtr target);
|
||||
|
||||
FileRequestPtr m_target; //!< The request that will be canceled.
|
||||
};
|
||||
|
||||
//! Updates the priority and deadline of a request that has not been queued yet.
|
||||
struct RescheduleData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
RescheduleData(FileRequestPtr target, AZStd::chrono::system_clock::time_point newDeadline, IStreamerTypes::Priority newPriority);
|
||||
|
||||
FileRequestPtr m_target; //!< The request that will be rescheduled.
|
||||
AZStd::chrono::system_clock::time_point m_newDeadline; //!< The new deadline for the request.
|
||||
IStreamerTypes::Priority m_newPriority; //!< The new priority for the request.
|
||||
};
|
||||
|
||||
//! Flushes all references to the provided file in the streaming stack.
|
||||
struct FlushData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
explicit FlushData(RequestPath path);
|
||||
|
||||
RequestPath m_path;
|
||||
};
|
||||
|
||||
//! Flushes all caches in the streaming stack.
|
||||
struct FlushAllData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
};
|
||||
|
||||
//! Creates a cache dedicated to a single file. This is best used for files where blocks are read from
|
||||
//! periodically such as audio banks of video files.
|
||||
struct CreateDedicatedCacheData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
CreateDedicatedCacheData(RequestPath path, const FileRange& range);
|
||||
|
||||
RequestPath m_path;
|
||||
FileRange m_range;
|
||||
};
|
||||
|
||||
//! Destroys a cache dedicated to a single file that was previously created by CreateDedicatedCache
|
||||
struct DestroyDedicatedCacheData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityHigh;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
DestroyDedicatedCacheData(RequestPath path, const FileRange& range);
|
||||
|
||||
RequestPath m_path;
|
||||
FileRange m_range;
|
||||
};
|
||||
|
||||
struct ReportData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityLow;
|
||||
inline constexpr static bool s_failWhenUnhandled = false;
|
||||
|
||||
enum class ReportType
|
||||
{
|
||||
FileLocks
|
||||
};
|
||||
|
||||
explicit ReportData(ReportType reportType);
|
||||
|
||||
ReportType m_reportType;
|
||||
};
|
||||
|
||||
//! Data for a custom command. This can be used by nodes added extensions that need data that can't be stored
|
||||
//! in the already provided data.
|
||||
struct CustomData
|
||||
{
|
||||
inline constexpr static IStreamerTypes::Priority s_orderPriority = IStreamerTypes::s_priorityMedium;
|
||||
|
||||
CustomData(AZStd::any data, bool failWhenUnhandled);
|
||||
|
||||
AZStd::any m_data; //!< The data for the custom request.
|
||||
bool m_failWhenUnhandled; //!< Whether or not the request is marked as failed or success when no node process it.
|
||||
};
|
||||
|
||||
using CommandVariant = AZStd::variant<AZStd::monostate, ExternalRequestData, RequestPathStoreData, ReadRequestData, ReadData,
|
||||
CompressedReadData, WaitData, FileExistsCheckData, FileMetaDataRetrievalData, CancelData, RescheduleData, FlushData,
|
||||
FlushAllData, CreateDedicatedCacheData, DestroyDedicatedCacheData, ReportData, CustomData>;
|
||||
using CommandVariant = Requests::CommandVariant;
|
||||
using OnCompletionCallback = AZStd::function<void(FileRequest& request)>;
|
||||
|
||||
AZ_CLASS_ALLOCATOR(FileRequest, SystemAllocator, 0);
|
||||
@@ -278,7 +312,7 @@ namespace AZ::IO
|
||||
void CreateFlushAll();
|
||||
void CreateDedicatedCacheCreation(RequestPath path, const FileRange& range = {}, FileRequest* parent = nullptr);
|
||||
void CreateDedicatedCacheDestruction(RequestPath path, const FileRange& range = {}, FileRequest* parent = nullptr);
|
||||
void CreateReport(ReportData::ReportType reportType);
|
||||
void CreateReport(Requests::ReportType reportType);
|
||||
void CreateCustom(AZStd::any data, bool failWhenUnhandled = true, FileRequest* parent = nullptr);
|
||||
|
||||
void SetCompletionCallback(OnCompletionCallback callback);
|
||||
@@ -325,8 +359,17 @@ namespace AZ::IO
|
||||
//! Command and parameters for the request.
|
||||
CommandVariant m_command;
|
||||
|
||||
//! Status of the request.
|
||||
AZStd::atomic<IStreamerTypes::RequestStatus> m_status{ IStreamerTypes::RequestStatus::Pending };
|
||||
//! Estimated time this request will complete. This is an estimation and depends on many
|
||||
//! factors which can cause it to change drastically from moment to moment.
|
||||
AZStd::chrono::system_clock::time_point m_estimatedCompletion;
|
||||
|
||||
//! The file request that has a dependency on this one. This can be null if there are no
|
||||
//! other request depending on this one to complete.
|
||||
FileRequest* m_parent{ nullptr };
|
||||
|
||||
|
||||
//! Id assigned when the request is added to the pending queue.
|
||||
size_t m_pendingId{ 0 };
|
||||
|
||||
//! Called once the request has completed. This will always be called from the Streamer thread
|
||||
//! and thread safety is the responsibility of called function. When assigning a lambda avoid
|
||||
@@ -336,16 +379,8 @@ namespace AZ::IO
|
||||
//! a longer running task is needed consider using a job to do the work.
|
||||
OnCompletionCallback m_onCompletion;
|
||||
|
||||
//! Estimated time this request will complete. This is an estimation and depends on many
|
||||
//! factors which can cause it to change drastically from moment to moment.
|
||||
AZStd::chrono::system_clock::time_point m_estimatedCompletion;
|
||||
|
||||
//! The file request that has a dependency on this one. This can be null if there are no
|
||||
//! other request depending on this one to complete.
|
||||
FileRequest* m_parent{ nullptr };
|
||||
|
||||
//! Id assigned when the request is added to the pending queue.
|
||||
size_t m_pendingId{ 0 };
|
||||
//! Status of the request.
|
||||
AZStd::atomic<IStreamerTypes::RequestStatus> m_status{ IStreamerTypes::RequestStatus::Pending };
|
||||
|
||||
//! The number of dependent file request that need to complete before this one is done.
|
||||
u16 m_dependencies{ 0 };
|
||||
|
||||
@@ -91,12 +91,12 @@ namespace AZ::IO
|
||||
AZStd::visit([this, request](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadRequestData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadRequestData>)
|
||||
{
|
||||
PrepareReadRequest(request, args);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CreateDedicatedCacheData> ||
|
||||
AZStd::is_same_v<Command, FileRequest::DestroyDedicatedCacheData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CreateDedicatedCacheData> ||
|
||||
AZStd::is_same_v<Command, Requests::DestroyDedicatedCacheData>)
|
||||
{
|
||||
PrepareDedicatedCache(request, args.m_path);
|
||||
}
|
||||
@@ -114,11 +114,11 @@ namespace AZ::IO
|
||||
AZStd::visit([this, request](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
m_pendingReads.push_back(request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileExistsCheckData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileExistsCheckData>)
|
||||
{
|
||||
m_pendingFileExistChecks.push_back(request);
|
||||
}
|
||||
@@ -203,7 +203,7 @@ namespace AZ::IO
|
||||
{
|
||||
FileRequest* compressedRequest = m_processingJobs[i].m_waitRequest->GetParent();
|
||||
AZ_Assert(compressedRequest, "A wait request attached to FullFileDecompressor was completed but didn't have a parent compressed request.");
|
||||
auto data = AZStd::get_if<FileRequest::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
AZ_Assert(data, "Compressed request in the decompression queue in FullFileDecompressor didn't contain compression read data.");
|
||||
|
||||
size_t bytesToDecompress = data->m_compressionInfo.m_compressedSize;
|
||||
@@ -255,7 +255,7 @@ namespace AZ::IO
|
||||
|
||||
// Calculate the amount of time it will take to decompress the data.
|
||||
FileRequest* compressedRequest = m_readRequests[i]->GetParent();
|
||||
auto data = AZStd::get_if<FileRequest::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
|
||||
size_t bytesToDecompress = data->m_compressionInfo.m_compressedSize;
|
||||
auto decompressionDuration = AZStd::chrono::microseconds(
|
||||
@@ -290,7 +290,7 @@ namespace AZ::IO
|
||||
void FullFileDecompressor::EstimateCompressedReadRequest(FileRequest* request, AZStd::chrono::microseconds& cumulativeDelay,
|
||||
AZStd::chrono::microseconds decompressionDelay, double totalDecompressionDurationUs, double totalBytesDecompressed) const
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::CompressedReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::CompressedReadData>(&request->GetCommand());
|
||||
if (data)
|
||||
{
|
||||
AZStd::chrono::microseconds processingTime = decompressionDelay;
|
||||
@@ -343,7 +343,7 @@ namespace AZ::IO
|
||||
m_numRunningJobs == 0;
|
||||
}
|
||||
|
||||
void FullFileDecompressor::PrepareReadRequest(FileRequest* request, FileRequest::ReadRequestData& data)
|
||||
void FullFileDecompressor::PrepareReadRequest(FileRequest* request, Requests::ReadRequestData &data)
|
||||
{
|
||||
CompressionInfo info;
|
||||
if (CompressionUtils::FindCompressionInfo(info, data.m_path.GetRelativePath()))
|
||||
@@ -359,7 +359,7 @@ namespace AZ::IO
|
||||
{
|
||||
FileRequest* pathStorageRequest = m_context->GetNewInternalRequest();
|
||||
pathStorageRequest->CreateRequestPathStore(request, AZStd::move(info.m_archiveFilename));
|
||||
auto& pathStorage = AZStd::get<FileRequest::RequestPathStoreData>(pathStorageRequest->GetCommand());
|
||||
auto& pathStorage = AZStd::get<Requests::RequestPathStoreData>(pathStorageRequest->GetCommand());
|
||||
|
||||
nextRequest->CreateRead(pathStorageRequest, data.m_output, data.m_outputSize, pathStorage.m_path,
|
||||
info.m_offset + data.m_offset, data.m_size, info.m_isSharedPak);
|
||||
@@ -370,13 +370,13 @@ namespace AZ::IO
|
||||
auto callback = [this, nextRequest](const FileRequest& checkRequest)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
auto check = AZStd::get_if<FileRequest::FileExistsCheckData>(&checkRequest.GetCommand());
|
||||
auto check = AZStd::get_if<Requests::FileExistsCheckData>(&checkRequest.GetCommand());
|
||||
AZ_Assert(check,
|
||||
"Callback in FullFileDecompressor::PrepareReadRequest expected FileExistsCheck but got another command.");
|
||||
if (check->m_found)
|
||||
{
|
||||
FileRequest* originalRequest = m_context->RejectRequest(nextRequest);
|
||||
if (AZStd::holds_alternative<FileRequest::RequestPathStoreData>(originalRequest->GetCommand()))
|
||||
if (AZStd::holds_alternative<Requests::RequestPathStoreData>(originalRequest->GetCommand()))
|
||||
{
|
||||
originalRequest = m_context->RejectRequest(originalRequest);
|
||||
}
|
||||
@@ -412,12 +412,12 @@ namespace AZ::IO
|
||||
AZStd::visit([request, &info, nextRequest](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::CreateDedicatedCacheData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::CreateDedicatedCacheData>)
|
||||
{
|
||||
nextRequest->CreateDedicatedCacheCreation(AZStd::move(info.m_archiveFilename),
|
||||
FileRange::CreateRange(info.m_offset, info.m_compressedSize), request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::DestroyDedicatedCacheData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::DestroyDedicatedCacheData>)
|
||||
{
|
||||
nextRequest->CreateDedicatedCacheDestruction(AZStd::move(info.m_archiveFilename),
|
||||
FileRange::CreateRange(info.m_offset, info.m_compressedSize), request);
|
||||
@@ -429,7 +429,7 @@ namespace AZ::IO
|
||||
auto callback = [this, nextRequest](const FileRequest& checkRequest)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
auto check = AZStd::get_if<FileRequest::FileExistsCheckData>(&checkRequest.GetCommand());
|
||||
auto check = AZStd::get_if<Requests::FileExistsCheckData>(&checkRequest.GetCommand());
|
||||
AZ_Assert(check,
|
||||
"Callback in FullFileDecompressor::PrepareDedicatedCache expected FileExistsCheck but got another command.");
|
||||
if (check->m_found)
|
||||
@@ -461,7 +461,7 @@ namespace AZ::IO
|
||||
|
||||
void FullFileDecompressor::FileExistsCheck(FileRequest* checkRequest)
|
||||
{
|
||||
auto& fileCheckRequest = AZStd::get<FileRequest::FileExistsCheckData>(checkRequest->GetCommand());
|
||||
auto& fileCheckRequest = AZStd::get<Requests::FileExistsCheckData>(checkRequest->GetCommand());
|
||||
CompressionInfo info;
|
||||
if (CompressionUtils::FindCompressionInfo(info, fileCheckRequest.m_path.GetRelativePath()))
|
||||
{
|
||||
@@ -487,7 +487,7 @@ namespace AZ::IO
|
||||
{
|
||||
if (m_readBufferStatus[i] == ReadBufferStatus::Unused)
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::CompressedReadData>(&compressedReadRequest->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::CompressedReadData>(&compressedReadRequest->GetCommand());
|
||||
AZ_Assert(data, "Compressed request that's starting a read in FullFileDecompressor didn't contain compression read data.");
|
||||
AZ_Assert(data->m_compressionInfo.m_decompressor,
|
||||
"FileRequest for FullFileDecompressor is missing a decompression callback.");
|
||||
@@ -549,7 +549,7 @@ namespace AZ::IO
|
||||
}
|
||||
else
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
AZ_Assert(data, "Compressed request in FullFileDecompressor that finished unsuccessfully didn't contain compression read data.");
|
||||
CompressionInfo& info = data->m_compressionInfo;
|
||||
size_t offsetAdjustment = info.m_offset - AZ_SIZE_ALIGN_DOWN(info.m_offset, aznumeric_cast<size_t>(m_alignment));
|
||||
@@ -591,7 +591,7 @@ namespace AZ::IO
|
||||
}
|
||||
|
||||
FileRequest* waitRequest = m_readRequests[readSlot];
|
||||
AZ_Assert(AZStd::holds_alternative<FileRequest::WaitData>(waitRequest->GetCommand()),
|
||||
AZ_Assert(AZStd::holds_alternative<Requests::WaitData>(waitRequest->GetCommand()),
|
||||
"File request waiting for decompression wasn't marked as being a wait operation.");
|
||||
FileRequest* compressedRequest = waitRequest->GetParent();
|
||||
AZ_Assert(compressedRequest, "Read requests started by FullFileDecompressor is missing a parent request.");
|
||||
@@ -610,7 +610,7 @@ namespace AZ::IO
|
||||
m_readBuffers[readSlot] = nullptr;
|
||||
|
||||
AZ::Job* decompressionJob;
|
||||
auto data = AZStd::get_if<FileRequest::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
AZ_Assert(data, "Compressed request in FullFileDecompressor that's starting decompression didn't contain compression read data.");
|
||||
AZ_Assert(data->m_compressionInfo.m_decompressor, "FullFileDecompressor is queuing a decompression job but couldn't find a decompressor.");
|
||||
|
||||
@@ -664,7 +664,7 @@ namespace AZ::IO
|
||||
|
||||
FileRequest* compressedRequest = jobInfo.m_waitRequest->GetParent();
|
||||
AZ_Assert(compressedRequest, "A wait request attached to FullFileDecompressor was completed but didn't have a parent compressed request.");
|
||||
auto data = AZStd::get_if<FileRequest::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
AZ_Assert(data, "Compressed request in FullFileDecompressor that completed decompression didn't contain compression read data.");
|
||||
CompressionInfo& info = data->m_compressionInfo;
|
||||
size_t offsetAdjustment = info.m_offset - AZ_SIZE_ALIGN_DOWN(info.m_offset, aznumeric_cast<size_t>(m_alignment));
|
||||
@@ -694,7 +694,7 @@ namespace AZ::IO
|
||||
|
||||
FileRequest* compressedRequest = info.m_waitRequest->GetParent();
|
||||
AZ_Assert(compressedRequest, "A wait request attached to FullFileDecompressor was completed but didn't have a parent compressed request.");
|
||||
auto request = AZStd::get_if<FileRequest::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
auto request = AZStd::get_if<Requests::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
AZ_Assert(request, "Compressed request in FullFileDecompressor that's running full decompression didn't contain compression read data.");
|
||||
CompressionInfo& compressionInfo = request->m_compressionInfo;
|
||||
AZ_Assert(compressionInfo.m_decompressor, "Full decompressor job started, but there's no decompressor callback assigned.");
|
||||
@@ -719,7 +719,7 @@ namespace AZ::IO
|
||||
|
||||
FileRequest* compressedRequest = info.m_waitRequest->GetParent();
|
||||
AZ_Assert(compressedRequest, "A wait request attached to FullFileDecompressor was completed but didn't have a parent compressed request.");
|
||||
auto request = AZStd::get_if<FileRequest::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
auto request = AZStd::get_if<Requests::CompressedReadData>(&compressedRequest->GetCommand());
|
||||
AZ_Assert(request, "Compressed request in FullFileDecompressor that's running partial decompression didn't contain compression read data.");
|
||||
CompressionInfo& compressionInfo = request->m_compressionInfo;
|
||||
AZ_Assert(compressionInfo.m_decompressor, "Partial decompressor job started, but there's no decompressor callback assigned.");
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
namespace Requests
|
||||
{
|
||||
struct ReadRequestData;
|
||||
}
|
||||
|
||||
struct FullFileDecompressorConfig final :
|
||||
public IStreamerStackConfig
|
||||
{
|
||||
@@ -87,7 +92,7 @@ namespace AZ::IO
|
||||
|
||||
bool IsIdle() const;
|
||||
|
||||
void PrepareReadRequest(FileRequest* request, FileRequest::ReadRequestData& data);
|
||||
void PrepareReadRequest(FileRequest* request, Requests::ReadRequestData& data);
|
||||
void PrepareDedicatedCache(FileRequest* request, const RequestPath& path);
|
||||
void FileExistsCheck(FileRequest* checkRequest);
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace AZ::IO
|
||||
return;
|
||||
}
|
||||
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
if (data == nullptr)
|
||||
{
|
||||
StreamStackEntry::QueueRequest(request);
|
||||
@@ -156,7 +156,7 @@ namespace AZ::IO
|
||||
|
||||
void ReadSplitter::QueueAlignedRead(FileRequest* request)
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
AZ_Assert(data != nullptr, "Provided request to queue by the Read Splitter did not contain a read command.");
|
||||
|
||||
if (data->m_size <= m_maxReadSize)
|
||||
@@ -187,7 +187,7 @@ namespace AZ::IO
|
||||
|
||||
bool ReadSplitter::QueueAlignedRead(PendingRead& pending)
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&pending.m_request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&pending.m_request->GetCommand());
|
||||
AZ_Assert(data != nullptr, "Provided request to queue by the Read Splitter did not contain a read command.");
|
||||
|
||||
while (pending.m_readSize > 0)
|
||||
@@ -237,7 +237,7 @@ namespace AZ::IO
|
||||
|
||||
void ReadSplitter::QueueBufferedRead(FileRequest* request)
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
AZ_Assert(data != nullptr, "Provided request to queue by the Read Splitter did not contain a read command.");
|
||||
|
||||
PendingRead pendingRead;
|
||||
@@ -262,7 +262,7 @@ namespace AZ::IO
|
||||
|
||||
bool ReadSplitter::QueueBufferedRead(PendingRead& pending)
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&pending.m_request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&pending.m_request->GetCommand());
|
||||
AZ_Assert(data != nullptr, "Provided request to queue by the Read Splitter did not contain a read command.");
|
||||
|
||||
while (pending.m_readSize > 0)
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/IO/Streamer/Scheduler.h>
|
||||
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/IO/Streamer/Scheduler.h>
|
||||
#include <AzCore/std/containers/deque.h>
|
||||
#include <AzCore/std/sort.h>
|
||||
|
||||
@@ -35,6 +37,10 @@ namespace AZ::IO
|
||||
m_threadData.m_streamStack = AZStd::move(streamStack);
|
||||
}
|
||||
|
||||
Scheduler::~Scheduler()
|
||||
{
|
||||
}
|
||||
|
||||
void Scheduler::Start(const AZStd::thread_desc& threadDesc)
|
||||
{
|
||||
if (!m_isRunning)
|
||||
@@ -222,10 +228,10 @@ namespace AZ::IO
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (
|
||||
AZStd::is_same_v<Command, FileRequest::ReadData> ||
|
||||
AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
AZStd::is_same_v<Command, Requests::ReadData> ||
|
||||
AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
auto parentReadRequest = next->GetCommandFromChain<FileRequest::ReadRequestData>();
|
||||
auto parentReadRequest = next->GetCommandFromChain<Requests::ReadRequestData>();
|
||||
AZ_Assert(parentReadRequest != nullptr, "The issued read request can't be found for the (compressed) read command.");
|
||||
|
||||
size_t size = parentReadRequest->m_size;
|
||||
@@ -234,7 +240,7 @@ namespace AZ::IO
|
||||
AZ_Assert(parentReadRequest->m_allocator,
|
||||
"The read request was issued without a memory allocator or valid output address.");
|
||||
u64 recommendedSize = size;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
recommendedSize = m_recommendations.CalculateRecommendedMemorySize(size, parentReadRequest->m_offset);
|
||||
}
|
||||
@@ -249,12 +255,12 @@ namespace AZ::IO
|
||||
parentReadRequest->m_output = allocation.m_address;
|
||||
parentReadRequest->m_outputSize = allocation.m_size;
|
||||
parentReadRequest->m_memoryType = allocation.m_type;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
args.m_output = parentReadRequest->m_output;
|
||||
args.m_outputSize = allocation.m_size;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
args.m_output = parentReadRequest->m_output;
|
||||
}
|
||||
@@ -267,7 +273,7 @@ namespace AZ::IO
|
||||
}
|
||||
#endif
|
||||
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
m_threadData.m_lastFilePath = args.m_path;
|
||||
m_threadData.m_lastFileOffset = args.m_offset + args.m_size;
|
||||
@@ -275,7 +281,7 @@ namespace AZ::IO
|
||||
m_processingSize += args.m_size;
|
||||
#endif
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
const CompressionInfo& info = args.m_compressionInfo;
|
||||
m_threadData.m_lastFilePath = info.m_archiveFilename;
|
||||
@@ -288,15 +294,15 @@ namespace AZ::IO
|
||||
"Streamer queued %zu: %s", next->GetCommand().index(), parentReadRequest->m_path.GetRelativePath());
|
||||
m_threadData.m_streamStack->QueueRequest(next);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CancelData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CancelData>)
|
||||
{
|
||||
return Thread_ProcessCancelRequest(next, args);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::RescheduleData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::RescheduleData>)
|
||||
{
|
||||
return Thread_ProcessRescheduleRequest(next, args);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData> || AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FlushData> || AZStd::is_same_v<Command, Requests::FlushAllData>)
|
||||
{
|
||||
AZ_PROFILE_INTERVAL_START_COLORED(AzCore, next, ProfilerColor,
|
||||
"Streamer queued %zu", next->GetCommand().index());
|
||||
@@ -345,7 +351,7 @@ namespace AZ::IO
|
||||
#endif
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadRequestData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadRequestData>)
|
||||
{
|
||||
if (args.m_output == nullptr && args.m_allocator != nullptr)
|
||||
{
|
||||
@@ -393,7 +399,7 @@ namespace AZ::IO
|
||||
}
|
||||
}
|
||||
|
||||
void Scheduler::Thread_ProcessCancelRequest(FileRequest* request, FileRequest::CancelData& data)
|
||||
void Scheduler::Thread_ProcessCancelRequest(FileRequest* request, Requests::CancelData& data)
|
||||
{
|
||||
AZ_PROFILE_INTERVAL_START_COLORED(AzCore, request, ProfilerColor, "Streamer queued cancel");
|
||||
auto& pending = m_context.GetPreparedRequests();
|
||||
@@ -415,7 +421,7 @@ namespace AZ::IO
|
||||
m_threadData.m_streamStack->QueueRequest(request);
|
||||
}
|
||||
|
||||
void Scheduler::Thread_ProcessRescheduleRequest(FileRequest* request, FileRequest::RescheduleData& data)
|
||||
void Scheduler::Thread_ProcessRescheduleRequest(FileRequest* request, Requests::RescheduleData& data)
|
||||
{
|
||||
AZ_PROFILE_INTERVAL_START_COLORED(AzCore, request, ProfilerColor, "Streamer queued reschedule");
|
||||
auto& pendingRequests = m_context.GetPreparedRequests();
|
||||
@@ -424,7 +430,7 @@ namespace AZ::IO
|
||||
if (pending->WorksOn(data.m_target))
|
||||
{
|
||||
// Read requests are the only requests that use deadlines and dynamic priorities.
|
||||
auto readRequest = pending->GetCommandFromChain<FileRequest::ReadRequestData>();
|
||||
auto readRequest = pending->GetCommandFromChain<Requests::ReadRequestData>();
|
||||
if (readRequest)
|
||||
{
|
||||
readRequest->m_deadline = data.m_newDeadline;
|
||||
@@ -463,8 +469,8 @@ namespace AZ::IO
|
||||
|
||||
// Order is the same for both requests, so prioritize the request that are at risk of missing
|
||||
// it's deadline.
|
||||
const FileRequest::ReadRequestData* firstRead = first->GetCommandFromChain<FileRequest::ReadRequestData>();
|
||||
const FileRequest::ReadRequestData* secondRead = second->GetCommandFromChain<FileRequest::ReadRequestData>();
|
||||
const Requests::ReadRequestData* firstRead = first->GetCommandFromChain<Requests::ReadRequestData>();
|
||||
const Requests::ReadRequestData* secondRead = second->GetCommandFromChain<Requests::ReadRequestData>();
|
||||
|
||||
if (firstRead == nullptr || secondRead == nullptr)
|
||||
{
|
||||
@@ -496,11 +502,11 @@ namespace AZ::IO
|
||||
auto sameFile = [this](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
return m_threadData.m_lastFilePath == args.m_path;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
return m_threadData.m_lastFilePath == args.m_compressionInfo.m_archiveFilename;
|
||||
}
|
||||
@@ -517,11 +523,11 @@ namespace AZ::IO
|
||||
auto offset = [](auto&& args) -> s64
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
return aznumeric_caster(args.m_offset);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
return aznumeric_caster(args.m_compressionInfo.m_offset);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/IO/Streamer/RequestPath.h>
|
||||
#include <AzCore/IO/IStreamerTypes.h>
|
||||
#include <AzCore/IO/Streamer/Statistics.h>
|
||||
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
|
||||
@@ -24,11 +25,19 @@ namespace AZ::IO
|
||||
{
|
||||
class FileRequest;
|
||||
|
||||
namespace Requests
|
||||
{
|
||||
struct CancelData;
|
||||
struct RescheduleData;
|
||||
} // namespace Requests
|
||||
|
||||
class Scheduler final
|
||||
{
|
||||
public:
|
||||
explicit Scheduler(AZStd::shared_ptr<StreamStackEntry> streamStack, u64 memoryAlignment = AZCORE_GLOBAL_NEW_ALIGNMENT,
|
||||
u64 sizeAlignment = 1, u64 granularity = 1_mib);
|
||||
~Scheduler();
|
||||
|
||||
void Start(const AZStd::thread_desc& threadDesc);
|
||||
void Stop();
|
||||
|
||||
@@ -61,14 +70,14 @@ namespace AZ::IO
|
||||
bool Thread_ExecuteRequests();
|
||||
bool Thread_PrepareRequests(AZStd::vector<FileRequestPtr>& outstandingRequests);
|
||||
void Thread_ProcessTillIdle();
|
||||
void Thread_ProcessCancelRequest(FileRequest* request, FileRequest::CancelData& data);
|
||||
void Thread_ProcessRescheduleRequest(FileRequest* request, FileRequest::RescheduleData& data);
|
||||
void Thread_ProcessCancelRequest(FileRequest* request, Requests::CancelData& data);
|
||||
void Thread_ProcessRescheduleRequest(FileRequest* request, Requests::RescheduleData& data);
|
||||
|
||||
enum class Order
|
||||
{
|
||||
FirstRequest, //< The first request is the most important to process next.
|
||||
SecondRequest, //< The second request is the most important to process next.
|
||||
Equal //< Both requests are equally important.
|
||||
FirstRequest, //!< The first request is the most important to process next.
|
||||
SecondRequest, //!< The second request is the most important to process next.
|
||||
Equal //!< Both requests are equally important.
|
||||
};
|
||||
//! Determine which of the two provided requests is more important to process next.
|
||||
Order Thread_PrioritizeRequests(const FileRequest* first, const FileRequest* second) const;
|
||||
|
||||
@@ -60,9 +60,9 @@ namespace AZ::IO
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
AZ_Assert(request, "PrepareRequest was provided a null request.");
|
||||
|
||||
if (AZStd::holds_alternative<FileRequest::ReadRequestData>(request->GetCommand()))
|
||||
if (AZStd::holds_alternative<Requests::ReadRequestData>(request->GetCommand()))
|
||||
{
|
||||
auto& readRequest = AZStd::get<FileRequest::ReadRequestData>(request->GetCommand());
|
||||
auto& readRequest = AZStd::get<Requests::ReadRequestData>(request->GetCommand());
|
||||
|
||||
FileRequest* read = m_context->GetNewInternalRequest();
|
||||
read->CreateRead(request, readRequest.m_output, readRequest.m_outputSize, readRequest.m_path,
|
||||
@@ -79,29 +79,29 @@ namespace AZ::IO
|
||||
AZStd::visit([this, request](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData> ||
|
||||
AZStd::is_same_v<Command, FileRequest::FileExistsCheckData> ||
|
||||
AZStd::is_same_v<Command, FileRequest::FileMetaDataRetrievalData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData> ||
|
||||
AZStd::is_same_v<Command, Requests::FileExistsCheckData> ||
|
||||
AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
|
||||
{
|
||||
m_pendingRequests.push_back(request);
|
||||
return;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CancelData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CancelData>)
|
||||
{
|
||||
CancelRequest(request, args.m_target);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::FlushData>)
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::ReportData>)
|
||||
{
|
||||
Report(args);
|
||||
}
|
||||
@@ -118,15 +118,15 @@ namespace AZ::IO
|
||||
AZStd::visit([this, request](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
ReadFile(request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileExistsCheckData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileExistsCheckData>)
|
||||
{
|
||||
FileExistsRequest(request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileMetaDataRetrievalData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
|
||||
{
|
||||
FileMetaDataRetrievalRequest(request);
|
||||
}
|
||||
@@ -199,25 +199,25 @@ namespace AZ::IO
|
||||
AZStd::visit([&](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
targetFile = &args.m_path;
|
||||
readSize = args.m_size;
|
||||
offset = args.m_offset;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
targetFile = &args.m_compressionInfo.m_archiveFilename;
|
||||
readSize = args.m_compressionInfo.m_compressedSize;
|
||||
offset = args.m_compressionInfo.m_offset;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileExistsCheckData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileExistsCheckData>)
|
||||
{
|
||||
readSize = 0;
|
||||
AZStd::chrono::microseconds averageTime = m_getFileExistsTimeAverage.CalculateAverage();
|
||||
startTime += averageTime;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileMetaDataRetrievalData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
|
||||
{
|
||||
readSize = 0;
|
||||
AZStd::chrono::microseconds averageTime = m_getFileMetaDataTimeAverage.CalculateAverage();
|
||||
@@ -254,7 +254,7 @@ namespace AZ::IO
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
AZ_Assert(data, "FileRequest queued on StorageDrive to be read didn't contain read data.");
|
||||
|
||||
SystemFile* file = nullptr;
|
||||
@@ -342,7 +342,7 @@ namespace AZ::IO
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
TIMED_AVERAGE_WINDOW_SCOPE(m_getFileExistsTimeAverage);
|
||||
|
||||
auto& fileExists = AZStd::get<FileRequest::FileExistsCheckData>(request->GetCommand());
|
||||
auto& fileExists = AZStd::get<Requests::FileExistsCheckData>(request->GetCommand());
|
||||
size_t cacheIndex = FindFileInCache(fileExists.m_path);
|
||||
if (cacheIndex != s_fileNotFound)
|
||||
{
|
||||
@@ -360,7 +360,7 @@ namespace AZ::IO
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
TIMED_AVERAGE_WINDOW_SCOPE(m_getFileMetaDataTimeAverage);
|
||||
|
||||
auto& command = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
auto& command = AZStd::get<Requests::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
// If the file is already open, use the file handle which usually is cheaper than asking for the file by name.
|
||||
size_t cacheIndex = FindFileInCache(command.m_path);
|
||||
if (cacheIndex != s_fileNotFound)
|
||||
@@ -446,11 +446,11 @@ namespace AZ::IO
|
||||
}
|
||||
}
|
||||
|
||||
void StorageDrive::Report(const FileRequest::ReportData& data) const
|
||||
void StorageDrive::Report(const Requests::ReportData& data) const
|
||||
{
|
||||
switch (data.m_reportType)
|
||||
{
|
||||
case FileRequest::ReportData::ReportType::FileLocks:
|
||||
case Requests::ReportType::FileLocks:
|
||||
for (u32 i = 0; i < m_fileHandles.size(); ++i)
|
||||
{
|
||||
if (m_fileHandles[i] != nullptr)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/IO/Streamer/RequestPath.h>
|
||||
#include <AzCore/IO/Streamer/Statistics.h>
|
||||
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
|
||||
#include <AzCore/IO/Streamer/StreamStackEntry.h>
|
||||
@@ -16,6 +17,11 @@
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/chrono/clocks.h>
|
||||
|
||||
namespace AZ::IO::Requests
|
||||
{
|
||||
struct ReportData;
|
||||
}
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
struct StorageDriveConfig final :
|
||||
@@ -72,7 +78,7 @@ namespace AZ::IO
|
||||
void EstimateCompletionTimeForRequest(FileRequest* request, AZStd::chrono::system_clock::time_point& startTime,
|
||||
const RequestPath*& activeFile, u64& activeOffset) const;
|
||||
|
||||
void Report(const FileRequest::ReportData& data) const;
|
||||
void Report(const Requests::ReportData& data) const;
|
||||
|
||||
TimedAverageWindow<s_statisticsWindowSize> m_fileOpenCloseTimeAverage;
|
||||
TimedAverageWindow<s_statisticsWindowSize> m_getFileExistsTimeAverage;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/IO/CompressionBus.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/IO/Streamer/Streamer.h>
|
||||
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
|
||||
#include <AzCore/IO/Streamer/StreamStackEntry.h>
|
||||
@@ -210,7 +211,7 @@ namespace AZ::IO
|
||||
IStreamerTypes::ClaimMemory claimMemory) const
|
||||
{
|
||||
AZ_Assert(request.m_request, "The request handle provided to Streamer::GetReadRequestResult is invalid.");
|
||||
auto readRequest = AZStd::get_if<FileRequest::ReadRequestData>(&request.m_request->GetCommand());
|
||||
auto readRequest = AZStd::get_if<Requests::ReadRequestData>(&request.m_request->GetCommand());
|
||||
if (readRequest != nullptr)
|
||||
{
|
||||
buffer = readRequest->m_output;
|
||||
@@ -281,14 +282,14 @@ namespace AZ::IO
|
||||
}
|
||||
}
|
||||
|
||||
FileRequestPtr Streamer::Report(FileRequest::ReportData::ReportType reportType)
|
||||
FileRequestPtr Streamer::Report(Requests::ReportType reportType)
|
||||
{
|
||||
FileRequestPtr result = CreateRequest();
|
||||
Report(result, reportType);
|
||||
return result;
|
||||
}
|
||||
|
||||
FileRequestPtr& Streamer::Report(FileRequestPtr& request, FileRequest::ReportData::ReportType reportType)
|
||||
FileRequestPtr& Streamer::Report(FileRequestPtr& request, Requests::ReportType reportType)
|
||||
{
|
||||
request->m_request.CreateReport(reportType);
|
||||
return request;
|
||||
|
||||
@@ -20,6 +20,10 @@ namespace AZStd
|
||||
struct thread_desc;
|
||||
}
|
||||
|
||||
namespace AZ::IO::Requests
|
||||
{
|
||||
enum class ReportType : int8_t;
|
||||
}
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
@@ -185,9 +189,9 @@ namespace AZ::IO
|
||||
void RecordStatistics();
|
||||
|
||||
//! Tells AZ::IO::Streamer the report the information for the report to the output.
|
||||
FileRequestPtr Report(FileRequest::ReportData::ReportType reportType);
|
||||
FileRequestPtr Report(Requests::ReportType reportType);
|
||||
//! Tells AZ::IO::Streamer the report the information for the report to the output.
|
||||
FileRequestPtr& Report(FileRequestPtr& request, FileRequest::ReportData::ReportType reportType);
|
||||
FileRequestPtr& Report(FileRequestPtr& request, Requests::ReportType reportType);
|
||||
|
||||
|
||||
Streamer(const AZStd::thread_desc& threadDesc, AZStd::unique_ptr<Scheduler> streamStack);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/IO/Streamer/BlockCache.h>
|
||||
#include <AzCore/IO/Streamer/DedicatedCache.h>
|
||||
#include <AzCore/IO/Streamer/FullFileDecompressor.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/IO/Streamer/Scheduler.h>
|
||||
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
||||
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
|
||||
@@ -207,7 +208,7 @@ namespace AZ
|
||||
{
|
||||
if (m_streamer)
|
||||
{
|
||||
m_streamer->QueueRequest(m_streamer->Report(AZ::IO::FileRequest::ReportData::ReportType::FileLocks));
|
||||
m_streamer->QueueRequest(m_streamer->Report(AZ::IO::Requests::ReportType::FileLocks));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ namespace AZ
|
||||
static constexpr char LatePredictionName[] = "Early completions";
|
||||
static constexpr char MissedDeadlinesName[] = "Missed deadlines";
|
||||
#endif // AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
|
||||
|
||||
StreamerContext::StreamerContext()
|
||||
{
|
||||
}
|
||||
StreamerContext::~StreamerContext()
|
||||
{
|
||||
for (FileRequest* entry : m_internalRecycleBin)
|
||||
@@ -204,7 +208,7 @@ namespace AZ
|
||||
m_latePredictionsPercentageStat.GetMostRecentSample());
|
||||
}
|
||||
}
|
||||
auto readRequest = AZStd::get_if<FileRequest::ReadRequestData>(&top->GetCommand());
|
||||
auto readRequest = AZStd::get_if<Requests::ReadRequestData>(&top->GetCommand());
|
||||
if (readRequest != nullptr)
|
||||
{
|
||||
m_missedDeadlinePercentageStat.PushSample(now < readRequest->m_deadline ? 0.0 : 1.0);
|
||||
|
||||
@@ -7,23 +7,28 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/IO/Streamer/Statistics.h>
|
||||
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
|
||||
#include <AzCore/IO/Streamer/StreamerContext_Platform.h>
|
||||
#include <AzCore/std/containers/deque.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/containers/queue.h>
|
||||
#include <AzCore/Statistics/RunningStatistic.h>
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/std/containers/deque.h>
|
||||
#include <AzCore/std/containers/queue.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
class FileRequest;
|
||||
class ExternalFileRequest;
|
||||
|
||||
using FileRequestPtr = AZStd::intrusive_ptr<ExternalFileRequest>;
|
||||
|
||||
class StreamerContext
|
||||
{
|
||||
public:
|
||||
using PreparedQueue = AZStd::deque<FileRequest*>;
|
||||
|
||||
StreamerContext();
|
||||
~StreamerContext();
|
||||
|
||||
//! Gets a new file request, either by creating a new instance or
|
||||
|
||||
+26
-26
@@ -172,9 +172,9 @@ namespace AZ::IO
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
AZ_Assert(request, "PrepareRequest was provided a null request.");
|
||||
|
||||
if (AZStd::holds_alternative<FileRequest::ReadRequestData>(request->GetCommand()))
|
||||
if (AZStd::holds_alternative<Requests::ReadRequestData>(request->GetCommand()))
|
||||
{
|
||||
auto& readRequest = AZStd::get<FileRequest::ReadRequestData>(request->GetCommand());
|
||||
auto& readRequest = AZStd::get<Requests::ReadRequestData>(request->GetCommand());
|
||||
if (IsServicedByThisDrive(readRequest.m_path.GetAbsolutePath()))
|
||||
{
|
||||
FileRequest* read = m_context->GetNewInternalRequest();
|
||||
@@ -195,7 +195,7 @@ namespace AZ::IO
|
||||
AZStd::visit([this, request](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
if (IsServicedByThisDrive(args.m_path.GetAbsolutePath()))
|
||||
{
|
||||
@@ -203,8 +203,8 @@ namespace AZ::IO
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileExistsCheckData> ||
|
||||
AZStd::is_same_v<Command, FileRequest::FileMetaDataRetrievalData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileExistsCheckData> ||
|
||||
AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
|
||||
{
|
||||
if (IsServicedByThisDrive(args.m_path.GetAbsolutePath()))
|
||||
{
|
||||
@@ -212,7 +212,7 @@ namespace AZ::IO
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CancelData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CancelData>)
|
||||
{
|
||||
if (CancelRequest(request, args.m_target))
|
||||
{
|
||||
@@ -221,15 +221,15 @@ namespace AZ::IO
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FlushData>)
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::ReportData>)
|
||||
{
|
||||
Report(args);
|
||||
}
|
||||
@@ -257,13 +257,13 @@ namespace AZ::IO
|
||||
hasWorked = AZStd::visit([this, request](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::FileExistsCheckData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::FileExistsCheckData>)
|
||||
{
|
||||
FileExistsRequest(request);
|
||||
m_pendingRequests.pop_front();
|
||||
return true;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileMetaDataRetrievalData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
|
||||
{
|
||||
FileMetaDataRetrievalRequest(request);
|
||||
m_pendingRequests.pop_front();
|
||||
@@ -308,7 +308,7 @@ namespace AZ::IO
|
||||
FileReadInformation& read = m_readSlots_readInfo[i];
|
||||
u64 totalBytesRead = m_readSizeAverage.GetTotal();
|
||||
double totalReadTimeUSec = aznumeric_caster(m_readTimeAverage.GetTotal().count());
|
||||
auto readCommand = AZStd::get_if<FileRequest::ReadData>(&read.m_request->GetCommand());
|
||||
auto readCommand = AZStd::get_if<Requests::ReadData>(&read.m_request->GetCommand());
|
||||
AZ_Assert(readCommand, "Request currently reading doesn't contain a read command.");
|
||||
auto endTime = read.m_startTime + AZStd::chrono::microseconds(aznumeric_cast<u64>((readCommand->m_size * totalReadTimeUSec) / totalBytesRead));
|
||||
earliestSlot = AZStd::min(earliestSlot, endTime);
|
||||
@@ -354,25 +354,25 @@ namespace AZ::IO
|
||||
AZStd::visit([&](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
targetFile = &args.m_path;
|
||||
readSize = args.m_size;
|
||||
offset = args.m_offset;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
targetFile = &args.m_compressionInfo.m_archiveFilename;
|
||||
readSize = args.m_compressionInfo.m_compressedSize;
|
||||
offset = args.m_compressionInfo.m_offset;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileExistsCheckData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileExistsCheckData>)
|
||||
{
|
||||
readSize = 0;
|
||||
AZStd::chrono::microseconds getFileExistsTimeAverage = m_getFileExistsTimeAverage.CalculateAverage();
|
||||
startTime += getFileExistsTimeAverage;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileMetaDataRetrievalData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
|
||||
{
|
||||
readSize = 0;
|
||||
AZStd::chrono::microseconds getFileExistsTimeAverage = m_getFileMetaDataRetrievalTimeAverage.CalculateAverage();
|
||||
@@ -411,15 +411,15 @@ namespace AZ::IO
|
||||
AZStd::visit([&, this](auto&& args)
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData> ||
|
||||
AZStd::is_same_v<Command, FileRequest::FileExistsCheckData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData> ||
|
||||
AZStd::is_same_v<Command, Requests::FileExistsCheckData>)
|
||||
{
|
||||
if (IsServicedByThisDrive(args.m_path.GetAbsolutePath()))
|
||||
{
|
||||
EstimateCompletionTimeForRequest(request, startTime, activeFile, activeOffset);
|
||||
}
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
if (IsServicedByThisDrive(args.m_compressionInfo.m_archiveFilename.GetAbsolutePath()))
|
||||
{
|
||||
@@ -435,7 +435,7 @@ namespace AZ::IO
|
||||
aznumeric_cast<s32>(m_pendingRequests.size()) - m_activeReads_Count;
|
||||
}
|
||||
|
||||
auto StorageDriveWin::OpenFile(HANDLE& fileHandle, size_t& cacheSlot, FileRequest* request, const FileRequest::ReadData& data) -> OpenFileResult
|
||||
auto StorageDriveWin::OpenFile(HANDLE& fileHandle, size_t& cacheSlot, FileRequest* request, const Requests::ReadData& data) -> OpenFileResult
|
||||
{
|
||||
HANDLE file = INVALID_HANDLE_VALUE;
|
||||
|
||||
@@ -553,7 +553,7 @@ namespace AZ::IO
|
||||
return false;
|
||||
}
|
||||
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
AZ_Assert(data, "Read request in StorageDriveWin doesn't contain read data.");
|
||||
|
||||
HANDLE file = INVALID_HANDLE_VALUE;
|
||||
@@ -780,7 +780,7 @@ namespace AZ::IO
|
||||
|
||||
void StorageDriveWin::FileExistsRequest(FileRequest* request)
|
||||
{
|
||||
auto& fileExists = AZStd::get<FileRequest::FileExistsCheckData>(request->GetCommand());
|
||||
auto& fileExists = AZStd::get<Requests::FileExistsCheckData>(request->GetCommand());
|
||||
|
||||
AZ_PROFILE_SCOPE(AzCore, "StorageDriveWin::FileExistsRequest %s : %s",
|
||||
m_name.c_str(), fileExists.m_path.GetRelativePath());
|
||||
@@ -836,7 +836,7 @@ namespace AZ::IO
|
||||
|
||||
void StorageDriveWin::FileMetaDataRetrievalRequest(FileRequest* request)
|
||||
{
|
||||
auto& command = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
auto& command = AZStd::get<Requests::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
|
||||
AZ_PROFILE_SCOPE(AzCore, "StorageDriveWin::FileMetaDataRetrievalRequest %s : %s",
|
||||
m_name.c_str(), command.m_path.GetRelativePath());
|
||||
@@ -1005,7 +1005,7 @@ namespace AZ::IO
|
||||
|
||||
FileReadInformation& fileReadInfo = m_readSlots_readInfo[readSlot];
|
||||
|
||||
auto readCommand = AZStd::get_if<FileRequest::ReadData>(&fileReadInfo.m_request->GetCommand());
|
||||
auto readCommand = AZStd::get_if<Requests::ReadData>(&fileReadInfo.m_request->GetCommand());
|
||||
AZ_Assert(readCommand != nullptr, "Request stored with the overlapped I/O call did not contain a read request.");
|
||||
|
||||
if (fileReadInfo.m_sectorAlignedOutput && !encounteredError)
|
||||
@@ -1147,11 +1147,11 @@ namespace AZ::IO
|
||||
StreamStackEntry::CollectStatistics(statistics);
|
||||
}
|
||||
|
||||
void StorageDriveWin::Report(const FileRequest::ReportData& data) const
|
||||
void StorageDriveWin::Report(const Requests::ReportData& data) const
|
||||
{
|
||||
switch (data.m_reportType)
|
||||
{
|
||||
case FileRequest::ReportData::ReportType::FileLocks:
|
||||
case Requests::ReportType::FileLocks:
|
||||
if (m_cachesInitialized)
|
||||
{
|
||||
for (u32 i = 0; i < m_maxFileHandles; ++i)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <AzCore/IO/Streamer/RequestPath.h>
|
||||
#include <AzCore/IO/Streamer/Statistics.h>
|
||||
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
|
||||
#include <AzCore/IO/Streamer/StreamStackEntry.h>
|
||||
@@ -19,6 +20,12 @@
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzCore/Statistics/RunningStatistic.h>
|
||||
|
||||
namespace AZ::IO::Requests
|
||||
{
|
||||
struct ReadData;
|
||||
struct ReportData;
|
||||
}
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
class StorageDriveWin
|
||||
@@ -111,7 +118,7 @@ namespace AZ::IO
|
||||
CacheFull
|
||||
};
|
||||
|
||||
OpenFileResult OpenFile(HANDLE& fileHandle, size_t& cacheSlot, FileRequest* request, const FileRequest::ReadData& data);
|
||||
OpenFileResult OpenFile(HANDLE& fileHandle, size_t& cacheSlot, FileRequest* request, const Requests::ReadData& data);
|
||||
bool ReadRequest(FileRequest* request);
|
||||
bool ReadRequest(FileRequest* request, size_t readSlot);
|
||||
bool CancelRequest(FileRequest* cancelRequest, FileRequestPtr& target);
|
||||
@@ -137,7 +144,7 @@ namespace AZ::IO
|
||||
void FinalizeSingleRequest(FileReadStatus& status, size_t readSlot, DWORD numBytesTransferred,
|
||||
bool isCanceled, bool encounteredError);
|
||||
|
||||
void Report(const FileRequest::ReportData& data) const;
|
||||
void Report(const Requests::ReportData& data) const;
|
||||
|
||||
TimedAverageWindow<s_statisticsWindowSize> m_fileOpenCloseTimeAverage;
|
||||
TimedAverageWindow<s_statisticsWindowSize> m_getFileExistsTimeAverage;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Asset/AssetDataStream.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AZTestShared/Utils/Utils.h>
|
||||
#include <Tests/Streamer/IStreamerMock.h>
|
||||
|
||||
+13
-13
@@ -406,7 +406,7 @@ namespace AZ::IO
|
||||
request->CreateFileMetaDataRetrieval(path);
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
EXPECT_FALSE(fileMetaData.m_found);
|
||||
EXPECT_EQ(0, fileMetaData.m_fileSize);
|
||||
});
|
||||
@@ -424,7 +424,7 @@ namespace AZ::IO
|
||||
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
EXPECT_TRUE(fileMetaData.m_found);
|
||||
EXPECT_EQ(4_kib, fileMetaData.m_fileSize);
|
||||
});
|
||||
@@ -442,7 +442,7 @@ namespace AZ::IO
|
||||
request->CreateFileMetaDataRetrieval(path);
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
EXPECT_FALSE(fileMetaData.m_found);
|
||||
EXPECT_EQ(0, fileMetaData.m_fileSize);
|
||||
});
|
||||
@@ -460,7 +460,7 @@ namespace AZ::IO
|
||||
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
EXPECT_TRUE(fileMetaData.m_found);
|
||||
EXPECT_EQ(16_kib, fileMetaData.m_fileSize);
|
||||
});
|
||||
@@ -484,7 +484,7 @@ namespace AZ::IO
|
||||
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileMetaData = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
auto& fileMetaData = AZStd::get<Requests::FileMetaDataRetrievalData>(request.GetCommand());
|
||||
EXPECT_TRUE(fileMetaData.m_found);
|
||||
EXPECT_EQ(4_kib, fileMetaData.m_fileSize);
|
||||
});
|
||||
@@ -502,7 +502,7 @@ namespace AZ::IO
|
||||
request->CreateFileExistsCheck(invalidPath);
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
|
||||
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
|
||||
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
|
||||
EXPECT_FALSE(fileExistsCheck.m_found);
|
||||
});
|
||||
@@ -519,7 +519,7 @@ namespace AZ::IO
|
||||
request->CreateFileExistsCheck(path);
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
|
||||
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
|
||||
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
|
||||
EXPECT_FALSE(fileExistsCheck.m_found);
|
||||
});
|
||||
@@ -535,7 +535,7 @@ namespace AZ::IO
|
||||
request->CreateFileExistsCheck(m_dummyRequestPath);
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
|
||||
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
|
||||
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
|
||||
EXPECT_TRUE(fileExistsCheck.m_found);
|
||||
});
|
||||
@@ -551,7 +551,7 @@ namespace AZ::IO
|
||||
request->CreateFileExistsCheck(m_dummyRequestPath);
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
|
||||
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
|
||||
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
|
||||
EXPECT_TRUE(fileExistsCheck.m_found);
|
||||
});
|
||||
@@ -573,7 +573,7 @@ namespace AZ::IO
|
||||
request->CreateFileExistsCheck(m_dummyRequestPath);
|
||||
request->SetCompletionCallback([](const FileRequest& request)
|
||||
{
|
||||
auto& fileExistsCheck = AZStd::get<FileRequest::FileExistsCheckData>(request.GetCommand());
|
||||
auto& fileExistsCheck = AZStd::get<Requests::FileExistsCheckData>(request.GetCommand());
|
||||
EXPECT_EQ(AZ::IO::IStreamerTypes::RequestStatus::Completed, request.GetStatus());
|
||||
EXPECT_TRUE(fileExistsCheck.m_found);
|
||||
});
|
||||
@@ -603,7 +603,7 @@ namespace AZ::IO
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
|
||||
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
|
||||
auto& readRequest = AZStd::get<AZ::IO::Requests::ReadData>(request.GetCommand());
|
||||
EXPECT_EQ(readRequest.m_size, fileSize);
|
||||
EXPECT_STREQ(readRequest.m_path.GetAbsolutePath(), m_dummyFilepath.c_str());
|
||||
};
|
||||
@@ -648,7 +648,7 @@ namespace AZ::IO
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
|
||||
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
|
||||
auto& readRequest = AZStd::get<AZ::IO::Requests::ReadData>(request.GetCommand());
|
||||
EXPECT_EQ(readRequest.m_size, unalignedSize);
|
||||
EXPECT_EQ(readRequest.m_offset, unalignedOffset);
|
||||
EXPECT_STREQ(readRequest.m_path.GetAbsolutePath(), m_dummyFilepath.c_str());
|
||||
@@ -796,7 +796,7 @@ namespace AZ::IO
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
EXPECT_EQ(request.GetStatus(), AZ::IO::IStreamerTypes::RequestStatus::Completed);
|
||||
auto& readRequest = AZStd::get<AZ::IO::FileRequest::ReadData>(request.GetCommand());
|
||||
auto& readRequest = AZStd::get<AZ::IO::Requests::ReadData>(request.GetCommand());
|
||||
EXPECT_EQ(readRequest.m_size, chunkSize);
|
||||
EXPECT_EQ(readRequest.m_offset, i * chunkSize);
|
||||
};
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace AZ::IO
|
||||
|
||||
void QueueReadRequest(FileRequest* request)
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
if (data)
|
||||
{
|
||||
if (m_fakeFileFound)
|
||||
@@ -122,15 +122,15 @@ namespace AZ::IO
|
||||
m_context->MarkRequestAsCompleted(request);
|
||||
}
|
||||
else if (
|
||||
AZStd::holds_alternative<FileRequest::FlushData>(request->GetCommand()) ||
|
||||
AZStd::holds_alternative<FileRequest::FlushAllData>(request->GetCommand()))
|
||||
AZStd::holds_alternative<Requests::FlushData>(request->GetCommand()) ||
|
||||
AZStd::holds_alternative<Requests::FlushAllData>(request->GetCommand()))
|
||||
{
|
||||
request->SetStatus(IStreamerTypes::RequestStatus::Completed);
|
||||
m_context->MarkRequestAsCompleted(request);
|
||||
}
|
||||
else if (AZStd::holds_alternative<FileRequest::FileMetaDataRetrievalData>(request->GetCommand()))
|
||||
else if (AZStd::holds_alternative<Requests::FileMetaDataRetrievalData>(request->GetCommand()))
|
||||
{
|
||||
auto& data2 = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
auto& data2 = AZStd::get<Requests::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
data2.m_found = m_fakeFileFound;
|
||||
data2.m_fileSize = m_fakeFileLength;
|
||||
request->SetStatus(m_fakeFileFound ? IStreamerTypes::RequestStatus::Completed : IStreamerTypes::RequestStatus::Failed);
|
||||
@@ -158,16 +158,16 @@ namespace AZ::IO
|
||||
|
||||
void QueueCanceledReadRequest(FileRequest* request)
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
if (data)
|
||||
{
|
||||
ReadFile(data->m_output, data->m_path, data->m_offset, data->m_size);
|
||||
request->SetStatus(IStreamerTypes::RequestStatus::Canceled);
|
||||
m_context->MarkRequestAsCompleted(request);
|
||||
}
|
||||
else if (AZStd::holds_alternative<FileRequest::FileMetaDataRetrievalData>(request->GetCommand()))
|
||||
else if (AZStd::holds_alternative<Requests::FileMetaDataRetrievalData>(request->GetCommand()))
|
||||
{
|
||||
auto& data2 = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
auto& data2 = AZStd::get<Requests::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
data2.m_found = true;
|
||||
data2.m_fileSize = m_fakeFileLength;
|
||||
request->SetStatus(IStreamerTypes::RequestStatus::Completed);
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace AZ::IO
|
||||
|
||||
void PrepareReadRequest(FileRequest* request)
|
||||
{
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
ASSERT_NE(nullptr, data);
|
||||
|
||||
u64 size = data->m_size >> 2;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
|
||||
using namespace AZ::IO;
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace AZ::IO
|
||||
{
|
||||
EXPECT_EQ(subRequests[i]->GetParent(), readRequest);
|
||||
|
||||
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequests[i]->GetCommand());
|
||||
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequests[i]->GetCommand());
|
||||
ASSERT_NE(nullptr, data);
|
||||
EXPECT_EQ(SplitSize, data->m_size);
|
||||
EXPECT_EQ(SplitSize * i, data->m_offset);
|
||||
@@ -210,7 +210,7 @@ namespace AZ::IO
|
||||
{
|
||||
EXPECT_EQ(subRequests[i]->GetParent(), readRequest);
|
||||
|
||||
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequests[i]->GetCommand());
|
||||
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequests[i]->GetCommand());
|
||||
ASSERT_NE(nullptr, data);
|
||||
EXPECT_EQ(SplitSize, data->m_size);
|
||||
EXPECT_EQ(SplitSize * i, data->m_offset);
|
||||
@@ -230,7 +230,7 @@ namespace AZ::IO
|
||||
{
|
||||
EXPECT_EQ(subRequests[i]->GetParent(), readRequest);
|
||||
|
||||
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequests[i]->GetCommand());
|
||||
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequests[i]->GetCommand());
|
||||
ASSERT_NE(nullptr, data);
|
||||
EXPECT_EQ(SplitSize, data->m_size);
|
||||
EXPECT_EQ(SplitSize * (batchSize + i), data->m_offset);
|
||||
@@ -265,7 +265,7 @@ namespace AZ::IO
|
||||
m_readSplitter->QueueRequest(readRequest);
|
||||
|
||||
ASSERT_NE(nullptr, subRequest);
|
||||
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequest->GetCommand());
|
||||
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequest->GetCommand());
|
||||
EXPECT_NE(buffer, data->m_output);
|
||||
EXPECT_EQ(readSize, data->m_size);
|
||||
EXPECT_EQ(0, data->m_offset);
|
||||
@@ -311,7 +311,7 @@ namespace AZ::IO
|
||||
m_readSplitter->QueueRequest(readRequest);
|
||||
|
||||
ASSERT_NE(nullptr, subRequest);
|
||||
FileRequest::ReadData* data = AZStd::get_if<FileRequest::ReadData>(&subRequest->GetCommand());
|
||||
Requests::ReadData* data = AZStd::get_if<Requests::ReadData>(&subRequest->GetCommand());
|
||||
EXPECT_NE(buffer, data->m_output);
|
||||
EXPECT_EQ(readSize + offsetAdjustment, data->m_size);
|
||||
EXPECT_EQ(0, data->m_offset);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AzCore/Casting/lossy_cast.h>
|
||||
#include <AzCore/IO/Streamer/Streamer.h>
|
||||
#include <AzCore/IO/Streamer/Scheduler.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/std/parallel/atomic.h>
|
||||
#include <AzCore/std/parallel/binary_semaphore.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
@@ -86,7 +87,7 @@ namespace AZ::IO
|
||||
.WillOnce([this](FileRequest* request)
|
||||
{
|
||||
AZ_Assert(m_streamerContext, "AZ::IO::Streamer is not ready to process requests.");
|
||||
auto readData = AZStd::get_if<FileRequest::ReadRequestData>(&request->GetCommand());
|
||||
auto readData = AZStd::get_if<Requests::ReadRequestData>(&request->GetCommand());
|
||||
AZ_Assert(readData, "Test didn't pass in the correct request.");
|
||||
FileRequest* read = m_streamerContext->GetNewInternalRequest();
|
||||
read->CreateRead(request, readData->m_output, readData->m_outputSize, readData->m_path,
|
||||
@@ -99,7 +100,7 @@ namespace AZ::IO
|
||||
.WillOnce([this](FileRequest* request)
|
||||
{
|
||||
AZ_Assert(m_streamerContext, "AZ::IO::Streamer is not ready to process requests.");
|
||||
auto readData = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto readData = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
AZ_Assert(readData, "Test didn't pass in the correct request.");
|
||||
auto output = reinterpret_cast<uint8_t*>(readData->m_output);
|
||||
AZ_Assert(output != nullptr, "Output buffer has not been set.");
|
||||
@@ -304,7 +305,7 @@ namespace AZ::IO
|
||||
EXPECT_CALL(*m_mock, QueueRequest(_)).Times(1)
|
||||
.WillOnce(Invoke([this](FileRequest* request)
|
||||
{
|
||||
auto* read = request->GetCommandFromChain<FileRequest::ReadRequestData>();
|
||||
auto* read = request->GetCommandFromChain<Requests::ReadRequestData>();
|
||||
ASSERT_NE(nullptr, read);
|
||||
EXPECT_LT(read->m_deadline, FileRequest::s_noDeadlineTime);
|
||||
EXPECT_EQ(read->m_priority, IStreamerTypes::s_priorityHighest);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <limits>
|
||||
#include <AzCore/IO/IStreamerTypes.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/IO/Streamer/StreamerContext.h>
|
||||
#include <AzCore/IO/Streamer/StreamStackEntry.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <FileIOBaseTestTypes.h>
|
||||
#include <AzCore/IO/CompressionBus.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/IO/Streamer/Streamer.h>
|
||||
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
||||
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/chrono/chrono.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
@@ -83,9 +83,9 @@ namespace AzFramework
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
AZ_Assert(request, "PrepareRequest was provided a null request.");
|
||||
|
||||
if (AZStd::holds_alternative<FileRequest::ReadRequestData>(request->GetCommand()))
|
||||
if (AZStd::holds_alternative<Requests::ReadRequestData>(request->GetCommand()))
|
||||
{
|
||||
auto& readRequest = AZStd::get<FileRequest::ReadRequestData>(request->GetCommand());
|
||||
auto& readRequest = AZStd::get<Requests::ReadRequestData>(request->GetCommand());
|
||||
|
||||
FileRequest* read = m_context->GetNewInternalRequest();
|
||||
read->CreateRead(request, readRequest.m_output, readRequest.m_outputSize, readRequest.m_path,
|
||||
@@ -106,14 +106,14 @@ namespace AzFramework
|
||||
{
|
||||
using namespace AZ::IO;
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData> ||
|
||||
AZStd::is_same_v<Command, FileRequest::FileExistsCheckData> ||
|
||||
AZStd::is_same_v<Command, FileRequest::FileMetaDataRetrievalData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData> ||
|
||||
AZStd::is_same_v<Command, Requests::FileExistsCheckData> ||
|
||||
AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
|
||||
{
|
||||
m_pendingRequests.push_back(request);
|
||||
return;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CancelData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CancelData>)
|
||||
{
|
||||
if (CancelRequest(request, args.m_target))
|
||||
{
|
||||
@@ -124,15 +124,15 @@ namespace AzFramework
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::FlushData>)
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::ReportData>)
|
||||
{
|
||||
Report(args);
|
||||
}
|
||||
@@ -152,15 +152,15 @@ namespace AzFramework
|
||||
{
|
||||
using namespace AZ::IO;
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
ReadFile(request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileExistsCheckData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileExistsCheckData>)
|
||||
{
|
||||
FileExistsRequest(request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileMetaDataRetrievalData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
|
||||
{
|
||||
FileMetaDataRetrievalRequest(request);
|
||||
}
|
||||
@@ -232,23 +232,23 @@ namespace AzFramework
|
||||
{
|
||||
using namespace AZ::IO;
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::ReadData>)
|
||||
if constexpr (AZStd::is_same_v<Command, Requests::ReadData>)
|
||||
{
|
||||
targetFile = &args.m_path;
|
||||
readSize = args.m_size;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::CompressedReadData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::CompressedReadData>)
|
||||
{
|
||||
targetFile = &args.m_compressionInfo.m_archiveFilename;
|
||||
readSize = args.m_compressionInfo.m_compressedSize;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileExistsCheckData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileExistsCheckData>)
|
||||
{
|
||||
readSize = 0;
|
||||
AZStd::chrono::microseconds averageTime = m_getFileExistsTimeAverage.CalculateAverage();
|
||||
startTime += averageTime;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FileMetaDataRetrievalData>)
|
||||
else if constexpr (AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
|
||||
{
|
||||
readSize = 0;
|
||||
AZStd::chrono::microseconds averageTime = m_getFileMetaDataTimeAverage.CalculateAverage();
|
||||
@@ -280,7 +280,7 @@ namespace AzFramework
|
||||
|
||||
AZ_PROFILE_FUNCTION(AzCore);
|
||||
|
||||
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
|
||||
auto data = AZStd::get_if<Requests::ReadData>(&request->GetCommand());
|
||||
AZ_Assert(data, "Request doing reading in the RemoteStorageDrive didn't contain read data.");
|
||||
|
||||
HandleType file = InvalidHandle;
|
||||
@@ -397,7 +397,7 @@ namespace AzFramework
|
||||
|
||||
TIMED_AVERAGE_WINDOW_SCOPE(m_getFileExistsTimeAverage);
|
||||
|
||||
auto& fileExists = AZStd::get<FileRequest::FileExistsCheckData>(request->GetCommand());
|
||||
auto& fileExists = AZStd::get<Requests::FileExistsCheckData>(request->GetCommand());
|
||||
size_t cacheIndex = FindFileInCache(fileExists.m_path);
|
||||
if (cacheIndex != s_fileNotFound)
|
||||
{
|
||||
@@ -430,7 +430,7 @@ namespace AzFramework
|
||||
AZ::u64 fileSize = 0;
|
||||
bool found = false;
|
||||
|
||||
auto& command = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
auto& command = AZStd::get<Requests::FileMetaDataRetrievalData>(request->GetCommand());
|
||||
// If the file is already open, use the file handle which usually is cheaper than asking for the file by name.
|
||||
size_t cacheIndex = FindFileInCache(command.m_path);
|
||||
if (cacheIndex != s_fileNotFound)
|
||||
@@ -526,13 +526,13 @@ namespace AzFramework
|
||||
StreamStackEntry::CollectStatistics(statistics);
|
||||
}
|
||||
|
||||
void RemoteStorageDrive::Report(const AZ::IO::FileRequest::ReportData& data) const
|
||||
void RemoteStorageDrive::Report(const AZ::IO::Requests::ReportData& data) const
|
||||
{
|
||||
using namespace AZ::IO;
|
||||
|
||||
switch (data.m_reportType)
|
||||
{
|
||||
case FileRequest::ReportData::ReportType::FileLocks:
|
||||
case Requests::ReportType::FileLocks:
|
||||
for (AZ::u32 i = 0; i < m_fileHandles.size(); ++i)
|
||||
{
|
||||
if (m_fileHandles[i] != InvalidHandle)
|
||||
|
||||
@@ -16,6 +16,15 @@
|
||||
#include <AzCore/std/chrono/clocks.h>
|
||||
#include <AzFramework/IO/RemoteFileIO.h>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
class RequestPath;
|
||||
namespace Requests
|
||||
{
|
||||
struct ReportData;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
struct RemoteStorageDriveConfig final :
|
||||
@@ -63,7 +72,7 @@ namespace AzFramework
|
||||
const AZ::IO::RequestPath*& activeFile) const;
|
||||
void FlushCache(const AZ::IO::RequestPath& filePath);
|
||||
void FlushEntireCache();
|
||||
void Report(const AZ::IO::FileRequest::ReportData& data) const;
|
||||
void Report(const AZ::IO::Requests::ReportData& data) const;
|
||||
|
||||
AZ::IO::RemoteFileIO m_fileIO;
|
||||
AZ::IO::TimedAverageWindow<AZ::IO::s_statisticsWindowSize> m_fileOpenCloseTimeAverage;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
#include <AzFramework/Physics/PhysicsScene.h>
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
|
||||
+1
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBodyAutomation.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBodyEvents.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <AzFramework/Physics/PhysicsScene.h>
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <AzFramework/Physics/Configuration/SceneConfiguration.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AzPhysics
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
|
||||
+1
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
|
||||
+3
-2
@@ -10,12 +10,13 @@
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#endif
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
using namespace AzToolsFramework::AssetBrowser;
|
||||
|
||||
|
||||
//! Model storing all the files that can be suggested in the Asset Autocompleter for PropertyAssetCtrl
|
||||
class AssetCompleterModel
|
||||
: public QAbstractTableModel
|
||||
@@ -45,7 +46,7 @@ namespace AzToolsFramework
|
||||
void SetFetchEntryType(AssetBrowserEntry::AssetEntryType entryType);
|
||||
|
||||
private:
|
||||
struct AssetItem
|
||||
struct AssetItem
|
||||
{
|
||||
AZStd::string m_displayName;
|
||||
AZStd::string m_path;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderVariantAsset.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderVariantTreeAsset.h>
|
||||
#include <Atom/RPI.Reflect/Shader/IShaderVariantFinder.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class ReflectContext;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Name/Name.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -267,7 +267,7 @@ namespace AZ
|
||||
return m_visScene->GetEntryCount();
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct WorklistData
|
||||
{
|
||||
CullingDebugContext* m_debugCtx = nullptr;
|
||||
@@ -296,13 +296,13 @@ namespace AZ
|
||||
#endif
|
||||
return worklistData;
|
||||
}
|
||||
|
||||
|
||||
constexpr size_t WorkListCapacity = 5;
|
||||
using WorkListType = AZStd::fixed_vector<AzFramework::IVisibilityScene::NodeData, WorkListCapacity>;
|
||||
|
||||
#if AZ_TRAIT_MASKED_OCCLUSION_CULLING_SUPPORTED
|
||||
static MaskedOcclusionCulling::CullingResult TestOcclusionCulling(
|
||||
const AZStd::shared_ptr<WorklistData>& worklistData,
|
||||
const AZStd::shared_ptr<WorklistData>& worklistData,
|
||||
AzFramework::VisibilityEntry* visibleEntry);
|
||||
#endif
|
||||
|
||||
@@ -320,8 +320,8 @@ namespace AZ
|
||||
for (const AzFramework::IVisibilityScene::NodeData& nodeData : worklist)
|
||||
{
|
||||
//If a node is entirely contained within the frustum, then we can skip the fine grained culling.
|
||||
bool nodeIsContainedInFrustum =
|
||||
!worklistData->m_debugCtx->m_enableFrustumCulling ||
|
||||
bool nodeIsContainedInFrustum =
|
||||
!worklistData->m_debugCtx->m_enableFrustumCulling ||
|
||||
ShapeIntersection::Contains(worklistData->m_frustum, nodeData.m_bounds);
|
||||
|
||||
#ifdef AZ_CULL_PROFILE_VERBOSE
|
||||
@@ -460,12 +460,14 @@ namespace AZ
|
||||
cullStats.m_numVisibleCullables += numVisibleCullables;
|
||||
++cullStats.m_numJobs;
|
||||
}
|
||||
#else
|
||||
(void)numDrawPackets; // prevent unused variable warning->error
|
||||
#endif //AZ_CULL_DEBUG_ENABLED
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_MASKED_OCCLUSION_CULLING_SUPPORTED
|
||||
static MaskedOcclusionCulling::CullingResult TestOcclusionCulling(
|
||||
const AZStd::shared_ptr<WorklistData>& worklistData,
|
||||
const AZStd::shared_ptr<WorklistData>& worklistData,
|
||||
AzFramework::VisibilityEntry* visibleEntry)
|
||||
{
|
||||
if (!worklistData->m_maskedOcclusionCulling)
|
||||
@@ -527,9 +529,9 @@ namespace AZ
|
||||
#endif
|
||||
|
||||
void CullingScene::ProcessCullablesCommon(
|
||||
const Scene& scene [[maybe_unused]],
|
||||
View& view,
|
||||
AZ::Frustum& frustum [[maybe_unused]],
|
||||
const Scene& scene [[maybe_unused]],
|
||||
View& view,
|
||||
AZ::Frustum& frustum [[maybe_unused]],
|
||||
void*& maskedOcclusionCulling [[maybe_unused]])
|
||||
{
|
||||
AZ_PROFILE_SCOPE(RPI, "CullingScene::ProcessCullablesCommon() - %s", view.GetName().GetCStr());
|
||||
@@ -898,7 +900,7 @@ namespace AZ
|
||||
{
|
||||
const Matrix4x4& worldToClip = viewPtr->GetWorldToClipMatrix();
|
||||
Frustum frustum = Frustum::CreateFromMatrixColumnMajor(worldToClip, Frustum::ReverseDepth::True);
|
||||
m_debugCtx.m_frozenFrustums.insert({ viewPtr.get(), frustum });
|
||||
m_debugCtx.m_frozenFrustums.insert({ viewPtr.get(), frustum });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -911,7 +913,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
void CullingScene::EndCulling()
|
||||
{
|
||||
{
|
||||
m_cullDataConcurrencyCheck.soft_unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
|
||||
|
||||
|
||||
#include <AzFramework/IO/LocalFileIO.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/Utils//Utils.h>
|
||||
|
||||
#include <AzCore/Serialization/Json/JsonUtils.h>
|
||||
|
||||
#include <AzFramework/IO/LocalFileIO.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
*/
|
||||
|
||||
#include "AssetManagerTestFixture.h"
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Memory/PoolAllocator.h>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/parallel/shared_mutex.h>
|
||||
#include <AzCore/Jobs/JobCompletion.h>
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/base.h>
|
||||
|
||||
#include <numeric>
|
||||
|
||||
namespace AZ::Render
|
||||
{
|
||||
static constexpr uint32_t s_maxActiveWrinkleMasks = 16;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <Rendering/SharedBuffer.h>
|
||||
#include <Rendering/HairCommon.h>
|
||||
|
||||
#include <numeric>
|
||||
|
||||
namespace AZ::Render
|
||||
{
|
||||
//! Setting the constructor as private will create compile error to remind the developer to set
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include <ATLEntities.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
@@ -285,5 +286,22 @@ namespace Audio
|
||||
|
||||
return sResult;
|
||||
}
|
||||
CATLAudioFileEntry::CATLAudioFileEntry(const char * const filePath, IATLAudioFileEntryData * const implData)
|
||||
: m_filePath(filePath)
|
||||
, m_fileSize(0)
|
||||
, m_useCount(0)
|
||||
, m_memoryBlockAlignment(AUDIO_MEMORY_ALIGNMENT)
|
||||
, m_flags(eAFF_NOTFOUND)
|
||||
, m_dataScope(eADS_ALL)
|
||||
, m_memoryBlock(nullptr)
|
||||
, m_implData(implData)
|
||||
{
|
||||
}
|
||||
|
||||
CATLAudioFileEntry::~CATLAudioFileEntry()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif // !AUDIO_RELEASE
|
||||
} // namespace Audio
|
||||
|
||||
@@ -379,19 +379,9 @@ namespace Audio
|
||||
class CATLAudioFileEntry
|
||||
{
|
||||
public:
|
||||
explicit CATLAudioFileEntry(const char* const filePath = nullptr, IATLAudioFileEntryData* const implData = nullptr)
|
||||
: m_filePath(filePath)
|
||||
, m_fileSize(0)
|
||||
, m_useCount(0)
|
||||
, m_memoryBlockAlignment(AUDIO_MEMORY_ALIGNMENT)
|
||||
, m_flags(eAFF_NOTFOUND)
|
||||
, m_dataScope(eADS_ALL)
|
||||
, m_memoryBlock(nullptr)
|
||||
, m_implData(implData)
|
||||
{
|
||||
}
|
||||
explicit CATLAudioFileEntry(const char* const filePath = nullptr, IATLAudioFileEntryData* const implData = nullptr);
|
||||
|
||||
~CATLAudioFileEntry() = default;
|
||||
~CATLAudioFileEntry();
|
||||
|
||||
AZStd::string m_filePath;
|
||||
size_t m_fileSize;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/std/parallel/binary_semaphore.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzTest/Utils.h>
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <IRenderAuxGeom.h>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
class FileRequestHandle;
|
||||
}
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
class FileCacheManagerMock
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include <EMotionFX/Source/DebugDraw.h>
|
||||
#include <EMotionFX/Source/RagdollInstance.h>
|
||||
|
||||
#include <numeric>
|
||||
|
||||
namespace EMotionFX
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_IMPL(ActorInstance, ActorInstanceAllocator, 0)
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <Tests/TestAssetCode/SimpleActors.h>
|
||||
#include <Tests/TestAssetCode/MeshFactory.h>
|
||||
|
||||
#include <numeric>
|
||||
|
||||
namespace EMotionFX
|
||||
{
|
||||
SimpleJointChainActor::SimpleJointChainActor(size_t jointCount, const char* name)
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
#include "AssetSystemDebugComponent.h"
|
||||
#include "ISystem.h"
|
||||
#include "IRenderAuxGeom.h"
|
||||
|
||||
#include "AzCore/Asset/AssetManager.h"
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Jobs/JobFunction.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "AudioAreaEnvironmentComponent.h"
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
|
||||
namespace NvCloth
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
#include <NvCloth/Types.h>
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/std/limits.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
|
||||
#include <PhysX/EditorJointBus.h>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Math/Aabb.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
|
||||
#include <Editor/EditorViewportEntityPicker.h>
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <Source/ForceRegionForces.h>
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Physics/PhysicsScene.h>
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
|
||||
@@ -6,18 +6,22 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzFramework/Physics/PhysicsScene.h>
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <Source/Joint/PhysXJointUtils.h>
|
||||
|
||||
#include <PhysX/Joint/Configuration/PhysXJointConfiguration.h>
|
||||
#include <PhysX/PhysXLocks.h>
|
||||
#include <PhysX/Debug/PhysXDebugConfiguration.h>
|
||||
#include <PhysX/MathConversion.h>
|
||||
#include <Source/Joint/PhysXJointUtils.h>
|
||||
#include <Include/PhysX/NativeTypeIdentifiers.h>
|
||||
|
||||
#include <AzFramework/Physics/PhysicsScene.h>
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
|
||||
|
||||
namespace PhysX::Utils
|
||||
{
|
||||
struct PxJointActorData
|
||||
|
||||
@@ -14,8 +14,15 @@
|
||||
|
||||
#include <PxPhysicsAPI.h>
|
||||
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
||||
|
||||
namespace PhysX
|
||||
{
|
||||
struct D6JointLimitConfiguration;
|
||||
struct FixedJointConfiguration;
|
||||
struct BallJointConfiguration;
|
||||
struct HingeJointConfiguration;
|
||||
|
||||
namespace JointConstants
|
||||
{
|
||||
// Setting joint limits to very small values can cause extreme stability problems, so clamp above a small
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include <Source/JointComponent.h>
|
||||
|
||||
#include <Source/Utils.h>
|
||||
#include <PhysX/MathConversion.h>
|
||||
#include <PhysX/NativeTypeIdentifiers.h>
|
||||
#include <PhysX/PhysXLocks.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzFramework/Physics/RigidBodyBus.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
||||
#include <AzFramework/Physics/SimulatedBodies/RigidBody.h>
|
||||
#include <PhysX/NativeTypeIdentifiers.h>
|
||||
#include <PhysX/PhysXLocks.h>
|
||||
#include <Source/JointComponent.h>
|
||||
#include <Source/Utils.h>
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <PhysX/MathConversion.h>
|
||||
|
||||
namespace PhysX
|
||||
{
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
*/
|
||||
|
||||
#include "Material.h"
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <PxPhysicsAPI.h>
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <PxPhysicsAPI.h>
|
||||
#include <PhysX/MeshAsset.h>
|
||||
|
||||
namespace PhysX
|
||||
|
||||
@@ -5,13 +5,10 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <PhysXCharacters/API/CharacterUtils.h>
|
||||
|
||||
#include <PhysXCharacters/API/CharacterController.h>
|
||||
#include <PhysXCharacters/API/Ragdoll.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/Physics/MaterialBus.h>
|
||||
#include <cfloat>
|
||||
#include <PhysX/PhysXLocks.h>
|
||||
#include <PhysX/Joint/Configuration/PhysXJointConfiguration.h>
|
||||
#include <PhysX/Debug/PhysXDebugConfiguration.h>
|
||||
@@ -20,6 +17,12 @@
|
||||
#include <Source/Scene/PhysXScene.h>
|
||||
#include <Source/Shape.h>
|
||||
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzFramework/Physics/MaterialBus.h>
|
||||
|
||||
#include <cfloat>
|
||||
|
||||
namespace PhysX::Utils::Characters
|
||||
{
|
||||
AZ::Outcome<size_t> GetNodeIndex(const Physics::RagdollConfiguration& configuration, const AZStd::string& nodeName)
|
||||
|
||||
@@ -5,16 +5,17 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzFramework/Physics/PhysicsScene.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSceneQueries.h>
|
||||
#include <PhysXCharacters/API/RagdollNode.h>
|
||||
|
||||
#include <PhysX/NativeTypeIdentifiers.h>
|
||||
#include <PhysX/Debug/PhysXDebugConfiguration.h>
|
||||
#include <PhysX/MathConversion.h>
|
||||
|
||||
#include <PxPhysicsAPI.h>
|
||||
#include <AzFramework/Physics/PhysicsScene.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSceneQueries.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
|
||||
namespace PhysX
|
||||
{
|
||||
|
||||
@@ -6,15 +6,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Source/Pipeline/HeightFieldAssetHandler.h>
|
||||
|
||||
#include <Pipeline/HeightFieldAssetHandler.h>
|
||||
#include <Pipeline/StreamWrapper.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/IO/GenericStreams.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <PhysX/HeightFieldAsset.h>
|
||||
#include <PhysX/SystemComponentBus.h>
|
||||
#include <PhysX/ComponentTypeIds.h>
|
||||
#include <Source/Pipeline/HeightFieldAssetHandler.h>
|
||||
#include <PxPhysicsAPI.h>
|
||||
|
||||
#include <extensions/PxSerialization.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/IO/GenericStreams.h>
|
||||
#include <AzCore/Asset/AssetDataStream.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <extensions/PxDefaultStreams.h>
|
||||
|
||||
namespace PhysX
|
||||
|
||||
@@ -7,14 +7,6 @@
|
||||
*/
|
||||
#include <Scene/PhysXScene.h>
|
||||
|
||||
#include <AzCore/Debug/ProfilerBus.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/Physics/Character.h>
|
||||
#include <AzFramework/Physics/Collision/CollisionEvents.h>
|
||||
#include <AzFramework/Physics/Configuration/RigidBodyConfiguration.h>
|
||||
#include <AzFramework/Physics/Configuration/StaticRigidBodyConfiguration.h>
|
||||
|
||||
#include <Collision.h>
|
||||
#include <RigidBody.h>
|
||||
@@ -31,6 +23,16 @@
|
||||
#include <PhysX/MathConversion.h>
|
||||
#include <Joint/PhysXJoint.h>
|
||||
|
||||
#include <AzCore/Debug/ProfilerBus.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzFramework/Physics/Character.h>
|
||||
#include <AzFramework/Physics/Collision/CollisionEvents.h>
|
||||
#include <AzFramework/Physics/Configuration/RigidBodyConfiguration.h>
|
||||
#include <AzFramework/Physics/Configuration/StaticRigidBodyConfiguration.h>
|
||||
|
||||
namespace PhysX
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_IMPL(PhysXScene, AZ::SystemAllocator, 0);
|
||||
|
||||
@@ -5,18 +5,20 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <System/PhysXSystem.h>
|
||||
|
||||
#include <PxPhysicsAPI.h>
|
||||
#include <PhysX/Debug/PhysXDebugConfiguration.h>
|
||||
#include <Scene/PhysXScene.h>
|
||||
#include <System/PhysXAllocator.h>
|
||||
#include <System/PhysXCpuDispatcher.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Component/ComponentApplicationLifecycle.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
|
||||
#include <Scene/PhysXScene.h>
|
||||
#include <System/PhysXSystem.h>
|
||||
#include <System/PhysXAllocator.h>
|
||||
#include <System/PhysXCpuDispatcher.h>
|
||||
#include <PhysX/Debug/PhysXDebugConfiguration.h>
|
||||
|
||||
#include <PxPhysicsAPI.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
|
||||
// only enable physx timestep warning when not running debug or in Release
|
||||
#if !defined(DEBUG) && !defined(RELEASE)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "PhysXTestUtil.h"
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <AzFramework/Physics/Collision/CollisionEvents.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
namespace PhysX
|
||||
{
|
||||
|
||||
@@ -8,10 +8,7 @@
|
||||
|
||||
#include "SystemComponent.h"
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <PhysX/Debug/PhysXDebugInterface.h>
|
||||
|
||||
#include <PhysX/SystemComponentBus.h>
|
||||
#include <PhysX/MathConversion.h>
|
||||
@@ -19,20 +16,24 @@
|
||||
#include <PhysX/Utils.h>
|
||||
#include <PhysX/PhysXLocks.h>
|
||||
|
||||
#include <CryCommon/IConsole.h>
|
||||
#include <CryCommon/IRenderAuxGeom.h>
|
||||
#include <CryCommon/ISystem.h>
|
||||
#include <CryCommon/MathConversion.h>
|
||||
|
||||
#include <AzFramework/Components/CameraBus.h>
|
||||
#include <AzFramework/Physics/PhysicsScene.h>
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <AzFramework/Physics/Ragdoll.h>
|
||||
#include <AzFramework/Physics/SystemBus.h>
|
||||
#include <AzFramework/Physics/Utils.h>
|
||||
#include <AzFramework/Components/CameraBus.h>
|
||||
|
||||
#include <IRenderAuxGeom.h>
|
||||
#include <MathConversion.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <IConsole.h>
|
||||
#include <CryCommon/ISystem.h>
|
||||
|
||||
#include <PhysX/Debug/PhysXDebugInterface.h>
|
||||
|
||||
namespace PhysXDebug
|
||||
{
|
||||
|
||||
@@ -10,11 +10,14 @@
|
||||
#include "ScriptCanvasMemoryAsset.h"
|
||||
#include "ScriptCanvasUndoHelper.h"
|
||||
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
|
||||
#include <AzCore/IO/Streamer/StreamerContext.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
|
||||
#include <ScriptCanvas/Asset/ScriptCanvasAssetBase.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/IO/IStreamer.h>
|
||||
#include <AzCore/IO/Streamer/FileRequest.h>
|
||||
#include <AzFramework/Asset/AssetSystemBus.h>
|
||||
#include <AzFramework/IO/FileOperations.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Debug/Budget.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_ptr.h>
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/Component/ComponentBus.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <WhiteBox/WhiteBoxToolApi.h>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user