Skip to content

Commit

Permalink
Merge pull request #268 from pinnacle-comp/render_improvements
Browse files Browse the repository at this point in the history
Rendering improvements
  • Loading branch information
Ottatop authored Aug 14, 2024
2 parents 8776281 + 15000cd commit 65f2dce
Show file tree
Hide file tree
Showing 17 changed files with 912 additions and 530 deletions.
18 changes: 0 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ anyhow = { version = "1.0.86", features = ["backtrace"] }
thiserror = "1.0.61"
# xcursor stuff
xcursor = { version = "0.3.5" }
image = { version = "0.25.1", default-features = false }
# gRPC
prost = { workspace = true }
tonic = { workspace = true }
Expand Down
4 changes: 3 additions & 1 deletion src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,9 @@ impl output_service_server::OutputService for OutputService {
return;
};

state.backend.set_output_powered(&output, powered);
state
.backend
.set_output_powered(&output, &state.pinnacle.loop_handle, powered);

if powered {
state.schedule_render(&output);
Expand Down
160 changes: 32 additions & 128 deletions src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,20 @@
// SPDX-License-Identifier: GPL-3.0-or-later

use std::time::Duration;

use smithay::{
backend::{
allocator::dmabuf::Dmabuf,
renderer::{
element::{
default_primary_scanout_output_compare, utils::select_dmabuf_feedback,
RenderElementStates,
},
gles::GlesRenderer,
ImportDma, Renderer, TextureFilter,
},
renderer::{gles::GlesRenderer, ImportDma, Renderer, TextureFilter},
},
delegate_dmabuf,
desktop::{
layer_map_for_output,
utils::{
send_frames_surface_tree, surface_primary_scanout_output,
update_surface_primary_scanout_output,
},
Space,
},
input::pointer::CursorImageStatus,
output::Output,
reexports::wayland_server::protocol::wl_surface::WlSurface,
wayland::{
dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier},
fractional_scale::with_fractional_scale,
},
reexports::{calloop::LoopHandle, wayland_server::protocol::wl_surface::WlSurface},
wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier},
};
use tracing::error;

use crate::{
output::OutputMode,
state::{Pinnacle, State, SurfaceDmabufFeedback, WithState},
window::WindowElement,
state::{Pinnacle, State},
};

#[cfg(feature = "testing")]
Expand Down Expand Up @@ -120,15 +98,34 @@ impl Backend {
}
}

pub fn set_output_powered(&mut self, output: &Output, powered: bool) {
pub fn set_output_powered(
&mut self,
output: &Output,
loop_handle: &LoopHandle<'static, State>,
powered: bool,
) {
match self {
Backend::Winit(_) => (),
Backend::Udev(udev) => udev.set_output_powered(output, powered),
Backend::Udev(udev) => udev.set_output_powered(output, loop_handle, powered),
#[cfg(feature = "testing")]
Backend::Dummy(dummy) => dummy.set_output_powered(output, powered),
}
}

pub fn render_scheduled_outputs(&mut self, pinnacle: &mut Pinnacle) {
if let Backend::Udev(udev) = self {
for output in pinnacle
.outputs
.iter()
.filter(|(_, global)| global.is_some())
.map(|(op, _)| op.clone())
.collect::<Vec<_>>()
{
udev.render_if_scheduled(pinnacle, &output);
}
}
}

/// Returns `true` if the backend is [`Winit`].
///
/// [`Winit`]: Backend::Winit
Expand All @@ -146,6 +143,13 @@ impl Backend {
}
}

#[derive(Debug, Clone, Copy)]
pub enum RenderResult {
Submitted,
NoDamage,
Skipped,
}

pub trait BackendData: 'static {
fn seat_name(&self) -> String;
fn reset_buffers(&mut self, output: &Output);
Expand Down Expand Up @@ -194,106 +198,6 @@ impl BackendData for Backend {
}
}

/// Update surface primary scanout outputs and send frames and dmabuf feedback to visible windows
/// and layers.
pub fn post_repaint(
output: &Output,
render_element_states: &RenderElementStates,
space: &Space<WindowElement>,
dmabuf_feedback: Option<SurfaceDmabufFeedback<'_>>,
time: Duration,
cursor_status: &CursorImageStatus,
) {
// let throttle = Some(Duration::from_secs(1));
let throttle = Some(Duration::ZERO);

space.elements().for_each(|window| {
window.with_surfaces(|surface, states_inner| {
let primary_scanout_output = update_surface_primary_scanout_output(
surface,
output,
states_inner,
render_element_states,
default_primary_scanout_output_compare,
);

if let Some(output) = primary_scanout_output {
with_fractional_scale(states_inner, |fraction_scale| {
fraction_scale.set_preferred_scale(output.current_scale().fractional_scale());
});
}
});

if space.outputs_for_element(window).contains(output) {
window.send_frame(output, time, throttle, surface_primary_scanout_output);
if let Some(dmabuf_feedback) = dmabuf_feedback {
window.send_dmabuf_feedback(
output,
surface_primary_scanout_output,
|surface, _| {
select_dmabuf_feedback(
surface,
render_element_states,
dmabuf_feedback.render_feedback,
dmabuf_feedback.scanout_feedback,
)
},
);
}
}
});

let map = layer_map_for_output(output);
for layer_surface in map.layers() {
layer_surface.with_surfaces(|surface, states| {
let primary_scanout_output = update_surface_primary_scanout_output(
surface,
output,
states,
render_element_states,
default_primary_scanout_output_compare,
);

if let Some(output) = primary_scanout_output {
with_fractional_scale(states, |fraction_scale| {
fraction_scale.set_preferred_scale(output.current_scale().fractional_scale());
});
}
});

layer_surface.send_frame(output, time, throttle, surface_primary_scanout_output);
if let Some(dmabuf_feedback) = dmabuf_feedback {
layer_surface.send_dmabuf_feedback(
output,
surface_primary_scanout_output,
|surface, _| {
select_dmabuf_feedback(
surface,
render_element_states,
dmabuf_feedback.render_feedback,
dmabuf_feedback.scanout_feedback,
)
},
);
}
}

// Send frames to the cursor surface so it updates correctly
if let CursorImageStatus::Surface(surf) = cursor_status {
send_frames_surface_tree(surf, output, time, Some(Duration::ZERO), |_, _| None);
}

if let Some(lock_surface) = output.with_state(|state| state.lock_surface.clone()) {
send_frames_surface_tree(
lock_surface.wl_surface(),
output,
time,
Some(Duration::ZERO),
|_, _| None,
);
}
}

impl DmabufHandler for State {
fn dmabuf_state(&mut self) -> &mut DmabufState {
match &mut self.backend {
Expand Down
Loading

0 comments on commit 65f2dce

Please sign in to comment.