218 lines
7.4 KiB
C++
218 lines
7.4 KiB
C++
/*******************************************************************************
|
|
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
|
|
Technology released in source code form as part of the game integration package.
|
|
The content of this file may not be used without valid licenses to the
|
|
AUDIOKINETIC Wwise Technology.
|
|
Note that the use of the game engine is subject to the Unreal(R) Engine End User
|
|
License Agreement at https://www.unrealengine.com/en-US/eula/unreal
|
|
|
|
License Usage
|
|
|
|
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
|
|
this file in accordance with the end user license agreement provided with the
|
|
software or, alternatively, in accordance with the terms contained
|
|
in a written agreement between you and Audiokinetic Inc.
|
|
Copyright (c) 2023 Audiokinetic Inc.
|
|
*******************************************************************************/
|
|
|
|
#include "Wwise/WwiseFileStateTools.h"
|
|
#include "Wwise/Stats/AsyncStats.h"
|
|
#include "Wwise/Stats/FileHandler.h"
|
|
|
|
#include "WwiseDefines.h"
|
|
|
|
#include "Misc/Paths.h"
|
|
#include "Async/MappedFileHandle.h"
|
|
#include "Async/AsyncFileHandle.h"
|
|
#include "HAL/FileManager.h"
|
|
#if UE_5_0_OR_LATER
|
|
#include "HAL/PlatformFileManager.h"
|
|
#else
|
|
#include "HAL/PlatformFilemanager.h"
|
|
#endif
|
|
|
|
#include <inttypes.h>
|
|
|
|
uint8* FWwiseFileStateTools::AllocateMemory(int64 InMemorySize, bool bInDeviceMemory, int32 InMemoryAlignment,
|
|
bool bInEnforceMemoryRequirements)
|
|
{
|
|
uint8* Result = nullptr;
|
|
|
|
if (bInDeviceMemory && bInEnforceMemoryRequirements)
|
|
{
|
|
#if AK_SUPPORT_DEVICE_MEMORY
|
|
UE_LOG(LogWwiseFileHandler, VeryVerbose, TEXT("Allocating %" PRIi64 " (%" PRIi32 ") bytes in Device Memory"), InMemorySize, InMemoryAlignment);
|
|
Result = static_cast<uint8*>(AKPLATFORM::AllocDevice((size_t)InMemorySize, nullptr));
|
|
if (Result)
|
|
{
|
|
INC_MEMORY_STAT_BY(STAT_WwiseFileHandlerDeviceMemoryAllocated, InMemorySize);
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, Error, TEXT("Could not allocate %" PRIi64 " (%" PRIi32 ") bytes in Device Memory"), InMemorySize, InMemoryAlignment);
|
|
}
|
|
#else
|
|
UE_LOG(LogWwiseFileHandler, Error, TEXT("No Device Memory, but trying to allocate %" PRIi64 " (%" PRIi32 ") bytes"), InMemorySize, InMemoryAlignment);
|
|
return AllocateMemory(InMemorySize, false, InMemoryAlignment, bInEnforceMemoryRequirements);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, VeryVerbose, TEXT("Allocating %" PRIi64 " (%" PRIi32 ") bytes in Unreal memory"), InMemorySize, InMemoryAlignment);
|
|
Result = static_cast<uint8*>(FMemory::Malloc(InMemorySize, bInEnforceMemoryRequirements ? InMemoryAlignment : 0));
|
|
if (Result)
|
|
{
|
|
INC_MEMORY_STAT_BY(STAT_WwiseFileHandlerMemoryAllocated, InMemorySize);
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, Error, TEXT("Could not allocate %" PRIi64 " (%" PRIi32 ") bytes in Unreal memory"), InMemorySize, InMemoryAlignment);
|
|
}
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
void FWwiseFileStateTools::DeallocateMemory(const uint8* InMemoryPtr, int64 InMemorySize, bool bInDeviceMemory,
|
|
int32 InMemoryAlignment, bool bInEnforceMemoryRequirements)
|
|
{
|
|
if (!InMemoryPtr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (bInDeviceMemory && bInEnforceMemoryRequirements)
|
|
{
|
|
#if AK_SUPPORT_DEVICE_MEMORY
|
|
UE_LOG(LogWwiseFileHandler, VeryVerbose, TEXT("Deallocating %" PRIi64 " (%" PRIi32 ") bytes in Device Memory"), InMemorySize, InMemoryAlignment);
|
|
DEC_MEMORY_STAT_BY(STAT_WwiseFileHandlerDeviceMemoryAllocated, InMemorySize);
|
|
AKPLATFORM::FreeDevice((void*)InMemoryPtr, InMemorySize, 0, true);
|
|
#else
|
|
UE_LOG(LogWwiseFileHandler, Error, TEXT("No Device Memory, but trying to deallocate %" PRIi64 " (%" PRIi32 ") bytes"), InMemorySize, InMemoryAlignment);
|
|
return DeallocateMemory(InMemoryPtr, InMemorySize, false, InMemoryAlignment, bInEnforceMemoryRequirements);
|
|
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, VeryVerbose, TEXT("Deallocating %" PRIi64 " (%" PRIi32 ") bytes in Unreal memory"), InMemorySize, InMemoryAlignment);
|
|
DEC_MEMORY_STAT_BY(STAT_WwiseFileHandlerMemoryAllocated, InMemorySize);
|
|
FMemory::Free(const_cast<uint8*>(InMemoryPtr));
|
|
}
|
|
}
|
|
|
|
bool FWwiseFileStateTools::GetMemoryMapped(IMappedFileHandle*& OutMappedHandle, IMappedFileRegion*& OutMappedRegion,
|
|
int64& OutSize, const FString& InFilePathname, int32 InMemoryAlignment)
|
|
{
|
|
if (!GetMemoryMapped(OutMappedHandle, OutSize, InFilePathname, InMemoryAlignment))
|
|
{
|
|
return false;
|
|
}
|
|
if (UNLIKELY(!GetMemoryMappedRegion(OutMappedRegion, *OutMappedHandle)))
|
|
{
|
|
UnmapHandle(*OutMappedHandle);
|
|
OutMappedHandle = nullptr;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool FWwiseFileStateTools::GetMemoryMapped(IMappedFileHandle*& OutMappedHandle, int64& OutSize,
|
|
const FString& InFilePathname, int32 InMemoryAlignment)
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, VeryVerbose, TEXT("Memory mapping %s"), *InFilePathname);
|
|
auto& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
|
|
auto* Handle = PlatformFile.OpenMapped(*InFilePathname);
|
|
if (UNLIKELY(!Handle))
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, VeryVerbose, TEXT("OpenMapped %s failed"), *InFilePathname);
|
|
return false;
|
|
}
|
|
|
|
OutMappedHandle = Handle;
|
|
OutSize = Handle->GetFileSize();
|
|
return true;
|
|
}
|
|
|
|
bool FWwiseFileStateTools::GetMemoryMappedRegion(IMappedFileRegion*& OutMappedRegion,
|
|
IMappedFileHandle& InMappedHandle)
|
|
{
|
|
auto* Region = InMappedHandle.MapRegion(0, MAX_int64, true);
|
|
if (UNLIKELY(!Region))
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, VeryVerbose, TEXT("MapRegion failed"));
|
|
return false;
|
|
}
|
|
|
|
INC_MEMORY_STAT_BY(STAT_WwiseFileHandlerMemoryMapped, Region->GetMappedSize());
|
|
OutMappedRegion = Region;
|
|
return true;
|
|
}
|
|
|
|
void FWwiseFileStateTools::UnmapRegion(IMappedFileRegion& InMappedRegion)
|
|
{
|
|
DEC_MEMORY_STAT_BY(STAT_WwiseFileHandlerMemoryMapped, InMappedRegion.GetMappedSize());
|
|
delete &InMappedRegion;
|
|
}
|
|
|
|
void FWwiseFileStateTools::UnmapHandle(IMappedFileHandle& InMappedHandle)
|
|
{
|
|
delete &InMappedHandle;
|
|
}
|
|
|
|
bool FWwiseFileStateTools::GetFileToPtr(const uint8*& OutPtr, int64& OutSize, const FString& InFilePathname,
|
|
bool bInDeviceMemory, int32 InMemoryAlignment, bool bInEnforceMemoryRequirements,
|
|
int64 ReadFirstBytes)
|
|
{
|
|
FScopedLoadingState ScopedLoadingState(*InFilePathname);
|
|
|
|
FArchive* Reader = IFileManager::Get().CreateFileReader(*InFilePathname, 0);
|
|
if (!Reader)
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, Verbose, TEXT("Could not get File Archive for %s"), *InFilePathname);
|
|
return false;
|
|
}
|
|
|
|
int64 Size = Reader->TotalSize();
|
|
if (UNLIKELY(!Size))
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, Error, TEXT("Empty file %s"), *InFilePathname);
|
|
delete Reader;
|
|
return false;
|
|
}
|
|
if (ReadFirstBytes >= 0 && Size > ReadFirstBytes)
|
|
{
|
|
Size = ReadFirstBytes;
|
|
}
|
|
|
|
if (UNLIKELY((InMemoryAlignment & (InMemoryAlignment - 1)) != 0))
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, Warning, TEXT("Invalid non-2^n Memory Alignment (%" PRIi32 ") while getting file %s. Resetting to 0."), InMemoryAlignment, *InFilePathname);
|
|
InMemoryAlignment = 0;
|
|
}
|
|
|
|
uint8* Ptr = AllocateMemory(Size, bInDeviceMemory, InMemoryAlignment, bInEnforceMemoryRequirements);
|
|
if (UNLIKELY(!Ptr))
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, Verbose, TEXT("Could not Allocate memory for %s"), *InFilePathname);
|
|
delete Reader;
|
|
return false;
|
|
}
|
|
|
|
UE_LOG(LogWwiseFileHandler, VeryVerbose, TEXT("Getting a copy of full file %s (%" PRIi64 " bytes)"), *InFilePathname, Size);
|
|
|
|
Reader->Serialize(Ptr, Size);
|
|
const bool Result = Reader->Close();
|
|
|
|
delete Reader;
|
|
if (!Result)
|
|
{
|
|
UE_LOG(LogWwiseFileHandler, Error, TEXT("Deserialization failed for file %s"), *InFilePathname);
|
|
DeallocateMemory(Ptr, Size, bInDeviceMemory, InMemoryAlignment, bInEnforceMemoryRequirements);
|
|
return false;
|
|
}
|
|
|
|
OutPtr = Ptr;
|
|
OutSize = Size;
|
|
return true;
|
|
}
|