forked from 1b-agent/opencadstudio-upstream
Every cursor movement over the viewport re-rendered the entire GPU scene (all wires, hatches, meshes) even when nothing visible changed: iced redraws the whole window on each input message, and the shader's draw/prepare/render runs every time. On large drawings one such redraw exceeds the frame budget, so moving the mouse or panning stutters — and it gets worse the bigger the drawing. The pipeline already resolves each frame into a persistent, clip-sized resolve texture and blits that to the surface. This hashes the inputs that determine the rendered image (camera uniforms, geometry/selection generations, wire content id, render-mode flags, clip size, live preview coordinates) into a per-viewport signature. When a frame's signature matches the previous one the image is pixel-identical, so `prepare` skips the buffer uploads + per-frame scissor/LOD recompute and `render` skips passes 1-7 plus the MSAA resolve, re-blitting the resolve texture instead. A pure cursor move becomes a single fullscreen blit rather than an O(N) re-rasterization. The ViewCube is excluded from the signature (it renders in its own always-on pass) so cube hover still tracks while the scene is cached. Any real change — edit (geometry_epoch), select/hover (selection_generation), camera move or render-mode toggle — differs the signature and forces a full render, so nothing goes stale. Navigation still renders every frame (the view genuinely changes); this targets the wasted re-render on cursor-only movement.