iced: Throttle resize updates

This commit is contained in:
Victoria Brekenfeld 2023-09-12 17:47:57 +02:00
parent 8038034a62
commit 9de5104cbc

View file

@ -3,6 +3,7 @@ use std::{
fmt,
hash::{Hash, Hasher},
sync::{mpsc::Receiver, Arc, Mutex},
time::{Duration, Instant},
};
use cosmic::{
@ -136,6 +137,7 @@ struct IcedElementInternal<P: Program + Send + 'static> {
// draw buffer
outputs: HashSet<Output>,
buffers: HashMap<OrderedFloat<f64>, (MemoryRenderBuffer, Option<(Vec<Primitive>, Color)>)>,
pending_resize: Option<(Instant, Size<i32, Logical>)>,
// state
size: Size<i32, Logical>,
@ -182,6 +184,7 @@ impl<P: Program + Send + Clone + 'static> Clone for IcedElementInternal<P> {
IcedElementInternal {
outputs: self.outputs.clone(),
buffers: self.buffers.clone(),
pending_resize: self.pending_resize.clone(),
size: self.size.clone(),
cursor_pos: self.cursor_pos.clone(),
theme: self.theme.clone(),
@ -201,6 +204,7 @@ impl<P: Program + Send + 'static> fmt::Debug for IcedElementInternal<P> {
f.debug_struct("IcedElementInternal")
.field("buffers", &"...")
.field("size", &self.size)
.field("pending_resize", &self.pending_resize)
.field("cursor_pos", &self.cursor_pos)
.field("theme", &self.theme)
.field("renderer", &"...")
@ -250,6 +254,7 @@ impl<P: Program + Send + 'static> IcedElement<P> {
let mut internal = IcedElementInternal {
outputs: HashSet::new(),
buffers: HashMap::new(),
pending_resize: None,
size,
cursor_pos: None,
theme: Theme::dark(), // TODO
@ -282,18 +287,9 @@ impl<P: Program + Send + 'static> IcedElement<P> {
return;
}
internal_ref.size = size;
for (scale, (buffer, old_primitives)) in internal_ref.buffers.iter_mut() {
let buffer_size = internal_ref
.size
.to_f64()
.to_buffer(**scale, Transform::Normal)
.to_i32_round();
*buffer =
MemoryRenderBuffer::new(Fourcc::Argb8888, buffer_size, 1, Transform::Normal, None);
*old_primitives = None;
if internal_ref.pending_resize.is_none() {
internal_ref.pending_resize = Some((Instant::now(), size));
}
internal_ref.update(true);
}
pub fn force_update(&self) {
@ -706,10 +702,34 @@ where
alpha: f32,
) -> Vec<C> {
let mut internal = self.0.lock().unwrap();
let _ = internal.update(false);
let internal_ref = &mut *internal;
let force = if matches!(
internal_ref.pending_resize,
Some((instant, _)) if Instant::now().duration_since(instant) > Duration::from_millis(25)
) {
internal_ref.size = internal_ref.pending_resize.take().unwrap().1;
for (scale, (buffer, old_primitives)) in internal_ref.buffers.iter_mut() {
let buffer_size = internal_ref
.size
.to_f64()
.to_buffer(**scale, Transform::Normal)
.to_i32_round();
*buffer = MemoryRenderBuffer::new(
Fourcc::Argb8888,
buffer_size,
1,
Transform::Normal,
None,
);
*old_primitives = None;
}
true
} else {
false
};
let _ = internal_ref.update(force);
// makes partial borrows easier
let internal_ref = &mut *internal;
if let Some((buffer, ref mut old_primitives)) =
internal_ref.buffers.get_mut(&OrderedFloat(scale.x))
{