mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Move Niri::render() invocation to backends
This commit is contained in:
+2
-11
@@ -7,7 +7,6 @@ use smithay::backend::renderer::gles::GlesRenderer;
|
|||||||
use smithay::output::Output;
|
use smithay::output::Output;
|
||||||
|
|
||||||
use crate::input::CompositorMod;
|
use crate::input::CompositorMod;
|
||||||
use crate::niri::OutputRenderElements;
|
|
||||||
use crate::Niri;
|
use crate::Niri;
|
||||||
|
|
||||||
pub mod tty;
|
pub mod tty;
|
||||||
@@ -57,12 +56,11 @@ impl Backend {
|
|||||||
&mut self,
|
&mut self,
|
||||||
niri: &mut Niri,
|
niri: &mut Niri,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
elements: &[OutputRenderElements<GlesRenderer>],
|
|
||||||
target_presentation_time: Duration,
|
target_presentation_time: Duration,
|
||||||
) -> RenderResult {
|
) -> RenderResult {
|
||||||
match self {
|
match self {
|
||||||
Backend::Tty(tty) => tty.render(niri, output, elements, target_presentation_time),
|
Backend::Tty(tty) => tty.render(niri, output, target_presentation_time),
|
||||||
Backend::Winit(winit) => winit.render(niri, output, elements),
|
Backend::Winit(winit) => winit.render(niri, output),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,13 +118,6 @@ impl Backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_active(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Backend::Tty(tty) => tty.is_active(),
|
|
||||||
Backend::Winit(_) => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_monitors_active(&self, active: bool) {
|
pub fn set_monitors_active(&self, active: bool) {
|
||||||
match self {
|
match self {
|
||||||
Backend::Tty(tty) => tty.set_monitors_active(active),
|
Backend::Tty(tty) => tty.set_monitors_active(active),
|
||||||
|
|||||||
+13
-12
@@ -40,7 +40,7 @@ use wayland_protocols::wp::presentation_time::server::wp_presentation_feedback;
|
|||||||
|
|
||||||
use super::RenderResult;
|
use super::RenderResult;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::niri::{OutputRenderElements, RedrawState, State};
|
use crate::niri::{RedrawState, State};
|
||||||
use crate::utils::get_monotonic_time;
|
use crate::utils::get_monotonic_time;
|
||||||
use crate::Niri;
|
use crate::Niri;
|
||||||
|
|
||||||
@@ -868,7 +868,6 @@ impl Tty {
|
|||||||
&mut self,
|
&mut self,
|
||||||
niri: &mut Niri,
|
niri: &mut Niri,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
elements: &[OutputRenderElements<GlesRenderer>],
|
|
||||||
target_presentation_time: Duration,
|
target_presentation_time: Duration,
|
||||||
) -> RenderResult {
|
) -> RenderResult {
|
||||||
let span = tracy_client::span!("Tty::render");
|
let span = tracy_client::span!("Tty::render");
|
||||||
@@ -880,6 +879,11 @@ impl Tty {
|
|||||||
return rv;
|
return rv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !device.drm.is_active() {
|
||||||
|
warn!("device is inactive");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
let tty_state: &TtyOutputState = output.user_data().get().unwrap();
|
let tty_state: &TtyOutputState = output.user_data().get().unwrap();
|
||||||
let Some(surface) = device.surfaces.get_mut(&tty_state.crtc) else {
|
let Some(surface) = device.surfaces.get_mut(&tty_state.crtc) else {
|
||||||
error!("missing surface");
|
error!("missing surface");
|
||||||
@@ -888,9 +892,14 @@ impl Tty {
|
|||||||
|
|
||||||
span.emit_text(&surface.name);
|
span.emit_text(&surface.name);
|
||||||
|
|
||||||
|
let renderer = &mut device.gles;
|
||||||
|
|
||||||
|
// Render the elements.
|
||||||
|
let elements = niri.render(renderer, output, true);
|
||||||
|
|
||||||
|
// Hand them over to the DRM.
|
||||||
let drm_compositor = &mut surface.compositor;
|
let drm_compositor = &mut surface.compositor;
|
||||||
match drm_compositor.render_frame::<_, _, GlesTexture>(&mut device.gles, elements, [0.; 4])
|
match drm_compositor.render_frame::<_, _, GlesTexture>(renderer, &elements, [0.; 4]) {
|
||||||
{
|
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
if self
|
if self
|
||||||
.config
|
.config
|
||||||
@@ -995,14 +1004,6 @@ impl Tty {
|
|||||||
self.output_device.as_ref().map(|d| d.gbm.clone())
|
self.output_device.as_ref().map(|d| d.gbm.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_active(&self) -> bool {
|
|
||||||
let Some(device) = &self.output_device else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
device.drm.is_active()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_monitors_active(&self, active: bool) {
|
pub fn set_monitors_active(&self, active: bool) {
|
||||||
let Some(device) = &self.output_device else {
|
let Some(device) = &self.output_device else {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use smithay::utils::Transform;
|
|||||||
|
|
||||||
use super::RenderResult;
|
use super::RenderResult;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::niri::{OutputRenderElements, RedrawState, State};
|
use crate::niri::{RedrawState, State};
|
||||||
use crate::utils::get_monotonic_time;
|
use crate::utils::get_monotonic_time;
|
||||||
use crate::Niri;
|
use crate::Niri;
|
||||||
|
|
||||||
@@ -133,19 +133,18 @@ impl Winit {
|
|||||||
self.backend.renderer()
|
self.backend.renderer()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(
|
pub fn render(&mut self, niri: &mut Niri, output: &Output) -> RenderResult {
|
||||||
&mut self,
|
|
||||||
niri: &mut Niri,
|
|
||||||
output: &Output,
|
|
||||||
elements: &[OutputRenderElements<GlesRenderer>],
|
|
||||||
) -> RenderResult {
|
|
||||||
let _span = tracy_client::span!("Winit::render");
|
let _span = tracy_client::span!("Winit::render");
|
||||||
|
|
||||||
|
// Render the elements.
|
||||||
|
let elements = niri.render(self.backend.renderer(), output, true);
|
||||||
|
|
||||||
|
// Hand them over to winit.
|
||||||
self.backend.bind().unwrap();
|
self.backend.bind().unwrap();
|
||||||
let age = self.backend.buffer_age().unwrap();
|
let age = self.backend.buffer_age().unwrap();
|
||||||
let res = self
|
let res = self
|
||||||
.damage_tracker
|
.damage_tracker
|
||||||
.render_output(self.backend.renderer(), age, elements, [0.; 4])
|
.render_output(self.backend.renderer(), age, &elements, [0.; 4])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
niri.update_primary_scanout_output(output, &res.states);
|
niri.update_primary_scanout_output(output, &res.states);
|
||||||
|
|||||||
+32
-57
@@ -1495,7 +1495,7 @@ impl Niri {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(
|
pub fn render(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut GlesRenderer,
|
renderer: &mut GlesRenderer,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
@@ -1620,75 +1620,50 @@ impl Niri {
|
|||||||
fn redraw(&mut self, backend: &mut Backend, output: &Output) {
|
fn redraw(&mut self, backend: &mut Backend, output: &Output) {
|
||||||
let _span = tracy_client::span!("Niri::redraw");
|
let _span = tracy_client::span!("Niri::redraw");
|
||||||
|
|
||||||
let monitors_active = self.monitors_active;
|
// Verify our invariant.
|
||||||
|
|
||||||
let state = self.output_state.get_mut(output).unwrap();
|
let state = self.output_state.get_mut(output).unwrap();
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
state.redraw_state,
|
state.redraw_state,
|
||||||
RedrawState::Queued(_) | RedrawState::WaitingForEstimatedVBlankAndQueued(_)
|
RedrawState::Queued(_) | RedrawState::WaitingForEstimatedVBlankAndQueued(_)
|
||||||
));
|
));
|
||||||
|
|
||||||
// FIXME: make this not cursed.
|
let target_presentation_time = state.frame_clock.next_presentation_time();
|
||||||
let mut reset = || {
|
|
||||||
let state = self.output_state.get_mut(output).unwrap();
|
let mut res = RenderResult::Error;
|
||||||
|
if self.monitors_active {
|
||||||
|
// Update from the config and advance the animations.
|
||||||
|
self.layout.advance_animations(target_presentation_time);
|
||||||
|
state.unfinished_animations_remain = self
|
||||||
|
.layout
|
||||||
|
.monitor_for_output(output)
|
||||||
|
.unwrap()
|
||||||
|
.are_animations_ongoing();
|
||||||
|
|
||||||
|
// Also keep redrawing if the current cursor is animated.
|
||||||
|
state.unfinished_animations_remain |= self
|
||||||
|
.cursor_manager
|
||||||
|
.is_current_cursor_animated(output.current_scale().integer_scale());
|
||||||
|
|
||||||
|
// Render.
|
||||||
|
res = backend.render(self, output, target_presentation_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
let is_locked = self.is_locked();
|
||||||
|
let state = self.output_state.get_mut(output).unwrap();
|
||||||
|
|
||||||
|
if res == RenderResult::Error {
|
||||||
|
// Update the redraw state on failed render.
|
||||||
state.redraw_state =
|
state.redraw_state =
|
||||||
if let RedrawState::WaitingForEstimatedVBlankAndQueued((token, _)) =
|
if let RedrawState::WaitingForEstimatedVBlank(token)
|
||||||
|
| RedrawState::WaitingForEstimatedVBlankAndQueued((token, _)) =
|
||||||
state.redraw_state
|
state.redraw_state
|
||||||
{
|
{
|
||||||
RedrawState::WaitingForEstimatedVBlank(token)
|
RedrawState::WaitingForEstimatedVBlank(token)
|
||||||
} else {
|
} else {
|
||||||
RedrawState::Idle
|
RedrawState::Idle
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
if matches!(self.lock_state, LockState::Locking { .. })
|
// Update the lock render state on successful render.
|
||||||
&& state.lock_render_state == LockRenderState::Unlocked
|
|
||||||
{
|
|
||||||
// We needed to redraw this output for locking and failed.
|
|
||||||
self.unlock();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if !monitors_active {
|
|
||||||
reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !backend.is_active() {
|
|
||||||
reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let Some(renderer) = backend.renderer() else {
|
|
||||||
reset();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let state = self.output_state.get_mut(output).unwrap();
|
|
||||||
let target_presentation_time = state.frame_clock.next_presentation_time();
|
|
||||||
|
|
||||||
// Update from the config and advance the animations.
|
|
||||||
self.layout.advance_animations(target_presentation_time);
|
|
||||||
state.unfinished_animations_remain = self
|
|
||||||
.layout
|
|
||||||
.monitor_for_output(output)
|
|
||||||
.unwrap()
|
|
||||||
.are_animations_ongoing();
|
|
||||||
|
|
||||||
// Also keep redrawing if the current cursor is animated.
|
|
||||||
state.unfinished_animations_remain |= self
|
|
||||||
.cursor_manager
|
|
||||||
.is_current_cursor_animated(output.current_scale().integer_scale());
|
|
||||||
|
|
||||||
// Render the elements.
|
|
||||||
let elements = self.render(renderer, output, true);
|
|
||||||
|
|
||||||
// Hand it over to the backend.
|
|
||||||
let res = backend.render(self, output, &elements, target_presentation_time);
|
|
||||||
|
|
||||||
// Update the lock render state on successful render.
|
|
||||||
let is_locked = self.is_locked();
|
|
||||||
let state = self.output_state.get_mut(output).unwrap();
|
|
||||||
if res != RenderResult::Error {
|
|
||||||
state.lock_render_state = if is_locked {
|
state.lock_render_state = if is_locked {
|
||||||
LockRenderState::Locked
|
LockRenderState::Locked
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user