refactor(viewport): unify content-viewport clipping on the stencil path

Rectangular paper viewports now go through the same GPU stencil clip as
non-rectangular ones: viewport_clip_boundary_ndc returns the four rect
corners (a full-target mask) instead of nothing, so the render path has
no rect/non-rect special case — every content viewport carries a clip
boundary and draws with stencil reference 0xFF.

With a single clip path, the old per-wire / -image / -wipeout scissor
mechanism is fully dead and removed: compute_*_scissors, the
*_pixel_scissors buffers, the project_scissor helper, the per-pass
set_scissor_rect blocks, the vp_scissor field threaded through
WireModel / ImageModel / HatchModel and their GPU mirrors (WireGpu /
ImageGpu / WipeoutGpu / HatchWebGpu), from_run's scissor parameter, the
scissor grouping in build_wire_buffers, and the is_arena_eligible gate.
Net -245 lines across 54 files.

Rectangular viewports still clip exactly via their own render rectangle;
the stencil mask is a redundant full-target no-op there, kept only so
the clip code path stays uniform. XCLIP keeps its CPU wire clip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-07-20 11:06:28 +03:00
1 parent c97c2a8250
commit 626e8091f7
54 files changed
+32 -277

No files matched your search

+1 -7
View File
@@ -387,10 +387,7 @@ impl shader::Primitive for Primitive {
#[cfg(not(target_arch = "wasm32"))]
let mut _patched = false;
#[cfg(not(target_arch = "wasm32"))]
if crate::scene::wire_gpu_patch_enabled()
&& inner.wire_const_bgl.is_some()
&& crate::scene::pipeline::wire_arena::is_arena_eligible(&vp.wires)
{
if crate::scene::wire_gpu_patch_enabled() && inner.wire_const_bgl.is_some() {
use crate::scene::pipeline::wire_arena::{self, WireArena};
// Split the resident set into the regular 2D wires and the
// mesh/solid EDGE wires (which need the mesh-edge draw
@@ -576,9 +573,6 @@ impl shader::Primitive for Primitive {
inner.upload_silhouettes(device, &[], vp.view_dir);
}
inner.upload_clip_boundary(device, &vp.clip_boundary_ndc);
inner.compute_wire_scissors(view_rot, eye, clip_size.width, clip_size.height);
inner.compute_wipeout_scissors(view_rot, eye, clip_size.width, clip_size.height);
inner.compute_image_scissors(view_rot, eye, clip_size.width, clip_size.height);
inner.compute_hatch_lod(queue, view_rot, eye, clip_size.width, clip_size.height);
inner.compute_wipeout_lod(view_rot, eye, clip_size.width, clip_size.height);
inner.compute_mesh_lod(view_rot, eye, clip_size.width, clip_size.height);