90 lines
2.8 KiB
C++
90 lines
2.8 KiB
C++
|
|
#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<UINT>((std::max)(clientRect.right - clientRect.left, 1L));
|
||
|
|
const UINT height = static_cast<UINT>((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
|