Commit 0e6ab4933125
tarball3 files changed+51-19
@@ -7,6 +7,7 @@
77
use crate::state::State;88
use monolith_render_vk::{DmabufImporter, ShmStager, StagedShm, VulkanTexture};99
use smithay::backend::allocator::dmabuf::{Dmabuf, WeakDmabuf};10
+use smithay::backend::renderer::ImportDma;1011
use smithay::reexports::calloop::LoopHandle;1112
use smithay::reexports::calloop::channel::{Event, channel};1213
use smithay::reexports::wayland_server::backend::ObjectId;@@ -100,12 +101,22 @@ impl Imports {
100101
})101102
}102103
103
- fn start(&mut self, buffer: &Dmabuf) -> &mut Waiters {104
- let jobs = &self.jobs;105
- self.dmabufs.entry(buffer.weak()).or_insert_with(|| {106
- let _ = jobs.send(Job::Dmabuf(buffer.clone()));107
- Waiters::default()108
- })104
+ /// None once the worker is gone, when the caller imports on the main105
+ /// thread instead of waiting on a job nobody will finish.106
+ fn start(&mut self, buffer: &Dmabuf) -> Option<&mut Waiters> {107
+ let key = buffer.weak();108
+ if !self.dmabufs.contains_key(&key) && !self.send(Job::Dmabuf(buffer.clone())) {109
+ return None;110
+ }111
+ Some(self.dmabufs.entry(key).or_default())112
+ }113
+114
+ fn send(&self, job: Job) -> bool {115
+ let sent = self.jobs.send(job).is_ok();116
+ if !sent {117
+ tracing::warn!("buffer import worker is gone");118
+ }119
+ sent109120
}110121
}111122
@@ -116,7 +127,15 @@ impl State {
116127
let _ = notifier.successful::<State>();117128
return;118129
}119
- self.services.imports.start(buffer).notifiers.push(notifier);130
+ match self.services.imports.start(buffer) {131
+ Some(waiters) => waiters.notifiers.push(notifier),132
+ None => match self.renderer.import_dmabuf(buffer, None) {133
+ Ok(_) => {134
+ let _ = notifier.successful::<State>();135
+ }136
+ Err(_) => notifier.failed(),137
+ },138
+ }120139
}121140
122141
/// A blocker for a commit whose dmabuf the renderer has not imported yet.@@ -124,7 +143,7 @@ impl State {
124143
if self.renderer.has_dmabuf(buffer) {125144
return None;126145
}127
- let waiters = self.services.imports.start(buffer);146
+ let waiters = self.services.imports.start(buffer)?;128147
waiters.clients.push(client);129148
Some(ImportBlocker(waiters.done.clone()))130149
}@@ -150,11 +169,12 @@ impl State {
150169
return None;151170
}152171
let imports = &mut self.services.imports;153
- let jobs = &imports.jobs;154
- let waiters = imports.shm.entry(buffer.id()).or_insert_with(|| {155
- let _ = jobs.send(Job::Shm(buffer.clone(), region));156
- Waiters::default()157
- });172
+ if !imports.shm.contains_key(&buffer.id())173
+ && !imports.send(Job::Shm(buffer.clone(), region))174
+ {175
+ return None;176
+ }177
+ let waiters = imports.shm.entry(buffer.id()).or_default();158178
waiters.clients.push(client);159179
Some(ImportBlocker(waiters.done.clone()))160180
}@@ -210,9 +210,13 @@ pub fn configure(window: &Window, rect: Rect, kind: Kind, maximized: bool) -> bo
210210
}211211
let (x0, y0) = (x as i32, y as i32);212212
if let Some(x) = window.x11_surface() {213
- let _ = x.configure(Rectangle::new((x0, y0).into(), (w, h).into()));214
- let _ = x.set_fullscreen(kind == Kind::Fullscreen);215
- let _ = x.set_maximized(maximized && kind == Kind::Tiled);213
+ let geo = Rectangle::new((x0, y0).into(), (w, h).into());214
+ crate::xwayland::logged("configure", x.configure(geo));215
+ crate::xwayland::logged("fullscreen", x.set_fullscreen(kind == Kind::Fullscreen));216
+ crate::xwayland::logged(217
+ "maximize",218
+ x.set_maximized(maximized && kind == Kind::Tiled),219
+ );216220
}217221
if let Some(t) = window.toplevel() {218222
t.with_pending_state(|s| {@@ -259,7 +259,7 @@ impl XwmHandler for State {
259259
fn unmapped_window(&mut self, _xwm: XwmId, window: X11Surface) {260260
self.forget_x11(&window);261261
if !window.is_override_redirect() {262
- let _ = window.set_mapped(false);262
+ logged("unmap", window.set_mapped(false));263263
}264264
}265265
@@ -278,7 +278,7 @@ impl XwmHandler for State {
278278
_reorder: Option<Reorder>,279279
) {280280
if self.x11_window_id(&window).is_some() {281
- let _ = window.configure(None);281
+ logged("configure", window.configure(None));282282
return;283283
}284284
let mut geo = window.geometry();@@ -286,7 +286,7 @@ impl XwmHandler for State {
286286
geo.loc.y = y.unwrap_or(geo.loc.y);287287
geo.size.w = w.map_or(geo.size.w, |w| w as i32);288288
geo.size.h = h.map_or(geo.size.h, |h| h as i32);289
- let _ = window.configure(geo);289
+ logged("configure", window.configure(geo));290290
}291291
292292
fn configure_notify(@@ -397,3 +397,11 @@ impl State {
397397
}398398
}399399
}400
+401
+/// X11 requests fail when the window is already gone, which is routine, but402
+/// a failure on a live window means it never got the geometry we chose.403
+pub fn logged<E: std::fmt::Display>(what: &str, result: Result<(), E>) {404
+ if let Err(e) = result {405
+ tracing::debug!("X11 {what} failed: {e}");406
+ }407
+}