Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync changes from mozilla-central gfx/wr #3845

Merged
merged 4 commits into from Jan 27, 2020
Prev

Bug 1558926 - Part 5: Store a reference to cached display item data i…

  • Loading branch information
mikokm authored and moz-gfx committed Jan 27, 2020
commit 1d7c4c964fda7539387a897082d68d7fa35b521e
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use api::{BuiltDisplayList, ColorF, DynamicProperties, Epoch, FontRenderMode};
use api::{BuiltDisplayList, DisplayItemCache, ColorF, DynamicProperties, Epoch, FontRenderMode};
use api::{PipelineId, PropertyBinding, PropertyBindingId, MixBlendMode, StackingContext};
use api::units::*;
use crate::composite::CompositorKind;
@@ -134,6 +134,7 @@ pub struct ScenePipeline {
pub content_size: LayoutSize,
pub background_color: Option<ColorF>,
pub display_list: BuiltDisplayList,
pub display_list_cache: DisplayItemCache,
}

/// A complete representation of the layout bundling visible pipelines together.
@@ -168,12 +169,20 @@ impl Scene {
viewport_size: LayoutSize,
content_size: LayoutSize,
) {
let pipeline = self.pipelines.remove(&pipeline_id);
let mut display_list_cache = pipeline.map_or(Default::default(), |p| {
p.display_list_cache
});

display_list_cache.update(&display_list);

let new_pipeline = ScenePipeline {
pipeline_id,
viewport_size,
content_size,
background_color,
display_list,
display_list_cache,
};

self.pipelines.insert(pipeline_id, new_pipeline);
@@ -449,8 +449,9 @@ impl<'a> SceneBuilder<'a> {
device_pixel_scale,
);

let cache = &root_pipeline.display_list_cache;
builder.build_items(
&mut root_pipeline.display_list.iter(),
&mut root_pipeline.display_list.iter_with_cache(cache),
root_pipeline.pipeline_id,
true,
);
@@ -687,30 +688,54 @@ impl<'a> SceneBuilder<'a> {
apply_pipeline_clip: bool,
) {
loop {
let subtraversal = {
let item = match traversal.next() {
Some(item) => item,
None => break,
};
let item = match traversal.next() {
Some(item) => item,
None => break,
};

match item.item() {
DisplayItem::PopReferenceFrame |
DisplayItem::PopStackingContext => return,
_ => (),
let subtraversal = match item.item() {
DisplayItem::PushStackingContext(ref info) => {
let space = self.get_space(&info.spatial_id);
let mut subtraversal = item.sub_iter();
self.build_stacking_context(
&mut subtraversal,
pipeline_id,
&info.stacking_context,
space,
info.origin,
item.filters(),
&item.filter_datas(),
item.filter_primitives(),
info.prim_flags,
apply_pipeline_clip,
);
Some(subtraversal)
}

self.build_item(
item,
pipeline_id,
apply_pipeline_clip,
)
DisplayItem::PushReferenceFrame(ref info) => {
let parent_space = self.get_space(&info.parent_spatial_id);
let mut subtraversal = item.sub_iter();
self.build_reference_frame(
&mut subtraversal,
pipeline_id,
parent_space,
info.origin,
&info.reference_frame,
apply_pipeline_clip,
);
Some(subtraversal)
}
DisplayItem::PopReferenceFrame |
DisplayItem::PopStackingContext => return,
_ => None,
};

// If build_item created a sub-traversal, we need `traversal` to have the
// same state as the completed subtraversal, so we reinitialize it here.
if let Some(mut subtraversal) = subtraversal {
subtraversal.merge_debug_stats_from(traversal);
*traversal = subtraversal;
} else {
self.build_item(item, pipeline_id, apply_pipeline_clip);
}
}

@@ -958,8 +983,10 @@ impl<'a> SceneBuilder<'a> {

self.rf_mapper.push_scope();
self.iframe_depth += 1;

let cache = &pipeline.display_list_cache;
self.build_items(
&mut pipeline.display_list.iter(),
&mut pipeline.display_list.iter_with_cache(cache),
pipeline.pipeline_id,
true,
);
@@ -1061,10 +1088,10 @@ impl<'a> SceneBuilder<'a> {

fn build_item<'b>(
&'b mut self,
item: DisplayItemRef<'a, 'b>,
item: DisplayItemRef,
pipeline_id: PipelineId,
apply_pipeline_clip: bool,
) -> Option<BuiltDisplayListIter<'a>> {
) {
match *item.item() {
DisplayItem::Image(ref info) => {
let (layout, _, clip_and_scroll) = self.process_common_properties_with_bounds(
@@ -1299,36 +1326,6 @@ impl<'a> SceneBuilder<'a> {
item.gradient_stops(),
);
}
DisplayItem::PushStackingContext(ref info) => {
let space = self.get_space(&info.spatial_id);
let mut subtraversal = item.sub_iter();
self.build_stacking_context(
&mut subtraversal,
pipeline_id,
&info.stacking_context,
space,
info.origin,
item.filters(),
item.filter_datas(),
item.filter_primitives(),
info.prim_flags,
apply_pipeline_clip,
);
return Some(subtraversal);
}
DisplayItem::PushReferenceFrame(ref info) => {
let parent_space = self.get_space(&info.parent_spatial_id);
let mut subtraversal = item.sub_iter();
self.build_reference_frame(
&mut subtraversal,
pipeline_id,
parent_space,
info.origin,
&info.reference_frame,
apply_pipeline_clip,
);
return Some(subtraversal);
}
DisplayItem::Iframe(ref info) => {
let space = self.get_space(&info.space_and_clip.spatial_id);
self.build_iframe(
@@ -1456,10 +1453,18 @@ impl<'a> SceneBuilder<'a> {
DisplayItem::SetFilterData |
DisplayItem::SetFilterPrimitives => {}

// Special items that are handled in the parent method
DisplayItem::PushStackingContext(..) |
DisplayItem::PushReferenceFrame(..) |
DisplayItem::PopReferenceFrame |
DisplayItem::PopStackingContext => {
unreachable!("Should have returned in parent method.")
}

DisplayItem::ReuseItem(..) => {
unreachable!("Iterator logic error")
}

DisplayItem::PushShadow(info) => {
let clip_and_scroll = self.get_clip_and_scroll(
&info.space_and_clip.clip_id,
@@ -1473,8 +1478,6 @@ impl<'a> SceneBuilder<'a> {
self.pop_all_shadows();
}
}

None
}

// Given a list of clip sources, a positioning node and
@@ -163,6 +163,8 @@ pub enum DisplayItem {
PopReferenceFrame,
PopStackingContext,
PopAllShadows,

ReuseItem(ItemKey),
}

/// This is a "complete" version of the DisplayItem, with all implicit trailing
@@ -203,6 +205,8 @@ pub enum DebugDisplayItem {
PopReferenceFrame,
PopStackingContext,
PopAllShadows,

ReuseItem(ItemKey),
}

#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
@@ -1476,6 +1480,7 @@ impl DisplayItem {
DisplayItem::Rectangle(..) => "rectangle",
DisplayItem::ScrollFrame(..) => "scroll_frame",
DisplayItem::SetGradientStops => "set_gradient_stops",
DisplayItem::ReuseItem(..) => "reuse_item",
DisplayItem::StickyFrame(..) => "sticky_frame",
DisplayItem::Text(..) => "text",
DisplayItem::YuvImage(..) => "yuv_image",
@@ -223,6 +223,58 @@ pub struct ItemStats {

pub struct DisplayItemRef<'a: 'b, 'b> {
iter: &'b BuiltDisplayListIter<'a>,
cached_item: Option<&'a CachedDisplayItem>,
}

// Some of these might just become ItemRanges
impl<'a, 'b> DisplayItemRef<'a, 'b> {
fn cached_or_iter_data<T>(
&self,
data: ItemRange<'a, T>
) -> ItemRange<'a, T> {
self.cached_item.map_or(data, |i| i.data_as_item_range())
}

pub fn display_list(&self) -> &BuiltDisplayList {
self.iter.display_list()
}

// Creates a new iterator where this element's iterator is, to hack around borrowck.
pub fn sub_iter(&self) -> BuiltDisplayListIter<'a> {
BuiltDisplayListIter::new(self.iter.list, self.iter.data, self.iter.cache)
}

pub fn item(&self) -> &di::DisplayItem {
self.cached_item.map_or(&self.iter.cur_item, |i| i.item())
}

pub fn clip_chain_items(&self) -> ItemRange<di::ClipId> {
self.iter.cur_clip_chain_items
}

pub fn complex_clip(&self) -> ItemRange<di::ComplexClipRegion> {
self.iter.cur_complex_clip
}

pub fn glyphs(&self) -> ItemRange<GlyphInstance> {
self.cached_or_iter_data(self.iter.cur_glyphs)
}

pub fn gradient_stops(&self) -> ItemRange<di::GradientStop> {
self.cached_or_iter_data(self.iter.cur_stops)
}

pub fn filters(&self) -> ItemRange<di::FilterOp> {
self.iter.cur_filters
}

pub fn filter_datas(&self) -> &Vec<TempFilterData> {
&self.iter.cur_filter_data
}

pub fn filter_primitives(&self) -> ItemRange<di::FilterPrimitive> {
self.iter.cur_filter_primitives
}
}

#[derive(PartialEq)]
@@ -457,7 +509,18 @@ impl<'a> BuiltDisplayListIter<'a> {
}

pub fn as_ref<'b>(&'b self) -> DisplayItemRef<'a, 'b> {
DisplayItemRef { iter: self }
let cached_item = match self.cur_item {
di::DisplayItem::ReuseItem(key) => {
debug_assert!(self.cache.is_some(), "Cache marker without cache!");
self.cache.and_then(|c| c.get_item(key))
}
_ => None
};

DisplayItemRef {
iter: self,
cached_item
}
}

pub fn skip_current_stacking_context(&mut self) {
@@ -517,50 +580,6 @@ impl<'a> BuiltDisplayListIter<'a> {
fn log_item_stats(&mut self) { /* no-op */ }
}

// Some of these might just become ItemRanges
impl<'a, 'b> DisplayItemRef<'a, 'b> {
pub fn item(&self) -> &di::DisplayItem {
&self.iter.cur_item
}

pub fn complex_clip(&self) -> ItemRange<di::ComplexClipRegion> {
self.iter.cur_complex_clip
}

pub fn gradient_stops(&self) -> ItemRange<di::GradientStop> {
self.iter.cur_stops
}

pub fn glyphs(&self) -> ItemRange<GlyphInstance> {
self.iter.cur_glyphs
}

pub fn filters(&self) -> ItemRange<di::FilterOp> {
self.iter.cur_filters
}

pub fn filter_datas(&self) -> &Vec<TempFilterData> {
&self.iter.cur_filter_data
}

pub fn filter_primitives(&self) -> ItemRange<di::FilterPrimitive> {
self.iter.cur_filter_primitives
}

pub fn clip_chain_items(&self) -> ItemRange<di::ClipId> {
self.iter.cur_clip_chain_items
}

pub fn display_list(&self) -> &BuiltDisplayList {
self.iter.display_list()
}

// Creates a new iterator where this element's iterator is, to hack around borrowck.
pub fn sub_iter(&self) -> BuiltDisplayListIter<'a> {
BuiltDisplayListIter::new_with_list_and_data(self.iter.list, self.iter.data)
}
}

impl<'a, T> AuxIter<'a, T> {
pub fn new(item: T, mut data: &'a [u8]) -> Self {
let mut size = 0usize;
@@ -674,6 +693,7 @@ impl Serialize for BuiltDisplayList {
Real::PopReferenceFrame => Debug::PopReferenceFrame,
Real::PopStackingContext => Debug::PopStackingContext,
Real::PopAllShadows => Debug::PopAllShadows,
Real::ReuseItem(k) => Debug::ReuseItem(k),
};
seq.serialize_element(&serial_di)?
}
@@ -777,6 +797,7 @@ impl<'de> Deserialize<'de> for BuiltDisplayList {
Debug::PopStackingContext => Real::PopStackingContext,
Debug::PopReferenceFrame => Real::PopReferenceFrame,
Debug::PopAllShadows => Real::PopAllShadows,
Debug::ReuseItem(k) => Real::ReuseItem(k),
};
poke_into_vec(&item, &mut data);
// the aux data is serialized after the item, hence the temporary
@@ -1448,6 +1448,10 @@ impl YamlFrameWriter {
DisplayItem::PopAllShadows => {
str_node(&mut v, "type", "pop-all-shadows");
}
DisplayItem::ReuseItem(key) => {
str_node(&mut v, "type", "reuse-item");
usize_node(&mut v, "key", key as usize);
}
}
if !v.is_empty() {
list.push(Yaml::Hash(v));
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.