Files
UnrealEngineUWP/Engine/Source/Developer/TextureFormatASTC/Private/TextureFormatASTC.cpp
Chris Babcock edb4242cb2 Copying //UE4/Dev-Mobile to //UE4/Dev-Main (Source: //UE4/Dev-Mobile @ 3771565)
#lockdown Nick.Penwarden
#rb none

============================
  MAJOR FEATURES & CHANGES
============================

Change 3627858 by Sorin.Gradinaru

	#jira UE-48948 Crash when pressing backspace on empty line

	Fixed:
	UE-48948 Backspace on empty line crashes app (virtual keyboard)
	UE-49112 Virtual keyboard text field isn't visible after rotating from landscape to portrait
	UE-49117 Chinese and Korean virtual keyboards don't allow native characters
	UE-49120 Virtual keyboard number pad "kicks" user back to regular keyboard
	UE-49121 Gboard and Swift swipe entry are not supported by Virtual keyboard
	UE-49124 Cursor in virtual keyboard and UMG don't match
	UE-49128 Virtual Keyboard text field doesn't appear if there is too much text
	UE-49141 Virtual keyboard is unresponsive with repeated tapping in control (some devices)
	UE-49139 Tapping in the same text box doesn't make the virtual keyboard disappear

Change 3630732 by Sorin.Gradinaru

	#jira UE-43488 GitHub 3440 : Fixes exposure with planar reflections.

	#3440
	Cancelled the applied exposure scale for non-hdr mobile

Change 3631436 by Nick.Shin

	HTML5

	recommended fix for "RuntimeError: integer result unrepresentable" from the emscripten makers

	#jira UE-49059  HTML5 - Unable to launch project onto HTML 5 from editor

Change 3632689 by Sorin.Gradinaru

	#jira UE - 49301 Text in UMG controls flickers during update from Virtual Keyboard

	Full refresh of the Slate control for Android experimental VK - the control has focus, but the cursor was removed

Change 3632769 by Adrian.Chelu

	#jira UEMOB-403 Improvements to "Device Mobile Preview" feature

Change 3633305 by Allan.Bentham

	Print out the callstack when a fatal error occurs.

Change 3633510 by Chris.Babcock

	Remove unneeded logging
	#jira none

Change 3634827 by Adrian.Chelu

	#fixed build editor buildsystem linux

Change 3640610 by Adrian.Chelu

	#fixed Cook Win64 warnings
	#fixed UE4Editor Static Analysis Win64 warnings

Change 3663057 by Sorin.Gradinaru

	UE-49301 Text in UMG controls flickers during update from Virtual Keyboard
	#jira UE-49301
	#ue4
	#android

	On some Android devices TextWatcher.onTextChanged gets called multiple times when typing/deleting the content of a EditText (internally, the first call resets the entire content, the second fills it with the new value)
	The workaround is to delays sending "empty string" to the Slate, waiting for 100ms to see if there is a second call (the "real" string to update)

	The CL contains a fix for a 5/5 crash : select some/all the text from the native edittext, press delete.

Change 3663630 by Jack.Porter

	Fix shader compile error on Galaxy S6

Change 3663972 by Allan.Bentham

	add ES3.1 framebuffer fetch.
	#jira UE-46251

Change 3671843 by Nick.Shin

	HTML5 - silence CIS warnings (changed to INFO message type)

	#jira UE-50415  ( Pri:1 - 4.18 )  //UE4/Release-4.18: Step "Package ShooterClient HTML5" has completed with 1 Warning: "File packager is creating an asset bundle of 815 MB. This is very large"

Change 3677675 by Sorin.Gradinaru

	Android Experimental Virtual Keyboard 4.18 issues
	#jira UE-49124 Cursor in virtual keyboard and UMG don't match
	#jira UE-49139 Tapping in the same text box doesn't make the virtual keyboard disappear
	#jira UE-49141 Virtual keyboard is unresponsive with repeated tapping in control (some devices)
	#ue4
	#android

	UE-49124 Cursor in virtual keyboard and UMG don't match - change in SlateTextLayout.cpp  - OnPaint() don't display the cursor

	Changed the show/hide vk routines (Game activity.java) to solve low-repro, Android O issues related to multiple click events.
	Should also be tested with multiple text boxes (fast click in/out different types of TextBox controls)

Change 3681555 by Adrian.Chelu

	UEMOB-403 Improvements to "Device Mobile Preview" feature

Change 3692020 by Sorin.Gradinaru

	#jira UE-50645 Carriage returns can be pasted into single line UMG fields on Android
	#ue4
	#4.19
	#android

Change 3692741 by Sorin.Gradinaru

	Andoid 3D WebBrowser
	#jira UE-32740 Web Browser on a Widget Component appears to be 2D when launching on to Android
	#ue4
	#android

Change 3695475 by Chris.Babcock

	Per project Android NDK/SDK API settings
	#jira UEMOB-394
	#ue4
	#android

Change 3701364 by Dmitriy.Dyomin

	Fixed: WEX - Android - Log spammed with "LogRHI: Error: Unsupported EPixelFormat 28"
	#jira UE-50714

Change 3701664 by Jack.Porter

	Fix typo

Change 3702355 by Cosmin.Sulea

	UEMOB-393 - Support "ETC 1.5" packaging
	#jira UEMOB-393

Change 3704950 by Chris.Babcock

	Add verification of support for cooked texture format(s) on device at runtime (optional with Validate texture formats checkbox in Android project settings) and skipped for cook on the fly
	#jira UE-50837
	#ue4
	#android

Change 3709817 by Nick.Shin

	HTML5 - silence CIS warnings (changed to INFO message type)

	finally have a repo case to test this proper fix

	#jira UE-50415  ( Pri:1 - 4.18 )  "Package ShooterClient HTML5" has completed with 1 Warning: "File packager is creating an asset bundle of 815 MB. This is very large"

Change 3717598 by Chris.Babcock

	Fix Android icon paths
	#jira UE-51585
	#ue4
	#android

Change 3718456 by Adrian.Chelu

	#fixed spelling in category localized name

Change 3719643 by Nick.Shin

	nuke PLATFORM_HTML5_WIN32

	more "old" code to remove

	#jira UEMOB-433  Remove Win32 SDL "HTML5 Simulator" code

Change 3720342 by Nick.Shin

	HTML5 redirect logs to console window

	#jira UE-50747  HTML5 log is not easily accessible to users

Change 3720652 by Sorin.Gradinaru

	UE-50382 Xcode Address Sanitizer feature does not work on iOS
	#jira 50382
	#iOS
	#ue4

	Address sanitizer dylib loader depends on the default SDKROOT parameter (<scheme> => Build Settings => Base SDK => <Build Configuration>)
	For macosx or missing (also translated as macosx), the path is incorrect for iphone/appletv.

Change 3720654 by Sorin.Gradinaru

	UE-48499 Android Voice Module has a few issues
	#jira 48499
	#Android
	#ue4

	1.Circular Buffer:  Does the engine already have an implementation? Do we want this into core libraries?
	R: There is an generic template class TCircularBuffer, but it lacks functionality like write/read checks, reading/writing data chunks.
	Plus the code from VoiceModuleAndroid is optimized for circular byte array. I suggest to keep it.

	2. Possible memory leaks: void free_circular_buffer (circular_buffer *p) is implemented, but not used. Presumably a memory leak on the variable inrb. Does CreateAudioRecorder need to be paired with any kind of destroy on shutdown?
	R: Fixed. Using an array ActiveVoiceCaptures to store VoiceCapture references (same as on Windows)

	3. Init() There are 4 calls to setup/init things that store the result in "result" but only the last call is checked against success. Should more checks against the values be made at each stage with informative log messaging in the event of failure?
	R: Fixed.

	4. GetVoiceData()
	// Workaround for dealing with noise after stand-by
	while(bytes<InVoiceBufferSize)
	{
		OutVoiceBuffer[bytes++]=0;
	}
	Isn't this just a memzero?
	R: Fixed.

	5. Missing features. Need to implement GetBufferSize and DumpState
	R: Added GetBufferSize. Can be used like in TestVoice.cpp
	DumpState is never used (same on Mac, iOS), plus the OpenSL objects do not expose internal properties.

Change 3722554 by Cosmin.Sulea

	UE-44224 - iOS - Remote Build - rsync error: files not transferred
	#jira UE-44224

Change 3723265 by Allan.Bentham

	Assign a texture format priority for ETC1a.
	prevents launch on from using ETC1a all the time..

Change 3729764 by Dmitriy.Dyomin

	Removed deprecated LightmapUVBias, ShadowmapUVBias from instanced static mesh component per-instance data (80 -> 64 bytes)

Change 3729899 by Dmitriy.Dyomin

	Fixed tiled landcape re-import

Change 3730895 by Bogdan.Vasilache

	UEMOB-442 --> [ Support texture streaming on Android ES 3.1 ]
	#jira UEMOB-442

Change 3733463 by Chris.Babcock

	Return error for external texture if not used in pixel shader
	#jira UE-51763
	#ue4

Change 3736226 by Chris.Babcock

	Change ExposureScale to PreExposure
	#jira UE-52007
	#jira UE-51691
	#ue4
	#android

Change 3740509 by Allan.Bentham

	Add LQ (direct lighting from stationary spot/point lights) to volumetric lightmaps.
	#jira UE-50551

Change 3740586 by Cosmin.Sulea

	UE-51747 - GitHub 4174 : [BUG-FIX] Invalid ASTC texture versioning is corrected.
	#jira UE-51747

Change 3741110 by Chris.Babcock

	Fix functional code in checks removed for shipping
	#ue4

Change 3741117 by Chris.Babcock

	Fix checkin error for check -> ensure fix
	#ue4

Change 3741156 by Chris.Babcock

	Swap order of SDK and NDK overrides in menu to match Android SDK settings
	#jira UE-52019
	#ue4
	#android

Change 3741271 by Chris.Babcock

	Use final NDK and SDK levels only in UEBuildSettings.txt and rename the overrides to be clearer
	#jira UE-52058
	#ue4
	#android

Change 3741464 by Chris.Babcock

	Add NDK and SDK platform validation (installed) for Android
	#jira UE-52069
	#ue4
	#android

Change 3744602 by Josh.Adams

	From Meerkat: - Added optional 0 or 1 param to showlayer that will set the visibility instead of toggling it for entire layer

Change 3744603 by Josh.Adams

	From Meerkat: - Fixed a comment about debug view modes on consoles

Change 3744607 by Josh.Adams

	From Meerkat: - Added HWInstances to the PrimitiveStats view in Statistics window

Change 3754890 by Chris.Babcock

	Updated IntelISPCTexComp DLLs to fix crashes with some processors on Windows
	#jira UE-52281
	#ue4

Change 3755147 by Jack.Porter

	Fixed Google Cardboard rendering upside down on iPhone 6S+
	#jira  UE-38555

Change 3755458 by Cosmin.Sulea

	UE-47801 - RSync Error when Generating SSH Key for Remote Mac Building when Mac username contains a space
	#jira UE-47801

Change 3755492 by Jack.Porter

	Fix merge error

Change 3759140 by Bogdan.Vasilache

	UE-52396 --> Assertion in FOpenGLDynamicRHI::CreateOpenGLTexture when launching on Mali Galaxy S III
	#jira UE-52396

Change 3760536 by Sorin.Gradinaru

	UE-51262 values for pinch input produce very different results for same area on android device
	#jira 51262
	#iOS
	#Android
	#ue4

	1. When the pinch goes beyond the viewport boundaries (when zooming out),  the touch that goes off-screen is "released" and the zooming effect is over.
	Solved by remembering last pinch event values

	2. "Hack" the initial distance for the pinch/ rotate, by touching the screen and moving the finger to another position before using the second finger.
	Solved by using the correct values  when the pinch event starts

Change 3761279 by Chris.Babcock

	Flag vertex and fragment shaders belonging to materials with external textures
	#jira UE-52398
	#ue4
	#android

Change 3761494 by Chris.Babcock

	Fix access to FrameUpdateInfo in MediaPlayer14.java and CameraPlayer14.java with Proguard
	#jira UE-52471
	#ue4
	#android

Change 3763146 by Jack.Porter

	Default assets for web browser widget
	#jira UE-51374

Change 3764242 by Chris.Babcock

	Disable Niagara vertex factories for mobile and Switch
	#jira UE-52425
	#ue4
	#mobile
	#switch

Change 3766027 by Allan.Bentham

	Fix crash when no LQ volumetric lightmap data exists
	#jira UE-52508

Change 3766075 by Josh.Adams

	- Updating UDKRemote. Still needs art updated, and some some unneeded assets removed

Change 3766141 by Allan.Bentham

	Show unbuilt lightmap warning when LQ data is missing from volumetric lightmap in mobile shading mode.

Change 3766163 by Josh.Adams

	- Updated icons and added a generator script when we get a new one

Change 3766560 by Allan.Bentham

	Workaround for broken offsets with automation screenshots.

	#jira UE-52491

Change 3767193 by Peter.Sauerbrei

	remove Oculus shader from being cached
	force a metal shader re-compile

	#jira UE-52587

Change 3767604 by Peter.Sauerbrei

	fix the Oculusshader the right way

	#jira UE-52587

Change 3768543 by Sorin.Gradinaru

	Android WebBrowser 3D - webbrowser plugin contins the assets, 2D behaviour restored

	#Android
	#UE4
	#4.19
	#jira UE-51374 Web Browser widget is not working on Android
	#jira UE-52399 Android web browser does not accept input


Change 3663915 by Jack.Porter

	Prevent FTcpListener from busy polling while waiting for connections
	#jira UE-50125

Change 3709224 by Allan.Bentham

	Add android target device to gauntlet.
	Automation screenshot uses high res screenshot api for mobile.

	#jira UEMOB-360

Change 3741453 by Chris.Babcock

	Match the 4.18.1 fixes for shipping checks removing code (from CL3741091)
	#ue4

Change 3769301 by Peter.Sauerbrei

	fix for missing ue4_stdmetal.lib, courtesty of MarkS
	#jira UE-52587

Change 3770597 by Sorin.Gradinaru

	Android WebBrowser - remove the WebBrowser plugin reference from the Engine
	Load the default material directly from the resources.

	#Android
	#UE4
	#jira UE-51374 Web Browser widget is not working on Android
	#jira UE-52399 Android web browser does not accept input

[CL 3771573 by Chris Babcock in Main branch]
2017-11-22 16:42:04 -05:00

459 lines
16 KiB
C++

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "CoreMinimal.h"
#include "HAL/PlatformProcess.h"
#include "HAL/FileManager.h"
#include "Misc/CommandLine.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "Misc/Guid.h"
#include "Misc/ConfigCacheIni.h"
#include "ImageCore.h"
#include "IImageWrapper.h"
#include "IImageWrapperModule.h"
#include "Modules/ModuleManager.h"
#include "Interfaces/ITextureFormat.h"
#include "Interfaces/ITextureFormatModule.h"
#include "TextureCompressorModule.h"
#include "PixelFormat.h"
#if PLATFORM_WINDOWS || PLATFORM_LINUX || PLATFORM_MAC
#define SUPPORTS_ISPC_ASTC 1
#else
#define SUPPORTS_ISPC_ASTC 0
#endif
// increment this if you change anything that will affect compression in this file, including FORCED_NORMAL_MAP_COMPRESSION_SIZE_VALUE
#define BASE_ASTC_FORMAT_VERSION 37
#define MAX_QUALITY_BY_SIZE 4
#define MAX_QUALITY_BY_SPEED 3
#define FORCED_NORMAL_MAP_COMPRESSION_SIZE_VALUE 4
DEFINE_LOG_CATEGORY_STATIC(LogTextureFormatASTC, Log, All);
/**
* Macro trickery for supported format names.
*/
#define ENUM_SUPPORTED_FORMATS(op) \
op(ASTC_RGB) \
op(ASTC_RGBA) \
op(ASTC_RGBAuto) \
op(ASTC_NormalAG) \
op(ASTC_NormalRG)
#define DECL_FORMAT_NAME(FormatName) static FName GTextureFormatName##FormatName = FName(TEXT(#FormatName));
ENUM_SUPPORTED_FORMATS(DECL_FORMAT_NAME);
#undef DECL_FORMAT_NAME
#define DECL_FORMAT_NAME_ENTRY(FormatName) GTextureFormatName##FormatName ,
static FName GSupportedTextureFormatNames[] =
{
ENUM_SUPPORTED_FORMATS(DECL_FORMAT_NAME_ENTRY)
};
#undef DECL_FORMAT_NAME_ENTRY
#undef ENUM_SUPPORTED_FORMATS
// ASTC file header format
#if PLATFORM_SUPPORTS_PRAGMA_PACK
#pragma pack(push, 4)
#endif
#define ASTC_MAGIC_CONSTANT 0x5CA1AB13
struct FASTCHeader
{
uint32 Magic;
uint8 BlockSizeX;
uint8 BlockSizeY;
uint8 BlockSizeZ;
uint8 TexelCountX[3];
uint8 TexelCountY[3];
uint8 TexelCountZ[3];
};
#if PLATFORM_SUPPORTS_PRAGMA_PACK
#pragma pack(pop)
#endif
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
static int32 GetDefaultCompressionBySizeValue()
{
// start at default quality, then lookup in .ini file
int32 CompressionModeValue = 0;
GConfig->GetInt(TEXT("/Script/UnrealEd.CookerSettings"), TEXT("DefaultASTCQualityBySize"), CompressionModeValue, GEngineIni);
FParse::Value(FCommandLine::Get(), TEXT("-astcqualitybysize="), CompressionModeValue);
CompressionModeValue = FMath::Min<uint32>(CompressionModeValue, MAX_QUALITY_BY_SIZE);
return CompressionModeValue;
}
static int32 GetDefaultCompressionBySpeedValue()
{
// start at default quality, then lookup in .ini file
int32 CompressionModeValue = 0;
GConfig->GetInt(TEXT("/Script/UnrealEd.CookerSettings"), TEXT("DefaultASTCQualityBySpeed"), CompressionModeValue, GEngineIni);
FParse::Value(FCommandLine::Get(), TEXT("-astcqualitybyspeed="), CompressionModeValue);
CompressionModeValue = FMath::Min<uint32>(CompressionModeValue, MAX_QUALITY_BY_SPEED);
return CompressionModeValue;
}
static FString GetQualityString(int32 OverrideSizeValue=-1, int32 OverrideSpeedValue=-1)
{
// convert to a string
FString CompressionMode;
switch (OverrideSizeValue >= 0 ? OverrideSizeValue : GetDefaultCompressionBySizeValue())
{
case 0: CompressionMode = TEXT("12x12"); break;
case 1: CompressionMode = TEXT("10x10"); break;
case 2: CompressionMode = TEXT("8x8"); break;
case 3: CompressionMode = TEXT("6x6"); break;
case 4: CompressionMode = TEXT("4x4"); break;
default: UE_LOG(LogTemp, Fatal, TEXT("ASTC size quality higher than expected"));
}
switch (OverrideSpeedValue >= 0 ? OverrideSpeedValue : GetDefaultCompressionBySpeedValue())
{
case 0: CompressionMode += TEXT(" -veryfast"); break;
case 1: CompressionMode += TEXT(" -fast"); break;
case 2: CompressionMode += TEXT(" -medium"); break;
case 3: CompressionMode += TEXT(" -thorough"); break;
default: UE_LOG(LogTemp, Fatal, TEXT("ASTC speed quality higher than expected"));
}
return CompressionMode;
}
static EPixelFormat GetQualityFormat(int32 OverrideSizeValue=-1)
{
// convert to a string
EPixelFormat Format = PF_Unknown;
switch (OverrideSizeValue >= 0 ? OverrideSizeValue : GetDefaultCompressionBySizeValue())
{
case 0: Format = PF_ASTC_12x12; break;
case 1: Format = PF_ASTC_10x10; break;
case 2: Format = PF_ASTC_8x8; break;
case 3: Format = PF_ASTC_6x6; break;
case 4: Format = PF_ASTC_4x4; break;
default: UE_LOG(LogTemp, Fatal, TEXT("Max quality higher than expected"));
}
return Format;
}
static uint16 GetQualityVersion(int32 OverrideSizeValue = -1)
{
// top 3 bits for size compression value, and next 3 for speed
return ((OverrideSizeValue >= 0 ? OverrideSizeValue : GetDefaultCompressionBySizeValue()) << 13) | (GetDefaultCompressionBySpeedValue() << 10);
}
static bool CompressSliceToASTC(
const void* SourceData,
int32 SizeX,
int32 SizeY,
FString CompressionParameters,
TArray<uint8>& OutCompressedData
)
{
// Always Y-invert the image prior to compression for proper orientation post-compression
TArray<uint8> LineBuffer;
LineBuffer.AddUninitialized(16384 * 4);
uint32 LineSize = SizeX * 4;
for (int32 LineIndex = 0; LineIndex < (SizeY / 2); LineIndex++)
{
uint8* LineData0 = ((uint8*)SourceData) + (LineSize * LineIndex);
uint8* LineData1 = ((uint8*)SourceData) + (LineSize * (SizeY - LineIndex - 1));
FMemory::Memcpy(LineBuffer.GetData(), LineData0, LineSize);
FMemory::Memcpy(LineData0, LineData1, LineSize);
FMemory::Memcpy(LineData1, LineBuffer.GetData(), LineSize);
}
// Compress and retrieve the PNG data to write out to disk
TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
ImageWrapper->SetRaw(SourceData, SizeX * SizeY * 4, SizeX, SizeY, ERGBFormat::RGBA, 8);
const TArray<uint8>& FileData = ImageWrapper->GetCompressed();
int32 FileDataSize = FileData.Num();
FGuid Guid;
FPlatformMisc::CreateGuid(Guid);
FString InputFilePath = FString::Printf(TEXT("Cache/%08x-%08x-%08x-%08x-RGBToASTCIn.png"), Guid.A, Guid.B, Guid.C, Guid.D);
FString OutputFilePath = FString::Printf(TEXT("Cache/%08x-%08x-%08x-%08x-RGBToASTCOut.astc"), Guid.A, Guid.B, Guid.C, Guid.D);
InputFilePath = FPaths::ProjectIntermediateDir() + InputFilePath;
OutputFilePath = FPaths::ProjectIntermediateDir() + OutputFilePath;
FArchive* PNGFile = NULL;
while (!PNGFile)
{
PNGFile = IFileManager::Get().CreateFileWriter(*InputFilePath); // Occasionally returns NULL due to error code ERROR_SHARING_VIOLATION
FPlatformProcess::Sleep(0.01f); // ... no choice but to wait for the file to become free to access
}
PNGFile->Serialize((void*)&FileData[0], FileDataSize);
delete PNGFile;
// Compress PNG file to ASTC (using the reference astcenc.exe from ARM)
FString Params = FString::Printf(TEXT("-c \"%s\" \"%s\" %s"),
*InputFilePath,
*OutputFilePath,
*CompressionParameters
);
UE_LOG(LogTextureFormatASTC, Display, TEXT("Compressing to ASTC (options = '%s')..."), *CompressionParameters);
// Start Compressor
#if PLATFORM_MAC
FString CompressorPath(FPaths::EngineDir() + TEXT("Binaries/ThirdParty/ARM/Mac/astcenc"));
#elif PLATFORM_LINUX
FString CompressorPath(FPaths::EngineDir() + TEXT("Binaries/ThirdParty/ARM/Linux32/astcenc"));
#elif PLATFORM_WINDOWS
FString CompressorPath(FPaths::EngineDir() + TEXT("Binaries/ThirdParty/ARM/Win32/astcenc.exe"));
#else
#error Unsupported platform
#endif
FProcHandle Proc = FPlatformProcess::CreateProc(*CompressorPath, *Params, true, false, false, NULL, -1, NULL, NULL);
// Failed to start the compressor process
if (!Proc.IsValid())
{
UE_LOG(LogTextureFormatASTC, Error, TEXT("Failed to start astcenc for compressing images (%s)"), *CompressorPath);
return false;
}
// Wait for the process to complete
int ReturnCode;
while (!FPlatformProcess::GetProcReturnCode(Proc, &ReturnCode))
{
FPlatformProcess::Sleep(0.01f);
}
// Did it work?
bool bConversionWasSuccessful = (ReturnCode == 0);
// Open compressed file and put the data in OutCompressedImage
if (bConversionWasSuccessful)
{
// Get raw file data
TArray<uint8> ASTCData;
FFileHelper::LoadFileToArray(ASTCData, *OutputFilePath);
// Process it
FASTCHeader* Header = (FASTCHeader*)ASTCData.GetData();
// Fiddle with the texel count data to get the right value
uint32 TexelCountX =
(Header->TexelCountX[0] << 0) +
(Header->TexelCountX[1] << 8) +
(Header->TexelCountX[2] << 16);
uint32 TexelCountY =
(Header->TexelCountY[0] << 0) +
(Header->TexelCountY[1] << 8) +
(Header->TexelCountY[2] << 16);
uint32 TexelCountZ =
(Header->TexelCountZ[0] << 0) +
(Header->TexelCountZ[1] << 8) +
(Header->TexelCountZ[2] << 16);
// UE_LOG(LogTextureFormatASTC, Display, TEXT(" Compressed Texture Header:"));
// UE_LOG(LogTextureFormatASTC, Display, TEXT(" Magic: %x"), Header->Magic);
// UE_LOG(LogTextureFormatASTC, Display, TEXT(" BlockSizeX: %u"), Header->BlockSizeX);
// UE_LOG(LogTextureFormatASTC, Display, TEXT(" BlockSizeY: %u"), Header->BlockSizeY);
// UE_LOG(LogTextureFormatASTC, Display, TEXT(" BlockSizeZ: %u"), Header->BlockSizeZ);
// UE_LOG(LogTextureFormatASTC, Display, TEXT(" TexelCountX: %u"), TexelCountX);
// UE_LOG(LogTextureFormatASTC, Display, TEXT(" TexelCountY: %u"), TexelCountY);
// UE_LOG(LogTextureFormatASTC, Display, TEXT(" TexelCountZ: %u"), TexelCountZ);
// Calculate size of this mip in blocks
uint32 MipSizeX = (TexelCountX + Header->BlockSizeX - 1) / Header->BlockSizeX;
uint32 MipSizeY = (TexelCountY + Header->BlockSizeY - 1) / Header->BlockSizeY;
// A block is always 16 bytes
uint32 MipSize = MipSizeX * MipSizeY * 16;
// Copy the compressed data
OutCompressedData.Empty(MipSize);
OutCompressedData.AddUninitialized(MipSize);
void* MipData = OutCompressedData.GetData();
// Calculate the offset to get to the mip data
check(sizeof(FASTCHeader) == 16);
check(ASTCData.Num() == (sizeof(FASTCHeader) + MipSize));
FMemory::Memcpy(MipData, ASTCData.GetData() + sizeof(FASTCHeader), MipSize);
// Delete intermediate files
IFileManager::Get().Delete(*InputFilePath);
IFileManager::Get().Delete(*OutputFilePath);
}
else
{
UE_LOG(LogTextureFormatASTC, Error, TEXT("ASTC encoder failed with return code %d, mip size (%d, %d). Leaving '%s' for testing."), ReturnCode, SizeX, SizeY, *InputFilePath);
// IFileManager::Get().Delete(*InputFilePath);
// IFileManager::Get().Delete(*OutputFilePath);
return false;
}
// Delete intermediate files
IFileManager::Get().Delete(*InputFilePath);
IFileManager::Get().Delete(*OutputFilePath);
return true;
}
/**
* ASTC texture format handler.
*/
class FTextureFormatASTC : public ITextureFormat
{
public:
FTextureFormatASTC()
: IntelISPCTexCompFormat(*FModuleManager::LoadModuleChecked<ITextureFormatModule>(TEXT("TextureFormatIntelISPCTexComp")).GetTextureFormat())
{
}
virtual bool AllowParallelBuild() const override
{
#if SUPPORTS_ISPC_ASTC
return IntelISPCTexCompFormat.AllowParallelBuild();
#else
return true;
#endif
}
// Version for all ASTC textures, whether it's handled by the ARM encoder or the ISPC encoder.
virtual uint16 GetVersion(
FName Format,
const struct FTextureBuildSettings* BuildSettings = nullptr
) const override
{
return GetQualityVersion(BuildSettings ? BuildSettings->CompressionQuality : -1) + BASE_ASTC_FORMAT_VERSION;
}
// // Since we want to have per texture [group] compression settings, we need to have the key based on the texture
// virtual FString GetDerivedDataKeyString(const class UTexture& Texture) const override
// {
// const int32 LODBias = UDeviceProfileManager::Get().GetActiveProfile()->GetTextureLODSettings()->CalculateLODBias(Texture.Source.GetSizeX(), Texture.Source.GetSizeY(), Texture.LODGroup, Texture.LODBias, Texture.NumCinematicMipLevels, Texture.MipGenSettings);
// check(LODBias >= 0);
// return FString::Printf(TEXT("%02u%d_"), (uint32)LODBias, CVarVirtualTextureReducedMemoryEnabled->GetValueOnGameThread());
// }
virtual FTextureFormatCompressorCaps GetFormatCapabilities() const override
{
FTextureFormatCompressorCaps RetCaps;
// use defaults
return RetCaps;
}
virtual void GetSupportedFormats(TArray<FName>& OutFormats) const override
{
for (int32 i = 0; i < ARRAY_COUNT(GSupportedTextureFormatNames); ++i)
{
OutFormats.Add(GSupportedTextureFormatNames[i]);
}
}
virtual bool CompressImage(
const FImage& InImage,
const struct FTextureBuildSettings& BuildSettings,
bool bImageHasAlphaChannel,
FCompressedImage2D& OutCompressedImage
) const override
{
#if SUPPORTS_ISPC_ASTC
// Route ASTC compression work to the ISPC module instead.
return IntelISPCTexCompFormat.CompressImage(InImage, BuildSettings, bImageHasAlphaChannel, OutCompressedImage);
#endif
// Get Raw Image Data from passed in FImage
FImage Image;
InImage.CopyTo(Image, ERawImageFormat::BGRA8, BuildSettings.GetGammaSpace());
// Determine the compressed pixel format and compression parameters
EPixelFormat CompressedPixelFormat = PF_Unknown;
FString CompressionParameters = TEXT("");
bool bIsRGBColor = (BuildSettings.TextureFormatName == GTextureFormatNameASTC_RGB ||
((BuildSettings.TextureFormatName == GTextureFormatNameASTC_RGBAuto) && !bImageHasAlphaChannel));
bool bIsRGBAColor = (BuildSettings.TextureFormatName == GTextureFormatNameASTC_RGBA ||
((BuildSettings.TextureFormatName == GTextureFormatNameASTC_RGBAuto) && bImageHasAlphaChannel));
if (bIsRGBColor)
{
CompressedPixelFormat = GetQualityFormat();
CompressionParameters = FString::Printf(TEXT("%s %s -esw bgra -ch 1 1 1 0"), *GetQualityString(BuildSettings.CompressionQuality), /*BuildSettings.bSRGB ? TEXT("-srgb") :*/ TEXT("") );
}
else if (bIsRGBAColor)
{
CompressedPixelFormat = GetQualityFormat();
CompressionParameters = FString::Printf(TEXT("%s %s -esw bgra -ch 1 1 1 1"), *GetQualityString(BuildSettings.CompressionQuality), /*BuildSettings.bSRGB ? TEXT("-srgb") :*/ TEXT("") );
}
else if (BuildSettings.TextureFormatName == GTextureFormatNameASTC_NormalAG)
{
CompressedPixelFormat = GetQualityFormat(FORCED_NORMAL_MAP_COMPRESSION_SIZE_VALUE);
CompressionParameters = FString::Printf(TEXT("%s -esw 0g0b -ch 0 1 0 1 -oplimit 1000 -mincorrel 0.99 -dblimit 60 -b 2.5 -v 3 1 1 0 50 0 -va 1 1 0 50"), *GetQualityString(FORCED_NORMAL_MAP_COMPRESSION_SIZE_VALUE, -1));
}
else if (BuildSettings.TextureFormatName == GTextureFormatNameASTC_NormalRG)
{
CompressedPixelFormat = GetQualityFormat(FORCED_NORMAL_MAP_COMPRESSION_SIZE_VALUE);
CompressionParameters = FString::Printf(TEXT("%s -esw bg00 -ch 1 1 0 0 -oplimit 1000 -mincorrel 0.99 -dblimit 60 -b 2.5 -v 3 1 1 0 50 0 -va 1 1 0 50"), *GetQualityString(FORCED_NORMAL_MAP_COMPRESSION_SIZE_VALUE, -1));
}
// Compress the image, slice by slice
bool bCompressionSucceeded = true;
int32 SliceSizeInTexels = Image.SizeX * Image.SizeY;
for (int32 SliceIndex = 0; SliceIndex < Image.NumSlices && bCompressionSucceeded; ++SliceIndex)
{
TArray<uint8> CompressedSliceData;
bCompressionSucceeded = CompressSliceToASTC(
Image.AsBGRA8() + (SliceIndex * SliceSizeInTexels),
Image.SizeX,
Image.SizeY,
CompressionParameters,
CompressedSliceData
);
OutCompressedImage.RawData.Append(CompressedSliceData);
}
if (bCompressionSucceeded)
{
OutCompressedImage.SizeX = Image.SizeX;
OutCompressedImage.SizeY = Image.SizeY;
OutCompressedImage.PixelFormat = CompressedPixelFormat;
}
return bCompressionSucceeded;
}
private:
const ITextureFormat& IntelISPCTexCompFormat;
};
/**
* Module for ASTC texture compression.
*/
static ITextureFormat* Singleton = NULL;
class FTextureFormatASTCModule : public ITextureFormatModule
{
public:
FTextureFormatASTCModule()
{
}
virtual ~FTextureFormatASTCModule()
{
delete Singleton;
Singleton = NULL;
}
virtual ITextureFormat* GetTextureFormat()
{
if (!Singleton)
{
Singleton = new FTextureFormatASTC();
}
return Singleton;
}
};
IMPLEMENT_MODULE(FTextureFormatASTCModule, TextureFormatASTC);