From cbb2d18bc020a7ad2d9b8194cf7efa9fe10f1eb0 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Tue, 27 May 2025 12:11:51 +0200 Subject: [PATCH] Address some code nits Signed-off-by: Martin Robinson --- components/net/image_cache.rs | 144 +++++++++--------- components/script/dom/datatransfer.rs | 8 +- components/script/dom/htmlimageelement.rs | 14 +- components/script/dom/htmlvideoelement.rs | 9 +- components/script/dom/notification.rs | 8 +- .../script/dom/webglrenderingcontext.rs | 32 ++-- components/script/dom/window.rs | 19 ++- components/script/messaging.rs | 14 +- components/script/script_thread.rs | 12 +- components/shared/net/image_cache.rs | 49 +++--- components/shared/script_layout/lib.rs | 5 +- 11 files changed, 166 insertions(+), 148 deletions(-) diff --git a/components/net/image_cache.rs b/components/net/image_cache.rs index 30d724e17f1..5ee2ee477ee 100644 --- a/components/net/image_cache.rs +++ b/components/net/image_cache.rs @@ -16,8 +16,9 @@ use malloc_size_of::{MallocSizeOf as MallocSizeOfTrait, MallocSizeOfOps}; use malloc_size_of_derive::MallocSizeOf; use mime::Mime; use net_traits::image_cache::{ - Image, ImageCache, ImageCacheMessage, ImageCacheResult, ImageLoadListener, - ImageOrMetadataAvailable, ImageResponse, PendingImageId, UsePlaceholder, VectorImage, + Image, ImageCache, ImageCacheResponseMessage, ImageCacheResult, ImageLoadListener, + ImageOrMetadataAvailable, ImageResponse, PendingImageId, RasterizationCompleteResponse, + UsePlaceholder, VectorImage, }; use net_traits::request::CorsSettings; use net_traits::{FetchMetadata, FetchResponseMsg, FilteredMetadata, NetworkError}; @@ -397,41 +398,39 @@ impl PendingLoad { } } -#[derive(MallocSizeOf)] +#[derive(Default, MallocSizeOf)] struct RasterizationTask { - listeners: Vec<(PipelineId, IpcSender)>, + listeners: Vec<(PipelineId, IpcSender)>, result: Option, } -// ====================================================================== -// Image cache implementation. -// ====================================================================== +/// ## Image cache implementation. #[derive(MallocSizeOf)] struct ImageCacheStore { - // Images that are loading over network, or decoding. + /// Images that are loading over network, or decoding. pending_loads: AllPendingLoads, - // Images that have finished loading (successful or not) + /// Images that have finished loading (successful or not) completed_loads: HashMap, - // Vector (e.g. SVG) images that have been sucessfully loaded and parsed - // but are yet to be rasterized. Since the same SVG data can be used for - // rasterizing at different sizes, we use this hasmap to share the data. + /// Vector (e.g. SVG) images that have been sucessfully loaded and parsed + /// but are yet to be rasterized. Since the same SVG data can be used for + /// rasterizing at different sizes, we use this hasmap to share the data. vector_images: HashMap, - // Vector images for which rasterization at a particular size has started - // or completed. If completed, the `result` member of `RasterizationTask` - // contains the rasterized image. + /// Vector images for which rasterization at a particular size has started + /// or completed. If completed, the `result` member of `RasterizationTask` + /// contains the rasterized image. rasterized_vector_images: HashMap<(PendingImageId, DeviceIntSize), RasterizationTask>, - // The placeholder image used when an image fails to load + /// The placeholder image used when an image fails to load #[conditional_malloc_size_of] placeholder_image: Arc, - // The URL used for the placeholder image + /// The URL used for the placeholder image placeholder_url: ServoUrl, - // Cross-process compositor API instance. + /// Cross-process compositor API instance. #[ignore_malloc_size_of = "Channel from another crate"] compositor_api: CrossProcessCompositorApi, } @@ -683,39 +682,38 @@ impl ImageCache for ImageCacheImpl { &self, pipeline_id: PipelineId, image_id: PendingImageId, - size: DeviceIntSize, - sender: IpcSender, + requested_size: DeviceIntSize, + sender: IpcSender, ) { - let key = (image_id, size); let completed = { let mut store = self.store.lock().unwrap(); + let key = (image_id, requested_size); if !store.vector_images.contains_key(&image_id) { warn!("Unknown image requested for rasterization for key {key:?}"); return; }; - match store.rasterized_vector_images.entry(key) { - Occupied(mut entry) => { - let task = entry.get_mut(); - if task.result.is_some() { - true - } else { - task.listeners.push((pipeline_id, sender.clone())); - false - } - }, - Vacant(_) => { - warn!("Image rasterization task not found in the cache for key {key:?}"); - return; + let Some(task) = store.rasterized_vector_images.get_mut(&key) else { + warn!("Image rasterization task not found in the cache for key {key:?}"); + return; + }; + + match task.result { + Some(_) => true, + None => { + task.listeners.push((pipeline_id, sender.clone())); + false }, } }; if completed { - let _ = sender.send(ImageCacheMessage::VectorImageRasterizationCompleted( - pipeline_id, - image_id, - size, + let _ = sender.send(ImageCacheResponseMessage::VectorImageRasterizationComplete( + RasterizationCompleteResponse { + pipeline_id, + image_id, + requested_size, + }, )); } } @@ -723,7 +721,7 @@ impl ImageCache for ImageCacheImpl { fn rasterize_vector_image( &self, image_id: PendingImageId, - size: DeviceIntSize, + requested_size: DeviceIntSize, ) -> Option { let mut store = self.store.lock().unwrap(); let Some(vector_image) = store.vector_images.get(&image_id).cloned() else { @@ -731,44 +729,48 @@ impl ImageCache for ImageCacheImpl { return None; }; - match store.rasterized_vector_images.entry((image_id, size)) { - Occupied(occupied_entry) => { - return occupied_entry.get().result.clone(); - }, - Vacant(entry) => entry.insert(RasterizationTask { - listeners: vec![], - result: None, - }), - }; + // This early return relies on the fact that the result of image rasterization cannot + // ever be `None`. If that were the case we would need to check whether the entry + // in the `HashMap` was `Occupied` or not. + let entry = store + .rasterized_vector_images + .entry((image_id, requested_size)) + .or_default(); + if let Some(result) = entry.result.as_ref() { + return Some(result.clone()); + } let store = self.store.clone(); self.thread_pool.spawn(move || { let natural_size = vector_image.svg_tree.size().to_int_size(); - let requested_size = { - let width = size.width.try_into().unwrap_or(0); - let height = size.height.try_into().unwrap_or(0); + let tinyskia_requested_size = { + let width = requested_size.width.try_into().unwrap_or(0); + let height = requested_size.height.try_into().unwrap_or(0); tiny_skia::IntSize::from_wh(width, height).unwrap_or(natural_size) }; let transform = tiny_skia::Transform::from_scale( - requested_size.width() as f32 / natural_size.width() as f32, - requested_size.height() as f32 / natural_size.height() as f32, + tinyskia_requested_size.width() as f32 / natural_size.width() as f32, + tinyskia_requested_size.height() as f32 / natural_size.height() as f32, ); - let mut pixmap = - tiny_skia::Pixmap::new(requested_size.width(), requested_size.height()).unwrap(); + let mut pixmap = tiny_skia::Pixmap::new( + tinyskia_requested_size.width(), + tinyskia_requested_size.height(), + ) + .unwrap(); resvg::render(&vector_image.svg_tree, transform, &mut pixmap.as_mut()); let bytes = pixmap.take(); let frame = ImageFrame { delay: None, byte_range: 0..bytes.len(), - width: requested_size.width(), - height: requested_size.height(), + width: tinyskia_requested_size.width(), + height: tinyskia_requested_size.height(), }; let mut rasterized_image = RasterImage { metadata: ImageMetadata { - width: requested_size.width(), - height: requested_size.height(), + width: tinyskia_requested_size.width(), + height: tinyskia_requested_size.height(), }, format: PixelFormat::RGBA8, frames: vec![frame], @@ -780,19 +782,23 @@ impl ImageCache for ImageCacheImpl { let listeners = { let mut store = store.lock().unwrap(); set_webrender_image_key(&store.compositor_api, &mut rasterized_image); - if let Some(task) = store.rasterized_vector_images.get_mut(&(image_id, size)) { - task.result = Some(rasterized_image); - std::mem::take(&mut task.listeners) - } else { - Vec::new() - } + store + .rasterized_vector_images + .get_mut(&(image_id, requested_size)) + .map(|task| { + task.result = Some(rasterized_image); + std::mem::take(&mut task.listeners) + }) + .unwrap_or_default() }; for (pipeline_id, sender) in listeners { - let _ = sender.send(ImageCacheMessage::VectorImageRasterizationCompleted( - pipeline_id, - image_id, - size, + let _ = sender.send(ImageCacheResponseMessage::VectorImageRasterizationComplete( + RasterizationCompleteResponse { + pipeline_id, + image_id, + requested_size, + }, )); } }); diff --git a/components/script/dom/datatransfer.rs b/components/script/dom/datatransfer.rs index aa554bf08d9..1cd977a8c18 100644 --- a/components/script/dom/datatransfer.rs +++ b/components/script/dom/datatransfer.rs @@ -7,6 +7,7 @@ use std::rc::Rc; use dom_struct::dom_struct; use js::rust::{HandleObject, MutableHandleValue}; +use net_traits::image_cache::Image; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::DataTransferBinding::DataTransferMethods; @@ -155,10 +156,9 @@ impl DataTransferMethods for DataTransfer { // Step 3 if let Some(image) = image.downcast::() { - if let Some(image) = image.image_data().and_then(|image| image.as_raster_image()) { - data_store.set_bitmap(Some(image), x, y); - } else { - warn!("Vector images are not yet supported in setDragImage"); + match image.image_data().as_ref().and_then(Image::as_raster_image) { + Some(image) => data_store.set_bitmap(Some(image), x, y), + None => warn!("Vector images are not yet supported in setDragImage"), } } } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 92a3d318d08..b9819000556 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -341,14 +341,12 @@ impl HTMLImageElement { is_placeholder, }) => { if is_placeholder { - let image = image - .as_raster_image() - .expect("Only raster images are supported as placeholders currently"); - - self.process_image_response( - ImageResponse::PlaceholderLoaded(image, url), - can_gc, - ) + if let Some(raster_image) = image.as_raster_image() { + self.process_image_response( + ImageResponse::PlaceholderLoaded(raster_image, url), + can_gc, + ) + } } else { self.process_image_response(ImageResponse::Loaded(image, url), can_gc) } diff --git a/components/script/dom/htmlvideoelement.rs b/components/script/dom/htmlvideoelement.rs index e8a0fa46e63..95124da8ea2 100644 --- a/components/script/dom/htmlvideoelement.rs +++ b/components/script/dom/htmlvideoelement.rs @@ -262,11 +262,10 @@ impl HTMLVideoElement { match response { ImageResponse::Loaded(image, url) => { debug!("Loaded poster image for video element: {:?}", url); - if let Some(image) = image.as_raster_image() { - self.htmlmediaelement.process_poster_image_loaded(image); - } else { - warn!("Vector images are not yet supported in video poster"); - }; + match image.as_raster_image() { + Some(image) => self.htmlmediaelement.process_poster_image_loaded(image), + None => warn!("Vector images are not yet supported in video poster"), + } LoadBlocker::terminate(&self.load_blocker, can_gc); }, ImageResponse::MetadataLoaded(..) => {}, diff --git a/components/script/dom/notification.rs b/components/script/dom/notification.rs index 43761ec3215..10550a4f219 100644 --- a/components/script/dom/notification.rs +++ b/components/script/dom/notification.rs @@ -21,8 +21,8 @@ use js::jsval::JSVal; use js::rust::{HandleObject, MutableHandleValue}; use net_traits::http_status::HttpStatus; use net_traits::image_cache::{ - ImageCache, ImageCacheMessage, ImageCacheResult, ImageLoadListener, ImageOrMetadataAvailable, - ImageResponse, PendingImageId, UsePlaceholder, + ImageCache, ImageCacheResponseMessage, ImageCacheResult, ImageLoadListener, + ImageOrMetadataAvailable, ImageResponse, PendingImageId, UsePlaceholder, }; use net_traits::request::{RequestBuilder, RequestId}; use net_traits::{ @@ -929,7 +929,7 @@ impl Notification { pending_image_id: PendingImageId, resource_type: ResourceType, ) { - let (sender, receiver) = ipc::channel::().expect("ipc channel failure"); + let (sender, receiver) = ipc::channel().expect("ipc channel failure"); let global: &GlobalScope = &self.global(); @@ -945,7 +945,7 @@ impl Notification { task_source.queue(task!(handle_response: move || { let this = trusted_this.root(); if let Ok(response) = response { - let ImageCacheMessage::NotifyPendingImageLoadStatus(status) = response else { + let ImageCacheResponseMessage::NotifyPendingImageLoadStatus(status) = response else { warn!("Received unexpected message from image cache: {response:?}"); return; }; diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index ff576690664..9b9f35aefee 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -609,23 +609,29 @@ impl WebGLRenderingContext { }; let cors_setting = cors_setting_for_element(image.upcast()); - let img = - match canvas_utils::request_image_from_cache(&window, img_url, cors_setting) { - ImageResponse::Loaded(image, _) => { - if let Some(image) = image.as_raster_image() { - image - } else { - // Related https://github.com/KhronosGroup/WebGL/issues/1503? + let img = match canvas_utils::request_image_from_cache( + &window, + img_url, + cors_setting, + ) { + ImageResponse::Loaded(image, _) => { + match image.as_raster_image() { + Some(image) => image, + None => { + // Vector images are not currently supported here and there are some open questions + // in the specification about how to handle them: + // See https://github.com/KhronosGroup/WebGL/issues/1503. warn!( "Vector images as are not yet supported as WebGL texture source" ); return Ok(None); - } - }, - ImageResponse::PlaceholderLoaded(_, _) | - ImageResponse::None | - ImageResponse::MetadataLoaded(_) => return Ok(None), - }; + }, + } + }, + ImageResponse::PlaceholderLoaded(_, _) | + ImageResponse::None | + ImageResponse::MetadataLoaded(_) => return Ok(None), + }; let size = Size2D::new(img.metadata.width, img.metadata.height); diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 8780ccfb5e9..dcaa025c778 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -55,8 +55,8 @@ use malloc_size_of::MallocSizeOf; use media::WindowGLContext; use net_traits::ResourceThreads; use net_traits::image_cache::{ - ImageCache, ImageCacheMessage, ImageLoadListener, ImageResponse, PendingImageId, - PendingImageResponse, + ImageCache, ImageCacheResponseMessage, ImageLoadListener, ImageResponse, PendingImageId, + PendingImageResponse, RasterizationCompleteResponse, }; use net_traits::storage_thread::StorageType; use num_traits::ToPrimitive; @@ -243,7 +243,7 @@ pub(crate) struct Window { #[no_trace] image_cache: Arc, #[no_trace] - image_cache_sender: IpcSender, + image_cache_sender: IpcSender, window_proxy: MutNullableDom, document: MutNullableDom, location: MutNullableDom, @@ -346,13 +346,13 @@ pub(crate) struct Window { pending_image_callbacks: DomRefCell>>, /// All of the elements that have an outstanding image request that was - /// initiated by layout during a reflow. They are stored in the script thread + /// initiated by layout during a reflow. They are stored in the [`ScriptThread`] /// to ensure that the element can be marked dirty when the image data becomes /// available at some point in the future. pending_layout_images: DomRefCell>>>, /// Vector images for which layout has intiated rasterization at a specific size - /// and whose results are not yet available. They are stored in the script thread + /// and whose results are not yet available. They are stored in the [`ScriptThread`] /// so that the element can be marked dirty once the rasterization is completed. pending_images_for_rasterization: DomRefCell>>>, @@ -577,7 +577,7 @@ impl Window { &self, id: PendingImageId, callback: impl Fn(PendingImageResponse) + 'static, - ) -> IpcSender { + ) -> IpcSender { self.pending_image_callbacks .borrow_mut() .entry(id) @@ -608,11 +608,10 @@ impl Window { pub(crate) fn handle_image_rasterization_complete_notification( &self, - image_id: PendingImageId, - size: DeviceIntSize, + response: RasterizationCompleteResponse, ) { let mut images = self.pending_images_for_rasterization.borrow_mut(); - let nodes = images.entry((image_id, size)); + let nodes = images.entry((response.image_id, response.requested_size)); let nodes = match nodes { Entry::Occupied(nodes) => nodes, Entry::Vacant(_) => return, @@ -3054,7 +3053,7 @@ impl Window { script_chan: Sender, layout: Box, font_context: Arc, - image_cache_sender: IpcSender, + image_cache_sender: IpcSender, image_cache: Arc, resource_threads: ResourceThreads, #[cfg(feature = "bluetooth")] bluetooth_thread: IpcSender, diff --git a/components/script/messaging.rs b/components/script/messaging.rs index 79bd8c056a9..41465796505 100644 --- a/components/script/messaging.rs +++ b/components/script/messaging.rs @@ -16,7 +16,7 @@ use crossbeam_channel::{Receiver, SendError, Sender, select}; use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg}; use ipc_channel::ipc::IpcSender; use net_traits::FetchResponseMsg; -use net_traits::image_cache::ImageCacheMessage; +use net_traits::image_cache::ImageCacheResponseMessage; use profile_traits::mem::{self as profile_mem, OpaqueSender, ReportsChan}; use profile_traits::time::{self as profile_time}; use script_traits::{Painter, ScriptThreadMessage}; @@ -40,7 +40,7 @@ pub(crate) enum MixedMessage { FromConstellation(ScriptThreadMessage), FromScript(MainThreadScriptMsg), FromDevtools(DevtoolScriptControlMsg), - FromImageCache(ImageCacheMessage), + FromImageCache(ImageCacheResponseMessage), #[cfg(feature = "webgpu")] FromWebGPUServer(WebGPUMsg), TimerFired, @@ -105,11 +105,11 @@ impl MixedMessage { MainThreadScriptMsg::WakeUp => None, }, MixedMessage::FromImageCache(response) => match response { - ImageCacheMessage::NotifyPendingImageLoadStatus(response) => { + ImageCacheResponseMessage::NotifyPendingImageLoadStatus(response) => { Some(response.pipeline_id) }, - ImageCacheMessage::VectorImageRasterizationCompleted(pipeline_id, ..) => { - Some(*pipeline_id) + ImageCacheResponseMessage::VectorImageRasterizationComplete(response) => { + Some(response.pipeline_id) }, }, MixedMessage::FromDevtools(_) | MixedMessage::TimerFired => None, @@ -333,7 +333,7 @@ pub(crate) struct ScriptThreadSenders { /// messages on this channel are routed to crossbeam [`Sender`] on the router thread, which /// in turn sends messages to [`ScriptThreadReceivers::image_cache_receiver`]. #[no_trace] - pub(crate) image_cache_sender: IpcSender, + pub(crate) image_cache_sender: IpcSender, /// For providing contact with the time profiler. #[no_trace] @@ -362,7 +362,7 @@ pub(crate) struct ScriptThreadReceivers { /// The [`Receiver`] which receives incoming messages from the `ImageCache`. #[no_trace] - pub(crate) image_cache_receiver: Receiver, + pub(crate) image_cache_receiver: Receiver, /// For receiving commands from an optional devtools server. Will be ignored if no such server /// exists. When devtools are not active this will be [`crossbeam_channel::never()`]. diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 7f641ede199..e138e7114d3 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -71,7 +71,7 @@ use js::jsval::UndefinedValue; use js::rust::ParentRuntime; use media::WindowGLContext; use metrics::MAX_TASK_NS; -use net_traits::image_cache::{ImageCache, ImageCacheMessage}; +use net_traits::image_cache::{ImageCache, ImageCacheResponseMessage}; use net_traits::request::{Referrer, RequestId}; use net_traits::response::ResponseInit; use net_traits::storage_thread::StorageType; @@ -2095,9 +2095,9 @@ impl ScriptThread { } } - fn handle_msg_from_image_cache(&self, response: ImageCacheMessage) { + fn handle_msg_from_image_cache(&self, response: ImageCacheResponseMessage) { match response { - ImageCacheMessage::NotifyPendingImageLoadStatus(pending_image_response) => { + ImageCacheResponseMessage::NotifyPendingImageLoadStatus(pending_image_response) => { let window = self .documents .borrow() @@ -2106,10 +2106,10 @@ impl ScriptThread { window.pending_image_notification(pending_image_response); } }, - ImageCacheMessage::VectorImageRasterizationCompleted(pipeline_id, image_id, size) => { - let window = self.documents.borrow().find_window(pipeline_id); + ImageCacheResponseMessage::VectorImageRasterizationComplete(response) => { + let window = self.documents.borrow().find_window(response.pipeline_id); if let Some(ref window) = window { - window.handle_image_rasterization_complete_notification(image_id, size); + window.handle_image_rasterization_complete_notification(response); } }, }; diff --git a/components/shared/net/image_cache.rs b/components/shared/net/image_cache.rs index 63bc61909d2..eab10475e9a 100644 --- a/components/shared/net/image_cache.rs +++ b/components/shared/net/image_cache.rs @@ -24,9 +24,10 @@ use crate::request::CorsSettings; // ====================================================================== pub type VectorImageId = PendingImageId; + // Represents either a raster image for which the pixel data is available // or a vector image for which only the natural dimensions are available -// and thus require an further rasterization step. +// and thus requires a further rasterization step to render. #[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] pub enum Image { Raster(#[conditional_malloc_size_of] Arc), @@ -82,12 +83,12 @@ pub enum ImageOrMetadataAvailable { pub struct ImageLoadListener { pipeline_id: PipelineId, pub id: PendingImageId, - sender: IpcSender, + sender: IpcSender, } impl ImageLoadListener { pub fn new( - sender: IpcSender, + sender: IpcSender, pipeline_id: PipelineId, id: PendingImageId, ) -> ImageLoadListener { @@ -103,14 +104,15 @@ impl ImageLoadListener { // This send can fail if thread waiting for this notification has panicked. // That's not a case that's worth warning about. // TODO(#15501): are there cases in which we should perform cleanup? - let msg = PendingImageResponse { - pipeline_id: self.pipeline_id, - response, - id: self.id, - }; let _ = self .sender - .send(ImageCacheMessage::NotifyPendingImageLoadStatus(msg)); + .send(ImageCacheResponseMessage::NotifyPendingImageLoadStatus( + PendingImageResponse { + pipeline_id: self.pipeline_id, + response, + id: self.id, + }, + )); } } @@ -139,9 +141,16 @@ pub struct PendingImageResponse { } #[derive(Clone, Debug, Deserialize, Serialize)] -pub enum ImageCacheMessage { +pub struct RasterizationCompleteResponse { + pub pipeline_id: PipelineId, + pub image_id: PendingImageId, + pub requested_size: DeviceIntSize, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum ImageCacheResponseMessage { NotifyPendingImageLoadStatus(PendingImageResponse), - VectorImageRasterizationCompleted(PipelineId, PendingImageId, DeviceIntSize), + VectorImageRasterizationComplete(RasterizationCompleteResponse), } #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] @@ -184,26 +193,26 @@ pub trait ImageCache: Sync + Send { use_placeholder: UsePlaceholder, ) -> ImageCacheResult; - // Returns `Some` if the given `image_id` has already been rasterized at the given `size`. - // Otherwise, triggers a new job to perform the rasterization. If a notification - // is needed after rasterization is completed, the `add_rasterization_complete_listener` - // API below can be used to add a listener. + /// Returns `Some` if the given `image_id` has already been rasterized at the given `size`. + /// Otherwise, triggers a new job to perform the rasterization. If a notification + /// is needed after rasterization is completed, the `add_rasterization_complete_listener` + /// API below can be used to add a listener. fn rasterize_vector_image( &self, image_id: VectorImageId, size: DeviceIntSize, ) -> Option; - // Adds a new listener to be notified once the given `image_id` has been rasterized at - // the given `size`. The listener will receive a `VectorImageRasterizationCompleted` - // message on the given `sender`, even if the listener is called after rasterization - // at has already completed. + /// Adds a new listener to be notified once the given `image_id` has been rasterized at + /// the given `size`. The listener will receive a `VectorImageRasterizationComplete` + /// message on the given `sender`, even if the listener is called after rasterization + /// at has already completed. fn add_rasterization_complete_listener( &self, pipeline_id: PipelineId, image_id: VectorImageId, size: DeviceIntSize, - sender: IpcSender, + sender: IpcSender, ); /// Add a new listener for the given pending image id. If the image is already present, diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs index 83a3f96057d..e82ee16e24b 100644 --- a/components/shared/script_layout/lib.rs +++ b/components/shared/script_layout/lib.rs @@ -154,8 +154,9 @@ pub struct PendingImage { pub origin: ImmutableOrigin, } -// A vector image that is fully loaded (i.e has a parsed SVG tree) but not yet -// rasterized to the size needed by layout. +/// A data structure to tarck vector image that are fully loaded (i.e has a parsed SVG +/// tree) but not yet rasterized to the size needed by layout. The rasterization is +/// happening in the image cache. #[derive(Debug)] pub struct PendingRasterizationImage { pub node: UntrustedNodeAddress,