feat(mod): Stage 3 (partial) — RenderBackendOps interface + 3 GL mixins

Per mod/docs/optimize-layer-design.md Stage 3 (partial). This commit ships
the simplest GL mixins and the strategy interface that splits GL/Vulkan
backends. SkinAtlas/AnimFreeze/HudCache/FrameFence deferred to a later pass
because they're more complex (vertex-format / glCopyImageSubData /
RenderPipeline+RenderPass).

RenderBackendOps interface (features/.../optimize/gl/RenderBackendOps.java):
- Backend-agnostic surface for lazy clear, TBO cache, RenderTypes cache.
- current() resolves the active backend — returns GlRenderBackendOps on GL,
  null on Vulkan (so all WrapOperations fall through to the vanilla call).
- Stage 4 will add a VulkanRenderBackendOps no-op implementation.

GlRenderBackendOps (features/.../optimize/gl/GlRenderBackendOps.java):
- Concrete GL implementation. Three caches ported from ZakoOpt:
  * Lazy clear (from zako.opt.mixin.gl.GlCommandEncoderClearMixin).
  * TBO cache (from zako.opt.gl.TexBufferCache + the TexBufferMixin).
  * RenderTypes cache (from zako.opt.mixin.gl.RenderTypesMixin).
- All three gated on OptimizeToggles.microOpts() (the Stage 1 'micro_opts'
  toggle wired in Optimize.java).
- Includes test helpers (resetForTesting, boundTboTextureForTesting,
  cachedRenderTypeCountForTesting).

Three new mixins (mixins/optimize/):
- RenderTypesMixin: WrapOperation on RenderTypes.entityTranslucent's
  BiFunction.apply — cache by Identifier when flag=true (the common case).
  Drops the per-call Objects.hash(Pair) hit.
- GlCommandEncoderClearMixin: WrapOperation on GlCommandEncoder's
  clearColorAndDepthTextures → GlStateManager._glBindFramebuffer — skip the
  bind-framebuffer-0 because the next render pass binds its own target
  anyway and GlStateManager's cache already skips redundant binds.
- GlCommandEncoderTexBufferMixin: WrapOperation on GlCommandEncoder's
  trySetup → glBindTexture (track bound) and glTexBuffer (skip re-attach
  when the same (format, buffer) pair is already attached). Re-attaching
  makes the driver revalidate the texture (clouds: ~2% of a frame).

lovisual.mixins.json:
- Register all three mixins + OptimizeDebugHudMixin in the 'client' array,
  alphabetically under optimize.* (before accessors.*).

OptimizeDebugHudMixin (mixins/optimize/OptimizeDebugHudMixin.java):
- F3 overlay for the Optimize layer — Stage 2 of the design doc.
- Adds three blocks of lines to F3 (after the existing LoVisual Engine block):
  * 'LoVisual Optimize' — toggles summary + budget mode + scale + frame time.
  * 'frame:' — EMA-averaged per-section timings (entities/particles/HUD/effects/text).
  * 'props:' — when any -Dlovisual.opt.* is set, list which ones.
- Mirrors the existing hud.DebugHudMixin pattern (ModifyArg on extractLines).

Tests (JUnit 5): 11 new tests in GlRenderBackendOpsTest — pure-logic pieces
of RenderBackendOps + Identifier equality/hash. Total suite: 849 tests,
0 failures. checkFolderLimit: OK (0 folders >4).
This commit is contained in:
LoVisual AI 2026-10-10 13:08:27 +00:00 • committed by loki5512344
parent 64f27ee9e3
commit e88718a32d
Signed by: boba
GPG key ID: 253067914055423B
8 changed files with 707 additions and 0 deletions

View file

@ -33,6 +33,10 @@
"world.level.LevelMixin"
],
"client": [
"optimize.GlCommandEncoderClearMixin",
"optimize.GlCommandEncoderTexBufferMixin",
"optimize.OptimizeDebugHudMixin",
"optimize.RenderTypesMixin",
"accessors.blaze3d.GlTextureInvoker",
"accessors.blaze3d.GpuDeviceAccessor",
"accessors.blaze3d.ShaderLoaderDefinitionsAccessor",