#include "NativeRendererSupport.h" namespace XCEngine::UI::Editor::Host { using namespace NativeRendererSupport; void NativeRenderer::Resize(UINT width, UINT height) { if (!m_renderTarget || width == 0 || height == 0) { return; } const HRESULT hr = m_renderTarget->Resize(D2D1::SizeU(width, height)); if (hr == D2DERR_RECREATE_TARGET) { DiscardRenderTarget(); } } bool NativeRenderer::EnsureRenderTarget() { if (!m_hwnd || !m_d2dFactory || !m_dwriteFactory) { m_lastRenderError = "EnsureRenderTarget requires hwnd, D2D factory, and DWrite factory."; return false; } return CreateDeviceResources(); } void NativeRenderer::DiscardRenderTarget() { InvalidateCachedTextureBitmaps(m_renderTarget.Get()); m_solidBrush.Reset(); m_renderTarget.Reset(); } bool NativeRenderer::CreateDeviceResources() { if (m_renderTarget) { return true; } RECT clientRect = {}; GetClientRect(m_hwnd, &clientRect); const UINT width = static_cast((std::max)(clientRect.right - clientRect.left, 1L)); const UINT height = static_cast((std::max)(clientRect.bottom - clientRect.top, 1L)); const D2D1_RENDER_TARGET_PROPERTIES renderTargetProps = D2D1::RenderTargetProperties( D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), kBaseDpi, kBaseDpi); const D2D1_HWND_RENDER_TARGET_PROPERTIES hwndProps = D2D1::HwndRenderTargetProperties( m_hwnd, D2D1::SizeU(width, height)); const HRESULT renderTargetHr = m_d2dFactory->CreateHwndRenderTarget( renderTargetProps, hwndProps, m_renderTarget.ReleaseAndGetAddressOf()); if (FAILED(renderTargetHr)) { m_lastRenderError = HrToString("ID2D1Factory::CreateHwndRenderTarget", renderTargetHr); return false; } const HRESULT brushHr = m_renderTarget->CreateSolidColorBrush( D2D1::ColorF(1.0f, 1.0f, 1.0f, 1.0f), m_solidBrush.ReleaseAndGetAddressOf()); if (FAILED(brushHr)) { m_lastRenderError = HrToString("ID2D1HwndRenderTarget::CreateSolidColorBrush", brushHr); DiscardRenderTarget(); return false; } m_renderTarget->SetDpi(kBaseDpi, kBaseDpi); m_renderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE); m_lastRenderError.clear(); return true; } void NativeRenderer::InvalidateCachedTextureBitmaps(const ID2D1RenderTarget* renderTarget) { for (NativeTextureResource* texture : m_liveTextures) { if (texture == nullptr) { continue; } if (renderTarget == nullptr || texture->cachedTarget == renderTarget) { texture->cachedBitmap.Reset(); texture->cachedTarget = nullptr; } } } } // namespace XCEngine::UI::Editor::Host