Update for Smithay MultiGpu shadow copies

This commit is contained in:
Ivan Molodetskikh
2024-02-18 16:43:33 +04:00
parent 2b5eeb6162
commit d8fb8d5ef0
7 changed files with 39 additions and 62 deletions
Generated
+4 -4
View File
@@ -1196,9 +1196,9 @@ dependencies = [
[[package]] [[package]]
name = "gbm" name = "gbm"
version = "0.14.1" version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f177420f6650dcd50042121adf7ff7ab265abdaf4862fe2624066e36e3a9ef34" checksum = "313702b30cdeb83ddc72bc14dcee67803cd0ae2d12282ea06e368c25a900c844"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"drm", "drm",
@@ -3007,7 +3007,7 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]] [[package]]
name = "smithay" name = "smithay"
version = "0.3.0" version = "0.3.0"
source = "git+https://github.com/Smithay/smithay.git#832dee8586d783d4c60a162ef8aabca2ba7fd499" source = "git+https://github.com/Smithay/smithay.git#3de7636e6cb562a1b9f14c76e17b0e4b27381c22"
dependencies = [ dependencies = [
"appendlist", "appendlist",
"bitflags 2.4.2", "bitflags 2.4.2",
@@ -3079,7 +3079,7 @@ dependencies = [
[[package]] [[package]]
name = "smithay-drm-extras" name = "smithay-drm-extras"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/Smithay/smithay.git#832dee8586d783d4c60a162ef8aabca2ba7fd499" source = "git+https://github.com/Smithay/smithay.git#3de7636e6cb562a1b9f14c76e17b0e4b27381c22"
dependencies = [ dependencies = [
"drm", "drm",
"edid-rs", "edid-rs",
+13 -31
View File
@@ -10,7 +10,7 @@ use std::{io, mem};
use anyhow::{anyhow, Context}; use anyhow::{anyhow, Context};
use libc::dev_t; use libc::dev_t;
use niri_config::Config; use niri_config::Config;
use smithay::backend::allocator::dmabuf::{Dmabuf, DmabufAllocator}; use smithay::backend::allocator::dmabuf::Dmabuf;
use smithay::backend::allocator::gbm::{GbmAllocator, GbmBufferFlags, GbmDevice}; use smithay::backend::allocator::gbm::{GbmAllocator, GbmBufferFlags, GbmDevice};
use smithay::backend::allocator::{Format, Fourcc}; use smithay::backend::allocator::{Format, Fourcc};
use smithay::backend::drm::compositor::{DrmCompositor, PrimaryPlaneElement}; use smithay::backend::drm::compositor::{DrmCompositor, PrimaryPlaneElement};
@@ -62,7 +62,7 @@ pub struct Tty {
session: LibSeatSession, session: LibSeatSession,
udev_dispatcher: Dispatcher<'static, UdevBackend, State>, udev_dispatcher: Dispatcher<'static, UdevBackend, State>,
libinput: Libinput, libinput: Libinput,
gpu_manager: GpuManager<GbmGlesBackend<GlesRenderer>>, gpu_manager: GpuManager<GbmGlesBackend<GlesRenderer, DrmDeviceFd>>,
// DRM node corresponding to the primary GPU. May or may not be the same as // DRM node corresponding to the primary GPU. May or may not be the same as
// primary_render_node. // primary_render_node.
primary_node: DrmNode, primary_node: DrmNode,
@@ -73,33 +73,28 @@ pub struct Tty {
// The dma-buf global corresponds to the output device (the primary GPU). It is only `Some()` // The dma-buf global corresponds to the output device (the primary GPU). It is only `Some()`
// if we have a device corresponding to the primary GPU. // if we have a device corresponding to the primary GPU.
dmabuf_global: Option<DmabufGlobal>, dmabuf_global: Option<DmabufGlobal>,
// The allocator for the primary GPU. It is only `Some()` if we have a device corresponding to
// the primary GPU.
primary_allocator: Option<DmabufAllocator<GbmAllocator<DrmDeviceFd>>>,
// The output config had changed, but the session is paused, so we need to update it on resume. // The output config had changed, but the session is paused, so we need to update it on resume.
update_output_config_on_resume: bool, update_output_config_on_resume: bool,
ipc_outputs: Rc<RefCell<HashMap<String, niri_ipc::Output>>>, ipc_outputs: Rc<RefCell<HashMap<String, niri_ipc::Output>>>,
enabled_outputs: Arc<Mutex<HashMap<String, Output>>>, enabled_outputs: Arc<Mutex<HashMap<String, Output>>>,
} }
pub type TtyRenderer<'render, 'alloc> = MultiRenderer< pub type TtyRenderer<'render> = MultiRenderer<
'render, 'render,
'render, 'render,
'alloc, GbmGlesBackend<GlesRenderer, DrmDeviceFd>,
GbmGlesBackend<GlesRenderer>, GbmGlesBackend<GlesRenderer, DrmDeviceFd>,
GbmGlesBackend<GlesRenderer>,
>; >;
pub type TtyFrame<'render, 'alloc, 'frame> = MultiFrame< pub type TtyFrame<'render, 'frame> = MultiFrame<
'render, 'render,
'render, 'render,
'alloc,
'frame, 'frame,
GbmGlesBackend<GlesRenderer>, GbmGlesBackend<GlesRenderer, DrmDeviceFd>,
GbmGlesBackend<GlesRenderer>, GbmGlesBackend<GlesRenderer, DrmDeviceFd>,
>; >;
pub type TtyRendererError<'render, 'alloc> = <TtyRenderer<'render, 'alloc> as Renderer>::Error; pub type TtyRendererError<'render> = <TtyRenderer<'render> as Renderer>::Error;
type GbmDrmCompositor = DrmCompositor< type GbmDrmCompositor = DrmCompositor<
GbmAllocator<DrmDeviceFd>, GbmAllocator<DrmDeviceFd>,
@@ -276,7 +271,6 @@ impl Tty {
primary_render_node, primary_render_node,
devices: HashMap::new(), devices: HashMap::new(),
dmabuf_global: None, dmabuf_global: None,
primary_allocator: None,
update_output_config_on_resume: false, update_output_config_on_resume: false,
ipc_outputs: Rc::new(RefCell::new(HashMap::new())), ipc_outputs: Rc::new(RefCell::new(HashMap::new())),
enabled_outputs: Arc::new(Mutex::new(HashMap::new())), enabled_outputs: Arc::new(Mutex::new(HashMap::new())),
@@ -460,11 +454,6 @@ impl Tty {
); );
assert!(self.dmabuf_global.replace(dmabuf_global).is_none()); assert!(self.dmabuf_global.replace(dmabuf_global).is_none());
// Create the primary allocator.
let primary_allocator =
DmabufAllocator(GbmAllocator::new(gbm.clone(), GbmBufferFlags::RENDERING));
assert!(self.primary_allocator.replace(primary_allocator).is_none());
// Update the dmabuf feedbacks for all surfaces. // Update the dmabuf feedbacks for all surfaces.
for device in self.devices.values_mut() { for device in self.devices.values_mut() {
for surface in device.surfaces.values_mut() { for surface in device.surfaces.values_mut() {
@@ -600,8 +589,6 @@ impl Tty {
) )
.unwrap(); .unwrap();
self.primary_allocator = None;
// Clear the dmabuf feedbacks for all surfaces. // Clear the dmabuf feedbacks for all surfaces.
for device in self.devices.values_mut() { for device in self.devices.values_mut() {
for surface in device.surfaces.values_mut() { for surface in device.surfaces.values_mut() {
@@ -1088,15 +1075,9 @@ impl Tty {
return rv; return rv;
} }
let Some(allocator) = self.primary_allocator.as_mut() else {
warn!("no primary allocator");
return rv;
};
let mut renderer = match self.gpu_manager.renderer( let mut renderer = match self.gpu_manager.renderer(
&self.primary_render_node, &self.primary_render_node,
&device.render_node, &device.render_node,
allocator,
surface.compositor.format(), surface.compositor.format(),
) { ) {
Ok(renderer) => renderer, Ok(renderer) => renderer,
@@ -1208,7 +1189,10 @@ impl Tty {
}; };
match renderer.import_dmabuf(dmabuf, None) { match renderer.import_dmabuf(dmabuf, None) {
Ok(_texture) => true, Ok(_texture) => {
dmabuf.set_node(Some(self.primary_render_node));
true
}
Err(err) => { Err(err) => {
debug!("error importing dmabuf: {err:?}"); debug!("error importing dmabuf: {err:?}");
false false
@@ -1218,8 +1202,6 @@ impl Tty {
pub fn early_import(&mut self, surface: &WlSurface) { pub fn early_import(&mut self, surface: &WlSurface) {
if let Err(err) = self.gpu_manager.early_import( if let Err(err) = self.gpu_manager.early_import(
// We always advertise the primary GPU in dmabuf feedback.
Some(self.primary_render_node),
// We always render on the primary GPU. // We always render on the primary GPU.
self.primary_render_node, self.primary_render_node,
surface, surface,
+4 -7
View File
@@ -188,14 +188,14 @@ impl RenderElement<GlesRenderer> for OffscreenRenderElement {
} }
} }
impl<'render, 'alloc> RenderElement<TtyRenderer<'render, 'alloc>> for OffscreenRenderElement { impl<'render> RenderElement<TtyRenderer<'render>> for OffscreenRenderElement {
fn draw( fn draw(
&self, &self,
frame: &mut TtyFrame<'_, '_, '_>, frame: &mut TtyFrame<'_, '_>,
src: Rectangle<f64, Buffer>, src: Rectangle<f64, Buffer>,
dst: Rectangle<i32, Physical>, dst: Rectangle<i32, Physical>,
damage: &[Rectangle<i32, Physical>], damage: &[Rectangle<i32, Physical>],
) -> Result<(), TtyRendererError<'render, 'alloc>> { ) -> Result<(), TtyRendererError<'render>> {
let gles_frame = frame.as_gles_frame(); let gles_frame = frame.as_gles_frame();
if let Some(texture) = &self.texture { if let Some(texture) = &self.texture {
RenderElement::<GlesRenderer>::draw(texture, gles_frame, src, dst, damage)?; RenderElement::<GlesRenderer>::draw(texture, gles_frame, src, dst, damage)?;
@@ -205,10 +205,7 @@ impl<'render, 'alloc> RenderElement<TtyRenderer<'render, 'alloc>> for OffscreenR
Ok(()) Ok(())
} }
fn underlying_storage( fn underlying_storage(&self, renderer: &mut TtyRenderer<'render>) -> Option<UnderlyingStorage> {
&self,
renderer: &mut TtyRenderer<'render, 'alloc>,
) -> Option<UnderlyingStorage> {
if let Some(texture) = &self.texture { if let Some(texture) = &self.texture {
texture.underlying_storage(renderer) texture.underlying_storage(renderer)
} else { } else {
+4 -6
View File
@@ -73,16 +73,14 @@ impl RenderElement<GlesRenderer> for PrimaryGpuTextureRenderElement {
} }
} }
impl<'render, 'alloc> RenderElement<TtyRenderer<'render, 'alloc>> impl<'render> RenderElement<TtyRenderer<'render>> for PrimaryGpuTextureRenderElement {
for PrimaryGpuTextureRenderElement
{
fn draw( fn draw(
&self, &self,
frame: &mut TtyFrame<'_, '_, '_>, frame: &mut TtyFrame<'_, '_>,
src: Rectangle<f64, Buffer>, src: Rectangle<f64, Buffer>,
dst: Rectangle<i32, Physical>, dst: Rectangle<i32, Physical>,
damage: &[Rectangle<i32, Physical>], damage: &[Rectangle<i32, Physical>],
) -> Result<(), TtyRendererError<'render, 'alloc>> { ) -> Result<(), TtyRendererError<'render>> {
let gles_frame = frame.as_gles_frame(); let gles_frame = frame.as_gles_frame();
RenderElement::<GlesRenderer>::draw(&self.0, gles_frame, src, dst, damage)?; RenderElement::<GlesRenderer>::draw(&self.0, gles_frame, src, dst, damage)?;
Ok(()) Ok(())
@@ -90,7 +88,7 @@ impl<'render, 'alloc> RenderElement<TtyRenderer<'render, 'alloc>>
fn underlying_storage( fn underlying_storage(
&self, &self,
_renderer: &mut TtyRenderer<'render, 'alloc>, _renderer: &mut TtyRenderer<'render>,
) -> Option<UnderlyingStorage> { ) -> Option<UnderlyingStorage> {
// If scanout for things other than Wayland buffers is implemented, this will need to take // If scanout for things other than Wayland buffers is implemented, this will need to take
// the target GPU into account. // the target GPU into account.
+6 -6
View File
@@ -90,26 +90,26 @@ macro_rules! niri_render_elements {
} }
} }
impl<'render, 'alloc> smithay::backend::renderer::element::RenderElement<$crate::backend::tty::TtyRenderer<'render, 'alloc>> impl<'render> smithay::backend::renderer::element::RenderElement<$crate::backend::tty::TtyRenderer<'render>>
for $name<$crate::backend::tty::TtyRenderer<'render, 'alloc>> for $name<$crate::backend::tty::TtyRenderer<'render>>
{ {
fn draw( fn draw(
&self, &self,
frame: &mut $crate::backend::tty::TtyFrame<'render, 'alloc, '_>, frame: &mut $crate::backend::tty::TtyFrame<'render, '_>,
src: smithay::utils::Rectangle<f64, smithay::utils::Buffer>, src: smithay::utils::Rectangle<f64, smithay::utils::Buffer>,
dst: smithay::utils::Rectangle<i32, smithay::utils::Physical>, dst: smithay::utils::Rectangle<i32, smithay::utils::Physical>,
damage: &[smithay::utils::Rectangle<i32, smithay::utils::Physical>], damage: &[smithay::utils::Rectangle<i32, smithay::utils::Physical>],
) -> Result<(), $crate::backend::tty::TtyRendererError<'render, 'alloc>> { ) -> Result<(), $crate::backend::tty::TtyRendererError<'render>> {
match self { match self {
$($name::$variant(elem) => { $($name::$variant(elem) => {
smithay::backend::renderer::element::RenderElement::<$crate::backend::tty::TtyRenderer<'render, 'alloc>>::draw(elem, frame, src, dst, damage) smithay::backend::renderer::element::RenderElement::<$crate::backend::tty::TtyRenderer<'render>>::draw(elem, frame, src, dst, damage)
})+ })+
} }
} }
fn underlying_storage( fn underlying_storage(
&self, &self,
renderer: &mut $crate::backend::tty::TtyRenderer<'render, 'alloc>, renderer: &mut $crate::backend::tty::TtyRenderer<'render>,
) -> Option<smithay::backend::renderer::element::UnderlyingStorage> { ) -> Option<smithay::backend::renderer::element::UnderlyingStorage> {
match self { match self {
$($name::$variant(elem) => elem.underlying_storage(renderer)),+ $($name::$variant(elem) => elem.underlying_storage(renderer)),+
+2 -2
View File
@@ -46,7 +46,7 @@ impl AsGlesRenderer for GlesRenderer {
} }
} }
impl<'render, 'alloc> AsGlesRenderer for TtyRenderer<'render, 'alloc> { impl<'render> AsGlesRenderer for TtyRenderer<'render> {
fn as_gles_renderer(&mut self) -> &mut GlesRenderer { fn as_gles_renderer(&mut self) -> &mut GlesRenderer {
self.as_mut() self.as_mut()
} }
@@ -66,7 +66,7 @@ impl<'frame> AsGlesFrame<'frame> for GlesFrame<'frame> {
} }
} }
impl<'render, 'alloc, 'frame> AsGlesFrame<'frame> for TtyFrame<'render, 'alloc, 'frame> { impl<'render, 'frame> AsGlesFrame<'frame> for TtyFrame<'render, 'frame> {
fn as_gles_frame(&mut self) -> &mut GlesFrame<'frame> { fn as_gles_frame(&mut self) -> &mut GlesFrame<'frame> {
self.as_mut() self.as_mut()
} }
+6 -6
View File
@@ -547,27 +547,27 @@ impl RenderElement<GlesRenderer> for ScreenshotUiRenderElement {
} }
} }
impl<'render, 'alloc> RenderElement<TtyRenderer<'render, 'alloc>> for ScreenshotUiRenderElement { impl<'render> RenderElement<TtyRenderer<'render>> for ScreenshotUiRenderElement {
fn draw( fn draw(
&self, &self,
frame: &mut TtyFrame<'render, 'alloc, '_>, frame: &mut TtyFrame<'render, '_>,
src: Rectangle<f64, Buffer>, src: Rectangle<f64, Buffer>,
dst: Rectangle<i32, Physical>, dst: Rectangle<i32, Physical>,
damage: &[Rectangle<i32, Physical>], damage: &[Rectangle<i32, Physical>],
) -> Result<(), TtyRendererError<'render, 'alloc>> { ) -> Result<(), TtyRendererError<'render>> {
match self { match self {
Self::Screenshot(elem) => { Self::Screenshot(elem) => {
RenderElement::<TtyRenderer<'render, 'alloc>>::draw(&elem, frame, src, dst, damage) RenderElement::<TtyRenderer<'render>>::draw(&elem, frame, src, dst, damage)
} }
Self::SolidColor(elem) => { Self::SolidColor(elem) => {
RenderElement::<TtyRenderer<'render, 'alloc>>::draw(&elem, frame, src, dst, damage) RenderElement::<TtyRenderer<'render>>::draw(&elem, frame, src, dst, damage)
} }
} }
} }
fn underlying_storage( fn underlying_storage(
&self, &self,
_renderer: &mut TtyRenderer<'render, 'alloc>, _renderer: &mut TtyRenderer<'render>,
) -> Option<UnderlyingStorage> { ) -> Option<UnderlyingStorage> {
// If scanout for things other than Wayland buffers is implemented, this will need to take // If scanout for things other than Wayland buffers is implemented, this will need to take
// the target GPU into account. // the target GPU into account.