зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
5161882196
Коммит
bb72f5aa20
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче