Auto merge of #16664 - emilio:fix-eternal-todo, r=bholley

style: Avoid allocating a unique nsStyleSVG and nsStyleBackground per element

Should also help with https://bugzilla.mozilla.org/show_bug.cgi?id=1360881, and it's a TODO that has always been there.

This is on top of #16663, so only last commit needs review.

<!-- 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/16664)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-04-30 19:14:43 -05:00 committed by GitHub
commit 38bbacda70
2 changed files with 23 additions and 9 deletions

View file

@ -2774,10 +2774,6 @@ fn static_assert() {
% for member in fill_fields.split(): % for member in fill_fields.split():
max_len = cmp::max(max_len, self.gecko.${image_layers_field}.${member}Count); max_len = cmp::max(max_len, self.gecko.${image_layers_field}.${member}Count);
% endfor % endfor
// XXXManishearth Gecko does an optimization here where it only
// fills things in if any of the properties have been set
unsafe { unsafe {
// While we could do this manually, we'd need to also manually // While we could do this manually, we'd need to also manually
// run all the copy constructors, so we just delegate to gecko // run all the copy constructors, so we just delegate to gecko

View file

@ -2044,6 +2044,15 @@ impl<'a, T: 'a> StyleStructRef<'a, T>
} }
} }
/// Get a mutable reference to the owned struct, or `None` if the struct
/// hasn't been mutated.
pub fn get_if_mutated(&mut self) -> Option<<&mut T> {
match *self {
StyleStructRef::Owned(ref mut v) => Some(v),
StyleStructRef::Borrowed(..) => None,
}
}
/// Returns an `Arc` to the internal struct, constructing one if /// Returns an `Arc` to the internal struct, constructing one if
/// appropriate. /// appropriate.
pub fn build(self) -> Arc<T> { pub fn build(self) -> Arc<T> {
@ -2141,6 +2150,13 @@ impl<'a> StyleBuilder<'a> {
pub fn mutate_${style_struct.name_lower}(&mut self) -> &mut style_structs::${style_struct.name} { pub fn mutate_${style_struct.name_lower}(&mut self) -> &mut style_structs::${style_struct.name} {
self.${style_struct.ident}.mutate() self.${style_struct.ident}.mutate()
} }
/// Gets a mutable view of the current `${style_struct.name}` style,
/// only if it's been mutated before.
pub fn get_${style_struct.name_lower}_if_mutated(&mut self)
-> Option<<&mut style_structs::${style_struct.name}> {
self.${style_struct.ident}.get_if_mutated()
}
% endfor % endfor
/// Returns whether this computed style represents a floated object. /// Returns whether this computed style represents a floated object.
@ -2546,11 +2562,13 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
} }
% if product == "gecko": % if product == "gecko":
// FIXME(emilio): This is effectively creating a new nsStyleBackground if let Some(ref mut bg) = style.get_background_if_mutated() {
// and nsStyleSVG per element. We should only do this when necessary bg.fill_arrays();
// using the `seen` bitfield! }
style.mutate_background().fill_arrays();
style.mutate_svg().fill_arrays(); if let Some(ref mut svg) = style.get_svg_if_mutated() {
svg.fill_arrays();
}
% endif % endif
if is_root_element { if is_root_element {