mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Auto merge of #18170 - emilio:stylist-stylesheet-set, r=SimonSapin
style: Move the StyleSheetSet into the Stylist. This will allow tracking whether there have been only additions to the stylesheet set, and in that case don't destroy and completely rebuild the invalidation map. This is on top of #18143. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18170) <!-- Reviewable:end -->
This commit is contained in:
commit
019b125963
8 changed files with 467 additions and 350 deletions
|
@ -129,15 +129,13 @@ use style::context::RegisteredSpeculativePainters;
|
|||
use style::dom::{ShowSubtree, ShowSubtreeDataAndPrimaryValues, TElement, TNode};
|
||||
use style::error_reporting::{NullReporter, RustLogReporter};
|
||||
use style::invalidation::element::restyle_hints::RestyleHint;
|
||||
use style::invalidation::media_queries::{MediaListKey, ToMediaListKey};
|
||||
use style::logical_geometry::LogicalPoint;
|
||||
use style::media_queries::{Device, MediaList, MediaType};
|
||||
use style::properties::PropertyId;
|
||||
use style::selector_parser::SnapshotMap;
|
||||
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW};
|
||||
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
|
||||
use style::stylesheet_set::StylesheetSet;
|
||||
use style::stylesheets::{Origin, Stylesheet, StylesheetContents, StylesheetInDocument, UserAgentStylesheets};
|
||||
use style::stylesheets::{Origin, OriginSet, Stylesheet, DocumentStyleSheet, StylesheetInDocument, UserAgentStylesheets};
|
||||
use style::stylist::Stylist;
|
||||
use style::thread_state;
|
||||
use style::timer::Timer;
|
||||
|
@ -147,35 +145,6 @@ use style_traits::CSSPixel;
|
|||
use style_traits::DevicePixel;
|
||||
use style_traits::SpeculativePainter;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct DocumentStyleSheet(ServoArc<Stylesheet>);
|
||||
|
||||
impl PartialEq for DocumentStyleSheet {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
ServoArc::ptr_eq(&self.0, &other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToMediaListKey for DocumentStyleSheet {
|
||||
fn to_media_list_key(&self) -> MediaListKey {
|
||||
self.0.to_media_list_key()
|
||||
}
|
||||
}
|
||||
|
||||
impl StylesheetInDocument for DocumentStyleSheet {
|
||||
fn contents(&self, guard: &SharedRwLockReadGuard) -> &StylesheetContents {
|
||||
self.0.contents(guard)
|
||||
}
|
||||
|
||||
fn media<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> Option<&'a MediaList> {
|
||||
self.0.media(guard)
|
||||
}
|
||||
|
||||
fn enabled(&self) -> bool {
|
||||
self.0.enabled()
|
||||
}
|
||||
}
|
||||
|
||||
/// Information needed by the layout thread.
|
||||
pub struct LayoutThread {
|
||||
/// The ID of the pipeline that we belong to.
|
||||
|
@ -190,9 +159,6 @@ pub struct LayoutThread {
|
|||
/// Performs CSS selector matching and style resolution.
|
||||
stylist: Stylist,
|
||||
|
||||
/// The list of stylesheets synchronized with the document.
|
||||
stylesheets: StylesheetSet<DocumentStyleSheet>,
|
||||
|
||||
/// Is the current reflow of an iframe, as opposed to a root window?
|
||||
is_iframe: bool,
|
||||
|
||||
|
@ -549,7 +515,6 @@ impl LayoutThread {
|
|||
webrender_api: webrender_api_sender.create_api(),
|
||||
webrender_document,
|
||||
stylist: Stylist::new(device, QuirksMode::NoQuirks),
|
||||
stylesheets: StylesheetSet::new(),
|
||||
rw_data: Arc::new(Mutex::new(
|
||||
LayoutThreadData {
|
||||
constellation_chan: constellation_chan,
|
||||
|
@ -704,16 +669,14 @@ impl LayoutThread {
|
|||
|
||||
match before_stylesheet {
|
||||
Some(insertion_point) => {
|
||||
self.stylesheets.insert_stylesheet_before(
|
||||
Some(self.stylist.device()),
|
||||
self.stylist.insert_stylesheet_before(
|
||||
DocumentStyleSheet(stylesheet.clone()),
|
||||
DocumentStyleSheet(insertion_point),
|
||||
&guard,
|
||||
)
|
||||
}
|
||||
None => {
|
||||
self.stylesheets.append_stylesheet(
|
||||
Some(self.stylist.device()),
|
||||
self.stylist.append_stylesheet(
|
||||
DocumentStyleSheet(stylesheet.clone()),
|
||||
&guard,
|
||||
)
|
||||
|
@ -722,8 +685,7 @@ impl LayoutThread {
|
|||
}
|
||||
Msg::RemoveStylesheet(stylesheet) => {
|
||||
let guard = stylesheet.shared_lock.read();
|
||||
self.stylesheets.remove_stylesheet(
|
||||
Some(self.stylist.device()),
|
||||
self.stylist.remove_stylesheet(
|
||||
DocumentStyleSheet(stylesheet.clone()),
|
||||
&guard,
|
||||
);
|
||||
|
@ -1188,8 +1150,9 @@ impl LayoutThread {
|
|||
let author_guard = document_shared_lock.read();
|
||||
let device = Device::new(MediaType::screen(), initial_viewport, device_pixel_ratio);
|
||||
let sheet_origins_affected_by_device_change =
|
||||
self.stylist.set_device(device, &author_guard, self.stylesheets.iter());
|
||||
self.stylist.set_device(device, &author_guard);
|
||||
|
||||
self.stylist.force_stylesheet_origins_dirty(sheet_origins_affected_by_device_change);
|
||||
self.viewport_size =
|
||||
self.stylist.viewport_constraints().map_or(current_screen_size, |constraints| {
|
||||
debug!("Viewport constraints: {:?}", constraints);
|
||||
|
@ -1207,7 +1170,7 @@ impl LayoutThread {
|
|||
.send(ConstellationMsg::ViewportConstrained(self.id, constraints.clone()))
|
||||
.unwrap();
|
||||
}
|
||||
if self.stylesheets.iter().any(|sheet| sheet.0.dirty_on_viewport_size_change()) {
|
||||
if self.stylist.iter_stylesheets().any(|sheet| sheet.0.dirty_on_viewport_size_change()) {
|
||||
let mut iter = element.as_node().traverse_preorder();
|
||||
|
||||
let mut next = iter.next();
|
||||
|
@ -1241,65 +1204,41 @@ impl LayoutThread {
|
|||
ua_or_user: &ua_or_user_guard,
|
||||
};
|
||||
|
||||
let needs_dirtying = {
|
||||
debug!("Flushing stylist");
|
||||
|
||||
let mut origins_dirty = sheet_origins_affected_by_device_change;
|
||||
|
||||
debug!("Device changes: {:?}", origins_dirty);
|
||||
|
||||
{
|
||||
if self.first_reflow.get() {
|
||||
debug!("First reflow, rebuilding user and UA rules");
|
||||
|
||||
origins_dirty |= Origin::User;
|
||||
origins_dirty |= Origin::UserAgent;
|
||||
let mut ua_and_user = OriginSet::empty();
|
||||
ua_and_user |= Origin::User;
|
||||
ua_and_user |= Origin::UserAgent;
|
||||
self.stylist.force_stylesheet_origins_dirty(ua_and_user);
|
||||
for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets {
|
||||
self.handle_add_stylesheet(stylesheet, &ua_or_user_guard);
|
||||
}
|
||||
}
|
||||
|
||||
let (iter, invalidation_origins_dirty) = self.stylesheets.flush(Some(element));
|
||||
debug!("invalidation: {:?}", invalidation_origins_dirty);
|
||||
|
||||
origins_dirty |= invalidation_origins_dirty;
|
||||
|
||||
if data.stylesheets_changed {
|
||||
debug!("Doc sheets changed, flushing author sheets too");
|
||||
origins_dirty |= Origin::Author;
|
||||
self.stylist.force_stylesheet_origins_dirty(Origin::Author.into());
|
||||
}
|
||||
|
||||
if !origins_dirty.is_empty() {
|
||||
let mut extra_data = Default::default();
|
||||
self.stylist.rebuild(
|
||||
iter,
|
||||
&guards,
|
||||
Some(ua_stylesheets),
|
||||
/* author_style_disabled = */ false,
|
||||
&mut extra_data,
|
||||
origins_dirty,
|
||||
);
|
||||
}
|
||||
|
||||
!origins_dirty.is_empty()
|
||||
};
|
||||
|
||||
let needs_reflow = viewport_size_changed && !needs_dirtying;
|
||||
if needs_dirtying {
|
||||
if let Some(mut d) = element.mutate_data() {
|
||||
if d.has_styles() {
|
||||
d.restyle.hint.insert(RestyleHint::restyle_subtree());
|
||||
}
|
||||
}
|
||||
let mut extra_data = Default::default();
|
||||
self.stylist.flush(
|
||||
&guards,
|
||||
Some(ua_stylesheets),
|
||||
&mut extra_data,
|
||||
Some(element),
|
||||
);
|
||||
}
|
||||
if needs_reflow {
|
||||
|
||||
if viewport_size_changed {
|
||||
if let Some(mut flow) = self.try_get_layout_root(element.as_node()) {
|
||||
LayoutThread::reflow_all_nodes(FlowRef::deref_mut(&mut flow));
|
||||
}
|
||||
}
|
||||
|
||||
let restyles = document.drain_pending_restyles();
|
||||
debug!("Draining restyles: {} (needs dirtying? {:?})",
|
||||
restyles.len(), needs_dirtying);
|
||||
debug!("Draining restyles: {}", restyles.len());
|
||||
|
||||
let mut map = SnapshotMap::new();
|
||||
let elements_with_snapshot: Vec<_> =
|
||||
restyles
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue