151 lines
4.4 KiB
C++
151 lines
4.4 KiB
C++
// Copyright OmixLab LTD. All Rights Reserved.
|
|
|
|
#include "MosisPhoneTexture.h"
|
|
#include "RenderingThread.h"
|
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LogMosisPhoneTexture, Log, All);
|
|
|
|
UMosisPhoneTexture::UMosisPhoneTexture()
|
|
{
|
|
// UTexture2DDynamic defaults are fine
|
|
SRGB = true;
|
|
Filter = TF_Bilinear;
|
|
}
|
|
|
|
void UMosisPhoneTexture::Initialize(uint32 InWidth, uint32 InHeight)
|
|
{
|
|
UE_LOG(LogMosisPhoneTexture, Log, TEXT("Initialize: %dx%d"), InWidth, InHeight);
|
|
|
|
// Use UTexture2DDynamic's Init method
|
|
Init(InWidth, InHeight, PF_R8G8B8A8, false);
|
|
|
|
bIsReady = true;
|
|
}
|
|
|
|
#if PLATFORM_ANDROID
|
|
|
|
void UMosisPhoneTexture::UpdateFromHardwareBuffer(AHardwareBuffer* Buffer)
|
|
{
|
|
if (!Buffer)
|
|
{
|
|
UE_LOG(LogMosisPhoneTexture, Warning, TEXT("UpdateFromHardwareBuffer: null buffer"));
|
|
return;
|
|
}
|
|
|
|
CurrentBuffer = Buffer;
|
|
|
|
// Get buffer dimensions
|
|
AHardwareBuffer_Desc Desc{};
|
|
AHardwareBuffer_describe(Buffer, &Desc);
|
|
|
|
UE_LOG(LogMosisPhoneTexture, Log, TEXT("UpdateFromHardwareBuffer: %dx%d"), Desc.width, Desc.height);
|
|
|
|
// Lock buffer and read data
|
|
void* LockedData = nullptr;
|
|
int32 Result = AHardwareBuffer_lock(Buffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr, &LockedData);
|
|
|
|
if (Result != 0 || !LockedData)
|
|
{
|
|
UE_LOG(LogMosisPhoneTexture, Error, TEXT("UpdateFromHardwareBuffer: Failed to lock buffer, result=%d"), Result);
|
|
return;
|
|
}
|
|
|
|
uint8* PixelData = static_cast<uint8*>(LockedData);
|
|
|
|
// Copy data to a buffer for update (accounting for stride)
|
|
uint32 StridePixels = Desc.stride > 0 ? Desc.stride : Desc.width;
|
|
TArray<uint8> TextureData;
|
|
TextureData.SetNumUninitialized(Desc.width * Desc.height * 4);
|
|
|
|
for (uint32 y = 0; y < Desc.height; y++)
|
|
{
|
|
FMemory::Memcpy(
|
|
TextureData.GetData() + y * Desc.width * 4,
|
|
PixelData + y * StridePixels * 4,
|
|
Desc.width * 4
|
|
);
|
|
}
|
|
|
|
AHardwareBuffer_unlock(Buffer, nullptr);
|
|
|
|
// Update the texture using UTexture2DDynamic's update regions
|
|
FTexture2DDynamicResource* TextureResource = static_cast<FTexture2DDynamicResource*>(GetResource());
|
|
if (TextureResource)
|
|
{
|
|
ENQUEUE_RENDER_COMMAND(UpdateMosisTexture)(
|
|
[TextureResource, Data = MoveTemp(TextureData), Width = Desc.width, Height = Desc.height](FRHICommandListImmediate& RHICmdList)
|
|
{
|
|
FUpdateTextureRegion2D Region(0, 0, 0, 0, Width, Height);
|
|
RHIUpdateTexture2D(
|
|
TextureResource->GetTexture2DRHI(),
|
|
0,
|
|
Region,
|
|
Width * 4,
|
|
Data.GetData()
|
|
);
|
|
}
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
void UMosisPhoneTexture::NotifyFrameAvailable()
|
|
{
|
|
if (!CurrentBuffer || !bIsReady)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get buffer dimensions
|
|
AHardwareBuffer_Desc Desc{};
|
|
AHardwareBuffer_describe(CurrentBuffer, &Desc);
|
|
|
|
// Lock buffer and read data
|
|
void* LockedData = nullptr;
|
|
int32 Result = AHardwareBuffer_lock(CurrentBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr, &LockedData);
|
|
|
|
if (Result != 0 || !LockedData)
|
|
{
|
|
return;
|
|
}
|
|
|
|
uint8* PixelData = static_cast<uint8*>(LockedData);
|
|
|
|
// Copy data to a buffer for update (accounting for stride)
|
|
uint32 StridePixels = Desc.stride > 0 ? Desc.stride : Desc.width;
|
|
TArray<uint8> TextureData;
|
|
TextureData.SetNumUninitialized(Desc.width * Desc.height * 4);
|
|
|
|
for (uint32 y = 0; y < Desc.height; y++)
|
|
{
|
|
FMemory::Memcpy(
|
|
TextureData.GetData() + y * Desc.width * 4,
|
|
PixelData + y * StridePixels * 4,
|
|
Desc.width * 4
|
|
);
|
|
}
|
|
|
|
AHardwareBuffer_unlock(CurrentBuffer, nullptr);
|
|
|
|
// Update the texture
|
|
FTexture2DDynamicResource* TextureResource = static_cast<FTexture2DDynamicResource*>(GetResource());
|
|
if (TextureResource)
|
|
{
|
|
ENQUEUE_RENDER_COMMAND(UpdateMosisTextureFrame)(
|
|
[TextureResource, Data = MoveTemp(TextureData), Width = Desc.width, Height = Desc.height](FRHICommandListImmediate& RHICmdList)
|
|
{
|
|
FUpdateTextureRegion2D Region(0, 0, 0, 0, Width, Height);
|
|
RHIUpdateTexture2D(
|
|
TextureResource->GetTexture2DRHI(),
|
|
0,
|
|
Region,
|
|
Width * 4,
|
|
Data.GetData()
|
|
);
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
#endif // PLATFORM_ANDROID
|