mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
layout: Only create a LayoutContext
if restyling (#37726)
The creation of `LayoutContext` does more work than necessary if layout just needs to do something like make a display list and not restyle and relayout. This change makes it so that these kind of non-restyle layouts do not need to create a display list. In addition, the creation of `LayoutContext` is better encapsulate Testing: This should not change observable behavior and is thus covered by existing WPT tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
5e44582277
commit
9232b0f550
9 changed files with 208 additions and 196 deletions
|
@ -4,7 +4,6 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use base::id::PipelineId;
|
||||
use euclid::Size2D;
|
||||
use fnv::FnvHashMap;
|
||||
use fonts::FontContext;
|
||||
|
@ -26,10 +25,8 @@ use webrender_api::units::{DeviceIntSize, DeviceSize};
|
|||
|
||||
pub(crate) type CachedImageOrError = Result<CachedImage, ResolveImageError>;
|
||||
|
||||
pub struct LayoutContext<'a> {
|
||||
pub id: PipelineId,
|
||||
pub(crate) struct LayoutContext<'a> {
|
||||
pub use_rayon: bool,
|
||||
pub origin: ImmutableOrigin,
|
||||
|
||||
/// Bits shared by the layout and style system.
|
||||
pub style_context: SharedStyleContext<'a>,
|
||||
|
@ -37,31 +34,12 @@ pub struct LayoutContext<'a> {
|
|||
/// A FontContext to be used during layout.
|
||||
pub font_context: Arc<FontContext>,
|
||||
|
||||
/// Reference to the script thread image cache.
|
||||
pub image_cache: Arc<dyn ImageCache>,
|
||||
|
||||
/// A list of in-progress image loads to be shared with the script thread.
|
||||
pub pending_images: Mutex<Vec<PendingImage>>,
|
||||
|
||||
/// A list of fully loaded vector images that need to be rasterized to a specific
|
||||
/// size determined by layout. This will be shared with the script thread.
|
||||
pub pending_rasterization_images: Mutex<Vec<PendingRasterizationImage>>,
|
||||
|
||||
/// A collection of `<iframe>` sizes to send back to script.
|
||||
pub iframe_sizes: Mutex<IFrameSizes>,
|
||||
|
||||
// A cache that maps image resources used in CSS (e.g as the `url()` value
|
||||
// for `background-image` or `content` property) to the final resolved image data.
|
||||
pub resolved_images_cache:
|
||||
Arc<RwLock<FnvHashMap<(ServoUrl, UsePlaceholder), CachedImageOrError>>>,
|
||||
|
||||
/// A shared reference to script's map of DOM nodes with animated images. This is used
|
||||
/// to manage image animations in script and inform the script about newly animating
|
||||
/// nodes.
|
||||
pub node_to_animating_image_map: Arc<RwLock<FxHashMap<OpaqueNode, ImageAnimationState>>>,
|
||||
|
||||
/// The DOM node that is highlighted by the devtools inspector, if any
|
||||
pub highlighted_dom_node: Option<OpaqueNode>,
|
||||
/// An [`ImageResolver`] used for resolving images during box and fragment
|
||||
/// tree construction. Later passed to display list construction.
|
||||
pub image_resolver: Arc<ImageResolver>,
|
||||
}
|
||||
|
||||
pub enum ResolvedImage<'a> {
|
||||
|
@ -74,15 +52,6 @@ pub enum ResolvedImage<'a> {
|
|||
},
|
||||
}
|
||||
|
||||
impl Drop for LayoutContext<'_> {
|
||||
fn drop(&mut self) {
|
||||
if !std::thread::panicking() {
|
||||
assert!(self.pending_images.lock().is_empty());
|
||||
assert!(self.pending_rasterization_images.lock().is_empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum ResolveImageError {
|
||||
LoadError,
|
||||
|
@ -103,12 +72,44 @@ pub(crate) enum LayoutImageCacheResult {
|
|||
LoadError,
|
||||
}
|
||||
|
||||
impl LayoutContext<'_> {
|
||||
#[inline(always)]
|
||||
pub fn shared_context(&self) -> &SharedStyleContext {
|
||||
&self.style_context
|
||||
}
|
||||
pub(crate) struct ImageResolver {
|
||||
/// The origin of the `Document` that this [`ImageResolver`] resolves images for.
|
||||
pub origin: ImmutableOrigin,
|
||||
|
||||
/// Reference to the script thread image cache.
|
||||
pub image_cache: Arc<dyn ImageCache>,
|
||||
|
||||
/// A list of in-progress image loads to be shared with the script thread.
|
||||
pub pending_images: Mutex<Vec<PendingImage>>,
|
||||
|
||||
/// A list of fully loaded vector images that need to be rasterized to a specific
|
||||
/// size determined by layout. This will be shared with the script thread.
|
||||
pub pending_rasterization_images: Mutex<Vec<PendingRasterizationImage>>,
|
||||
|
||||
/// A shared reference to script's map of DOM nodes with animated images. This is used
|
||||
/// to manage image animations in script and inform the script about newly animating
|
||||
/// nodes.
|
||||
pub node_to_animating_image_map: Arc<RwLock<FxHashMap<OpaqueNode, ImageAnimationState>>>,
|
||||
|
||||
// A cache that maps image resources used in CSS (e.g as the `url()` value
|
||||
// for `background-image` or `content` property) to the final resolved image data.
|
||||
pub resolved_images_cache:
|
||||
Arc<RwLock<FnvHashMap<(ServoUrl, UsePlaceholder), CachedImageOrError>>>,
|
||||
|
||||
/// The current animation timeline value used to properly initialize animating images.
|
||||
pub animation_timeline_value: f64,
|
||||
}
|
||||
|
||||
impl Drop for ImageResolver {
|
||||
fn drop(&mut self) {
|
||||
if !std::thread::panicking() {
|
||||
assert!(self.pending_images.lock().is_empty());
|
||||
assert!(self.pending_rasterization_images.lock().is_empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ImageResolver {
|
||||
pub(crate) fn get_or_request_image_or_meta(
|
||||
&self,
|
||||
node: OpaqueNode,
|
||||
|
@ -155,18 +156,14 @@ impl LayoutContext<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn handle_animated_image(&self, node: OpaqueNode, image: Arc<RasterImage>) {
|
||||
pub(crate) fn handle_animated_image(&self, node: OpaqueNode, image: Arc<RasterImage>) {
|
||||
let mut map = self.node_to_animating_image_map.write();
|
||||
if !image.should_animate() {
|
||||
map.remove(&node);
|
||||
return;
|
||||
}
|
||||
let new_image_animation_state = || {
|
||||
ImageAnimationState::new(
|
||||
image.clone(),
|
||||
self.shared_context().current_time_for_animations,
|
||||
)
|
||||
};
|
||||
let new_image_animation_state =
|
||||
|| ImageAnimationState::new(image.clone(), self.animation_timeline_value);
|
||||
|
||||
let entry = map.entry(node).or_insert_with(new_image_animation_state);
|
||||
|
||||
|
@ -218,7 +215,7 @@ impl LayoutContext<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn rasterize_vector_image(
|
||||
pub(crate) fn rasterize_vector_image(
|
||||
&self,
|
||||
image_id: PendingImageId,
|
||||
size: DeviceIntSize,
|
||||
|
@ -237,7 +234,7 @@ impl LayoutContext<'_> {
|
|||
result
|
||||
}
|
||||
|
||||
pub fn resolve_image<'a>(
|
||||
pub(crate) fn resolve_image<'a>(
|
||||
&self,
|
||||
node: Option<OpaqueNode>,
|
||||
image: &'a Image,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue