Merge pull request #2409 from iced-rs/rc-cache-eviction
Retain caches in `iced_wgpu` as long as `Rc` values are alive
This commit is contained in:
commit
e617d7e929
4 changed files with 140 additions and 14 deletions
12
examples/the_matrix/Cargo.toml
Normal file
12
examples/the_matrix/Cargo.toml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "the_matrix"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
iced.workspace = true
|
||||||
|
iced.features = ["canvas", "tokio", "debug"]
|
||||||
|
|
||||||
|
rand = "0.8"
|
||||||
116
examples/the_matrix/src/main.rs
Normal file
116
examples/the_matrix/src/main.rs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
use iced::mouse;
|
||||||
|
use iced::time::{self, Instant};
|
||||||
|
use iced::widget::canvas;
|
||||||
|
use iced::widget::canvas::{Cache, Geometry};
|
||||||
|
use iced::{
|
||||||
|
Color, Element, Font, Length, Point, Rectangle, Renderer, Subscription,
|
||||||
|
Theme,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main() -> iced::Result {
|
||||||
|
iced::program("The Matrix - Iced", TheMatrix::update, TheMatrix::view)
|
||||||
|
.subscription(TheMatrix::subscription)
|
||||||
|
.antialiasing(true)
|
||||||
|
.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TheMatrix {
|
||||||
|
ticks: usize,
|
||||||
|
backgrounds: Vec<Cache>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum Message {
|
||||||
|
Tick(Instant),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TheMatrix {
|
||||||
|
fn update(&mut self, message: Message) {
|
||||||
|
match message {
|
||||||
|
Message::Tick(_now) => {
|
||||||
|
self.ticks += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view(&self) -> Element<Message> {
|
||||||
|
canvas(self as &Self)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subscription(&self) -> Subscription<Message> {
|
||||||
|
time::every(std::time::Duration::from_millis(50)).map(Message::Tick)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TheMatrix {
|
||||||
|
fn default() -> Self {
|
||||||
|
let mut backgrounds = Vec::with_capacity(30);
|
||||||
|
backgrounds.resize_with(30, Cache::default);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
ticks: 0,
|
||||||
|
backgrounds,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Message> canvas::Program<Message> for TheMatrix {
|
||||||
|
type State = ();
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
_state: &Self::State,
|
||||||
|
renderer: &Renderer,
|
||||||
|
_theme: &Theme,
|
||||||
|
bounds: Rectangle,
|
||||||
|
_cursor: mouse::Cursor,
|
||||||
|
) -> Vec<Geometry> {
|
||||||
|
use rand::distributions::Distribution;
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
const CELL_SIZE: f32 = 10.0;
|
||||||
|
|
||||||
|
vec![self.backgrounds[self.ticks % self.backgrounds.len()].draw(
|
||||||
|
renderer,
|
||||||
|
bounds.size(),
|
||||||
|
|frame| {
|
||||||
|
frame.fill_rectangle(Point::ORIGIN, frame.size(), Color::BLACK);
|
||||||
|
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let rows = (frame.height() / CELL_SIZE).ceil() as usize;
|
||||||
|
let columns = (frame.width() / CELL_SIZE).ceil() as usize;
|
||||||
|
|
||||||
|
for row in 0..rows {
|
||||||
|
for column in 0..columns {
|
||||||
|
let position = Point::new(
|
||||||
|
column as f32 * CELL_SIZE,
|
||||||
|
row as f32 * CELL_SIZE,
|
||||||
|
);
|
||||||
|
|
||||||
|
let alphas = [0.05, 0.1, 0.2, 0.5];
|
||||||
|
let weights = [10, 4, 2, 1];
|
||||||
|
let distribution =
|
||||||
|
rand::distributions::WeightedIndex::new(weights)
|
||||||
|
.expect("Create distribution");
|
||||||
|
|
||||||
|
frame.fill_text(canvas::Text {
|
||||||
|
content: rng.gen_range('!'..'z').to_string(),
|
||||||
|
position,
|
||||||
|
color: Color {
|
||||||
|
a: alphas[distribution.sample(&mut rng)],
|
||||||
|
g: 1.0,
|
||||||
|
..Color::BLACK
|
||||||
|
},
|
||||||
|
size: CELL_SIZE.into(),
|
||||||
|
font: Font::MONOSPACE,
|
||||||
|
..canvas::Text::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,9 +4,9 @@ use crate::graphics::color;
|
||||||
use crate::graphics::text::cache::{self, Cache as BufferCache};
|
use crate::graphics::text::cache::{self, Cache as BufferCache};
|
||||||
use crate::graphics::text::{font_system, to_color, Editor, Paragraph};
|
use crate::graphics::text::{font_system, to_color, Editor, Paragraph};
|
||||||
|
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::FxHashMap;
|
||||||
use std::collections::hash_map;
|
use std::collections::hash_map;
|
||||||
use std::rc::Rc;
|
use std::rc::{self, Rc};
|
||||||
use std::sync::atomic::{self, AtomicU64};
|
use std::sync::atomic::{self, AtomicU64};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
|
@ -69,12 +69,12 @@ struct Upload {
|
||||||
buffer_cache: BufferCache,
|
buffer_cache: BufferCache,
|
||||||
transformation: Transformation,
|
transformation: Transformation,
|
||||||
version: usize,
|
version: usize,
|
||||||
|
text: rc::Weak<[Text]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Storage {
|
pub struct Storage {
|
||||||
uploads: FxHashMap<Id, Upload>,
|
uploads: FxHashMap<Id, Upload>,
|
||||||
recently_used: FxHashSet<Id>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Storage {
|
impl Storage {
|
||||||
|
|
@ -162,6 +162,7 @@ impl Storage {
|
||||||
buffer_cache,
|
buffer_cache,
|
||||||
transformation: new_transformation,
|
transformation: new_transformation,
|
||||||
version: 0,
|
version: 0,
|
||||||
|
text: Rc::downgrade(&cache.text),
|
||||||
});
|
});
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
|
|
@ -171,13 +172,11 @@ impl Storage {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = self.recently_used.insert(cache.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trim(&mut self) {
|
pub fn trim(&mut self) {
|
||||||
self.uploads.retain(|id, _| self.recently_used.contains(id));
|
self.uploads
|
||||||
self.recently_used.clear();
|
.retain(|_id, upload| upload.text.strong_count() > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ use crate::graphics::mesh::{self, Mesh};
|
||||||
use crate::graphics::Antialiasing;
|
use crate::graphics::Antialiasing;
|
||||||
use crate::Buffer;
|
use crate::Buffer;
|
||||||
|
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::FxHashMap;
|
||||||
use std::collections::hash_map;
|
use std::collections::hash_map;
|
||||||
use std::rc::Rc;
|
use std::rc::{self, Rc};
|
||||||
use std::sync::atomic::{self, AtomicU64};
|
use std::sync::atomic::{self, AtomicU64};
|
||||||
|
|
||||||
const INITIAL_INDEX_COUNT: usize = 1_000;
|
const INITIAL_INDEX_COUNT: usize = 1_000;
|
||||||
|
|
@ -64,12 +64,12 @@ struct Upload {
|
||||||
layer: Layer,
|
layer: Layer,
|
||||||
transformation: Transformation,
|
transformation: Transformation,
|
||||||
version: usize,
|
version: usize,
|
||||||
|
batch: rc::Weak<[Mesh]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Storage {
|
pub struct Storage {
|
||||||
uploads: FxHashMap<Id, Upload>,
|
uploads: FxHashMap<Id, Upload>,
|
||||||
recently_used: FxHashSet<Id>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Storage {
|
impl Storage {
|
||||||
|
|
@ -134,6 +134,7 @@ impl Storage {
|
||||||
layer,
|
layer,
|
||||||
transformation: new_transformation,
|
transformation: new_transformation,
|
||||||
version: 0,
|
version: 0,
|
||||||
|
batch: Rc::downgrade(&cache.batch),
|
||||||
});
|
});
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
|
|
@ -143,13 +144,11 @@ impl Storage {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = self.recently_used.insert(cache.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trim(&mut self) {
|
pub fn trim(&mut self) {
|
||||||
self.uploads.retain(|id, _| self.recently_used.contains(id));
|
self.uploads
|
||||||
self.recently_used.clear();
|
.retain(|_id, upload| upload.batch.strong_count() > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue