mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
The draw fast path still paid for its own proofs: the hottest single load (20% of TrySetupDrawFastPath) was chasing the cold VertexInputStateFactory heap entry just to answer "same vertex-input layout?". That answer now comes from the frontend VAO's config-guarded aux memo (layout hash + attribute masks), and a VAO-cycling stream with a stable layout skips the pre-flight AND pipeline re-resolution entirely. The VkProgramObject* is memoized on the snapshot behind a new ProgramFactory cache-structure epoch (bumped on every insert/erase; use is re-stamped so the idle sweep can never evict a live entry). A render-state version move no longer forces the full path: the pipeline value hash is refreshed in place and the 8-entry memo probed directly (the GL_BLEND-toggle case). The resolved-vertex-bindings memo now revalidates all-resident unmapped entries ACROSS frames via per-binding slice epochs - minted from a process-lifetime counter so a recycled address can never revalidate, with every mutation path funnelled through BumpSliceEpoch - while stamping each resource's GPU-use serial exactly as the skipped acquire would, preserving the busy-tracking that glBufferSubData's host-write-vs-staged-copy choice depends on. Resident index buffers get the same treatment through an EBO slice memo. The six-part dynamic-state tail (viewport/scissor/blend constants/depth bias/line width/stencil) is gated behind one render-state-parameters version + pass-geometry compare per command buffer. GetSlice is inlined; SampledBindingsUnchanged walks only the program's declared bindings. Quiet-box 6-round order-alternating A/B (on top of the frontend VAO-bind commit): vanilla_draw -20.8% (790 -> 626 ns/op, 3.4x native to 2.5x), sampler_churn -28.2%, ubo_range -8.4%, state_toggle -3.8%; tex_param's matrix flag (+10%) was adjudicated by an isolated alternating re-run at +1.0% - position bias, not regression. Unit tests 421/421.