gpui: Add wgpu Surface element and GPU device requirements API for Linux (#39)

This commit is contained in:
Leonard Seibold
2026-06-07 01:53:18 -04:00
committed by GitHub
parent d54ef9dcbe
commit 6d043b22e4
13 changed files with 304 additions and 56 deletions
+5
View File
@@ -92,6 +92,7 @@ pub(crate) trait LinuxClient {
fn read_from_clipboard(&self) -> Option<ClipboardItem>;
fn active_window(&self) -> Option<AnyWindowHandle>;
fn window_stack(&self) -> Option<Vec<AnyWindowHandle>>;
fn set_gpu_requirements(&self, _requirements: Box<dyn std::any::Any>) {}
fn run(&self);
#[cfg(any(feature = "wayland", feature = "x11"))]
@@ -316,6 +317,10 @@ impl<P: LinuxClient + 'static> Platform for LinuxPlatform<P> {
self.inner.open_window(handle, options)
}
fn set_gpu_requirements(&self, requirements: Box<dyn std::any::Any>) {
self.inner.set_gpu_requirements(requirements);
}
fn open_url(&self, url: &str) {
self.inner.open_uri(url);
}
@@ -217,6 +217,7 @@ pub(crate) struct WaylandClientState {
globals: Globals,
pub gpu_context: GpuContext,
pub compositor_gpu: Option<CompositorGpuHint>,
pub gpu_requirements: Option<gpui_wgpu::WgpuDeviceRequirements>,
wl_seat: wl_seat::WlSeat, // TODO: Multi seat support
wl_pointer: Option<wl_pointer::WlPointer>,
pinch_gesture: Option<zwp_pointer_gesture_pinch_v1::ZwpPointerGesturePinchV1>,
@@ -667,6 +668,7 @@ impl WaylandClient {
globals,
gpu_context,
compositor_gpu,
gpu_requirements: None,
wl_seat: seat,
wl_pointer: None,
wl_keyboard: None,
@@ -800,6 +802,14 @@ impl LinuxClient for WaylandClient {
sources_rx
}
fn set_gpu_requirements(&self, requirements: Box<dyn std::any::Any>) {
if let Ok(reqs) = requirements.downcast::<gpui_wgpu::WgpuDeviceRequirements>() {
self.0.borrow_mut().gpu_requirements = Some(*reqs);
} else {
log::warn!("set_gpu_requirements: unexpected type, expected WgpuDeviceRequirements");
}
}
fn open_window(
&self,
handle: AnyWindowHandle,
@@ -820,11 +830,13 @@ impl LinuxClient for WaylandClient {
let appearance = state.common.appearance;
let compositor_gpu = state.compositor_gpu.take();
let gpu_requirements = state.gpu_requirements.clone();
let (window, surface_id) = WaylandWindow::new(
handle,
state.globals.clone(),
state.gpu_context.clone(),
compositor_gpu,
gpu_requirements,
WaylandClientStatePtr(Rc::downgrade(&self.0)),
params,
appearance,
+15 -1
View File
@@ -328,6 +328,7 @@ impl WaylandWindowState {
globals: Globals,
gpu_context: gpui_wgpu::GpuContext,
compositor_gpu: Option<CompositorGpuHint>,
gpu_requirements: Option<gpui_wgpu::WgpuDeviceRequirements>,
options: WindowParams,
parent: Option<WaylandWindowStatePtr>,
) -> anyhow::Result<Self> {
@@ -350,7 +351,13 @@ impl WaylandWindowState {
// Prefer Mailbox to avoid blocking. Falls back to FIFO if Mailbox is unsupported.
preferred_present_mode: Some(wgpu::PresentMode::Mailbox),
};
WgpuRenderer::new(gpu_context, &raw_window, config, compositor_gpu)?
WgpuRenderer::new(
gpu_context,
&raw_window,
config,
compositor_gpu,
gpu_requirements,
)?
};
if let WaylandSurfaceState::Xdg(ref xdg_state) = surface_state {
@@ -514,6 +521,7 @@ impl WaylandWindow {
globals: Globals,
gpu_context: gpui_wgpu::GpuContext,
compositor_gpu: Option<CompositorGpuHint>,
gpu_requirements: Option<gpui_wgpu::WgpuDeviceRequirements>,
client: WaylandClientStatePtr,
params: WindowParams,
appearance: WindowAppearance,
@@ -544,6 +552,7 @@ impl WaylandWindow {
globals,
gpu_context,
compositor_gpu,
gpu_requirements,
params,
parent,
)?)),
@@ -1513,6 +1522,11 @@ impl PlatformWindow for WaylandWindow {
self.borrow().renderer.gpu_specs().into()
}
fn gpu_context(&self) -> Option<Box<dyn std::any::Any>> {
let (device, queue) = self.borrow().renderer.gpu_context();
Some(Box::new((device, queue)))
}
fn play_system_bell(&self) {
let state = self.borrow();
let surface = if state.surface_state.toplevel().is_some() {
+12
View File
@@ -180,6 +180,7 @@ pub struct X11ClientState {
pub(crate) gpu_context: GpuContext,
pub(crate) compositor_gpu: Option<CompositorGpuHint>,
pub(crate) gpu_requirements: Option<gpui_wgpu::WgpuDeviceRequirements>,
pub(crate) scale_factor: f32,
@@ -523,6 +524,7 @@ impl X11Client {
pinch_scale: 1.0,
gpu_context: Rc::new(RefCell::new(None)),
compositor_gpu,
gpu_requirements: None,
scale_factor,
xkb_context,
@@ -1586,6 +1588,14 @@ impl LinuxClient for X11Client {
gpui::scap_screen_capture::scap_screen_sources(&self.0.borrow().common.foreground_executor)
}
fn set_gpu_requirements(&self, requirements: Box<dyn std::any::Any>) {
if let Ok(reqs) = requirements.downcast::<gpui_wgpu::WgpuDeviceRequirements>() {
self.0.borrow_mut().gpu_requirements = Some(*reqs);
} else {
log::warn!("set_gpu_requirements: unexpected type, expected WgpuDeviceRequirements");
}
}
fn open_window(
&self,
handle: AnyWindowHandle,
@@ -1608,6 +1618,7 @@ impl LinuxClient for X11Client {
let scale_factor = state.scale_factor;
let appearance = state.common.appearance;
let compositor_gpu = state.compositor_gpu.take();
let gpu_requirements = state.gpu_requirements.clone();
let supports_xinput_gestures = state.supports_xinput_gestures;
let is_bgr = state
.resource_database
@@ -1619,6 +1630,7 @@ impl LinuxClient for X11Client {
state.common.foreground_executor.clone(),
state.gpu_context.clone(),
compositor_gpu,
gpu_requirements,
params,
&xcb_connection,
client_side_decorations_supported,
+15 -1
View File
@@ -416,6 +416,7 @@ impl X11WindowState {
executor: ForegroundExecutor,
gpu_context: gpui_wgpu::GpuContext,
compositor_gpu: Option<CompositorGpuHint>,
gpu_requirements: Option<gpui_wgpu::WgpuDeviceRequirements>,
params: WindowParams,
xcb: &Rc<XCBConnection>,
client_side_decorations_supported: bool,
@@ -724,7 +725,13 @@ impl X11WindowState {
transparent: false,
preferred_present_mode: None,
};
WgpuRenderer::new(gpu_context, &raw_window, config, compositor_gpu)?
WgpuRenderer::new(
gpu_context,
&raw_window,
config,
compositor_gpu,
gpu_requirements,
)?
};
renderer.set_subpixel_layout(is_bgr);
@@ -878,6 +885,7 @@ impl X11Window {
executor: ForegroundExecutor,
gpu_context: gpui_wgpu::GpuContext,
compositor_gpu: Option<CompositorGpuHint>,
gpu_requirements: Option<gpui_wgpu::WgpuDeviceRequirements>,
params: WindowParams,
xcb: &Rc<XCBConnection>,
client_side_decorations_supported: bool,
@@ -897,6 +905,7 @@ impl X11Window {
executor,
gpu_context,
compositor_gpu,
gpu_requirements,
params,
xcb,
client_side_decorations_supported,
@@ -1887,6 +1896,11 @@ impl PlatformWindow for X11Window {
self.0.state.borrow().renderer.gpu_specs().into()
}
fn gpu_context(&self) -> Option<Box<dyn std::any::Any>> {
let (device, queue) = self.0.state.borrow().renderer.gpu_context();
Some(Box::new((device, queue)))
}
fn play_system_bell(&self) {
// Volume 0% means don't increase or decrease from system volume
let _ = self.0.xcb.bell(0);