You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#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]
459 lines
16 KiB
C++
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);
|