diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-01-03 18:16:20 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-01-03 18:16:20 +0400 |
| commit | 5cd31e5730160f9162502d2388dc00400c7a87ae (patch) | |
| tree | a718ad47e0554263042ae4eebd5e49af34346732 /src/niri.rs | |
| parent | de3fc2def0cf3683fff7994cd294d325e4f033b2 (diff) | |
| download | niri-5cd31e5730160f9162502d2388dc00400c7a87ae.tar.gz niri-5cd31e5730160f9162502d2388dc00400c7a87ae.tar.bz2 niri-5cd31e5730160f9162502d2388dc00400c7a87ae.zip | |
Implement multi-GPU support
Rendering always happens on the primary GPU.
Diffstat (limited to 'src/niri.rs')
| -rw-r--r-- | src/niri.rs | 103 |
1 files changed, 96 insertions, 7 deletions
diff --git a/src/niri.rs b/src/niri.rs index d251ef6b..52cb41fa 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -16,6 +16,7 @@ use smithay::backend::renderer::element::surface::{ render_elements_from_surface_tree, WaylandSurfaceRenderElement, }; use smithay::backend::renderer::element::texture::TextureRenderElement; +use smithay::backend::renderer::element::utils::select_dmabuf_feedback; use smithay::backend::renderer::element::{ default_primary_scanout_output_compare, AsRenderElements, Element, Id, Kind, RenderElement, RenderElementStates, UnderlyingStorage, @@ -61,7 +62,7 @@ use smithay::wayland::compositor::{ CompositorState, SurfaceData, TraversalAction, }; use smithay::wayland::cursor_shape::CursorShapeManagerState; -use smithay::wayland::dmabuf::{DmabufFeedback, DmabufState}; +use smithay::wayland::dmabuf::DmabufState; use smithay::wayland::input_method::InputMethodManagerState; use smithay::wayland::output::OutputManagerState; use smithay::wayland::pointer_constraints::{with_pointer_constraint, PointerConstraintsState}; @@ -83,6 +84,7 @@ use smithay::wayland::text_input::TextInputManagerState; use smithay::wayland::virtual_keyboard::VirtualKeyboardManagerState; use crate::animation; +use crate::backend::tty::{SurfaceDmabufFeedback, TtyFrame, TtyRenderer, TtyRendererError}; use crate::backend::{Backend, RenderResult, Tty, Winit}; use crate::config::{Config, TrackLayout}; use crate::cursor::{CursorManager, CursorTextureCache, RenderCursor, XCursor}; @@ -1829,18 +1831,45 @@ impl Niri { } } - pub fn send_dmabuf_feedbacks(&self, output: &Output, feedback: &DmabufFeedback) { + pub fn send_dmabuf_feedbacks( + &self, + output: &Output, + feedback: &SurfaceDmabufFeedback, + render_element_states: &RenderElementStates, + ) { let _span = tracy_client::span!("Niri::send_dmabuf_feedbacks"); // We can unconditionally send the current output's feedback to regular and layer-shell // surfaces, as they can only be displayed on a single output at a time. Even if a surface // is currently invisible, this is the DMABUF feedback that it should know about. for win in self.layout.windows_for_output(output) { - win.send_dmabuf_feedback(output, |_, _| Some(output.clone()), |_, _| feedback); + win.send_dmabuf_feedback( + output, + |_, _| Some(output.clone()), + |surface, _| { + select_dmabuf_feedback( + surface, + render_element_states, + &feedback.render, + &feedback.scanout, + ) + }, + ); } for surface in layer_map_for_output(output).layers() { - surface.send_dmabuf_feedback(output, |_, _| Some(output.clone()), |_, _| feedback); + surface.send_dmabuf_feedback( + output, + |_, _| Some(output.clone()), + |surface, _| { + select_dmabuf_feedback( + surface, + render_element_states, + &feedback.render, + &feedback.scanout, + ) + }, + ); } if let Some(surface) = &self.output_state[output].lock_surface { @@ -1848,7 +1877,14 @@ impl Niri { surface.wl_surface(), output, |_, _| Some(output.clone()), - |_, _| feedback, + |surface, _| { + select_dmabuf_feedback( + surface, + render_element_states, + &feedback.render, + &feedback.scanout, + ) + }, ); } @@ -1857,7 +1893,14 @@ impl Niri { surface, output, surface_primary_scanout_output, - |_, _| feedback, + |surface, _| { + select_dmabuf_feedback( + surface, + render_element_states, + &feedback.render, + &feedback.scanout, + ) + }, ); } @@ -1866,7 +1909,14 @@ impl Niri { surface, output, surface_primary_scanout_output, - |_, _| feedback, + |surface, _| { + select_dmabuf_feedback( + surface, + render_element_states, + &feedback.render, + &feedback.scanout, + ) + }, ); } } @@ -2642,6 +2692,45 @@ impl RenderElement<GlesRenderer> for OutputRenderElements<GlesRenderer> { } } +impl<'render, 'alloc> RenderElement<TtyRenderer<'render, 'alloc>> + for OutputRenderElements<TtyRenderer<'render, 'alloc>> +{ + fn draw( + &self, + frame: &mut TtyFrame<'render, 'alloc, '_>, + src: Rectangle<f64, Buffer>, + dst: Rectangle<i32, Physical>, + damage: &[Rectangle<i32, Physical>], + ) -> Result<(), TtyRendererError<'render, 'alloc>> { + match self { + Self::Monitor(elem) => elem.draw(frame, src, dst, damage), + Self::Wayland(elem) => elem.draw(frame, src, dst, damage), + Self::NamedPointer(elem) => { + RenderElement::<TtyRenderer<'render, 'alloc>>::draw(&elem, frame, src, dst, damage) + } + Self::SolidColor(elem) => { + RenderElement::<TtyRenderer<'render, 'alloc>>::draw(&elem, frame, src, dst, damage) + } + Self::ScreenshotUi(elem) => { + RenderElement::<TtyRenderer<'render, 'alloc>>::draw(&elem, frame, src, dst, damage) + } + } + } + + fn underlying_storage( + &self, + renderer: &mut TtyRenderer<'render, 'alloc>, + ) -> Option<UnderlyingStorage> { + match self { + Self::Monitor(elem) => elem.underlying_storage(renderer), + Self::Wayland(elem) => elem.underlying_storage(renderer), + Self::NamedPointer(elem) => elem.underlying_storage(renderer), + Self::SolidColor(elem) => elem.underlying_storage(renderer), + Self::ScreenshotUi(elem) => elem.underlying_storage(renderer), + } + } +} + impl<R: NiriRenderer> From<MonitorRenderElement<R>> for OutputRenderElements<R> { fn from(x: MonitorRenderElement<R>) -> Self { Self::Monitor(x) |
