aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020
diff options
context:
space:
mode:
authorTIN TUN AUNG <62133983+rayguo17@users.noreply.github.com>2025-03-29 07:19:49 +0800
committerGitHub <noreply@github.com>2025-03-28 23:19:49 +0000
commited3dd8fbe03f41ee816cbe87c898a0cdc71d1115 (patch)
tree823700876b510f00ee1972c352dc1e5dbd644b15 /components/layout_2020
parent53f7c7b1dec3dfaa215e4a3c678e5e42214b4f05 (diff)
downloadservo-ed3dd8fbe03f41ee816cbe87c898a0cdc71d1115.tar.gz
servo-ed3dd8fbe03f41ee816cbe87c898a0cdc71d1115.zip
Animation: Aggregate Animated Image Info to Document (#36141)
Signed-off-by: rayguo17 <rayguo17@gmail.com>
Diffstat (limited to 'components/layout_2020')
-rw-r--r--components/layout_2020/context.rs27
-rw-r--r--components/layout_2020/replaced.rs4
2 files changed, 30 insertions, 1 deletions
diff --git a/components/layout_2020/context.rs b/components/layout_2020/context.rs
index 2dbfb7eabb8..c825852dae5 100644
--- a/components/layout_2020/context.rs
+++ b/components/layout_2020/context.rs
@@ -7,11 +7,13 @@ use std::sync::Arc;
use base::id::PipelineId;
use fnv::FnvHashMap;
use fonts::FontContext;
+use fxhash::FxHashMap;
use net_traits::image_cache::{
ImageCache, ImageCacheResult, ImageOrMetadataAvailable, UsePlaceholder,
};
use parking_lot::{Mutex, RwLock};
-use script_layout_interface::{IFrameSizes, PendingImage, PendingImageState};
+use pixels::Image;
+use script_layout_interface::{IFrameSizes, ImageAnimationState, PendingImage, PendingImageState};
use servo_url::{ImmutableOrigin, ServoUrl};
use style::context::SharedStyleContext;
use style::dom::OpaqueNode;
@@ -40,6 +42,8 @@ pub struct LayoutContext<'a> {
pub webrender_image_cache:
Arc<RwLock<FnvHashMap<(ServoUrl, UsePlaceholder), WebRenderImageInfo>>>,
+
+ pub node_image_animation_map: Arc<RwLock<FxHashMap<OpaqueNode, ImageAnimationState>>>,
}
impl Drop for LayoutContext<'_> {
@@ -100,6 +104,26 @@ impl LayoutContext<'_> {
}
}
+ pub fn handle_animated_image(&self, node: OpaqueNode, image: Arc<Image>) {
+ let mut store = self.node_image_animation_map.write();
+
+ // 1. first check whether node previously being track for animated image.
+ if let Some(image_state) = store.get(&node) {
+ // a. if the node is not containing the same image as before.
+ if image_state.image_key() != image.id {
+ if image.should_animate() {
+ // i. Register/Replace tracking item in image_animation_manager.
+ store.insert(node, ImageAnimationState::new(image));
+ } else {
+ // ii. Cancel Action if the node's image is no longer animated.
+ store.remove(&node);
+ }
+ }
+ } else if image.should_animate() {
+ store.insert(node, ImageAnimationState::new(image));
+ }
+ }
+
pub fn get_webrender_image_for_url(
&self,
node: OpaqueNode,
@@ -116,6 +140,7 @@ impl LayoutContext<'_> {
match self.get_or_request_image_or_meta(node, url.clone(), use_placeholder) {
Some(ImageOrMetadataAvailable::ImageAvailable { image, .. }) => {
+ self.handle_animated_image(node, image.clone());
let image_info = WebRenderImageInfo {
width: image.width,
height: image.height,
diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs
index f387b47731e..47bb932fa9e 100644
--- a/components/layout_2020/replaced.rs
+++ b/components/layout_2020/replaced.rs
@@ -182,6 +182,10 @@ impl ReplacedContents {
}
};
+ if let ReplacedContentKind::Image(Some(ref image)) = kind {
+ context.handle_animated_image(element.opaque(), image.clone());
+ }
+
let natural_size = if let Some(naturalc_size_in_dots) = natural_size_in_dots {
// FIXME: should 'image-resolution' (when implemented) be used *instead* of
// `script::dom::htmlimageelement::ImageRequest::current_pixel_density`?