Skip to content

Use display-bound wgpu instance#119

Merged
eval-exec merged 1 commit into
mainfrom
fix/carefreelee-wgpu-display-handle
May 26, 2026
Merged

Use display-bound wgpu instance#119
eval-exec merged 1 commit into
mainfrom
fix/carefreelee-wgpu-display-handle

Conversation

@eval-exec
Copy link
Copy Markdown
Owner

Summary

  • create GUI wgpu instances from winit's owned display handle
  • keep one render-thread GPU context and reuse its instance for secondary window surfaces
  • switch remaining local wgpu instance setup to env-aware descriptors so WGPU_BACKEND is honored

Why

CarefreeLee's logs in #109 show wgpu GLES initializing with no known windowing system and falling back to surfaceless EGL, then rejecting the GL adapter as incompatible with the Wayland surface. wgpu 29 documents that GLES presentation needs the display handle, especially on Wayland.

Verification

  • cargo check -p neomacs-display-runtime -p neomacs-renderer-wgpu
  • cargo check -p neomacs
  • cargo nextest run -p neomacs-display-runtime --lib backend::wgpu
  • push hook: cargo fmt --all --check, cargo check

Not Verified

  • Haswell Intel HD 4600 under niri/Wayland, because this machine has different GPU hardware. This draft needs validation by @CarefreeLee.

Fixes #109

Create the GUI render instance from winit's display handle.

This gives GLES presentation the Wayland display connection wgpu expects.

Keep that instance in the render GPU context.

Reuse it for secondary window surfaces.

Use env-aware descriptors so WGPU_BACKEND is honored.

Constraint: Scope to wgpu ownership and adapter selection

Rejected: Replace renderer backend | too broad for this fix

Confidence: medium

Scope-risk: moderate

Not-tested: Haswell HD 4600 under niri/Wayland
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the wgpu initialization and state management in the display runtime. It consolidates several wgpu-related fields (instance, adapter, device, and queue) into a unified RenderGpuContext struct, and updates the initialization paths to use display-bound descriptors from the environment (which is particularly important for GLES presentation on Wayland). The feedback highlights two opportunities to avoid unnecessary cloning of wgpu resources: first, by passing a reference to the device during window resize events, and second, by moving the device and queue directly into the RenderGpuContext during bootstrap.

Comment on lines +57 to 59
} else if let Some(device) = self.gpu.as_ref().map(|gpu| gpu.device.clone()) {
if let Some(ws) = self.multi_windows.get_mut(emacs_fid) {
ws.handle_resize(&device, size.width, size.height);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

We can avoid cloning the Arc<wgpu::Device> here by matching on &self.gpu and passing a reference to gpu.device directly, since ws.handle_resize only requires a reference &wgpu::Device.

Suggested change
} else if let Some(device) = self.gpu.as_ref().map(|gpu| gpu.device.clone()) {
if let Some(ws) = self.multi_windows.get_mut(emacs_fid) {
ws.handle_resize(&device, size.width, size.height);
} else if let Some(gpu) = &self.gpu {
if let Some(ws) = self.multi_windows.get_mut(emacs_fid) {
ws.handle_resize(&gpu.device, size.width, size.height);

Comment on lines +143 to +148
self.gpu = Some(RenderGpuContext {
instance,
adapter,
device: device.clone(),
queue: queue.clone(),
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since device and queue are not used after this point in init_wgpu, we can move them directly into RenderGpuContext instead of cloning them.

Suggested change
self.gpu = Some(RenderGpuContext {
instance,
adapter,
device: device.clone(),
queue: queue.clone(),
});
self.gpu = Some(RenderGpuContext {
instance,
adapter,
device,
queue,
});

@CarefreeLee
Copy link
Copy Markdown

thanks,it work.
here is Verification:

~/neomacs fix/carefreelee-wgpu-display-handle* 1m 11s
❯ cargo check -p neomacs-display-runtime -p neomacs-renderer-wgpu
    Checking neovm-core v0.0.2 (/home/lee/neomacs/neovm-core)
    Checking neomacs-layout-engine v0.0.2 (/home/lee/neomacs/neomacs-layout-engine)
   Compiling neomacs-display-runtime v0.0.2 (/home/lee/neomacs/neomacs-display-runtime)
    Checking neomacs-renderer-wgpu v0.0.2 (/home/lee/neomacs/neomacs-renderer-wgpu)
    Finished [`dev` profile [unoptimized + debuginfo]](https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles) target(s) in 36.08s
~/neomacs fix/carefreelee-wgpu-display-handle* 36s
❯ cargo check -p neomacs
    Checking bitflags v2.11.1
   Compiling rustix v1.1.4
    Checking wayland-backend v0.3.15
    Checking regex-automata v0.4.14
    Checking wayland-client v0.31.14
    Checking polling v3.11.0
    Checking png v0.18.1
    Checking spirv v0.4.0+sdk-1.4.341.0
    Checking naga v29.0.3
    Checking wgpu-types v29.0.3
    Checking gethostname v1.1.0
    Checking gpu-descriptor-types v0.2.0
   Compiling serde_core v1.0.228
    Checking x11rb v0.13.2
    Checking rustix v0.38.44
    Checking gpu-descriptor v0.3.2
    Checking glib v0.22.7
    Checking wgpu-naga-bridge v29.0.3
    Checking wayland-protocols v0.32.12
    Checking matchers v0.2.0
   Compiling serde v1.0.228
    Checking tracing-subscriber v0.3.23
    Checking wgpu-hal v29.0.3
    Checking gstreamer v0.25.1
    Checking inotify v0.11.1
    Checking image v0.25.10
    Checking nix v0.28.0
    Checking calloop v0.13.0
    Checking regex v1.12.3
    Checking notify-types v2.1.0
    Checking tree-sitter v0.26.8
    Checking wayland-cursor v0.31.14
    Checking gstreamer-base v0.25.0
    Checking wayland-csd-frame v0.3.0
    Checking rustybuzz v0.20.1
    Checking tracing-appender v0.2.5
    Checking rusqlite v0.35.0
    Checking tempfile v3.27.0
    Checking portable-pty v0.9.0
    Checking notify v8.2.0
    Checking calloop-wayland-source v0.3.0
    Checking arboard v3.6.1
    Checking wgpu-core-deps-windows-linux-android v29.0.3
    Checking wayland-protocols-wlr v0.3.12
    Checking harfrust v0.5.2
    Checking fs4 v1.1.0
    Checking usvg v0.47.0
    Checking allsorts v0.16.1
    Checking cosmic-text v0.18.2 (https://github.com/eval-exec/cosmic-text?rev=5dd3fec8572e771794e3f203ab6780d828e9ce09#5dd3fec8)
    Checking neovm-core v0.0.2 (/home/lee/neomacs/neovm-core)
    Checking smithay-client-toolkit v0.19.2
    Checking wgpu-core v29.0.3
    Checking tiny-skia v0.12.0
    Checking neomacs-display-protocol v0.0.2 (/home/lee/neomacs/neomacs-display-protocol)
    Checking gstreamer-app v0.25.0
    Checking neomacs-layout-engine v0.0.2 (/home/lee/neomacs/neomacs-layout-engine)
    Checking resvg v0.47.0
    Checking gstreamer-video v0.25.0
    Checking wgpu v29.0.3
    Checking sctk-adwaita v0.10.1
    Checking xkbcommon-dl v0.4.2
    Checking wayland-protocols-plasma v0.3.12
   Compiling neomacs-display-runtime v0.0.2 (/home/lee/neomacs/neomacs-display-runtime)
    Checking neomacs-renderer-wgpu v0.0.2 (/home/lee/neomacs/neomacs-renderer-wgpu)
    Checking winit v0.30.13
    Checking crossterm v0.29.0
   Compiling neomacs v0.0.2 (/home/lee/neomacs/neomacs-bin)
warning: function `detect_dpi_scale` is never used
   --> neomacs-bin/src/bin/mock-display.rs:882:4
    |
882 | fn detect_dpi_scale() -> f32 {
    |    ^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default

warning: `neomacs` (bin "mock-display") generated 1 warning
    Finished [`dev` profile [unoptimized + debuginfo]](https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles) target(s) in 1m 58s
❯ cargo nextest run -p neomacs-display-runtime --lib backend::wgpu
error: no such command: `nextest`

help: a command with a similar name exists: `test`

help: view all installed commands with `cargo --list`
help: find a package to install `nextest` with `cargo search cargo-nextest`
~/neomacs fix/carefreelee-wgpu-display-handle* 15s
❯ cargo check
warning: function `detect_dpi_scale` is never used
   --> neomacs-bin/src/bin/mock-display.rs:882:4
    |
882 | fn detect_dpi_scale() -> f32 {
    |    ^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default

warning: `neomacs` (bin "mock-display") generated 1 warning
    Checking xtask v0.0.2 (/home/lee/neomacs/xtask)
    Finished [`dev` profile [unoptimized + debuginfo]](https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles) target(s) in 2.70s

@eval-exec
Copy link
Copy Markdown
Owner Author

can neomacs -Q work? Can window show? Can cursor animate? @CarefreeLee

@CarefreeLee
Copy link
Copy Markdown

@eval-exec eval-exec marked this pull request as ready for review May 26, 2026 04:09
Copilot AI review requested due to automatic review settings May 26, 2026 04:09
@eval-exec eval-exec merged commit 30b40ba into main May 26, 2026
1 check failed
@eval-exec eval-exec review requested due to automatic review settings May 26, 2026 04:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants