Checkpoint current new editor host iteration
This commit is contained in:
@@ -36,6 +36,7 @@ constexpr const wchar_t* kWindowClassName = L"XCEditorShellHost";
|
||||
constexpr const wchar_t* kWindowTitle = L"Main Scene * - Main.xx - XCEngine Editor";
|
||||
constexpr UINT kDefaultDpi = 96u;
|
||||
constexpr float kBaseDpiScale = 96.0f;
|
||||
constexpr UINT kDeferredRenderMessage = WM_APP + 1u;
|
||||
|
||||
bool ResolveVerboseRuntimeTraceEnabled() {
|
||||
wchar_t buffer[8] = {};
|
||||
@@ -541,6 +542,8 @@ void Application::RenderFrame() {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyPendingWindowResize();
|
||||
|
||||
RECT clientRect = {};
|
||||
GetClientRect(m_hwnd, &clientRect);
|
||||
const unsigned int pixelWidth =
|
||||
@@ -607,7 +610,7 @@ void Application::RenderFrame() {
|
||||
ApplyHostedContentCaptureRequests();
|
||||
ApplyCurrentCursor();
|
||||
m_editorWorkspace.Append(drawList);
|
||||
if (d3d12FrameBegun && !m_inInteractiveResize) {
|
||||
if (d3d12FrameBegun) {
|
||||
m_editorWorkspace.RenderRequestedViewports(m_windowRenderer.GetRenderContext());
|
||||
}
|
||||
} else {
|
||||
@@ -760,36 +763,51 @@ std::string Application::DescribeInputEvents(
|
||||
}
|
||||
|
||||
void Application::OnResize() {
|
||||
QueueCurrentClientResize();
|
||||
}
|
||||
|
||||
void Application::OnEnterSizeMove() {
|
||||
m_inInteractiveResize = true;
|
||||
}
|
||||
|
||||
void Application::OnExitSizeMove() {
|
||||
m_inInteractiveResize = false;
|
||||
QueueCurrentClientResize();
|
||||
}
|
||||
|
||||
void Application::QueueWindowResize(UINT width, UINT height) {
|
||||
if (width == 0u || height == 0u) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_pendingWindowResizeWidth = width;
|
||||
m_pendingWindowResizeHeight = height;
|
||||
m_hasPendingWindowResize = true;
|
||||
}
|
||||
|
||||
void Application::QueueCurrentClientResize() {
|
||||
UINT width = 0u;
|
||||
UINT height = 0u;
|
||||
if (!QueryCurrentClientPixelSize(width, height)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_renderer.Resize(width, height);
|
||||
CommitWindowResize();
|
||||
if (m_inInteractiveResize) {
|
||||
m_editorWorkspace.SetViewportSurfacePresentationEnabled(false);
|
||||
QueueWindowResize(width, height);
|
||||
}
|
||||
|
||||
bool Application::ApplyPendingWindowResize() {
|
||||
if (!m_hasPendingWindowResize) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::OnEnterSizeMove() {
|
||||
m_inInteractiveResize = true;
|
||||
m_editorWorkspace.SetViewportSurfacePresentationEnabled(false);
|
||||
}
|
||||
|
||||
void Application::OnExitSizeMove() {
|
||||
m_inInteractiveResize = false;
|
||||
CommitWindowResize();
|
||||
}
|
||||
|
||||
bool Application::CommitWindowResize() {
|
||||
UINT width = 0u;
|
||||
UINT height = 0u;
|
||||
if (!QueryCurrentClientPixelSize(width, height)) {
|
||||
const UINT width = m_pendingWindowResizeWidth;
|
||||
const UINT height = m_pendingWindowResizeHeight;
|
||||
m_hasPendingWindowResize = false;
|
||||
if (width == 0u || height == 0u) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_renderer.Resize(width, height);
|
||||
m_renderer.DetachWindowRenderer();
|
||||
const bool resizedWindowRenderer =
|
||||
m_windowRenderer.Resize(static_cast<int>(width), static_cast<int>(height));
|
||||
@@ -816,6 +834,15 @@ bool Application::CommitWindowResize() {
|
||||
return hasHealthyD3D12WindowInterop;
|
||||
}
|
||||
|
||||
void Application::RequestDeferredRenderFrame() {
|
||||
if (m_hwnd == nullptr || !IsWindow(m_hwnd) || m_renderFrameQueued) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_renderFrameQueued = true;
|
||||
PostMessageW(m_hwnd, kDeferredRenderMessage, 0, 0);
|
||||
}
|
||||
|
||||
bool Application::QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const {
|
||||
outWidth = 0u;
|
||||
outHeight = 0u;
|
||||
@@ -844,16 +871,18 @@ void Application::OnDpiChanged(UINT dpi, const RECT& suggestedRect) {
|
||||
m_dpiScale = GetDpiScale();
|
||||
m_renderer.SetDpiScale(m_dpiScale);
|
||||
if (m_hwnd != nullptr) {
|
||||
const LONG windowWidth = suggestedRect.right - suggestedRect.left;
|
||||
const LONG windowHeight = suggestedRect.bottom - suggestedRect.top;
|
||||
SetWindowPos(
|
||||
m_hwnd,
|
||||
nullptr,
|
||||
suggestedRect.left,
|
||||
suggestedRect.top,
|
||||
suggestedRect.right - suggestedRect.left,
|
||||
suggestedRect.bottom - suggestedRect.top,
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
CommitWindowResize();
|
||||
InvalidateRect(m_hwnd, nullptr, FALSE);
|
||||
QueueCurrentClientResize();
|
||||
RequestDeferredRenderFrame();
|
||||
}
|
||||
|
||||
std::ostringstream trace = {};
|
||||
@@ -1011,16 +1040,23 @@ LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT message, WPARAM wParam, LP
|
||||
case WM_EXITSIZEMOVE:
|
||||
if (application != nullptr) {
|
||||
application->OnExitSizeMove();
|
||||
application->RenderFrame();
|
||||
application->RequestDeferredRenderFrame();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
if (application != nullptr && wParam != SIZE_MINIMIZED) {
|
||||
application->OnResize();
|
||||
application->RenderFrame();
|
||||
application->RequestDeferredRenderFrame();
|
||||
}
|
||||
return 0;
|
||||
case kDeferredRenderMessage:
|
||||
if (application != nullptr) {
|
||||
application->m_renderFrameQueued = false;
|
||||
application->RenderFrame();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_PAINT:
|
||||
if (application != nullptr) {
|
||||
PAINTSTRUCT paintStruct = {};
|
||||
|
||||
@@ -37,8 +37,15 @@ private:
|
||||
bool Initialize(HINSTANCE hInstance, int nCmdShow);
|
||||
void Shutdown();
|
||||
void RenderFrame();
|
||||
void OnResize(UINT width, UINT height);
|
||||
void OnResize();
|
||||
void OnEnterSizeMove();
|
||||
void OnExitSizeMove();
|
||||
void OnDpiChanged(UINT dpi, const RECT& suggestedRect);
|
||||
void QueueWindowResize(UINT width, UINT height);
|
||||
void QueueCurrentClientResize();
|
||||
bool ApplyPendingWindowResize();
|
||||
void RequestDeferredRenderFrame();
|
||||
bool QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const;
|
||||
bool IsPointerInsideClientArea() const;
|
||||
bool ApplyCurrentCursor() const;
|
||||
LPCWSTR ResolveCurrentCursorResource() const;
|
||||
@@ -64,6 +71,7 @@ private:
|
||||
void QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType type);
|
||||
static std::filesystem::path ResolveRepoRootPath();
|
||||
static LONG WINAPI HandleUnhandledException(EXCEPTION_POINTERS* exceptionInfo);
|
||||
static bool IsVerboseRuntimeTraceEnabled();
|
||||
|
||||
HWND m_hwnd = nullptr;
|
||||
HINSTANCE m_hInstance = nullptr;
|
||||
@@ -78,6 +86,11 @@ private:
|
||||
bool m_trackingMouseLeave = false;
|
||||
UINT m_windowDpi = 96u;
|
||||
float m_dpiScale = 1.0f;
|
||||
bool m_inInteractiveResize = false;
|
||||
bool m_renderFrameQueued = false;
|
||||
bool m_hasPendingWindowResize = false;
|
||||
UINT m_pendingWindowResizeWidth = 0u;
|
||||
UINT m_pendingWindowResizeHeight = 0u;
|
||||
};
|
||||
|
||||
int RunXCUIEditorApp(HINSTANCE hInstance, int nCmdShow);
|
||||
|
||||
@@ -22,7 +22,10 @@
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <windows.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine::UI::Editor::Host {
|
||||
@@ -34,13 +37,17 @@ public:
|
||||
|
||||
bool Initialize(HWND hwnd, int width, int height);
|
||||
void Shutdown();
|
||||
void Resize(int width, int height);
|
||||
bool Resize(int width, int height);
|
||||
bool BeginFrame();
|
||||
bool PreparePresentSurface();
|
||||
bool SubmitFrame(bool presentSwapChain);
|
||||
bool SignalFrameCompletion();
|
||||
bool PresentFrame();
|
||||
|
||||
ID3D12Device* GetDevice() const;
|
||||
ID3D12DescriptorHeap* GetSrvHeap() const;
|
||||
ID3D12CommandQueue* GetCommandQueue() const;
|
||||
const std::string& GetLastError() const;
|
||||
void AllocateShaderResourceDescriptor(
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE* outCpuHandle,
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE* outGpuHandle);
|
||||
@@ -57,6 +64,9 @@ public:
|
||||
::XCEngine::RHI::RHIDevice* GetRHIDevice() const;
|
||||
::XCEngine::RHI::RHISwapChain* GetSwapChain() const;
|
||||
const ::XCEngine::Rendering::RenderSurface* GetCurrentRenderSurface() const;
|
||||
const ::XCEngine::RHI::D3D12Texture* GetCurrentBackBufferTexture() const;
|
||||
const ::XCEngine::RHI::D3D12Texture* GetBackBufferTexture(std::uint32_t index) const;
|
||||
std::uint32_t GetBackBufferCount() const;
|
||||
::XCEngine::Rendering::RenderContext GetRenderContext() const;
|
||||
|
||||
private:
|
||||
@@ -64,13 +74,18 @@ private:
|
||||
::XCEngine::RHI::D3D12CommandQueue* GetD3D12CommandQueue() const;
|
||||
::XCEngine::RHI::D3D12CommandList* GetD3D12CommandList() const;
|
||||
::XCEngine::RHI::D3D12SwapChain* GetD3D12SwapChain() const;
|
||||
::XCEngine::RHI::RHICommandList* GetCurrentCommandList() const;
|
||||
void AllocateShaderResourceDescriptorInternal(
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE* outCpuHandle,
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE* outGpuHandle);
|
||||
void FreeShaderResourceDescriptorInternal(
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle,
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle);
|
||||
bool InitializeFrameCompletionFence();
|
||||
void ReleaseFrameCompletionFence();
|
||||
void WaitForBackBufferFrame(std::uint32_t backBufferIndex);
|
||||
void WaitForGpuIdle();
|
||||
void ReleaseBackBufferCommandReferences();
|
||||
void ReleaseBackBufferViews();
|
||||
bool RecreateBackBufferViews();
|
||||
|
||||
@@ -80,13 +95,19 @@ private:
|
||||
|
||||
::XCEngine::RHI::RHIDevice* m_device = nullptr;
|
||||
::XCEngine::RHI::RHICommandQueue* m_commandQueue = nullptr;
|
||||
::XCEngine::RHI::RHICommandList* m_commandList = nullptr;
|
||||
std::array<::XCEngine::RHI::RHICommandList*, kSwapChainBufferCount> m_commandLists = {};
|
||||
::XCEngine::RHI::RHISwapChain* m_swapChain = nullptr;
|
||||
::XCEngine::RHI::RHIDescriptorPool* m_srvPool = nullptr;
|
||||
::XCEngine::RHI::D3D12DescriptorHeap* m_srvHeap = nullptr;
|
||||
std::vector<bool> m_srvUsage = {};
|
||||
std::vector<::XCEngine::RHI::RHIResourceView*> m_backBufferViews = {};
|
||||
std::vector<::XCEngine::Rendering::RenderSurface> m_backBufferSurfaces = {};
|
||||
Microsoft::WRL::ComPtr<ID3D12Fence> m_frameCompletionFence = {};
|
||||
HANDLE m_frameCompletionEvent = nullptr;
|
||||
std::array<std::uint64_t, kSwapChainBufferCount> m_backBufferFenceValues = {};
|
||||
std::uint32_t m_activeBackBufferIndex = 0u;
|
||||
std::uint64_t m_lastSubmittedFrameValue = 0;
|
||||
std::string m_lastError = {};
|
||||
UINT m_srvDescriptorSize = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,12 +4,17 @@
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include "D3D12WindowRenderer.h"
|
||||
|
||||
#include <XCEditor/Foundation/UIEditorTextMeasurement.h>
|
||||
|
||||
#include <XCEngine/UI/DrawData.h>
|
||||
|
||||
#include <d2d1.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>
|
||||
@@ -30,7 +35,13 @@ public:
|
||||
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,
|
||||
@@ -47,15 +58,6 @@ public:
|
||||
std::string& outError);
|
||||
|
||||
private:
|
||||
bool EnsureRenderTarget();
|
||||
bool EnsureWicFactory(std::string& outError);
|
||||
void DiscardRenderTarget();
|
||||
bool CreateDeviceResources();
|
||||
void InvalidateCachedTextureBitmaps(const ID2D1RenderTarget* renderTarget);
|
||||
bool RenderToTarget(
|
||||
ID2D1RenderTarget& renderTarget,
|
||||
ID2D1SolidColorBrush& solidBrush,
|
||||
const ::XCEngine::UI::UIDrawData& drawData);
|
||||
struct NativeTextureResource {
|
||||
std::vector<std::uint8_t> pixels = {};
|
||||
Microsoft::WRL::ComPtr<ID2D1Bitmap> cachedBitmap = {};
|
||||
@@ -63,6 +65,30 @@ private:
|
||||
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,
|
||||
@@ -71,6 +97,9 @@ private:
|
||||
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,
|
||||
@@ -82,11 +111,21 @@ private:
|
||||
static std::wstring Utf8ToWide(std::string_view text);
|
||||
|
||||
HWND m_hwnd = nullptr;
|
||||
Microsoft::WRL::ComPtr<ID2D1Factory> m_d2dFactory;
|
||||
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 = {};
|
||||
|
||||
@@ -429,11 +429,10 @@ UIEditorWorkspacePanelPresentationModel BuildViewportPresentation(
|
||||
presentation.panelId = std::move(panelId);
|
||||
presentation.kind = UIEditorPanelPresentationKind::ViewportShell;
|
||||
presentation.viewportShellModel.spec.chrome.title = std::move(title);
|
||||
presentation.viewportShellModel.spec.chrome.subtitle = std::move(subtitle);
|
||||
presentation.viewportShellModel.spec.chrome.showTopBar = true;
|
||||
presentation.viewportShellModel.spec.chrome.showBottomBar = true;
|
||||
presentation.viewportShellModel.frame.statusText =
|
||||
"Viewport request chain is active.";
|
||||
presentation.viewportShellModel.spec.chrome.subtitle = {};
|
||||
presentation.viewportShellModel.spec.chrome.showTopBar = false;
|
||||
presentation.viewportShellModel.spec.chrome.showBottomBar = false;
|
||||
presentation.viewportShellModel.frame.statusText.clear();
|
||||
return presentation;
|
||||
}
|
||||
|
||||
@@ -448,8 +447,8 @@ UIEditorShellInteractionDefinition BuildBaseShellDefinition() {
|
||||
definition.statusSegments = {};
|
||||
definition.workspacePresentations = {
|
||||
BuildHostedContentPresentation("hierarchy"),
|
||||
BuildViewportPresentation("scene", "Scene", "New Editor viewport shell"),
|
||||
BuildViewportPresentation("game", "Game", "New Editor viewport shell"),
|
||||
BuildViewportPresentation("scene", "Scene", {}),
|
||||
BuildViewportPresentation("game", "Game", {}),
|
||||
BuildHostedContentPresentation("inspector"),
|
||||
BuildHostedContentPresentation("console"),
|
||||
BuildHostedContentPresentation("project")
|
||||
|
||||
@@ -8,24 +8,6 @@ namespace {
|
||||
|
||||
using ::XCEngine::RHI::ResourceStates;
|
||||
|
||||
std::string BuildViewportPendingStatus(ProductViewportKind kind) {
|
||||
return kind == ProductViewportKind::Scene
|
||||
? "Scene viewport host pending D3D12 presenter integration."
|
||||
: "Game viewport host pending D3D12 presenter integration.";
|
||||
}
|
||||
|
||||
std::string BuildViewportReadyStatus(ProductViewportKind kind) {
|
||||
return kind == ProductViewportKind::Scene
|
||||
? "Scene viewport render target ready; presenter still uses NativeRenderer."
|
||||
: "Game viewport render target ready; presenter still uses NativeRenderer.";
|
||||
}
|
||||
|
||||
std::string BuildViewportPresentedStatus(ProductViewportKind kind) {
|
||||
return kind == ProductViewportKind::Scene
|
||||
? "Scene viewport frame ready."
|
||||
: "Game viewport frame ready.";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ProductViewportHostService::AttachWindowRenderer(
|
||||
@@ -81,23 +63,17 @@ ProductViewportFrame ProductViewportHostService::RequestViewport(
|
||||
: 0u;
|
||||
|
||||
if (!entry.requestedThisFrame) {
|
||||
entry.statusText = "Viewport is waiting for a visible surface.";
|
||||
return BuildFrame(entry, requestedSize);
|
||||
}
|
||||
|
||||
if (m_windowRenderer == nullptr || m_device == nullptr) {
|
||||
entry.statusText = BuildViewportPendingStatus(kind);
|
||||
return BuildFrame(entry, requestedSize);
|
||||
}
|
||||
|
||||
if (!EnsureViewportResources(entry)) {
|
||||
entry.statusText = "Failed to create viewport render targets.";
|
||||
return BuildFrame(entry, requestedSize);
|
||||
}
|
||||
|
||||
entry.statusText = m_surfacePresentationEnabled
|
||||
? BuildViewportPresentedStatus(kind)
|
||||
: BuildViewportReadyStatus(kind);
|
||||
return BuildFrame(entry, requestedSize);
|
||||
}
|
||||
|
||||
@@ -119,9 +95,6 @@ void ProductViewportHostService::RenderRequestedViewports(
|
||||
}
|
||||
|
||||
entry.renderedThisFrame = true;
|
||||
entry.statusText = m_surfacePresentationEnabled
|
||||
? BuildViewportPresentedStatus(entry.kind)
|
||||
: BuildViewportReadyStatus(entry.kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,33 +36,62 @@ void ApplyViewportFrameToPresentation(
|
||||
presentation.viewportShellModel.frame.statusText = viewportFrame.statusText;
|
||||
}
|
||||
|
||||
std::vector<UIEditorWorkspacePanelPresentationModel> BuildWorkspacePresentations(
|
||||
const UIEditorShellInteractionDefinition& definition,
|
||||
const UIEditorShellInteractionRequest& shellRequest,
|
||||
ProductViewportHostService& viewportHostService) {
|
||||
std::vector<UIEditorWorkspacePanelPresentationModel> presentations =
|
||||
definition.workspacePresentations;
|
||||
for (UIEditorWorkspacePanelPresentationModel& presentation : presentations) {
|
||||
if (presentation.kind != UIEditorPanelPresentationKind::ViewportShell ||
|
||||
!IsProductViewportPanel(presentation.panelId)) {
|
||||
continue;
|
||||
}
|
||||
void ApplyViewportFrameToShellModel(
|
||||
const ProductViewportFrame& viewportFrame,
|
||||
UIEditorViewportShellModel& shellModel) {
|
||||
shellModel.frame.texture = viewportFrame.texture;
|
||||
shellModel.frame.requestedSize = viewportFrame.requestedSize;
|
||||
shellModel.frame.presentedSize = viewportFrame.renderSize;
|
||||
shellModel.frame.hasTexture = viewportFrame.hasTexture;
|
||||
shellModel.frame.statusText = viewportFrame.statusText;
|
||||
}
|
||||
|
||||
const UIEditorWorkspaceViewportComposeRequest* viewportRequest =
|
||||
FindUIEditorWorkspaceViewportPresentationRequest(
|
||||
shellRequest.shellRequest.workspaceRequest,
|
||||
presentation.panelId);
|
||||
const ::XCEngine::UI::UISize requestedSize =
|
||||
viewportRequest != nullptr
|
||||
? viewportRequest->viewportShellRequest.requestedViewportSize
|
||||
: ::XCEngine::UI::UISize();
|
||||
ApplyViewportFrameToPresentation(
|
||||
viewportHostService.RequestViewport(
|
||||
ResolveProductViewportKind(presentation.panelId),
|
||||
requestedSize),
|
||||
presentation);
|
||||
UIEditorWorkspacePanelPresentationModel* FindMutableWorkspacePresentation(
|
||||
std::vector<UIEditorWorkspacePanelPresentationModel>& presentations,
|
||||
std::string_view panelId) {
|
||||
for (UIEditorWorkspacePanelPresentationModel& presentation : presentations) {
|
||||
if (presentation.panelId == panelId) {
|
||||
return &presentation;
|
||||
}
|
||||
}
|
||||
return presentations;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ApplyViewportFramesToShellFrame(
|
||||
UIEditorShellInteractionFrame& shellFrame,
|
||||
ProductViewportHostService& viewportHostService) {
|
||||
auto applyToViewportFrames =
|
||||
[&](std::vector<UIEditorWorkspaceViewportComposeFrame>& viewportFrames) {
|
||||
for (UIEditorWorkspaceViewportComposeFrame& viewportComposeFrame : viewportFrames) {
|
||||
if (!IsProductViewportPanel(viewportComposeFrame.panelId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const ProductViewportFrame viewportFrame =
|
||||
viewportHostService.RequestViewport(
|
||||
ResolveProductViewportKind(viewportComposeFrame.panelId),
|
||||
viewportComposeFrame.viewportShellFrame.requestedViewportSize);
|
||||
ApplyViewportFrameToShellModel(
|
||||
viewportFrame,
|
||||
viewportComposeFrame.viewportShellModel);
|
||||
if (UIEditorWorkspacePanelPresentationModel* presentation =
|
||||
FindMutableWorkspacePresentation(
|
||||
shellFrame.model.workspacePresentations,
|
||||
viewportComposeFrame.panelId);
|
||||
presentation != nullptr) {
|
||||
ApplyViewportFrameToPresentation(viewportFrame, *presentation);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
applyToViewportFrames(shellFrame.workspaceInteractionFrame.composeFrame.viewportFrames);
|
||||
applyToViewportFrames(shellFrame.shellFrame.workspaceFrame.viewportFrames);
|
||||
}
|
||||
|
||||
std::vector<UIEditorWorkspacePanelPresentationModel> BuildWorkspacePresentations(
|
||||
const UIEditorShellInteractionDefinition& definition) {
|
||||
return definition.workspacePresentations;
|
||||
}
|
||||
|
||||
UIEditorShellComposeModel BuildShellComposeModelFromFrame(
|
||||
@@ -168,18 +197,7 @@ void ProductEditorWorkspace::Update(
|
||||
UIEditorShellInteractionDefinition definition =
|
||||
context.BuildShellDefinition(captureText);
|
||||
m_viewportHostService.BeginFrame();
|
||||
const UIEditorShellInteractionRequest shellRequest =
|
||||
ResolveUIEditorShellInteractionRequest(
|
||||
bounds,
|
||||
context.GetWorkspaceController(),
|
||||
definition,
|
||||
m_shellInteractionState,
|
||||
metrics,
|
||||
context.GetShellServices());
|
||||
definition.workspacePresentations = BuildWorkspacePresentations(
|
||||
definition,
|
||||
shellRequest,
|
||||
m_viewportHostService);
|
||||
definition.workspacePresentations = BuildWorkspacePresentations(definition);
|
||||
const std::vector<UIInputEvent> hostedContentEvents = inputEvents;
|
||||
const std::vector<UIInputEvent> shellEvents =
|
||||
HasHostedContentCapture()
|
||||
@@ -194,6 +212,7 @@ void ProductEditorWorkspace::Update(
|
||||
shellEvents,
|
||||
context.GetShellServices(),
|
||||
metrics);
|
||||
ApplyViewportFramesToShellFrame(m_shellFrame, m_viewportHostService);
|
||||
context.SyncSessionFromWorkspace();
|
||||
context.UpdateStatusFromShellResult(m_shellFrame.result);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user