Skip to content

Conversation

@vmarcella
Copy link
Member

Summary

Add user-configurable presentation mode (VSync) support to the rendering API.
This change exposes controls for selecting the swapchain present mode, allowing
applications to choose between VSync-enabled rendering, immediate presentation,
or triple buffering (mailbox) for their desired latency/tearing tradeoffs.

Related Issues

Changes

  • Add PresentMode enum to lambda-rs with Vsync, Immediate, and Mailbox
    variants
  • Add with_vsync(bool) convenience method to RenderContextBuilder
  • Add with_present_mode(PresentMode) for explicit mode selection
  • Implement select_present_mode helper in platform layer with intelligent
    fallback logic when requested mode is unavailable
  • Wire WindowBuilder::with_vsync to influence default present mode when no
    explicit mode is provided to the renderer
  • Change default VSync preference in WindowBuilder from false to true
  • Add unit tests for present mode selection fallback behavior

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (updates to docs, specs, tutorials, or comments)
  • Refactor (code change that neither fixes a bug nor adds a feature)
  • Performance (change that improves performance)
  • Test (adding or updating tests)
  • Build/CI (changes to build process or CI configuration)

Affected Crates

  • lambda-rs
  • lambda-rs-platform
  • lambda-rs-args
  • lambda-rs-logging
  • Other:

Checklist

  • Code follows the repository style guidelines (cargo +nightly fmt --all)
  • Code passes clippy (cargo clippy --workspace --all-targets -- -D warnings)
  • Tests pass (cargo test --workspace)
  • New code includes appropriate documentation
  • Public API changes are documented
  • Breaking changes are noted in this PR description

Testing

cargo build --workspace
cargo test --workspace

Manual verification steps (if applicable):

  1. Run cargo run --example minimal and observe the window uses Mailbox mode
  2. Modify the example to use PresentMode::Vsync and verify VSync behavior
  3. Modify the example to use PresentMode::Immediate and verify uncapped FPS

Screenshots/Recordings

Platform Testing

  • macOS
  • Windows
  • Linux

Additional Notes

The present mode can be configured in two ways:

  1. Via RenderContextBuilder (recommended for explicit control):

    .with_renderer_configured_as(|builder| {
      builder.with_present_mode(PresentMode::Mailbox)
    })
  2. Via WindowBuilder (legacy/convenience):

    .with_window_configured_as(|builder| {
      builder.with_vsync(false)
    })

Fallback Behavior

When the requested present mode is not supported by the adapter, the platform
layer selects a fallback with similar behavior:

  • Immediate → tries MailboxAutoNoVsyncFifo
  • Mailbox → tries FifoAutoVsync
  • Vsync (Fifo) → tries AutoVsyncFifoRelaxed → other modes

Default Behavior Change

The default VSync preference in WindowBuilder changed from false to true.
This aligns with common expectations that applications should not tear by
default. Applications wanting uncapped frame rates should explicitly request
PresentMode::Immediate or call with_vsync(false).

@vmarcella vmarcella merged commit 8191149 into main Jan 27, 2026
5 checks passed
@vmarcella vmarcella deleted the vmarcella/expose-vsync branch January 27, 2026 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Expose Present Mode and VSync Configuration in RenderContextBuilder

2 participants