Summary
A viewport has nothing to render into and no pass to render with. M9 e11a landed the Camera/View
value type and the camera math (src/render/include/context/render/view.h, PR #465), but nothing
consumes it: EditorWindow::handle_event's case InputTarget::viewport: is a bare break;, and
src/render/ has no per-view render target and no scene pass at all.
This is the second child of the decomposed e11 (viewports / picking / gizmos, design
m9-editor D5). It delivers the two pieces every later child needs underneath it.
Context
DynamicTextureRegistry cannot host a per-viewport render target. It exposes
create_panel_target / get / size_of / contains / count over an append-only vector —
handles are never reused and nothing is freed until the registry dies. A viewport panel is resized
every frame of an edge drag, and the only way to change size on that API is another
create_panel_target(), so a per-viewport RT built on it leaks a handle and its texture per
resize.
"A real project scene" can only mean PROXY GEOMETRY. Two facts bound what a scene can ask to be
drawn, and both are worth stating so the rest of the chain inherits them rather than rediscovering
them:
- The
ctx:scene schema (kSceneSchemaJson, src/editor/schema/src/kind_schema.cpp) declares
exactly two components. transform is additionalProperties:false with required:["position"]
and carries a position and nothing else — no rotation, no scale. camera carries
fov/near/far.
Renderable::mesh_id (render_world.h) is opaque with NO registry anywhere. The only mapping
in the tree is the hardcoded lit-golden 0 = ground / 1 = blocker in
src/render/lit/src/lit_scene.cpp.
There is no mesh pipeline to look for.
Proposed approach
- A sibling per-viewport target registry in
context_render, not an extension of
DynamicTextureRegistry. Extending the latter is blocked outright by layering (it lives in
context_render_ui, which links context_render, so a context_render pass cannot reach it —
the same constraint that promoted lit_math.h into context/render/math.h for e11a), and would
break the persistence contract M7 a9/a10 rely on. The new registry has real create / resize
(in place, keeping the handle) / release (frees the slot AND destroys the textures), owns a
colour + Depth32Float pair per target, and makes slot reuse safe with generation-tagged handles
so a stale handle is refused rather than aliasing onto the recycled entry.
render_viewport_view(...) — one render pass drawing a box proxy per renderable at its
authored transform, tinted with Renderable::color, over a ground grid (major/minor lines plus
the two axis lines). A grid line is a thin box, because the T1 RHI's PrimitiveTopology has
exactly one value, TriangleList.
- T1 tests against
rendertest::FakeDevice, asserting the uploaded per-draw matrices against
e11a's own project() rather than pixels, since the fake rasterizes nothing but its reference
triangle.
Acceptance criteria
Out of scope
Shell/compositor binding (e11e), picking (e11g), gizmos and selection outline (e11h),
camera controls (e11f), any extract_render_world / culling / per-view-visible-set change, and
the scene-data wire verb (e11c).
Summary
A viewport has nothing to render into and no pass to render with. M9 e11a landed the
Camera/Viewvalue type and the camera math (
src/render/include/context/render/view.h, PR #465), but nothingconsumes it:
EditorWindow::handle_event'scase InputTarget::viewport:is a barebreak;, andsrc/render/has no per-view render target and no scene pass at all.This is the second child of the decomposed e11 (viewports / picking / gizmos, design
m9-editorD5). It delivers the two pieces every later child needs underneath it.Context
DynamicTextureRegistrycannot host a per-viewport render target. It exposescreate_panel_target/get/size_of/contains/countover an append-only vector —handles are never reused and nothing is freed until the registry dies. A viewport panel is resized
every frame of an edge drag, and the only way to change size on that API is another
create_panel_target(), so a per-viewport RT built on it leaks a handle and its texture perresize.
"A real project scene" can only mean PROXY GEOMETRY. Two facts bound what a scene can ask to be
drawn, and both are worth stating so the rest of the chain inherits them rather than rediscovering
them:
ctx:sceneschema (kSceneSchemaJson,src/editor/schema/src/kind_schema.cpp) declaresexactly two components.
transformisadditionalProperties:falsewithrequired:["position"]and carries a
positionand nothing else — no rotation, no scale.cameracarriesfov/near/far.Renderable::mesh_id(render_world.h) is opaque with NO registry anywhere. The only mappingin the tree is the hardcoded lit-golden
0 = ground / 1 = blockerinsrc/render/lit/src/lit_scene.cpp.There is no mesh pipeline to look for.
Proposed approach
context_render, not an extension ofDynamicTextureRegistry. Extending the latter is blocked outright by layering (it lives incontext_render_ui, which linkscontext_render, so acontext_renderpass cannot reach it —the same constraint that promoted
lit_math.hintocontext/render/math.hfor e11a), and wouldbreak the persistence contract M7 a9/a10 rely on. The new registry has real
create/resize(in place, keeping the handle) /
release(frees the slot AND destroys the textures), owns acolour + Depth32Float pair per target, and makes slot reuse safe with generation-tagged handles
so a stale handle is refused rather than aliasing onto the recycled entry.
render_viewport_view(...)— one render pass drawing a box proxy per renderable at itsauthored transform, tinted with
Renderable::color, over a ground grid (major/minor lines plusthe two axis lines). A grid line is a thin box, because the T1 RHI's
PrimitiveTopologyhasexactly one value,
TriangleList.rendertest::FakeDevice, asserting the uploaded per-draw matrices againste11a's own
project()rather than pixels, since the fake rasterizes nothing but its referencetriangle.
Acceptance criteria
repeatedly and asserts the handles/resources are actually reclaimed — not merely that the call
returned
render_viewport_view(...)draws proxy geometry at authored transforms plus the grid, drivenby an e11a
Viewrendertest::FakeDevice, planted and proven RED per claimOut of scope
Shell/compositor binding (e11e), picking (e11g), gizmos and selection outline (e11h),
camera controls (e11f), any
extract_render_world/ culling / per-view-visible-set change, andthe scene-data wire verb (e11c).