#include "NativeRendererSupport.h" #include #include namespace XCEngine::UI::Editor::Host { using namespace NativeRendererSupport; bool NativeRenderer::LoadTextureFromFile( const std::filesystem::path& path, ::XCEngine::UI::UITextureHandle& outTexture, std::string& outError) { outError.clear(); ReleaseTexture(outTexture); auto texture = std::make_unique(); if (!DecodeTextureFile(path, *texture, outError)) { outTexture = {}; return false; } outTexture.nativeHandle = reinterpret_cast(texture.get()); outTexture.width = texture->width; outTexture.height = texture->height; outTexture.kind = ::XCEngine::UI::UITextureHandleKind::DescriptorHandle; m_liveTextures.insert(texture.get()); texture.release(); return true; } bool NativeRenderer::LoadTextureFromMemory( const std::uint8_t* data, std::size_t size, ::XCEngine::UI::UITextureHandle& outTexture, std::string& outError) { outError.clear(); ReleaseTexture(outTexture); auto texture = std::make_unique(); if (!DecodeTextureMemory(data, size, *texture, outError)) { outTexture = {}; return false; } outTexture.nativeHandle = reinterpret_cast(texture.get()); outTexture.width = texture->width; outTexture.height = texture->height; outTexture.kind = ::XCEngine::UI::UITextureHandleKind::DescriptorHandle; m_liveTextures.insert(texture.get()); texture.release(); return true; } void NativeRenderer::ReleaseTexture(::XCEngine::UI::UITextureHandle& texture) { if (!texture.IsValid()) { texture = {}; return; } auto* resource = reinterpret_cast(texture.nativeHandle); if (resource != nullptr) { const auto found = m_liveTextures.find(resource); if (found != m_liveTextures.end()) { m_liveTextures.erase(found); delete resource; } } texture = {}; } bool NativeRenderer::ResolveTextureBitmap( ID2D1RenderTarget& renderTarget, NativeTextureResource& texture, Microsoft::WRL::ComPtr& outBitmap) { outBitmap.Reset(); if (texture.width == 0u || texture.height == 0u || texture.pixels.empty()) { return false; } if (texture.cachedBitmap && texture.cachedTarget == &renderTarget) { outBitmap = texture.cachedBitmap; return true; } Microsoft::WRL::ComPtr bitmap; const D2D1_BITMAP_PROPERTIES properties = D2D1::BitmapProperties( D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), kBaseDpi, kBaseDpi); const HRESULT hr = renderTarget.CreateBitmap( D2D1::SizeU(texture.width, texture.height), texture.pixels.data(), texture.width * 4u, &properties, bitmap.ReleaseAndGetAddressOf()); if (FAILED(hr) || !bitmap) { return false; } if (&renderTarget == m_renderTarget.Get()) { texture.cachedBitmap = bitmap; texture.cachedTarget = &renderTarget; } outBitmap = std::move(bitmap); return true; } bool NativeRenderer::ResolveInteropBitmap( const ::XCEngine::UI::UITextureHandle& texture, Microsoft::WRL::ComPtr& outBitmap) const { return m_windowInterop.ResolveInteropBitmap(texture, outBitmap); } } // namespace XCEngine::UI::Editor::Host