refactor(editor): neutralize render surface handoff

This commit is contained in:
2026-04-27 17:17:29 +08:00
parent 2a7f6d0b60
commit 0d97cb5e51
7 changed files with 44 additions and 59 deletions

View File

@@ -41,7 +41,8 @@ incomplete:
- Feature panels no longer use `Composition/EditorContext.h` directly, but the
app include surface still needs to be narrowed before this boundary is
build-enforced.
- Win32 and D3D12 currently know about each other through concrete headers.
- The direct Win32/D3D12 render-surface cross-include has been cut; broader
host include-surface cleanup remains.
- App-side tests exist but are not consistently wired into CMake; some are
stale and reference removed headers.
@@ -63,6 +64,9 @@ Completed boundary cuts:
utility-window runtime contracts accept this service view instead of
`EditorContext`, so concrete feature panels no longer depend on
`Composition/EditorContext.h`.
- Win32 now hands render startup a neutral
`Rendering::Host::EditorWindowRenderRuntimeSurface` value, and D3D12 no
longer includes `Platform/Win32/**` editor surface headers to obtain `HWND`.
The root issue is not the existence of a single executable target by itself.
The root issue is that shared app contracts are stored inside concrete layer
@@ -377,6 +381,17 @@ app/Host/D3D12/
Then replace concrete Win32/D3D12 cross-includes with a neutral surface or
factory contract.
Completed first cut:
- The old `Win32EditorWindowRenderRuntimeSurface` concrete adapter was removed.
- `EditorWindowRenderRuntimeSurface` is now a value contract in
`Rendering/Host/EditorWindowRenderRuntime.h`.
- Win32 fills that neutral contract during native surface capture; D3D12 reads
the native handle from the contract instead of including a Win32 editor
windowing header.
- Remaining work in this phase is to move/rename host interface directories
and continue narrowing CMake include surfaces.
## Phase 6: Documentation Update
Update `editor/AGENTS.md` after each completed boundary cut.

View File

@@ -245,8 +245,11 @@ inside pure shell/widget code.
renderer and owns object-id picking state. Keep editor picking/render support
behind `XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT`.
- D3D12 window rendering is behind the abstract
`Rendering::Host::EditorWindowRenderRuntime`; use the host interfaces when
adding app-level features.
`Rendering::Host::EditorWindowRenderRuntime`; native startup surface data is
passed through the neutral
`Rendering::Host::EditorWindowRenderRuntimeSurface` value contract, not a
concrete Win32 adapter type. Use the host interfaces when adding app-level
features.
## Modification Rules
@@ -394,3 +397,7 @@ ownership rule.
and `EditorProjectRuntime` now live under `app/Services/Project`, and the
Project panel owns the widget-tree projection instead of making the service
model depend on `UIEditorTreeViewItem`.
- The old `Win32EditorWindowRenderRuntimeSurface` adapter was removed. Win32
now captures native render startup data into the neutral
`Rendering::Host::EditorWindowRenderRuntimeSurface` value contract, so D3D12
no longer includes concrete `app/Platform/Win32/**` editor surface headers.

View File

@@ -3,7 +3,6 @@
#include "Platform/Win32/Chrome/EditorWindowChromeController.h"
#include "Platform/Win32/Windowing/EditorWindowSession.h"
#include "Platform/Win32/Windowing/EditorWindowSupport.h"
#include "Platform/Win32/Windowing/Win32EditorWindowRenderRuntimeSurface.h"
#include "Platform/Win32/Runtime/EditorWindowInputController.h"
#include "Windowing/Host/EditorWindowContentBindings.h"
#include <XCEditor/Docking/UIEditorDockHostTransfer.h>
@@ -181,8 +180,10 @@ bool EditorWindow::CaptureRuntimeSurface(
clientHeight = 1u;
}
outSurface.renderSurface =
std::make_shared<Win32EditorWindowRenderRuntimeSurface>(hwnd);
outSurface.renderSurface = Rendering::Host::EditorWindowRenderRuntimeSurface{
.kind = Rendering::Host::EditorWindowRenderRuntimeSurfaceKind::Win32Window,
.nativeHandle = reinterpret_cast<std::uintptr_t>(hwnd),
};
outSurface.widthPixels = clientWidth;
outSurface.heightPixels = clientHeight;
outSurface.dpiScale = GetDpiScale();

View File

@@ -1,33 +0,0 @@
#pragma once
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "Rendering/Host/EditorWindowRenderRuntime.h"
#include <windows.h>
namespace XCEngine::UI::Editor::App {
class Win32EditorWindowRenderRuntimeSurface final
: public ::XCEngine::UI::Editor::Rendering::Host::EditorWindowRenderRuntimeSurface {
public:
explicit Win32EditorWindowRenderRuntimeSurface(HWND hwnd)
: m_hwnd(hwnd) {}
::XCEngine::UI::Editor::Rendering::Host::EditorWindowRenderRuntimeSurfaceKind
GetKind() const override {
return ::XCEngine::UI::Editor::Rendering::Host::
EditorWindowRenderRuntimeSurfaceKind::Win32Window;
}
HWND GetHwnd() const {
return m_hwnd;
}
private:
HWND m_hwnd = nullptr;
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,7 +1,5 @@
#include "Rendering/D3D12/D3D12EditorWindowRenderRuntime.h"
#include "Platform/Win32/Windowing/Win32EditorWindowRenderRuntimeSurface.h"
#include <algorithm>
#include <memory>
@@ -56,12 +54,10 @@ EditorWindowRenderRuntimeInitializeResult D3D12EditorWindowRenderRuntime::Initia
const EditorWindowRenderRuntimeInitializeParams& params) {
EditorWindowRenderRuntimeInitializeResult result = {};
const auto* surface = params.surface != nullptr
? dynamic_cast<
const ::XCEngine::UI::Editor::App::Win32EditorWindowRenderRuntimeSurface*>(
params.surface.get())
: nullptr;
HWND hwnd = surface != nullptr ? surface->GetHwnd() : nullptr;
const HWND hwnd =
params.surface.kind == Rendering::Host::EditorWindowRenderRuntimeSurfaceKind::Win32Window
? reinterpret_cast<HWND>(params.surface.nativeHandle)
: nullptr;
if (hwnd == nullptr) {
result.errorMessage = "window initialize skipped: hwnd is null";
return result;

View File

@@ -19,20 +19,22 @@ enum class EditorWindowRenderRuntimeSurfaceKind : std::uint8_t {
Win32Window,
};
class EditorWindowRenderRuntimeSurface {
public:
virtual ~EditorWindowRenderRuntimeSurface() = default;
struct EditorWindowRenderRuntimeSurface {
EditorWindowRenderRuntimeSurfaceKind kind = EditorWindowRenderRuntimeSurfaceKind::Unknown;
std::uintptr_t nativeHandle = 0u;
virtual EditorWindowRenderRuntimeSurfaceKind GetKind() const = 0;
bool IsValid() const {
return kind != EditorWindowRenderRuntimeSurfaceKind::Unknown && nativeHandle != 0u;
}
};
struct EditorWindowRenderRuntimeInitializeParams {
std::shared_ptr<const EditorWindowRenderRuntimeSurface> surface = {};
EditorWindowRenderRuntimeSurface surface = {};
std::uint32_t widthPixels = 0u;
std::uint32_t heightPixels = 0u;
bool IsValid() const {
return surface != nullptr && widthPixels > 0u && heightPixels > 0u;
return surface.IsValid() && widthPixels > 0u && heightPixels > 0u;
}
};

View File

@@ -1,5 +1,6 @@
#pragma once
#include "Rendering/Host/EditorWindowRenderRuntime.h"
#include "Windowing/EditorWindowShared.h"
#include "Windowing/Frame/EditorWindowTransferRequests.h"
#include "Windowing/Host/EditorWindowHostTypes.h"
@@ -29,10 +30,6 @@ namespace XCEngine::UI::Editor {
struct UIEditorDockHostTabDropTarget;
namespace Rendering::Host {
class EditorWindowRenderRuntimeSurface;
}
} // namespace XCEngine::UI::Editor
namespace XCEngine::UI::Editor::App {
@@ -49,13 +46,13 @@ struct EditorHostWindowRuntimeInitializationParams {
};
struct EditorNativeWindowRuntimeSurface {
std::shared_ptr<const Rendering::Host::EditorWindowRenderRuntimeSurface> renderSurface = {};
Rendering::Host::EditorWindowRenderRuntimeSurface renderSurface = {};
std::uint32_t widthPixels = 0u;
std::uint32_t heightPixels = 0u;
float dpiScale = 1.0f;
bool IsValid() const {
return renderSurface != nullptr && widthPixels > 0u && heightPixels > 0u;
return renderSurface.IsValid() && widthPixels > 0u && heightPixels > 0u;
}
};