You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
fix RHI upload of textures that are multiple of 4 in top mip but not in lower mips dont pad CompressedImage sizes, store true size clean up Texture size limits and VT conditions better default settings for texture import clean up initialization order of TextureFormatManagerModule #preflight 6250814a11261bc7b23d8f4b #rb fabian.giesen,julien.stjean [CL 19693287 by charles bloom in ue5-main branch]
249 lines
7.6 KiB
C++
249 lines
7.6 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Interfaces/ITextureFormatManagerModule.h"
|
|
#include "Interfaces/ITextureFormat.h"
|
|
#include "Interfaces/ITextureFormatModule.h"
|
|
#include "Modules/ModuleManager.h"
|
|
#include "TextureFormatManager.h"
|
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LogTextureFormatManager, Log, All);
|
|
|
|
/**
|
|
* Module for the target platform manager
|
|
*/
|
|
class FTextureFormatManagerModule
|
|
: public ITextureFormatManagerModule
|
|
{
|
|
public:
|
|
|
|
enum class EInitPhase
|
|
{
|
|
JustConstructedNotInit = 0,
|
|
Invalidated = 1,
|
|
GetTextureFormatsInProgressDontTouch = 2,
|
|
GetTextureFormatsPartialOkayToRead = 3, // values >= here are okay to make queries
|
|
GetTextureFormatsDone = 4
|
|
};
|
|
|
|
/** Default constructor. */
|
|
FTextureFormatManagerModule()
|
|
: ModuleName(TEXT("TextureFormat"))
|
|
, bForceCacheUpdate(true)
|
|
, bModuleChangeCallbackEnabled(false)
|
|
, TextureFormatsInitPhase(EInitPhase::JustConstructedNotInit)
|
|
{
|
|
FModuleManager::Get().OnModulesChanged().AddRaw(this, &FTextureFormatManagerModule::ModulesChangesCallback);
|
|
|
|
// not usable until first Invalidate is called
|
|
}
|
|
|
|
/** Destructor. */
|
|
virtual ~FTextureFormatManagerModule() = default;
|
|
|
|
virtual void ShutdownModule()
|
|
{
|
|
FModuleManager::Get().OnModulesChanged().RemoveAll(this);
|
|
}
|
|
|
|
|
|
virtual const TArray<const ITextureFormat*>& GetTextureFormats() override
|
|
{
|
|
// should not be called recursively while I am building the list :
|
|
check( TextureFormatsInitPhase!= EInitPhase::GetTextureFormatsInProgressDontTouch );
|
|
|
|
// bForceCacheUpdate should be true on first call, so we don't need a separate static init flag
|
|
if ( bForceCacheUpdate )
|
|
{
|
|
// turn off flag immediately so that repeated calls to GetTextureFormats will not come in here again
|
|
bForceCacheUpdate = false;
|
|
bModuleChangeCallbackEnabled = false; // don't re-call me from my own module loads
|
|
TextureFormatsInitPhase = EInitPhase::GetTextureFormatsInProgressDontTouch;
|
|
|
|
// note the first time this is done is from FTargetPlatformManagerModule::FTargetPlatformManagerModule()
|
|
// so calls to it are dangerous
|
|
|
|
TextureFormats.Empty(TextureFormats.Num());
|
|
TextureFormatMetadata.Empty(TextureFormatMetadata.Num());
|
|
|
|
TArray<FName> Modules;
|
|
|
|
FModuleManager::Get().FindModules(TEXT("*TextureFormat*"), Modules);
|
|
|
|
if (!Modules.Num())
|
|
{
|
|
UE_LOG(LogTextureFormatManager, Error, TEXT("No texture formats found!"));
|
|
}
|
|
|
|
TArray<FTextureFormatMetadata> BaseModules;
|
|
TArray<FTextureFormatMetadata> ChildModules;
|
|
|
|
for (int32 Index = 0; Index < Modules.Num(); Index++)
|
|
{
|
|
if (Modules[Index] != ModuleName) // Avoid our own module when going through this list that was gathered by name
|
|
{
|
|
ITextureFormatModule* Module = FModuleManager::LoadModulePtr<ITextureFormatModule>(Modules[Index]);
|
|
if (Module)
|
|
{
|
|
FTextureFormatMetadata ModuleMeta;
|
|
ModuleMeta.Module = Module;
|
|
ModuleMeta.ModuleName = Modules[Index];
|
|
if ( Module->CanCallGetTextureFormats() )
|
|
{
|
|
ChildModules.Add(ModuleMeta);
|
|
}
|
|
else
|
|
{
|
|
BaseModules.Add(ModuleMeta);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// first populate TextureFormats[] with all Base Modules
|
|
//
|
|
for (int32 Index = 0; Index < BaseModules.Num(); Index++)
|
|
{
|
|
ITextureFormatModule* Module = BaseModules[Index].Module;
|
|
|
|
ITextureFormat* Format = Module->GetTextureFormat();
|
|
if (Format != nullptr)
|
|
{
|
|
UE_LOG(LogTextureFormatManager, Display, TEXT("Loaded Base TextureFormat: %s"),*BaseModules[Index].ModuleName.ToString());
|
|
|
|
TextureFormats.Add(Format);
|
|
TextureFormatMetadata.Add(BaseModules[Index]);
|
|
}
|
|
}
|
|
|
|
// Init phase 3 means you are now allowd to call GetTextureFormats() and you will get only the Base formats
|
|
TextureFormatsInitPhase = EInitPhase::GetTextureFormatsPartialOkayToRead;
|
|
|
|
// run through the Child formats and call GetTextureFormat() on them
|
|
// this will call back to me and do GetTextureFormats() which will get only the base formats
|
|
for (int32 Index = 0; Index < ChildModules.Num(); Index++)
|
|
{
|
|
ITextureFormatModule* Module = ChildModules[Index].Module;
|
|
|
|
ITextureFormat* Format = Module->GetTextureFormat();
|
|
if (Format != nullptr)
|
|
{
|
|
UE_LOG(LogTextureFormatManager, Display, TEXT("Loaded Child TextureFormat: %s"),*ChildModules[Index].ModuleName.ToString());
|
|
|
|
// do not add me to TextureFormats yet
|
|
}
|
|
}
|
|
|
|
// back up phase to 2, no calls to GetTextureFormats() allowed now
|
|
TextureFormatsInitPhase = EInitPhase::GetTextureFormatsInProgressDontTouch;
|
|
|
|
for (int32 Index = 0; Index < ChildModules.Num(); Index++)
|
|
{
|
|
ITextureFormatModule* Module = ChildModules[Index].Module;
|
|
|
|
// GetTextureFormat was already done so this should just return a stored pointer, no more init
|
|
ITextureFormat* Format = Module->GetTextureFormat();
|
|
if (Format != nullptr)
|
|
{
|
|
// now add to the list :
|
|
TextureFormats.Add(Format);
|
|
TextureFormatMetadata.Add(ChildModules[Index]);
|
|
}
|
|
}
|
|
|
|
// all done :
|
|
TextureFormatsInitPhase = EInitPhase::GetTextureFormatsDone;
|
|
bModuleChangeCallbackEnabled = true;
|
|
}
|
|
|
|
check( (int)TextureFormatsInitPhase >= (int)EInitPhase::GetTextureFormatsPartialOkayToRead );
|
|
|
|
return TextureFormats;
|
|
}
|
|
|
|
virtual const ITextureFormat* FindTextureFormat(FName Name) override
|
|
{
|
|
check( (int)TextureFormatsInitPhase >= (int)EInitPhase::GetTextureFormatsPartialOkayToRead );
|
|
|
|
FName ModuleNameUnused;
|
|
ITextureFormatModule* ModuleUnused;
|
|
return FindTextureFormatAndModule(Name, ModuleNameUnused, ModuleUnused);
|
|
}
|
|
|
|
virtual const class ITextureFormat* FindTextureFormatAndModule(FName Name, FName& OutModuleName, ITextureFormatModule*& OutModule) override
|
|
{
|
|
check( (int)TextureFormatsInitPhase >= (int)EInitPhase::GetTextureFormatsPartialOkayToRead );
|
|
|
|
// Called to ensure the arrays are populated
|
|
// dangerous and not necessary, removed :
|
|
check( ! bForceCacheUpdate );
|
|
//GetTextureFormats();
|
|
|
|
for (int32 Index = 0; Index < TextureFormats.Num(); Index++)
|
|
{
|
|
TArray<FName> Formats;
|
|
|
|
TextureFormats[Index]->GetSupportedFormats(Formats);
|
|
|
|
for (int32 FormatIndex = 0; FormatIndex < Formats.Num(); FormatIndex++)
|
|
{
|
|
if (Formats[FormatIndex] == Name)
|
|
{
|
|
const FTextureFormatMetadata& FoundMeta = TextureFormatMetadata[Index];
|
|
OutModuleName = FoundMeta.ModuleName;
|
|
OutModule = FoundMeta.Module;
|
|
return TextureFormats[Index];
|
|
}
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
virtual void Invalidate() override
|
|
{
|
|
// this is called right after the constructor
|
|
// we are not usable until the first Invalidate is called
|
|
TextureFormatsInitPhase = EInitPhase::Invalidated;
|
|
bForceCacheUpdate = true;
|
|
GetTextureFormats();
|
|
}
|
|
|
|
private:
|
|
|
|
void ModulesChangesCallback(FName InModuleName, EModuleChangeReason ReasonForChange)
|
|
{
|
|
if (bModuleChangeCallbackEnabled && (InModuleName != ModuleName) && InModuleName.ToString().Contains(TEXT("TextureFormat")))
|
|
{
|
|
// when a "TextureFormat" module is loaded, rebuild my list
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
FName ModuleName;
|
|
|
|
TArray<const ITextureFormat*> TextureFormats;
|
|
|
|
struct FTextureFormatMetadata
|
|
{
|
|
FName ModuleName;
|
|
ITextureFormatModule* Module;
|
|
};
|
|
TArray<FTextureFormatMetadata> TextureFormatMetadata;
|
|
|
|
// Flag to force reinitialization of all cached data. This is needed to have up-to-date caches
|
|
// in case of a module reload of a TextureFormat-Module.
|
|
bool bForceCacheUpdate;
|
|
|
|
// Flag to avoid redunant reloads
|
|
bool bModuleChangeCallbackEnabled;
|
|
|
|
// Track tricky initialization progress
|
|
EInitPhase TextureFormatsInitPhase;
|
|
|
|
// @@!! Mutex and ScopeLock everything in case this is called from multiple threads ?
|
|
|
|
};
|
|
|
|
IMPLEMENT_MODULE(FTextureFormatManagerModule, TextureFormat);
|