Skip to content

Commit

Permalink
feat: Images cache
Browse files Browse the repository at this point in the history
  • Loading branch information
marc2332 committed Jan 31, 2025
1 parent 88078ec commit f92c8c0
Show file tree
Hide file tree
Showing 20 changed files with 134 additions and 38 deletions.
29 changes: 29 additions & 0 deletions crates/common/src/images_cache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::ops::{
Deref,
DerefMut,
};

use freya_engine::prelude::Image;
use rustc_hash::FxHashMap;

#[derive(Default, PartialEq, Eq, Hash, Clone, Debug)]
pub struct ImageCacheKey(pub String);

#[derive(Default)]
pub struct ImagesCache {
cache: FxHashMap<ImageCacheKey, Image>,
}

impl Deref for ImagesCache {
type Target = FxHashMap<ImageCacheKey, Image>;

fn deref(&self) -> &Self::Target {
&self.cache
}
}

impl DerefMut for ImagesCache {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.cache
}
}
2 changes: 2 additions & 0 deletions crates/common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
mod accessibility;
mod compositor_dirty_nodes;
mod images_cache;
mod layers;
mod layout;
mod paragraphs;

pub use accessibility::*;
pub use compositor_dirty_nodes::*;
pub use images_cache::*;
pub use layers::*;
pub use layout::*;
pub use paragraphs::*;
1 change: 1 addition & 0 deletions crates/components/src/network_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ pub fn NetworkImage(
a11y_role: "image",
a11y_name: alt,
aspect_ratio,
cache_key: "{url}"
})
}
ImageState::Loading => {
Expand Down
11 changes: 11 additions & 0 deletions crates/core/src/dom/doms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use freya_common::{
AccessibilityDirtyNodes,
AccessibilityGenerator,
CompositorDirtyNodes,
ImagesCache,
Layers,
ParagraphElements,
};
Expand Down Expand Up @@ -133,6 +134,7 @@ pub struct FreyaDOM {
compositor_cache: Arc<Mutex<CompositorCache>>,
accessibility_dirty_nodes: Arc<Mutex<AccessibilityDirtyNodes>>,
accessibility_generator: Arc<AccessibilityGenerator>,
images_cache: Arc<Mutex<ImagesCache>>,
}

impl Default for FreyaDOM {
Expand Down Expand Up @@ -160,6 +162,7 @@ impl Default for FreyaDOM {
compositor_cache: Arc::default(),
accessibility_dirty_nodes: Arc::default(),
accessibility_generator: Arc::default(),
images_cache: Arc::default(),
}
}
}
Expand Down Expand Up @@ -197,6 +200,10 @@ impl FreyaDOM {
&self.accessibility_generator
}

pub fn images_cache(&self) -> MutexGuard<ImagesCache> {
self.images_cache.lock().unwrap()
}

/// Create the initial DOM from the given Mutations
pub fn init_dom(&mut self, vdom: &mut VirtualDom, scale_factor: f32) {
// Build the RealDOM
Expand All @@ -212,6 +219,7 @@ impl FreyaDOM {
compositor_dirty_area: &mut self.compositor_dirty_area.lock().unwrap(),
compositor_cache: &mut self.compositor_cache.lock().unwrap(),
accessibility_dirty_nodes: &mut self.accessibility_dirty_nodes.lock().unwrap(),
images_cache: &mut self.images_cache.lock().unwrap(),
});

let mut ctx = SendAnyMap::new();
Expand All @@ -222,6 +230,7 @@ impl FreyaDOM {
ctx.insert(self.accessibility_dirty_nodes.clone());
ctx.insert(self.rdom.root_id());
ctx.insert(self.accessibility_generator.clone());
ctx.insert(self.images_cache.clone());

self.rdom.update_state(ctx);
}
Expand All @@ -241,6 +250,7 @@ impl FreyaDOM {
compositor_dirty_area: &mut self.compositor_dirty_area.lock().unwrap(),
compositor_cache: &mut self.compositor_cache.lock().unwrap(),
accessibility_dirty_nodes: &mut self.accessibility_dirty_nodes.lock().unwrap(),
images_cache: &mut self.images_cache.lock().unwrap(),
});

// Update the Nodes states
Expand All @@ -252,6 +262,7 @@ impl FreyaDOM {
ctx.insert(self.accessibility_dirty_nodes.clone());
ctx.insert(self.rdom.root_id());
ctx.insert(self.accessibility_generator.clone());
ctx.insert(self.images_cache.clone());

// Update the Node's states
let diff = self.rdom.update_state(ctx);
Expand Down
9 changes: 9 additions & 0 deletions crates/core/src/dom/mutations_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use dioxus_core::{
use freya_common::{
AccessibilityDirtyNodes,
CompositorDirtyNodes,
ImagesCache,
Layers,
ParagraphElements,
};
Expand All @@ -21,6 +22,7 @@ use freya_node_state::{
CursorState,
CustomAttributeValues,
LayerState,
StyleState,
};
use torin::torin::{
DirtyReason,
Expand All @@ -45,6 +47,7 @@ pub struct MutationsWriter<'a> {
pub compositor_dirty_area: &'a mut CompositorDirtyArea,
pub compositor_cache: &'a mut CompositorCache,
pub accessibility_dirty_nodes: &'a mut AccessibilityDirtyNodes,
pub images_cache: &'a mut ImagesCache,
}

impl<'a> MutationsWriter<'a> {
Expand Down Expand Up @@ -112,6 +115,12 @@ impl<'a> MutationsWriter<'a> {

// Remove the node from the compositor cache
self.compositor_cache.remove(&node_id);

let style = node.get::<StyleState>().unwrap();

if let Some(image_cache_key) = &style.image_cache_key {
self.images_cache.remove(image_cache_key);
}
}
}

Expand Down
34 changes: 26 additions & 8 deletions crates/core/src/elements/image.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use freya_common::ImagesCache;
use freya_engine::prelude::*;
use freya_native_core::real_dom::NodeImmutable;
use freya_node_state::{
Expand All @@ -21,32 +22,49 @@ impl ElementUtils for ImageElement {
_font_collection: &mut FontCollection,
_font_manager: &FontMgr,
_default_fonts: &[String],
images_cache: &mut ImagesCache,
_scale_factor: f32,
) {
let area = layout_node.visible_area();
let node_style = node_ref.get::<StyleState>().unwrap();
let node_references = node_ref.get::<ReferencesState>().unwrap();
let node_transform = node_ref.get::<TransformState>().unwrap();

let draw_img = |bytes: &[u8]| {
let pic = Image::from_encoded(unsafe { Data::new_bytes(bytes) });
if let Some(pic) = pic {
let mut draw_img = |bytes: &[u8]| {
let image = if let Some(image_cache_key) = &node_style.image_cache_key {
let cached_image = if let Some(image) = images_cache.get(image_cache_key).cloned() {
image
} else {
let Some(image) = Image::from_encoded(unsafe { Data::new_bytes(bytes) }) else {
return;
};
images_cache.insert(image_cache_key.clone(), image.clone());

image
};

Some(cached_image)
} else {
Image::from_encoded(unsafe { Data::new_bytes(bytes) })
};

if let Some(image) = image {
let mut paint = Paint::default();
paint.set_anti_alias(true);

let width_ratio = area.width() / pic.width() as f32;
let height_ratio = area.height() / pic.height() as f32;
let width_ratio = area.width() / image.width() as f32;
let height_ratio = area.height() / image.height() as f32;

let (width, height) = match node_transform.aspect_ratio {
AspectRatio::Max => {
let ratio = width_ratio.max(height_ratio);

(pic.width() as f32 * ratio, pic.height() as f32 * ratio)
(image.width() as f32 * ratio, image.height() as f32 * ratio)
}
AspectRatio::Min => {
let ratio = width_ratio.min(height_ratio);

(pic.width() as f32 * ratio, pic.height() as f32 * ratio)
(image.width() as f32 * ratio, image.height() as f32 * ratio)
}
AspectRatio::None => (area.width(), area.height()),
};
Expand All @@ -57,7 +75,7 @@ impl ElementUtils for ImageElement {
area.min_x() + width,
area.min_y() + height,
);
canvas.draw_image_rect(pic, None, rect, &paint);
canvas.draw_image_rect(image, None, rect, &paint);
}
};

Expand Down
6 changes: 5 additions & 1 deletion crates/core/src/elements/label.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use freya_common::CachedParagraph;
use freya_common::{
CachedParagraph,
ImagesCache,
};
use freya_engine::prelude::*;
use freya_native_core::prelude::NodeImmutable;
use freya_node_state::FontStyleState;
Expand Down Expand Up @@ -27,6 +30,7 @@ impl ElementUtils for LabelElement {
_font_collection: &mut FontCollection,
_font_manager: &FontMgr,
_default_fonts: &[String],
_images_cache: &mut ImagesCache,
_scale_factor: f32,
) {
let paragraph = &layout_node
Expand Down
2 changes: 2 additions & 0 deletions crates/core/src/elements/paragraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::ops::Mul;
use freya_common::{
CachedParagraph,
CursorLayoutResponse,
ImagesCache,
};
use freya_engine::prelude::*;
use freya_native_core::{
Expand Down Expand Up @@ -121,6 +122,7 @@ impl ElementUtils for ParagraphElement {
font_collection: &mut FontCollection,
_font_manager: &FontMgr,
default_fonts: &[String],
_images_cache: &mut ImagesCache,
scale_factor: f32,
) {
let area = layout_node.visible_area();
Expand Down
2 changes: 2 additions & 0 deletions crates/core/src/elements/rect.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use freya_common::ImagesCache;
use freya_engine::prelude::*;
use freya_native_core::real_dom::NodeImmutable;
use freya_node_state::{
Expand Down Expand Up @@ -88,6 +89,7 @@ impl ElementUtils for RectElement {
font_collection: &mut FontCollection,
_font_manager: &FontMgr,
_default_fonts: &[String],
_images_cache: &mut ImagesCache,
scale_factor: f32,
) {
let node_style = &*node_ref.get::<StyleState>().unwrap();
Expand Down
2 changes: 2 additions & 0 deletions crates/core/src/elements/svg.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use freya_common::ImagesCache;
use freya_engine::prelude::*;
use freya_native_core::real_dom::NodeImmutable;
use freya_node_state::{
Expand All @@ -20,6 +21,7 @@ impl ElementUtils for SvgElement {
_font_collection: &mut FontCollection,
font_manager: &FontMgr,
_default_fonts: &[String],
_images_cache: &mut ImagesCache,
_scale_factor: f32,
) {
let area = layout_node.visible_area();
Expand Down
8 changes: 8 additions & 0 deletions crates/core/src/elements/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use freya_common::ImagesCache;
use freya_engine::prelude::{
Canvas,
FontCollection,
Expand Down Expand Up @@ -54,6 +55,7 @@ pub trait ElementUtils {
font_collection: &mut FontCollection,
font_manager: &FontMgr,
default_fonts: &[String],
images_cache: &mut ImagesCache,
scale_factor: f32,
);

Expand Down Expand Up @@ -206,6 +208,7 @@ impl ElementUtils for ElementWithUtils {
font_collection: &mut FontCollection,
font_manager: &FontMgr,
default_fonts: &[String],
images_cache: &mut ImagesCache,
scale_factor: f32,
) {
match self {
Expand All @@ -216,6 +219,7 @@ impl ElementUtils for ElementWithUtils {
font_collection,
font_manager,
default_fonts,
images_cache,
scale_factor,
),
Self::Svg(el) => el.render(
Expand All @@ -225,6 +229,7 @@ impl ElementUtils for ElementWithUtils {
font_collection,
font_manager,
default_fonts,
images_cache,
scale_factor,
),
Self::Paragraph(el) => el.render(
Expand All @@ -234,6 +239,7 @@ impl ElementUtils for ElementWithUtils {
font_collection,
font_manager,
default_fonts,
images_cache,
scale_factor,
),
Self::Image(el) => el.render(
Expand All @@ -243,6 +249,7 @@ impl ElementUtils for ElementWithUtils {
font_collection,
font_manager,
default_fonts,
images_cache,
scale_factor,
),
Self::Label(el) => el.render(
Expand All @@ -252,6 +259,7 @@ impl ElementUtils for ElementWithUtils {
font_collection,
font_manager,
default_fonts,
images_cache,
scale_factor,
),
}
Expand Down
3 changes: 3 additions & 0 deletions crates/core/src/render/pipeline.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use freya_common::{
CompositorDirtyNodes,
ImagesCache,
Layers,
};
use freya_engine::prelude::{
Expand Down Expand Up @@ -63,6 +64,7 @@ pub struct RenderPipeline<'a> {
pub compositor: &'a mut Compositor,
pub font_collection: &'a mut FontCollection,
pub font_manager: &'a FontMgr,
pub images_cache: &'a mut ImagesCache,
pub canvas_area: Area,
pub background: Color,
pub scale_factor: f32,
Expand Down Expand Up @@ -266,6 +268,7 @@ impl RenderPipeline<'_> {
self.font_collection,
self.font_manager,
self.default_fonts,
self.images_cache,
self.scale_factor,
);

Expand Down
2 changes: 2 additions & 0 deletions crates/elements/src/attributes/image_attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ def_attribute!(
/// }
/// ```
aspect_ratio,

cache_key,
);
1 change: 1 addition & 0 deletions crates/elements/src/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ def_element!(
// Image
image_data,
aspect_ratio,
cache_key,

// Reference
reference,
Expand Down
Loading

0 comments on commit f92c8c0

Please sign in to comment.