Files
XCEngine/new_editor/app/Host/NativeRenderer.h

137 lines
5.1 KiB
C
Raw Normal View History

#pragma once
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "D3D12WindowRenderer.h"
#include <XCEditor/Foundation/UIEditorTextMeasurement.h>
#include <XCEngine/UI/DrawData.h>
#include <d2d1_1.h>
#include <d3d11_4.h>
#include <d3d11on12.h>
#include <dwrite.h>
#include <dxgi1_2.h>
#include <wincodec.h>
#include <windows.h>
#include <wrl/client.h>
#include <filesystem>
#include <string>
#include <string_view>
#include <unordered_set>
#include <unordered_map>
#include <vector>
namespace XCEngine::UI::Editor::Host {
class NativeRenderer : public ::XCEngine::UI::Editor::UIEditorTextMeasurer {
public:
bool Initialize(HWND hwnd);
void Shutdown();
void SetDpiScale(float dpiScale);
float GetDpiScale() const;
void Resize(UINT width, UINT height);
bool AttachWindowRenderer(D3D12WindowRenderer& windowRenderer);
void DetachWindowRenderer();
void ReleaseWindowRendererBackBufferTargets();
bool RebuildWindowRendererBackBufferTargets();
bool HasAttachedWindowRenderer() const;
bool Render(const ::XCEngine::UI::UIDrawData& drawData);
bool RenderToWindowRenderer(const ::XCEngine::UI::UIDrawData& drawData);
const std::string& GetLastRenderError() const;
bool LoadTextureFromFile(
const std::filesystem::path& path,
::XCEngine::UI::UITextureHandle& outTexture,
std::string& outError);
void ReleaseTexture(::XCEngine::UI::UITextureHandle& texture);
float MeasureTextWidth(
const ::XCEngine::UI::Editor::UIEditorTextMeasureRequest& request) const override;
bool CaptureToPng(
const ::XCEngine::UI::UIDrawData& drawData,
UINT width,
UINT height,
const std::filesystem::path& outputPath,
std::string& outError);
private:
struct NativeTextureResource {
std::vector<std::uint8_t> pixels = {};
Microsoft::WRL::ComPtr<ID2D1Bitmap> cachedBitmap = {};
const ID2D1RenderTarget* cachedTarget = nullptr;
UINT width = 0u;
UINT height = 0u;
};
struct D3D12BackBufferInteropTarget {
Microsoft::WRL::ComPtr<ID3D11Resource> wrappedResource = {};
Microsoft::WRL::ComPtr<ID2D1Bitmap1> targetBitmap = {};
};
struct D3D12SourceTextureInteropResource {
std::uintptr_t key = 0u;
Microsoft::WRL::ComPtr<ID3D11Resource> wrappedResource = {};
Microsoft::WRL::ComPtr<ID2D1Bitmap1> bitmap = {};
};
bool EnsureRenderTarget();
bool EnsureWindowRendererInterop();
bool EnsureWicFactory(std::string& outError);
void DiscardRenderTarget();
bool CreateDeviceResources();
void ReleaseWindowRendererInterop();
bool RebuildBackBufferInteropTargets();
void ClearActiveInteropSourceTextures();
bool PrepareActiveInteropSourceTextures(const ::XCEngine::UI::UIDrawData& drawData);
void InvalidateCachedTextureBitmaps(const ID2D1RenderTarget* renderTarget);
bool RenderToTarget(
ID2D1RenderTarget& renderTarget,
ID2D1SolidColorBrush& solidBrush,
const ::XCEngine::UI::UIDrawData& drawData);
bool DecodeTextureFile(
const std::filesystem::path& path,
NativeTextureResource& outTexture,
std::string& outError);
bool ResolveTextureBitmap(
ID2D1RenderTarget& renderTarget,
NativeTextureResource& texture,
Microsoft::WRL::ComPtr<ID2D1Bitmap>& outBitmap);
bool ResolveInteropBitmap(
const ::XCEngine::UI::UITextureHandle& texture,
Microsoft::WRL::ComPtr<ID2D1Bitmap>& outBitmap) const;
void RenderCommand(
ID2D1RenderTarget& renderTarget,
ID2D1SolidColorBrush& solidBrush,
const ::XCEngine::UI::UIDrawCommand& command,
std::vector<D2D1_RECT_F>& clipStack);
IDWriteTextFormat* GetTextFormat(float fontSize) const;
static D2D1_COLOR_F ToD2DColor(const ::XCEngine::UI::UIColor& color);
static std::wstring Utf8ToWide(std::string_view text);
HWND m_hwnd = nullptr;
D3D12WindowRenderer* m_windowRenderer = nullptr;
Microsoft::WRL::ComPtr<ID2D1Factory1> m_d2dFactory;
Microsoft::WRL::ComPtr<IDWriteFactory> m_dwriteFactory;
Microsoft::WRL::ComPtr<IWICImagingFactory> m_wicFactory;
Microsoft::WRL::ComPtr<ID3D11Device> m_d3d11Device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_d3d11DeviceContext;
Microsoft::WRL::ComPtr<ID3D11On12Device> m_d3d11On12Device;
Microsoft::WRL::ComPtr<ID2D1Device> m_d2dDevice;
Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_d2dDeviceContext;
Microsoft::WRL::ComPtr<ID2D1HwndRenderTarget> m_renderTarget;
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> m_solidBrush;
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> m_interopBrush;
std::vector<D3D12BackBufferInteropTarget> m_backBufferInteropTargets = {};
std::vector<D3D12SourceTextureInteropResource> m_activeInteropSourceTextures = {};
std::unordered_map<std::uintptr_t, Microsoft::WRL::ComPtr<ID2D1Bitmap1>> m_activeInteropBitmaps;
mutable std::unordered_map<int, Microsoft::WRL::ComPtr<IDWriteTextFormat>> m_textFormats;
std::unordered_set<NativeTextureResource*> m_liveTextures;
std::string m_lastRenderError = {};
bool m_wicComInitialized = false;
float m_dpiScale = 1.0f;
};
} // namespace XCEngine::UI::Editor::Host