kms: Dmabuf feedback support
This commit is contained in:
parent
636d38921a
commit
bc49507353
8 changed files with 267 additions and 36 deletions
100
src/state.rs
100
src/state.rs
|
|
@ -1,7 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{
|
||||
backend::{kms::KmsState, winit::WinitState, x11::X11State},
|
||||
backend::{
|
||||
kms::{source_node_for_surface, KmsState},
|
||||
winit::WinitState,
|
||||
x11::X11State,
|
||||
},
|
||||
config::{Config, OutputConfig},
|
||||
shell::{layout::floating::SeatMoveGrabState, Shell},
|
||||
utils::prelude::*,
|
||||
|
|
@ -20,15 +24,18 @@ use smithay::{
|
|||
backend::{
|
||||
drm::DrmNode,
|
||||
renderer::{
|
||||
element::{default_primary_scanout_output_compare, RenderElementStates},
|
||||
element::{
|
||||
default_primary_scanout_output_compare, utils::select_dmabuf_feedback,
|
||||
RenderElementStates,
|
||||
},
|
||||
glow::GlowRenderer,
|
||||
},
|
||||
},
|
||||
desktop::utils::{
|
||||
send_frames_surface_tree, surface_presentation_feedback_flags_from_states,
|
||||
surface_primary_scanout_output, take_presentation_feedback_surface_tree,
|
||||
update_surface_primary_scanout_output, with_surfaces_surface_tree,
|
||||
OutputPresentationFeedback,
|
||||
send_dmabuf_feedback_surface_tree, send_frames_surface_tree,
|
||||
surface_presentation_feedback_flags_from_states, surface_primary_scanout_output,
|
||||
take_presentation_feedback_surface_tree, update_surface_primary_scanout_output,
|
||||
with_surfaces_surface_tree, OutputPresentationFeedback,
|
||||
},
|
||||
input::{pointer::CursorImageStatus, Seat, SeatState},
|
||||
output::{Mode as OutputMode, Output, Scale},
|
||||
|
|
@ -45,11 +52,12 @@ use smithay::{
|
|||
wayland::{
|
||||
compositor::CompositorState,
|
||||
data_device::DataDeviceState,
|
||||
dmabuf::DmabufState,
|
||||
dmabuf::{DmabufFeedback, DmabufState},
|
||||
keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState,
|
||||
output::OutputManagerState,
|
||||
presentation::PresentationState,
|
||||
primary_selection::PrimarySelectionState,
|
||||
seat::WaylandFocus,
|
||||
shell::{kde::decoration::KdeDecorationState, xdg::decoration::XdgDecorationState},
|
||||
shm::ShmState,
|
||||
viewporter::ViewporterState,
|
||||
|
|
@ -130,6 +138,12 @@ pub enum BackendData {
|
|||
Unset,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SurfaceDmabufFeedback {
|
||||
pub render_feedback: DmabufFeedback,
|
||||
pub scanout_feedback: DmabufFeedback,
|
||||
}
|
||||
|
||||
impl BackendData {
|
||||
pub fn kms(&mut self) -> &mut KmsState {
|
||||
match self {
|
||||
|
|
@ -363,7 +377,12 @@ impl Common {
|
|||
self.last_active_seat.as_ref().expect("No seat?")
|
||||
}
|
||||
|
||||
pub fn send_frames(&self, output: &Output, render_element_states: &RenderElementStates) {
|
||||
pub fn send_frames(
|
||||
&self,
|
||||
output: &Output,
|
||||
render_element_states: &RenderElementStates,
|
||||
mut dmabuf_feedback: impl FnMut(DrmNode) -> Option<SurfaceDmabufFeedback>,
|
||||
) {
|
||||
let time = self.clock.now();
|
||||
let throttle = Some(Duration::from_secs(1));
|
||||
|
||||
|
|
@ -401,6 +420,21 @@ impl Common {
|
|||
throttle,
|
||||
surface_primary_scanout_output,
|
||||
);
|
||||
let window = grab_state.window();
|
||||
if let Some(feedback) = window
|
||||
.wl_surface()
|
||||
.and_then(|wl_surface| {
|
||||
source_node_for_surface(&wl_surface, &self.display_handle)
|
||||
})
|
||||
.and_then(|source| dmabuf_feedback(source))
|
||||
{
|
||||
window.send_dmabuf_feedback(
|
||||
output,
|
||||
&feedback,
|
||||
render_element_states,
|
||||
surface_primary_scanout_output,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -432,6 +466,20 @@ impl Common {
|
|||
);
|
||||
});
|
||||
window.send_frame(output, time, throttle, surface_primary_scanout_output);
|
||||
if let Some(feedback) = window
|
||||
.wl_surface()
|
||||
.and_then(|wl_surface| {
|
||||
source_node_for_surface(&wl_surface, &self.display_handle)
|
||||
})
|
||||
.and_then(|source| dmabuf_feedback(source))
|
||||
{
|
||||
window.send_dmabuf_feedback(
|
||||
output,
|
||||
&feedback,
|
||||
render_element_states,
|
||||
surface_primary_scanout_output,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -466,7 +514,24 @@ impl Common {
|
|||
time,
|
||||
throttle,
|
||||
surface_primary_scanout_output,
|
||||
)
|
||||
);
|
||||
if let Some(feedback) = source_node_for_surface(&wl_surface, &self.display_handle)
|
||||
.and_then(|source| dmabuf_feedback(source))
|
||||
{
|
||||
send_dmabuf_feedback_surface_tree(
|
||||
&wl_surface,
|
||||
output,
|
||||
surface_primary_scanout_output,
|
||||
|surface, _| {
|
||||
select_dmabuf_feedback(
|
||||
surface,
|
||||
render_element_states,
|
||||
&feedback.render_feedback,
|
||||
&feedback.scanout_feedback,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -482,6 +547,23 @@ impl Common {
|
|||
);
|
||||
});
|
||||
layer_surface.send_frame(output, time, throttle, surface_primary_scanout_output);
|
||||
if let Some(feedback) =
|
||||
source_node_for_surface(layer_surface.wl_surface(), &self.display_handle)
|
||||
.and_then(|source| dmabuf_feedback(source))
|
||||
{
|
||||
layer_surface.send_dmabuf_feedback(
|
||||
output,
|
||||
surface_primary_scanout_output,
|
||||
|surface, _| {
|
||||
select_dmabuf_feedback(
|
||||
surface,
|
||||
render_element_states,
|
||||
&feedback.render_feedback,
|
||||
&feedback.scanout_feedback,
|
||||
)
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue