Compare commits

...

2 Commits

Author SHA1 Message Date
Ivan Molodetskikh
92e5525753 Raise nofile rlimit on powerset tests
Hopefully this helps.
2025-11-28 15:19:42 +01:00
yuxqiu
7c77ed81b7 tty: Handle multiple primary nodes having the same render node 2025-11-28 15:19:42 +01:00
3 changed files with 66 additions and 43 deletions

View File

@@ -147,8 +147,7 @@ install -Dm644 -t %{buildroot}%{zsh_completions_dir} ./_niri
%if %{with check}
%check
# Skip tests that run into open fd limits, until we figure out a fix.
%cargo_test -- --workspace --exclude niri-visual-tests -- --skip=target_output_and_workspaces --skip=target_size --skip=fullscreen_maximize
%cargo_test -- --workspace --exclude niri-visual-tests
%endif
%files

View File

@@ -780,15 +780,20 @@ impl Tty {
Ok(render_node)
};
let render_node = try_initialize_gpu()
.inspect_err(|err| {
let render_node = match try_initialize_gpu() {
Ok(render_node) => {
debug!("got render node: {render_node}");
Some(render_node)
}
Err(err) => {
debug!("failed to initialize renderer, falling back to primary gpu: {err:?}");
})
.ok();
None
}
};
if render_node == Some(self.primary_render_node) {
if render_node == Some(self.primary_render_node) && self.dmabuf_global.is_none() {
let render_node = self.primary_render_node;
debug!("this is the primary render node");
debug!("initializing the primary renderer");
let mut renderer = self
.gpu_manager
@@ -1099,46 +1104,58 @@ impl Tty {
lease_state.disable_global::<State>();
}
if device.render_node == Some(self.primary_render_node) {
match self.gpu_manager.single_renderer(&self.primary_render_node) {
Ok(mut renderer) => renderer.unbind_wl_display(),
Err(err) => {
warn!("error creating renderer during device removal: {err}");
}
}
if let Some(render_node) = device.render_node {
// Sometimes (Asahi DisplayLink), multiple primary nodes will correspond to the same
// render node. In this case, we want to keep the render node active until the last
// primary node that uses it is gone.
let was_last = !self
.devices
.values()
.any(|device| device.render_node == Some(render_node));
// Disable and destroy the dmabuf global.
if let Some(global) = self.dmabuf_global.take() {
niri.dmabuf_state
.disable_global::<State>(&niri.display_handle, &global);
niri.event_loop
.insert_source(
Timer::from_duration(Duration::from_secs(10)),
move |_, _, state| {
state
.niri
.dmabuf_state
.destroy_global::<State>(&state.niri.display_handle, global);
TimeoutAction::Drop
},
)
.unwrap();
if was_last && render_node == self.primary_render_node {
debug!("destroying the primary renderer");
// Clear the dmabuf feedbacks for all surfaces.
for device in self.devices.values_mut() {
for surface in device.surfaces.values_mut() {
surface.dmabuf_feedback = None;
match self.gpu_manager.single_renderer(&self.primary_render_node) {
Ok(mut renderer) => renderer.unbind_wl_display(),
Err(err) => {
warn!("error creating renderer during device removal: {err}");
}
}
} else {
error!("dmabuf global was already missing");
}
}
if let Some(render_node) = device.render_node {
self.gpu_manager.as_mut().remove_node(&render_node);
// Trigger re-enumeration in order to remove the device from gpu_manager.
let _ = self.gpu_manager.devices();
// Disable and destroy the dmabuf global.
if let Some(global) = self.dmabuf_global.take() {
niri.dmabuf_state
.disable_global::<State>(&niri.display_handle, &global);
niri.event_loop
.insert_source(
Timer::from_duration(Duration::from_secs(10)),
move |_, _, state| {
state
.niri
.dmabuf_state
.destroy_global::<State>(&state.niri.display_handle, global);
TimeoutAction::Drop
},
)
.unwrap();
// Clear the dmabuf feedbacks for all surfaces.
for device in self.devices.values_mut() {
for surface in device.surfaces.values_mut() {
surface.dmabuf_feedback = None;
}
}
} else {
error!("dmabuf global was already missing");
}
}
if was_last {
self.gpu_manager.as_mut().remove_node(&render_node);
// Trigger re-enumeration in order to remove the device from gpu_manager.
let _ = self.gpu_manager.devices();
}
}
niri.event_loop.remove(device.token);

View File

@@ -6,6 +6,7 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator};
use super::*;
use crate::layout::LayoutElement as _;
use crate::utils::spawning::store_and_increase_nofile_rlimit;
use crate::utils::with_toplevel_role;
#[test]
@@ -162,6 +163,8 @@ impl fmt::Display for DefaultSize {
#[test]
fn target_output_and_workspaces() {
store_and_increase_nofile_rlimit();
// Here we test a massive powerset of settings that can affect where a window opens:
//
// * open-on-workspace
@@ -438,6 +441,8 @@ fn target_size() {
return;
}
store_and_increase_nofile_rlimit();
// Here we test a massive powerset of settings that can affect the window size:
//
// * want fullscreen
@@ -682,6 +687,8 @@ post-map configures:
#[test]
fn fullscreen_maximize() {
store_and_increase_nofile_rlimit();
let open_fullscreen = [None, Some("false"), Some("true")];
let want_fullscreen = [
WantFullscreen::No,