Fix new editor window resize presentation
This commit is contained in:
@@ -37,6 +37,15 @@ constexpr const wchar_t* kWindowTitle = L"Main Scene * - Main.xx - XCEngine Edit
|
||||
constexpr UINT kDefaultDpi = 96u;
|
||||
constexpr float kBaseDpiScale = 96.0f;
|
||||
|
||||
bool ResolveVerboseRuntimeTraceEnabled() {
|
||||
wchar_t buffer[8] = {};
|
||||
const DWORD length = GetEnvironmentVariableW(
|
||||
L"XCUIEDITOR_VERBOSE_TRACE",
|
||||
buffer,
|
||||
static_cast<DWORD>(std::size(buffer)));
|
||||
return length > 0u && buffer[0] != L'0';
|
||||
}
|
||||
|
||||
Application* GetApplicationFromWindow(HWND hwnd) {
|
||||
return reinterpret_cast<Application*>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));
|
||||
}
|
||||
@@ -394,7 +403,6 @@ int Application::Run(HINSTANCE hInstance, int nCmdShow) {
|
||||
}
|
||||
|
||||
RenderFrame();
|
||||
Sleep(8);
|
||||
}
|
||||
|
||||
Shutdown();
|
||||
@@ -472,10 +480,17 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) {
|
||||
LogRuntimeTrace("app", "d3d12 window renderer initialization failed");
|
||||
return false;
|
||||
}
|
||||
const bool hasD3D12WindowInterop = m_renderer.AttachWindowRenderer(m_windowRenderer);
|
||||
if (!hasD3D12WindowInterop) {
|
||||
LogRuntimeTrace(
|
||||
"app",
|
||||
"native renderer d3d12 interop unavailable; falling back to hwnd renderer: " +
|
||||
m_renderer.GetLastRenderError());
|
||||
}
|
||||
m_editorContext.AttachTextMeasurer(m_renderer);
|
||||
m_editorWorkspace.Initialize(repoRoot, m_renderer);
|
||||
m_editorWorkspace.AttachViewportWindowRenderer(m_windowRenderer);
|
||||
m_editorWorkspace.SetViewportSurfacePresentationEnabled(false);
|
||||
m_editorWorkspace.SetViewportSurfacePresentationEnabled(hasD3D12WindowInterop);
|
||||
if (!m_editorWorkspace.GetBuiltInIconError().empty()) {
|
||||
LogRuntimeTrace("icons", m_editorWorkspace.GetBuiltInIconError());
|
||||
}
|
||||
@@ -544,7 +559,7 @@ void Application::RenderFrame() {
|
||||
if (m_editorContext.IsValid()) {
|
||||
std::vector<UIInputEvent> frameEvents = std::move(m_pendingInputEvents);
|
||||
m_pendingInputEvents.clear();
|
||||
if (!frameEvents.empty()) {
|
||||
if (!frameEvents.empty() && IsVerboseRuntimeTraceEnabled()) {
|
||||
LogRuntimeTrace(
|
||||
"input",
|
||||
DescribeInputEvents(frameEvents) + " | " +
|
||||
@@ -552,8 +567,10 @@ void Application::RenderFrame() {
|
||||
m_editorWorkspace.GetShellInteractionState()));
|
||||
}
|
||||
|
||||
const bool d3d12FrameBegun = m_windowRenderer.BeginFrame();
|
||||
if (!d3d12FrameBegun) {
|
||||
const bool canUseWindowRenderer = m_renderer.HasAttachedWindowRenderer();
|
||||
const bool d3d12FrameBegun =
|
||||
canUseWindowRenderer && m_windowRenderer.BeginFrame();
|
||||
if (canUseWindowRenderer && !d3d12FrameBegun) {
|
||||
LogRuntimeTrace("viewport", "d3d12 frame begin failed");
|
||||
}
|
||||
|
||||
@@ -562,17 +579,12 @@ void Application::RenderFrame() {
|
||||
UIRect(0.0f, 0.0f, width, height),
|
||||
frameEvents,
|
||||
BuildCaptureStatusText());
|
||||
if (d3d12FrameBegun) {
|
||||
m_editorWorkspace.RenderRequestedViewports(m_windowRenderer.GetRenderContext());
|
||||
if (!m_windowRenderer.SubmitFrame(false)) {
|
||||
LogRuntimeTrace("viewport", "d3d12 offscreen frame submit failed");
|
||||
}
|
||||
}
|
||||
const UIEditorShellInteractionFrame& shellFrame =
|
||||
m_editorWorkspace.GetShellFrame();
|
||||
if (!frameEvents.empty() ||
|
||||
shellFrame.result.workspaceResult.dockHostResult.layoutChanged ||
|
||||
shellFrame.result.workspaceResult.dockHostResult.commandExecuted) {
|
||||
if (IsVerboseRuntimeTraceEnabled() &&
|
||||
(!frameEvents.empty() ||
|
||||
shellFrame.result.workspaceResult.dockHostResult.layoutChanged ||
|
||||
shellFrame.result.workspaceResult.dockHostResult.commandExecuted)) {
|
||||
std::ostringstream frameTrace = {};
|
||||
frameTrace << "result consumed="
|
||||
<< (shellFrame.result.consumed ? "true" : "false")
|
||||
@@ -595,6 +607,9 @@ void Application::RenderFrame() {
|
||||
ApplyHostedContentCaptureRequests();
|
||||
ApplyCurrentCursor();
|
||||
m_editorWorkspace.Append(drawList);
|
||||
if (d3d12FrameBegun && !m_inInteractiveResize) {
|
||||
m_editorWorkspace.RenderRequestedViewports(m_windowRenderer.GetRenderContext());
|
||||
}
|
||||
} else {
|
||||
drawList.AddText(
|
||||
UIPoint(28.0f, 28.0f),
|
||||
@@ -610,7 +625,20 @@ void Application::RenderFrame() {
|
||||
12.0f);
|
||||
}
|
||||
|
||||
const bool framePresented = m_renderer.Render(drawData);
|
||||
bool framePresented = false;
|
||||
if (m_renderer.HasAttachedWindowRenderer()) {
|
||||
framePresented = m_renderer.RenderToWindowRenderer(drawData);
|
||||
if (!framePresented) {
|
||||
LogRuntimeTrace(
|
||||
"present",
|
||||
"d3d12 window composition failed, falling back to hwnd renderer: " +
|
||||
m_renderer.GetLastRenderError());
|
||||
}
|
||||
}
|
||||
|
||||
if (!framePresented) {
|
||||
framePresented = m_renderer.Render(drawData);
|
||||
}
|
||||
m_autoScreenshot.CaptureIfRequested(
|
||||
m_renderer,
|
||||
drawData,
|
||||
@@ -707,6 +735,11 @@ void Application::LogRuntimeTrace(
|
||||
AppendUIEditorRuntimeTrace(channel, message);
|
||||
}
|
||||
|
||||
bool Application::IsVerboseRuntimeTraceEnabled() {
|
||||
static const bool s_enabled = ResolveVerboseRuntimeTraceEnabled();
|
||||
return s_enabled;
|
||||
}
|
||||
|
||||
std::string Application::DescribeInputEvents(
|
||||
const std::vector<UIInputEvent>& events) const {
|
||||
std::ostringstream stream = {};
|
||||
@@ -726,13 +759,84 @@ std::string Application::DescribeInputEvents(
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
void Application::OnResize(UINT width, UINT height) {
|
||||
if (width == 0 || height == 0) {
|
||||
void Application::OnResize() {
|
||||
UINT width = 0u;
|
||||
UINT height = 0u;
|
||||
if (!QueryCurrentClientPixelSize(width, height)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_renderer.Resize(width, height);
|
||||
m_windowRenderer.Resize(static_cast<int>(width), static_cast<int>(height));
|
||||
CommitWindowResize();
|
||||
if (m_inInteractiveResize) {
|
||||
m_editorWorkspace.SetViewportSurfacePresentationEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_renderer.DetachWindowRenderer();
|
||||
const bool resizedWindowRenderer =
|
||||
m_windowRenderer.Resize(static_cast<int>(width), static_cast<int>(height));
|
||||
const bool hasD3D12WindowInterop = resizedWindowRenderer &&
|
||||
m_renderer.AttachWindowRenderer(m_windowRenderer);
|
||||
const bool hasHealthyD3D12WindowInterop =
|
||||
resizedWindowRenderer &&
|
||||
hasD3D12WindowInterop;
|
||||
m_editorWorkspace.SetViewportSurfacePresentationEnabled(hasHealthyD3D12WindowInterop);
|
||||
|
||||
if (!resizedWindowRenderer || !m_windowRenderer.GetLastError().empty()) {
|
||||
LogRuntimeTrace(
|
||||
"present",
|
||||
"window renderer resize warning: " + m_windowRenderer.GetLastError());
|
||||
}
|
||||
|
||||
if (!hasD3D12WindowInterop) {
|
||||
LogRuntimeTrace(
|
||||
"present",
|
||||
"failed to rebuild d3d12 window interop after resize: " +
|
||||
m_renderer.GetLastRenderError());
|
||||
}
|
||||
|
||||
return hasHealthyD3D12WindowInterop;
|
||||
}
|
||||
|
||||
bool Application::QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const {
|
||||
outWidth = 0u;
|
||||
outHeight = 0u;
|
||||
if (m_hwnd == nullptr || !IsWindow(m_hwnd)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RECT clientRect = {};
|
||||
if (!GetClientRect(m_hwnd, &clientRect)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const LONG width = clientRect.right - clientRect.left;
|
||||
const LONG height = clientRect.bottom - clientRect.top;
|
||||
if (width <= 0 || height <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outWidth = static_cast<UINT>(width);
|
||||
outHeight = static_cast<UINT>(height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Application::OnDpiChanged(UINT dpi, const RECT& suggestedRect) {
|
||||
@@ -748,6 +852,7 @@ void Application::OnDpiChanged(UINT dpi, const RECT& suggestedRect) {
|
||||
suggestedRect.right - suggestedRect.left,
|
||||
suggestedRect.bottom - suggestedRect.top,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
CommitWindowResize();
|
||||
InvalidateRect(m_hwnd, nullptr, FALSE);
|
||||
}
|
||||
|
||||
@@ -897,9 +1002,23 @@ LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT message, WPARAM wParam, LP
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_ENTERSIZEMOVE:
|
||||
if (application != nullptr) {
|
||||
application->OnEnterSizeMove();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_EXITSIZEMOVE:
|
||||
if (application != nullptr) {
|
||||
application->OnExitSizeMove();
|
||||
application->RenderFrame();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
if (application != nullptr && wParam != SIZE_MINIMIZED) {
|
||||
application->OnResize(static_cast<UINT>(LOWORD(lParam)), static_cast<UINT>(HIWORD(lParam)));
|
||||
application->OnResize();
|
||||
application->RenderFrame();
|
||||
}
|
||||
return 0;
|
||||
case WM_PAINT:
|
||||
|
||||
Reference in New Issue
Block a user