2023-06-19 13:59:07 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "CookMetadata.h"
2023-09-08 19:51:52 -04:00
# include "HAL/FileManager.h"
2023-06-19 13:59:07 -04:00
# include "Hash/xxhash.h"
2023-06-26 17:21:53 -04:00
# include "Internationalization/Internationalization.h"
2023-06-19 13:59:07 -04:00
# include "Memory/MemoryView.h"
2023-09-08 19:51:52 -04:00
# include "Misc/FileHelper.h"
# include "Serialization/ArrayWriter.h"
# include "Serialization/LargeMemoryReader.h"
2023-06-19 13:59:07 -04:00
namespace UE : : Cook
{
const FString & GetCookMetadataFilename ( )
{
static const FString CookMetadataFilename ( TEXT ( " CookMetadata.ucookmeta " ) ) ;
return CookMetadataFilename ;
}
constexpr uint32 COOK_METADATA_HEADER_MAGIC = ' UCMT ' ;
2023-09-08 19:51:52 -04:00
DEFINE_LOG_CATEGORY_STATIC ( LogCookedMetadata , Log , All )
2023-06-19 13:59:07 -04:00
bool FCookMetadataState : : Serialize ( FArchive & Ar )
{
uint32 MagicHeader = 0 ;
if ( Ar . IsLoading ( ) )
{
Ar < < MagicHeader ;
if ( MagicHeader ! = COOK_METADATA_HEADER_MAGIC )
{
return false ; // not a metadata file.
}
}
else
{
MagicHeader = COOK_METADATA_HEADER_MAGIC ;
Ar < < MagicHeader ;
2023-06-23 19:05:46 -04:00
Version = ECookMetadataStateVersion : : LatestVersion ;
2023-06-19 13:59:07 -04:00
}
2023-06-23 19:05:46 -04:00
2023-10-12 16:58:13 -04:00
bool bSerializeShaderHierarchy = true ;
2023-06-19 13:59:07 -04:00
Ar < < Version ;
2023-06-23 19:05:46 -04:00
if ( Ar . IsLoading ( ) )
{
2023-10-12 16:58:13 -04:00
if ( Version < ECookMetadataStateVersion : : AddedPluginEntryType )
2023-06-23 19:05:46 -04:00
{
2023-10-12 16:58:13 -04:00
UE_LOG ( LogCookedMetadata , Error , TEXT ( " Cook metadata version too old: found %d, we can load %d, latest is %d " ) , Version , ECookMetadataStateVersion : : AddedPluginEntryType , ECookMetadataStateVersion : : LatestVersion ) ;
2023-06-23 19:05:46 -04:00
return false ; // invalid version - current we don't support backcompat
}
2023-10-12 16:58:13 -04:00
if ( Version > ECookMetadataStateVersion : : LatestVersion )
{
UE_LOG ( LogCookedMetadata , Error , TEXT ( " Cook metadata version too new: found %d, latest is %d " ) , Version , ECookMetadataStateVersion : : LatestVersion ) ;
return false ;
}
bSerializeShaderHierarchy = Version > = ECookMetadataStateVersion : : ActualAddShaderPseudoHierarchy ;
2023-06-23 19:05:46 -04:00
}
2023-06-19 13:59:07 -04:00
Ar < < PluginHierarchy ;
Ar < < AssociatedDevelopmentAssetRegistryHash ;
2023-06-22 17:32:20 -04:00
Ar < < AssociatedDevelopmentAssetRegistryHashPostWriteback ;
Ar < < Platform ;
Ar < < BuildVersion ;
Ar < < HordeJobId ;
2023-06-23 19:05:46 -04:00
Ar < < SizesPresent ;
2023-10-12 16:58:13 -04:00
if ( bSerializeShaderHierarchy )
{
Ar < < ShaderPseudoHierarchy ;
}
2023-06-19 13:59:07 -04:00
return true ;
}
2023-09-08 19:51:52 -04:00
bool FCookMetadataState : : ReadFromFile ( const FString & FilePath )
{
TUniquePtr < FArchive > FileReader ( IFileManager : : Get ( ) . CreateFileReader ( * FilePath ) ) ;
if ( FileReader )
{
TArray64 < uint8 > Data ;
Data . SetNumUninitialized ( FileReader - > TotalSize ( ) ) ;
FileReader - > Serialize ( Data . GetData ( ) , Data . Num ( ) ) ;
check ( ! FileReader - > IsError ( ) ) ;
FLargeMemoryReader MemoryReader ( Data . GetData ( ) , Data . Num ( ) ) ;
if ( Serialize ( MemoryReader ) )
{
return true ;
}
else
{
UE_LOG ( LogCookedMetadata , Error , TEXT ( " Failed to serialize cook metadata from file (%s) " ) , * FilePath ) ;
}
}
else
{
UE_LOG ( LogCookedMetadata , Error , TEXT ( " Failed to make file reader from (%s) " ) , * FilePath ) ;
}
return false ;
}
bool FCookMetadataState : : SaveToFile ( const FString & FilePath )
{
FArrayWriter SerializedCookMetadata ;
Serialize ( SerializedCookMetadata ) ;
if ( FFileHelper : : SaveArrayToFile ( SerializedCookMetadata , * FilePath ) )
{
return true ;
}
else
{
UE_LOG ( LogCookedMetadata , Error , TEXT ( " Failed to write cook metadata file (%s) " ) , * FilePath ) ;
return false ;
}
}
2023-06-19 13:59:07 -04:00
/* static */
uint64 FCookMetadataState : : ComputeHashOfDevelopmentAssetRegistry ( FMemoryView InSerializedDevelopmentAssetRegistry )
{
return FXxHash64 : : HashBufferChunked ( InSerializedDevelopmentAssetRegistry . GetData ( ) , InSerializedDevelopmentAssetRegistry . GetSize ( ) , 1ULL < < 19 ) . Hash ;
}
2023-06-26 17:21:53 -04:00
FText FCookMetadataState : : GetSizesPresentAsText ( ) const
{
// Uncapitalized, presentation-ready
static FText CookMetadataSizesPresentStrings [ ] =
{
NSLOCTEXT ( " CookMetadata " , " CookMetadataNotPresent " , " not present " ) ,
NSLOCTEXT ( " CookMetadata " , " CookMetadataCompressed " , " compressed " ) ,
NSLOCTEXT ( " CookMetadata " , " CookMetadataUncompressed " , " uncompressed " )
} ;
static_assert ( sizeof ( CookMetadataSizesPresentStrings ) / sizeof ( CookMetadataSizesPresentStrings [ 0 ] ) = = static_cast < size_t > ( ECookMetadataSizesPresent : : Count ) ) ;
return CookMetadataSizesPresentStrings [ static_cast < size_t > ( SizesPresent ) ] ;
}
2023-06-19 13:59:07 -04:00
} // end namespace