mirror of
https://github.com/servo/servo.git
synced 2025-06-13 19:04:30 +00:00
layout: Cache content block size contributions (#33964)
This is the first part of caching intermediary layout during flexbox layout. A later change will try to reuse these layouts, when possible, for actual item layout and re-layout due to stretching. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
7015e0fb5f
commit
01c9ecfe01
3 changed files with 57 additions and 10 deletions
|
@ -181,6 +181,7 @@ where
|
||||||
independent_formatting_context: IndependentFormattingContext::NonReplaced(
|
independent_formatting_context: IndependentFormattingContext::NonReplaced(
|
||||||
non_replaced,
|
non_replaced,
|
||||||
),
|
),
|
||||||
|
cached_layout: Default::default(),
|
||||||
})))
|
})))
|
||||||
},
|
},
|
||||||
FlexLevelJob::Element {
|
FlexLevelJob::Element {
|
||||||
|
@ -212,6 +213,7 @@ where
|
||||||
contents,
|
contents,
|
||||||
self.text_decoration_line,
|
self.text_decoration_line,
|
||||||
),
|
),
|
||||||
|
cached_layout: Default::default(),
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
box_slot.set(LayoutBox::FlexLevel(box_.clone()));
|
box_slot.set(LayoutBox::FlexLevel(box_.clone()));
|
||||||
|
|
|
@ -21,7 +21,10 @@ use style::values::specified::align::AlignFlags;
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
|
|
||||||
use super::geom::{FlexAxis, FlexRelativeRect, FlexRelativeSides, FlexRelativeVec2};
|
use super::geom::{FlexAxis, FlexRelativeRect, FlexRelativeSides, FlexRelativeVec2};
|
||||||
use super::{FlexContainer, FlexContainerConfig, FlexItemBox, FlexLevelBox};
|
use super::{
|
||||||
|
FlexContainer, FlexContainerConfig, FlexItemBox, FlexItemLayoutCache,
|
||||||
|
FlexItemLayoutCacheDescriptor, FlexLevelBox,
|
||||||
|
};
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::formatting_contexts::{Baselines, IndependentFormattingContext, IndependentLayout};
|
use crate::formatting_contexts::{Baselines, IndependentFormattingContext, IndependentLayout};
|
||||||
|
@ -1708,6 +1711,9 @@ impl FlexItem<'_> {
|
||||||
flex_context: &FlexContext,
|
flex_context: &FlexContext,
|
||||||
used_cross_size_override: Option<Au>,
|
used_cross_size_override: Option<Au>,
|
||||||
) -> FlexItemLayoutResult {
|
) -> FlexItemLayoutResult {
|
||||||
|
// Clear any layout cache information so that it doesn't persist until the next layout.
|
||||||
|
self.box_.cached_layout.borrow_mut().take();
|
||||||
|
|
||||||
let containing_block = flex_context.containing_block;
|
let containing_block = flex_context.containing_block;
|
||||||
let mut positioning_context = PositioningContext::new_for_style(self.box_.style())
|
let mut positioning_context = PositioningContext::new_for_style(self.box_.style())
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
|
@ -2572,14 +2578,27 @@ impl FlexItemBox {
|
||||||
style: &non_replaced.style,
|
style: &non_replaced.style,
|
||||||
};
|
};
|
||||||
let mut content_block_size = || {
|
let mut content_block_size = || {
|
||||||
non_replaced
|
if let Some(cache) = &*self.cached_layout.borrow() {
|
||||||
.layout(
|
if cache.descriptor.compatible_with_size(inline_size) {
|
||||||
|
return cache.descriptor.content_block_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let layout = non_replaced.layout(
|
||||||
flex_context.layout_context,
|
flex_context.layout_context,
|
||||||
&mut positioning_context,
|
&mut positioning_context,
|
||||||
&item_as_containing_block,
|
&item_as_containing_block,
|
||||||
flex_context.containing_block,
|
flex_context.containing_block,
|
||||||
)
|
);
|
||||||
.content_block_size
|
|
||||||
|
let content_block_size = layout.content_block_size;
|
||||||
|
*self.cached_layout.borrow_mut() = Some(FlexItemLayoutCache {
|
||||||
|
descriptor: FlexItemLayoutCacheDescriptor {
|
||||||
|
containing_block_inline_size: item_as_containing_block.inline_size,
|
||||||
|
content_block_size: layout.content_block_size,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
content_block_size
|
||||||
};
|
};
|
||||||
match intrinsic_sizing_mode {
|
match intrinsic_sizing_mode {
|
||||||
IntrinsicSizingMode::Contribution => {
|
IntrinsicSizingMode::Contribution => {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use app_units::Au;
|
||||||
use geom::{FlexAxis, MainStartCrossStart};
|
use geom::{FlexAxis, MainStartCrossStart};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use servo_arc::Arc as ServoArc;
|
use servo_arc::Arc as ServoArc;
|
||||||
|
@ -112,9 +113,17 @@ pub(crate) enum FlexLevelBox {
|
||||||
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
|
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Serialize)]
|
||||||
pub(crate) struct FlexItemBox {
|
pub(crate) struct FlexItemBox {
|
||||||
independent_formatting_context: IndependentFormattingContext,
|
independent_formatting_context: IndependentFormattingContext,
|
||||||
|
#[serde(skip)]
|
||||||
|
cached_layout: ArcRefCell<Option<FlexItemLayoutCache>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for FlexItemBox {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str("FlexItemBox")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlexItemBox {
|
impl FlexItemBox {
|
||||||
|
@ -126,3 +135,20 @@ impl FlexItemBox {
|
||||||
self.independent_formatting_context.base_fragment_info()
|
self.independent_formatting_context.base_fragment_info()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct FlexItemLayoutCacheDescriptor {
|
||||||
|
containing_block_inline_size: Au,
|
||||||
|
content_block_size: Au,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlexItemLayoutCacheDescriptor {
|
||||||
|
fn compatible_with_size(&self, inline: Au) -> bool {
|
||||||
|
inline == self.containing_block_inline_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A cache to avoid multiple layouts during flexbox layout.
|
||||||
|
struct FlexItemLayoutCache {
|
||||||
|
descriptor: FlexItemLayoutCacheDescriptor,
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue