Files
UnrealEngineUWP/Engine/Source/Runtime/ImageWriteQueue/Public/ImagePixelData.h
Julien StJean 547c7f160d Optimisation to the legacy texture import and improvement to texture wrapper
Minor change to FImageWrapperBase. GetRaw and GetCompressed now consume the array with the same name instead of having to do a copy of it.
I changed the api IImageWrapper::GetCompressed to return a TArray64<uint8> instead of returning a const TArray64<uint8>&.
Added the format RGBAF to the struct ERGBFormat. Changed the engine code using the EXR image wrapper to reflect that.
The EXR image wrapper now avoid doing an unessary copy of the compressed image when calling compress.

Improvement to the performence of the function UTextureFactory::ImportImage. We now use the magic bytes of the file for certains format to skip some tests.

Here is some performance metrics I captured on my desktop (6 core, 12 threads XEON)

Importing a folder of tiff files (22 files, 4.16 GB Total)
Before: 66.152738 seconds
After: 43.609245 seconds

#jira UEENT-3822
#rb Alexis.Matte

[CL 16128765 by Julien StJean in ue5-main branch]
2021-04-27 11:59:02 -04:00

249 lines
6.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Misc/CoreDefines.h"
#include "Math/IntPoint.h"
#include "IImageWrapper.h"
#include "Templates/UniquePtr.h"
class FFloat16Color;
template<typename PixelType> struct TImagePixelDataTraits;
enum class EImagePixelType
{
Color,
Float16,
Float32,
};
struct IImagePixelDataPayload
{
virtual ~IImagePixelDataPayload() {}
};
typedef TSharedPtr<IImagePixelDataPayload, ESPMode::ThreadSafe> FImagePixelPayloadPtr;
struct FImagePixelData
{
virtual ~FImagePixelData() {}
/**
* Retrieve the type of this data
*/
EImagePixelType GetType() const
{
return Type;
}
/**
* Retrieve the size of this data
*/
FIntPoint GetSize() const
{
return Size;
}
/**
* Retrieve the pixel layout of this data
*/
ERGBFormat GetPixelLayout() const
{
return PixelLayout;
}
/**
* Retrieve the number of bits per each channel of color in the data
*/
uint8 GetBitDepth() const
{
return BitDepth;
}
/**
* Retrieve the number of channels in the data
*/
uint8 GetNumChannels() const
{
return NumChannels;
}
/**
* Check that this data is the size it should be
*/
bool IsDataWellFormed() const
{
const void* RawPtr = nullptr;
int64 SizeBytes = 0;
return GetRawData(RawPtr, SizeBytes);
}
/**
* Get the data and its size only if it is well formed
*/
bool GetRawData(const void*& OutRawData, int64& OutSizeBytes) const
{
const void* RawPtr = nullptr;
int64 SizeBytes = 0;
RetrieveData(RawPtr, SizeBytes);
int64 FoundTotalSize = int64(Size.X)*int64(Size.Y)*int64(BitDepth / 8)*int64(NumChannels);
if (RawPtr && SizeBytes == FoundTotalSize)
{
OutRawData = RawPtr;
OutSizeBytes = SizeBytes;
return true;
}
return false;
}
/**
* Get the size in bytes, regardless of if it is well formed.
*/
int64 GetRawDataSizeInBytes() const
{
const void* RawPtr = nullptr;
int64 SizeBytes = 0;
RetrieveData(RawPtr, SizeBytes);
return SizeBytes;
}
/**
* Copy this whole image buffer. This can be very costly for large images.
*/
TUniquePtr<FImagePixelData> CopyImageData() const
{
return Copy();
}
/**
* Move this whole image buffer to a new allocation.
*/
TUniquePtr<FImagePixelData> MoveImageDataToNew()
{
return Move();
}
/**
* Return a pointer to the Payload stored in this data.
*/
template<typename T>
T* GetPayload() { return static_cast<T*>(Payload.Get()); }
/**
* Return a const pointer to the Payload stored in this data.
*/
template<typename T>
const T* GetPayload() const { return static_cast<T*>(Payload.Get()); }
protected:
FImagePixelData(const FIntPoint& InSize, EImagePixelType InPixelType, ERGBFormat InPixelLayout, uint8 InBitDepth, uint8 InNumChannels, FImagePixelPayloadPtr InPayload)
: Size(InSize)
, Type(InPixelType)
, PixelLayout(InPixelLayout)
, BitDepth(InBitDepth)
, NumChannels(InNumChannels)
, Payload(InPayload)
{}
private:
/**
* Retrieve the raw pixel data
*/
virtual void RetrieveData(const void*& OutDataPtr, int64& OutSizeBytes) const = 0;
virtual TUniquePtr<FImagePixelData> Copy() const = 0;
virtual TUniquePtr<FImagePixelData> Move() = 0;
/** The size of the pixel data */
FIntPoint Size;
/** The type of the derived data */
EImagePixelType Type;
/** The pixel layout of this data */
ERGBFormat PixelLayout;
/** The number of bits per each channel of color in the data */
uint8 BitDepth;
/** Number of channels in the data */
uint8 NumChannels;
/** Optional user-specified payload */
FImagePixelPayloadPtr Payload;
};
/**
* Templated pixel data - currently supports FColor, FFloat16Color and FLinearColor
*/
template<typename PixelType>
struct TImagePixelData : FImagePixelData
{
TArray64<PixelType> Pixels;
TImagePixelData(const FIntPoint& InSize)
: FImagePixelData(InSize, TImagePixelDataTraits<PixelType>::PixelType, TImagePixelDataTraits<PixelType>::PixelLayout, TImagePixelDataTraits<PixelType>::BitDepth, TImagePixelDataTraits<PixelType>::NumChannels, nullptr)
{}
TImagePixelData(const FIntPoint& InSize, TArray64<PixelType>&& InPixels)
: FImagePixelData(InSize, TImagePixelDataTraits<PixelType>::PixelType, TImagePixelDataTraits<PixelType>::PixelLayout, TImagePixelDataTraits<PixelType>::BitDepth, TImagePixelDataTraits<PixelType>::NumChannels, nullptr)
, Pixels(MoveTemp(InPixels))
{}
TImagePixelData(const FIntPoint& InSize, FImagePixelPayloadPtr InPayload)
: FImagePixelData(InSize, TImagePixelDataTraits<PixelType>::PixelType, TImagePixelDataTraits<PixelType>::PixelLayout, TImagePixelDataTraits<PixelType>::BitDepth, TImagePixelDataTraits<PixelType>::NumChannels, InPayload)
{}
TImagePixelData(const FIntPoint& InSize, TArray64<PixelType>&& InPixels, FImagePixelPayloadPtr InPayload)
: FImagePixelData(InSize, TImagePixelDataTraits<PixelType>::PixelType, TImagePixelDataTraits<PixelType>::PixelLayout, TImagePixelDataTraits<PixelType>::BitDepth, TImagePixelDataTraits<PixelType>::NumChannels, InPayload)
, Pixels(MoveTemp(InPixels))
{}
virtual TUniquePtr<FImagePixelData> Move() override
{
return MakeUnique<TImagePixelData<PixelType>>(MoveTemp(*this));
}
virtual TUniquePtr<FImagePixelData> Copy() const override
{
return MakeUnique<TImagePixelData<PixelType>>(*this);
}
virtual void RetrieveData(const void*& OutDataPtr, int64& OutSizeBytes) const override
{
OutDataPtr = static_cast<const void*>(&Pixels[0]);
OutSizeBytes = Pixels.Num() * sizeof(PixelType);
}
};
template<> struct TImagePixelDataTraits<FColor>
{
static const ERGBFormat PixelLayout = ERGBFormat::BGRA;
static const EImagePixelType PixelType = EImagePixelType::Color;
enum { BitDepth = 8, NumChannels = 4 };
};
template<> struct TImagePixelDataTraits<FFloat16Color>
{
static const ERGBFormat PixelLayout = ERGBFormat::RGBAF;
static const EImagePixelType PixelType = EImagePixelType::Float16;
enum { BitDepth = 16, NumChannels = 4 };
};
template<> struct TImagePixelDataTraits<FLinearColor>
{
static const ERGBFormat PixelLayout = ERGBFormat::RGBAF;
static const EImagePixelType PixelType = EImagePixelType::Float32;
enum { BitDepth = 32, NumChannels = 4 };
};