aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-09-03 15:15:55 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-09-03 15:15:55 +0400
commit95cbe2a636e89b4ccd24baa8420e02a519658efd (patch)
tree983d1b93844d378c6678cd89e99421331a15f8e4 /src/backend
parentcc1c9d93254df120fc1041e121cb3b5edd00ffc9 (diff)
downloadniri-95cbe2a636e89b4ccd24baa8420e02a519658efd.tar.gz
niri-95cbe2a636e89b4ccd24baa8420e02a519658efd.tar.bz2
niri-95cbe2a636e89b4ccd24baa8420e02a519658efd.zip
Send scanout feedbacks to surfaces
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/mod.rs3
-rw-r--r--src/backend/tty.rs40
-rw-r--r--src/backend/winit.rs5
3 files changed, 38 insertions, 10 deletions
diff --git a/src/backend/mod.rs b/src/backend/mod.rs
index d70ee2aa..8a59e6f3 100644
--- a/src/backend/mod.rs
+++ b/src/backend/mod.rs
@@ -1,5 +1,6 @@
use smithay::backend::renderer::gles::GlesRenderer;
use smithay::output::Output;
+use smithay::wayland::dmabuf::DmabufFeedback;
use crate::input::CompositorMod;
use crate::niri::OutputRenderElements;
@@ -43,7 +44,7 @@ impl Backend {
niri: &mut Niri,
output: &Output,
elements: &[OutputRenderElements<GlesRenderer>],
- ) {
+ ) -> Option<&DmabufFeedback> {
match self {
Backend::Tty(tty) => tty.render(niri, output, elements),
Backend::Winit(winit) => winit.render(niri, output, elements),
diff --git a/src/backend/tty.rs b/src/backend/tty.rs
index 2db762fc..e5555984 100644
--- a/src/backend/tty.rs
+++ b/src/backend/tty.rs
@@ -25,9 +25,10 @@ use smithay::reexports::drm::control::{
use smithay::reexports::input::Libinput;
use smithay::reexports::nix::fcntl::OFlag;
use smithay::reexports::nix::libc::dev_t;
+use smithay::reexports::wayland_protocols::wp::linux_dmabuf::zv1::server::zwp_linux_dmabuf_feedback_v1::TrancheFlags;
use smithay::reexports::wayland_protocols::wp::presentation_time::server::wp_presentation_feedback;
use smithay::utils::DeviceFd;
-use smithay::wayland::dmabuf::{DmabufFeedbackBuilder, DmabufGlobal, DmabufState};
+use smithay::wayland::dmabuf::{DmabufFeedbackBuilder, DmabufGlobal, DmabufState, DmabufFeedback};
use smithay_drm_extras::drm_scanner::{DrmScanEvent, DrmScanner};
use smithay_drm_extras::edid::EdidInfo;
@@ -59,7 +60,7 @@ struct OutputDevice {
gles: GlesRenderer,
formats: HashSet<DrmFormat>,
drm_scanner: DrmScanner,
- surfaces: HashMap<crtc::Handle, GbmDrmCompositor>,
+ surfaces: HashMap<crtc::Handle, (GbmDrmCompositor, DmabufFeedback)>,
dmabuf_state: DmabufState,
dmabuf_global: DmabufGlobal,
}
@@ -274,7 +275,7 @@ impl Tty {
trace!("vblank {metadata:?}");
let device = tty.output_device.as_mut().unwrap();
- let drm_compositor = device.surfaces.get_mut(&crtc).unwrap();
+ let drm_compositor = &mut device.surfaces.get_mut(&crtc).unwrap().0;
let presentation_time = match metadata.as_mut().unwrap().time {
DrmEventTime::Monotonic(time) => time,
@@ -479,6 +480,20 @@ impl Tty {
crtc,
});
+ let planes = surface.planes().unwrap();
+ let scanout_formats = surface
+ .supported_formats(planes.primary.handle)
+ .unwrap()
+ .into_iter()
+ .chain(
+ planes
+ .overlay
+ .into_iter()
+ .flat_map(|p| surface.supported_formats(p.handle).unwrap()),
+ )
+ .collect::<HashSet<_>>();
+ let scanout_formats = scanout_formats.intersection(&device.formats).copied();
+
// Create the compositor.
let compositor = DrmCompositor::new(
OutputModeSource::Auto(output.clone()),
@@ -492,7 +507,12 @@ impl Tty {
Some(device.gbm.clone()),
)?;
- let res = device.surfaces.insert(crtc, compositor);
+ let dmabuf_feedback = DmabufFeedbackBuilder::new(device.id, device.formats.clone())
+ .add_preference_tranche(device.id, Some(TrancheFlags::Scanout), scanout_formats)
+ .build()
+ .unwrap();
+
+ let res = device.surfaces.insert(crtc, (compositor, dmabuf_feedback));
assert!(res.is_none(), "crtc must not have already existed");
niri.add_output(output.clone(), Some(refresh_interval(*mode)));
@@ -541,12 +561,12 @@ impl Tty {
niri: &mut Niri,
output: &Output,
elements: &[OutputRenderElements<GlesRenderer>],
- ) {
+ ) -> Option<&DmabufFeedback> {
let _span = tracy_client::span!("Tty::render");
let device = self.output_device.as_mut().unwrap();
let tty_state: &TtyOutputState = output.user_data().get().unwrap();
- let drm_compositor = device.surfaces.get_mut(&tty_state.crtc).unwrap();
+ let (drm_compositor, dmabuf_feedback) = device.surfaces.get_mut(&tty_state.crtc).unwrap();
match drm_compositor.render_frame::<_, _, GlesTexture>(
&mut device.gles,
@@ -564,7 +584,9 @@ impl Tty {
niri.output_state
.get_mut(output)
.unwrap()
- .waiting_for_vblank = true
+ .waiting_for_vblank = true;
+
+ return Some(dmabuf_feedback);
}
Err(err) => {
error!("error queueing frame: {err}");
@@ -577,6 +599,8 @@ impl Tty {
error!("error rendering frame: {err}");
}
}
+
+ None
}
pub fn change_vt(&mut self, vt: i32) {
@@ -593,7 +617,7 @@ impl Tty {
pub fn toggle_debug_tint(&mut self) {
if let Some(device) = self.output_device.as_mut() {
- for (_, compositor) in &mut device.surfaces {
+ for (_, (compositor, _)) in &mut device.surfaces {
compositor.set_debug_flags(compositor.debug_flags() ^ DebugFlags::TINT);
}
}
diff --git a/src/backend/winit.rs b/src/backend/winit.rs
index 767bf7f4..dc2e8bc6 100644
--- a/src/backend/winit.rs
+++ b/src/backend/winit.rs
@@ -11,6 +11,7 @@ use smithay::reexports::wayland_protocols::wp::presentation_time::server::wp_pre
use smithay::reexports::winit::dpi::LogicalSize;
use smithay::reexports::winit::window::WindowBuilder;
use smithay::utils::Transform;
+use smithay::wayland::dmabuf::DmabufFeedback;
use crate::niri::OutputRenderElements;
use crate::utils::get_monotonic_time;
@@ -129,7 +130,7 @@ impl Winit {
niri: &mut Niri,
output: &Output,
elements: &[OutputRenderElements<GlesRenderer>],
- ) {
+ ) -> Option<&DmabufFeedback> {
let _span = tracy_client::span!("Winit::render");
self.backend.bind().unwrap();
@@ -152,6 +153,8 @@ impl Winit {
self.backend.window().request_redraw();
}
+
+ None
}
pub fn toggle_debug_tint(&mut self) {