Bug 1501325 - Update webrender to a7052abfe8e41bcc8904cb5b3add99735fedcd1f. r=kats

Differential Revision: https://phabricator.services.mozilla.com/D9541

--HG--
extra : moz-landing-system : lando
This commit is contained in:
WR Updater Bot 2018-10-23 15:26:49 +00:00
Родитель 5161882196
Коммит bb72f5aa20
5 изменённых файлов: 107 добавлений и 25 удалений

Просмотреть файл

@ -102,7 +102,7 @@ pub struct ClipDataMarker;
pub type ClipDataStore = intern::DataStore<ClipItemKey, ClipNode, ClipDataMarker>; pub type ClipDataStore = intern::DataStore<ClipItemKey, ClipNode, ClipDataMarker>;
pub type ClipDataHandle = intern::Handle<ClipDataMarker>; pub type ClipDataHandle = intern::Handle<ClipDataMarker>;
pub type ClipDataUpdateList = intern::UpdateList<ClipItemKey>; pub type ClipDataUpdateList = intern::UpdateList<ClipItemKey>;
pub type ClipDataInterner = intern::Interner<ClipItemKey, ClipDataMarker>; pub type ClipDataInterner = intern::Interner<ClipItemKey, ClipItemSceneData, ClipDataMarker>;
// Result of comparing a clip node instance against a local rect. // Result of comparing a clip node instance against a local rect.
#[derive(Debug)] #[derive(Debug)]
@ -752,6 +752,20 @@ impl ClipRegion<Option<ComplexClipRegion>> {
} }
} }
/// The information about an interned clip item that
/// is stored and available in the scene builder
/// thread.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct ClipItemSceneData {
// TODO(gw): We will store the local clip rect of
// the clip item here. This will allow
// calculation of the local clip rect
// for a primitive and its clip chain
// during scene building, rather than
// frame building.
}
// The ClipItemKey is a hashable representation of the contents // The ClipItemKey is a hashable representation of the contents
// of a clip item. It is used during interning to de-duplicate // of a clip item. It is used during interning to de-duplicate
// clip nodes between frames and display lists. This allows quick // clip nodes between frames and display lists. This allows quick

Просмотреть файл

@ -13,7 +13,7 @@ use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
use api::{PropertyBinding, ReferenceFrame, RepeatMode, ScrollFrameDisplayItem, ScrollSensitivity}; use api::{PropertyBinding, ReferenceFrame, RepeatMode, ScrollFrameDisplayItem, ScrollSensitivity};
use api::{Shadow, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect}; use api::{Shadow, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect};
use api::{ClipMode, TransformStyle, YuvColorSpace, YuvData}; use api::{ClipMode, TransformStyle, YuvColorSpace, YuvData};
use clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore}; use clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore, ClipItemSceneData};
use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex}; use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex};
use euclid::vec2; use euclid::vec2;
use frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig}; use frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig};
@ -25,7 +25,7 @@ use image::simplify_repeated_primitive;
use internal_types::{FastHashMap, FastHashSet}; use internal_types::{FastHashMap, FastHashSet};
use picture::{Picture3DContext, PictureCompositeMode, PictureIdGenerator, PicturePrimitive}; use picture::{Picture3DContext, PictureCompositeMode, PictureIdGenerator, PicturePrimitive};
use prim_store::{BrushKind, BrushPrimitive, BrushSegmentDescriptor, PrimitiveInstance}; use prim_store::{BrushKind, BrushPrimitive, BrushSegmentDescriptor, PrimitiveInstance};
use prim_store::{EdgeAaSegmentMask, ImageSource, PrimitiveOpacity, PrimitiveKey}; use prim_store::{EdgeAaSegmentMask, ImageSource, PrimitiveOpacity, PrimitiveKey, PrimitiveSceneData};
use prim_store::{BorderSource, BrushSegment, BrushSegmentVec, PrimitiveContainer, PrimitiveDataHandle, PrimitiveStore}; use prim_store::{BorderSource, BrushSegment, BrushSegmentVec, PrimitiveContainer, PrimitiveDataHandle, PrimitiveStore};
use prim_store::{OpacityBinding, ScrollNodeAndClipChain, TextRunPrimitive, PictureIndex}; use prim_store::{OpacityBinding, ScrollNodeAndClipChain, TextRunPrimitive, PictureIndex};
use render_backend::{DocumentView}; use render_backend::{DocumentView};
@ -799,7 +799,12 @@ impl<'a> DisplayListFlattener<'a> {
for item in clip_items { for item in clip_items {
// Intern this clip item, and store the handle // Intern this clip item, and store the handle
// in the clip chain node. // in the clip chain node.
let handle = self.resources.clip_interner.intern(&item); let handle = self.resources
.clip_interner
.intern(&item, || {
ClipItemSceneData {
}
});
clip_chain_id = self.clip_store clip_chain_id = self.clip_store
.add_clip_chain_node( .add_clip_chain_node(
@ -825,7 +830,12 @@ impl<'a> DisplayListFlattener<'a> {
) -> PrimitiveInstance { ) -> PrimitiveInstance {
let prim_key = PrimitiveKey::new(info.is_backface_visible); let prim_key = PrimitiveKey::new(info.is_backface_visible);
let prim_data_handle = self.resources.prim_interner.intern(&prim_key); let prim_data_handle = self.resources
.prim_interner
.intern(&prim_key, || {
PrimitiveSceneData {
}
});
let prim_index = self.prim_store.add_primitive( let prim_index = self.prim_store.add_primitive(
&info.rect, &info.rect,
@ -1003,7 +1013,13 @@ impl<'a> DisplayListFlattener<'a> {
let should_isolate = clipping_node.is_some(); let should_isolate = clipping_node.is_some();
let prim_key = PrimitiveKey::new(is_backface_visible); let prim_key = PrimitiveKey::new(is_backface_visible);
let primitive_data_handle = self.resources.prim_interner.intern(&prim_key); let primitive_data_handle = self.resources
.prim_interner
.intern(&prim_key, || {
PrimitiveSceneData {
}
}
);
// Push the SC onto the stack, so we know how to handle things in // Push the SC onto the stack, so we know how to handle things in
// pop_stacking_context. // pop_stacking_context.
@ -1326,7 +1342,10 @@ impl<'a> DisplayListFlattener<'a> {
let handle = self let handle = self
.resources .resources
.clip_interner .clip_interner
.intern(&ClipItemKey::rectangle(clip_region.main, ClipMode::Clip)); .intern(&ClipItemKey::rectangle(clip_region.main, ClipMode::Clip), || {
ClipItemSceneData {
}
});
parent_clip_chain_index = self parent_clip_chain_index = self
.clip_store .clip_store
@ -1341,7 +1360,10 @@ impl<'a> DisplayListFlattener<'a> {
let handle = self let handle = self
.resources .resources
.clip_interner .clip_interner
.intern(&ClipItemKey::image_mask(image_mask)); .intern(&ClipItemKey::image_mask(image_mask), || {
ClipItemSceneData {
}
});
parent_clip_chain_index = self parent_clip_chain_index = self
.clip_store .clip_store
@ -1357,7 +1379,10 @@ impl<'a> DisplayListFlattener<'a> {
let handle = self let handle = self
.resources .resources
.clip_interner .clip_interner
.intern(&ClipItemKey::rounded_rect(region.rect, region.radii, region.mode)); .intern(&ClipItemKey::rounded_rect(region.rect, region.radii, region.mode), || {
ClipItemSceneData {
}
});
parent_clip_chain_index = self parent_clip_chain_index = self
.clip_store .clip_store
@ -1514,7 +1539,13 @@ impl<'a> DisplayListFlattener<'a> {
); );
let shadow_prim_key = PrimitiveKey::new(true); let shadow_prim_key = PrimitiveKey::new(true);
let shadow_prim_data_handle = self.resources.prim_interner.intern(&shadow_prim_key); let shadow_prim_data_handle = self.resources
.prim_interner
.intern(&shadow_prim_key, || {
PrimitiveSceneData {
}
}
);
let shadow_prim_instance = PrimitiveInstance::new( let shadow_prim_instance = PrimitiveInstance::new(
shadow_prim_index, shadow_prim_index,

Просмотреть файл

@ -173,28 +173,29 @@ impl<S, T, M> ops::IndexMut<Handle<M>> for DataStore<S, T, M> {
/// an update list of additions / removals. /// an update list of additions / removals.
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct Interner<S : Eq + Hash + Clone + Debug, M> { pub struct Interner<S : Eq + Hash + Clone + Debug, D, M> {
/// Uniquely map an interning key to a handle /// Uniquely map an interning key to a handle
map: FastHashMap<S, Handle<M>>, map: FastHashMap<S, Handle<M>>,
/// List of free slots in the data store for re-use. /// List of free slots in the data store for re-use.
free_list: Vec<usize>, free_list: Vec<usize>,
/// The next index to append items to if free-list is empty.
next_index: usize,
/// Pending list of updates that need to be applied. /// Pending list of updates that need to be applied.
updates: Vec<Update<S>>, updates: Vec<Update<S>>,
/// The current epoch for the interner. /// The current epoch for the interner.
current_epoch: Epoch, current_epoch: Epoch,
/// The information associated with each interned
/// item that can be accessed by the interner.
local_data: Vec<Item<D>>,
} }
impl<S, M> Interner<S, M> where S: Eq + Hash + Clone + Debug, M: Copy + Debug { impl<S, D, M> Interner<S, D, M> where S: Eq + Hash + Clone + Debug, M: Copy + Debug {
/// Construct a new interner /// Construct a new interner
pub fn new() -> Self { pub fn new() -> Self {
Interner { Interner {
map: FastHashMap::default(), map: FastHashMap::default(),
free_list: Vec::new(), free_list: Vec::new(),
next_index: 0,
updates: Vec::new(), updates: Vec::new(),
current_epoch: Epoch(1), current_epoch: Epoch(1),
local_data: Vec::new(),
} }
} }
@ -202,10 +203,14 @@ impl<S, M> Interner<S, M> where S: Eq + Hash + Clone + Debug, M: Copy + Debug {
/// that data. The handle can then be stored in the /// that data. The handle can then be stored in the
/// frame builder, and safely accessed via the data /// frame builder, and safely accessed via the data
/// store that lives in the frame builder thread. /// store that lives in the frame builder thread.
pub fn intern( /// The provided closure is invoked to build the
/// local data about an interned structure if the
/// key isn't already interned.
pub fn intern<F>(
&mut self, &mut self,
data: &S, data: &S,
) -> Handle<M> { f: F,
) -> Handle<M> where F: FnOnce() -> D {
// Use get_mut rather than entry here to avoid // Use get_mut rather than entry here to avoid
// cloning the (sometimes large) key in the common // cloning the (sometimes large) key in the common
// case, where the data already exists in the interner. // case, where the data already exists in the interner.
@ -218,7 +223,8 @@ impl<S, M> Interner<S, M> where S: Eq + Hash + Clone + Debug, M: Copy + Debug {
self.updates.push(Update { self.updates.push(Update {
index: handle.index, index: handle.index,
kind: UpdateKind::UpdateEpoch, kind: UpdateKind::UpdateEpoch,
}) });
self.local_data[handle.index].epoch = self.current_epoch;
} }
handle.epoch = self.current_epoch; handle.epoch = self.current_epoch;
return *handle; return *handle;
@ -229,11 +235,7 @@ impl<S, M> Interner<S, M> where S: Eq + Hash + Clone + Debug, M: Copy + Debug {
// can use. Otherwise, append to the end of the list. // can use. Otherwise, append to the end of the list.
let index = match self.free_list.pop() { let index = match self.free_list.pop() {
Some(index) => index, Some(index) => index,
None => { None => self.local_data.len(),
let index = self.next_index;
self.next_index += 1;
index
}
}; };
// Add a pending update to insert the new data. // Add a pending update to insert the new data.
@ -253,6 +255,18 @@ impl<S, M> Interner<S, M> where S: Eq + Hash + Clone + Debug, M: Copy + Debug {
// interned, it gets re-used. // interned, it gets re-used.
self.map.insert(data.clone(), handle); self.map.insert(data.clone(), handle);
// Create the local data for this item that is
// being interned.
let local_item = Item {
epoch: self.current_epoch,
data: f(),
};
if self.local_data.len() == index {
self.local_data.push(local_item);
} else {
self.local_data[index] = local_item;
}
handle handle
} }
@ -299,3 +313,13 @@ impl<S, M> Interner<S, M> where S: Eq + Hash + Clone + Debug, M: Copy + Debug {
updates updates
} }
} }
/// Retrieve the local data for an item from the interner via handle
impl<S, D, M> ops::Index<Handle<M>> for Interner<S, D, M> where S: Eq + Clone + Hash + Debug, M: Copy + Debug {
type Output = D;
fn index(&self, handle: Handle<M>) -> &D {
let item = &self.local_data[handle.index];
assert_eq!(item.epoch, handle.epoch);
&item.data
}
}

Просмотреть файл

@ -275,6 +275,19 @@ impl GpuCacheAddress {
} }
} }
/// The information about an interned primitive that
/// is stored and available in the scene builder
/// thread.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct PrimitiveSceneData {
// TODO(gw): We will store the local clip rect of
// the primitive here. This will allow
// fast calculation of the tight local
// bounding rect of a primitive during
// picture traversal.
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Eq, PartialEq, Hash)]
@ -315,7 +328,7 @@ pub struct PrimitiveDataMarker;
pub type PrimitiveDataStore = intern::DataStore<PrimitiveKey, PrimitiveTemplate, PrimitiveDataMarker>; pub type PrimitiveDataStore = intern::DataStore<PrimitiveKey, PrimitiveTemplate, PrimitiveDataMarker>;
pub type PrimitiveDataHandle = intern::Handle<PrimitiveDataMarker>; pub type PrimitiveDataHandle = intern::Handle<PrimitiveDataMarker>;
pub type PrimitiveDataUpdateList = intern::UpdateList<PrimitiveKey>; pub type PrimitiveDataUpdateList = intern::UpdateList<PrimitiveKey>;
pub type PrimitiveDataInterner = intern::Interner<PrimitiveKey, PrimitiveDataMarker>; pub type PrimitiveDataInterner = intern::Interner<PrimitiveKey, PrimitiveSceneData, PrimitiveDataMarker>;
// Maintains a list of opacity bindings that have been collapsed into // Maintains a list of opacity bindings that have been collapsed into
// the color of a single primitive. This is an important optimization // the color of a single primitive. This is an important optimization

Просмотреть файл

@ -1 +1 @@
a8817b943a2fd0038307a7432fdf5cbccf4a943e a7052abfe8e41bcc8904cb5b3add99735fedcd1f