mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-24 02:01:18 +07:00
tile: Use OffscreenBuffer for resize anims
OffscreenBuffer knows how to avoid recreating the texture every frame.
This commit is contained in:
+18
-14
@@ -2,10 +2,9 @@ use core::f64;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use niri_config::{Color, CornerRadius, GradientInterpolation};
|
use niri_config::{Color, CornerRadius, GradientInterpolation};
|
||||||
use smithay::backend::allocator::Fourcc;
|
|
||||||
use smithay::backend::renderer::element::{Element, Kind};
|
use smithay::backend::renderer::element::{Element, Kind};
|
||||||
use smithay::backend::renderer::gles::GlesRenderer;
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
use smithay::utils::{Logical, Point, Rectangle, Scale, Size, Transform};
|
use smithay::utils::{Logical, Point, Rectangle, Scale, Size};
|
||||||
|
|
||||||
use super::focus_ring::{FocusRing, FocusRingRenderElement};
|
use super::focus_ring::{FocusRing, FocusRingRenderElement};
|
||||||
use super::opening_window::{OpenAnimation, OpeningWindowRenderElement};
|
use super::opening_window::{OpenAnimation, OpeningWindowRenderElement};
|
||||||
@@ -24,7 +23,7 @@ use crate::render_helpers::resize::ResizeRenderElement;
|
|||||||
use crate::render_helpers::shadow::ShadowRenderElement;
|
use crate::render_helpers::shadow::ShadowRenderElement;
|
||||||
use crate::render_helpers::snapshot::RenderSnapshot;
|
use crate::render_helpers::snapshot::RenderSnapshot;
|
||||||
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
|
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
|
||||||
use crate::render_helpers::{render_to_encompassing_texture, RenderTarget};
|
use crate::render_helpers::RenderTarget;
|
||||||
use crate::utils::round_logical_in_physical;
|
use crate::utils::round_logical_in_physical;
|
||||||
use crate::utils::transaction::Transaction;
|
use crate::utils::transaction::Transaction;
|
||||||
|
|
||||||
@@ -135,6 +134,7 @@ struct ResizeAnimation {
|
|||||||
anim: Animation,
|
anim: Animation,
|
||||||
size_from: Size<f64, Logical>,
|
size_from: Size<f64, Logical>,
|
||||||
snapshot: LayoutElementRenderSnapshot,
|
snapshot: LayoutElementRenderSnapshot,
|
||||||
|
offscreen: OffscreenBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -228,7 +228,7 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
self.is_fullscreen = self.window.is_fullscreen();
|
self.is_fullscreen = self.window.is_fullscreen();
|
||||||
|
|
||||||
if let Some(animate_from) = self.window.take_animation_snapshot() {
|
if let Some(animate_from) = self.window.take_animation_snapshot() {
|
||||||
let size_from = if let Some(resize) = self.resize_animation.take() {
|
let (size_from, offscreen) = if let Some(resize) = self.resize_animation.take() {
|
||||||
// Compute like in animated_window_size(), but using the snapshot geometry (since
|
// Compute like in animated_window_size(), but using the snapshot geometry (since
|
||||||
// the current one is already overwritten).
|
// the current one is already overwritten).
|
||||||
let mut size = animate_from.size;
|
let mut size = animate_from.size;
|
||||||
@@ -239,9 +239,10 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
size.w = size_from.w + (size.w - size_from.w) * val;
|
size.w = size_from.w + (size.w - size_from.w) * val;
|
||||||
size.h = size_from.h + (size.h - size_from.h) * val;
|
size.h = size_from.h + (size.h - size_from.h) * val;
|
||||||
|
|
||||||
size
|
// Also try to reuse the existing offscreen buffer if we have one.
|
||||||
|
(size, resize.offscreen)
|
||||||
} else {
|
} else {
|
||||||
animate_from.size
|
(animate_from.size, OffscreenBuffer::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
let change = self.window.size().to_f64().to_point() - size_from.to_point();
|
let change = self.window.size().to_f64().to_point() - size_from.to_point();
|
||||||
@@ -258,6 +259,7 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
anim,
|
anim,
|
||||||
size_from,
|
size_from,
|
||||||
snapshot: animate_from,
|
snapshot: animate_from,
|
||||||
|
offscreen,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.resize_animation = None;
|
self.resize_animation = None;
|
||||||
@@ -848,13 +850,9 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
target,
|
target,
|
||||||
);
|
);
|
||||||
|
|
||||||
let current = render_to_encompassing_texture(
|
let current = resize
|
||||||
gles_renderer,
|
.offscreen
|
||||||
scale,
|
.render(gles_renderer, scale, &window_elements)
|
||||||
Transform::Normal,
|
|
||||||
Fourcc::Abgr8888,
|
|
||||||
&window_elements,
|
|
||||||
)
|
|
||||||
.map_err(|err| warn!("error rendering window to texture: {err:?}"))
|
.map_err(|err| warn!("error rendering window to texture: {err:?}"))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
@@ -869,7 +867,13 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
clip_to_geometry
|
clip_to_geometry
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((texture_current, _sync_point, texture_current_geo)) = current {
|
if let Some((elem_current, _sync_point)) = current {
|
||||||
|
let texture_current = elem_current.texture().clone();
|
||||||
|
// The offset and size are computed in physical pixels and converted to
|
||||||
|
// logical with the same `scale`, so converting them back with rounding
|
||||||
|
// inside the geometry() call gives us the same physical result back.
|
||||||
|
let texture_current_geo = elem_current.geometry(scale);
|
||||||
|
|
||||||
let elem = ResizeRenderElement::new(
|
let elem = ResizeRenderElement::new(
|
||||||
area,
|
area,
|
||||||
scale,
|
scale,
|
||||||
|
|||||||
Reference in New Issue
Block a user