refactor(new_editor/app): split frame support and texture decoding

This commit is contained in:
2026-04-15 08:45:04 +08:00
parent 9f3ea11dbc
commit 0e7bf8d16e
5 changed files with 223 additions and 199 deletions

View File

@@ -1,7 +1,6 @@
#include "NativeRendererSupport.h"
#include <filesystem>
#include <limits>
#include <memory>
namespace XCEngine::UI::Editor::Host {
@@ -71,147 +70,6 @@ void NativeRenderer::ReleaseTexture(::XCEngine::UI::UITextureHandle& texture) {
texture = {};
}
bool NativeRenderer::DecodeTextureFile(
const std::filesystem::path& path,
NativeTextureResource& outTexture,
std::string& outError) {
outError.clear();
if (!EnsureWicFactory(outError)) {
return false;
}
const std::wstring widePath = path.wstring();
Microsoft::WRL::ComPtr<IWICBitmapDecoder> decoder;
HRESULT hr = m_wicFactory->CreateDecoderFromFilename(
widePath.c_str(),
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
decoder.ReleaseAndGetAddressOf());
if (FAILED(hr) || !decoder) {
outError = HrToString("IWICImagingFactory::CreateDecoderFromFilename", hr);
return false;
}
Microsoft::WRL::ComPtr<IWICBitmapFrameDecode> frame;
hr = decoder->GetFrame(0u, frame.ReleaseAndGetAddressOf());
if (FAILED(hr) || !frame) {
outError = HrToString("IWICBitmapDecoder::GetFrame", hr);
return false;
}
return DecodeTextureFrame(*frame.Get(), outTexture, outError);
}
bool NativeRenderer::DecodeTextureMemory(
const std::uint8_t* data,
std::size_t size,
NativeTextureResource& outTexture,
std::string& outError) {
outError.clear();
if (data == nullptr || size == 0u) {
outError = "DecodeTextureMemory rejected an empty image payload.";
return false;
}
if (size > static_cast<std::size_t>((std::numeric_limits<DWORD>::max)())) {
outError = "DecodeTextureMemory payload exceeds WIC stream limits.";
return false;
}
if (!EnsureWicFactory(outError)) {
return false;
}
Microsoft::WRL::ComPtr<IWICStream> stream;
HRESULT hr = m_wicFactory->CreateStream(stream.ReleaseAndGetAddressOf());
if (FAILED(hr) || !stream) {
outError = HrToString("IWICImagingFactory::CreateStream", hr);
return false;
}
hr = stream->InitializeFromMemory(
const_cast<BYTE*>(reinterpret_cast<const BYTE*>(data)),
static_cast<DWORD>(size));
if (FAILED(hr)) {
outError = HrToString("IWICStream::InitializeFromMemory", hr);
return false;
}
Microsoft::WRL::ComPtr<IWICBitmapDecoder> decoder;
hr = m_wicFactory->CreateDecoderFromStream(
stream.Get(),
nullptr,
WICDecodeMetadataCacheOnLoad,
decoder.ReleaseAndGetAddressOf());
if (FAILED(hr) || !decoder) {
outError = HrToString("IWICImagingFactory::CreateDecoderFromStream", hr);
return false;
}
Microsoft::WRL::ComPtr<IWICBitmapFrameDecode> frame;
hr = decoder->GetFrame(0u, frame.ReleaseAndGetAddressOf());
if (FAILED(hr) || !frame) {
outError = HrToString("IWICBitmapDecoder::GetFrame", hr);
return false;
}
return DecodeTextureFrame(*frame.Get(), outTexture, outError);
}
bool NativeRenderer::DecodeTextureFrame(
IWICBitmapSource& source,
NativeTextureResource& outTexture,
std::string& outError) {
outError.clear();
Microsoft::WRL::ComPtr<IWICFormatConverter> converter;
HRESULT hr = m_wicFactory->CreateFormatConverter(converter.ReleaseAndGetAddressOf());
if (FAILED(hr) || !converter) {
outError = HrToString("IWICImagingFactory::CreateFormatConverter", hr);
return false;
}
hr = converter->Initialize(
&source,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
nullptr,
0.0f,
WICBitmapPaletteTypeCustom);
if (FAILED(hr)) {
outError = HrToString("IWICFormatConverter::Initialize", hr);
return false;
}
UINT width = 0u;
UINT height = 0u;
hr = converter->GetSize(&width, &height);
if (FAILED(hr) || width == 0u || height == 0u) {
outError = HrToString("IWICBitmapSource::GetSize", hr);
return false;
}
std::vector<std::uint8_t> pixels(
static_cast<std::size_t>(width) * static_cast<std::size_t>(height) * 4u);
hr = converter->CopyPixels(
nullptr,
width * 4u,
static_cast<UINT>(pixels.size()),
pixels.data());
if (FAILED(hr)) {
outError = HrToString("IWICBitmapSource::CopyPixels", hr);
return false;
}
outTexture.pixels = std::move(pixels);
outTexture.width = width;
outTexture.height = height;
outTexture.cachedBitmap.Reset();
outTexture.cachedTarget = nullptr;
return true;
}
bool NativeRenderer::ResolveTextureBitmap(
ID2D1RenderTarget& renderTarget,
NativeTextureResource& texture,