зеркало из 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 ClipDataHandle = intern::Handle<ClipDataMarker>;
|
||||
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.
|
||||
#[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
|
||||
// of a clip item. It is used during interning to de-duplicate
|
||||
// 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::{Shadow, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect};
|
||||
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 euclid::vec2;
|
||||
use frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig};
|
||||
|
@ -25,7 +25,7 @@ use image::simplify_repeated_primitive;
|
|||
use internal_types::{FastHashMap, FastHashSet};
|
||||
use picture::{Picture3DContext, PictureCompositeMode, PictureIdGenerator, PicturePrimitive};
|
||||
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::{OpacityBinding, ScrollNodeAndClipChain, TextRunPrimitive, PictureIndex};
|
||||
use render_backend::{DocumentView};
|
||||
|
@ -799,7 +799,12 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
for item in clip_items {
|
||||
// Intern this clip item, and store the handle
|
||||
// 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
|
||||
.add_clip_chain_node(
|
||||
|
@ -825,7 +830,12 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
) -> PrimitiveInstance {
|
||||
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(
|
||||
&info.rect,
|
||||
|
@ -1003,7 +1013,13 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
let should_isolate = clipping_node.is_some();
|
||||
|
||||
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
|
||||
// pop_stacking_context.
|
||||
|
@ -1326,7 +1342,10 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
let handle = self
|
||||
.resources
|
||||
.clip_interner
|
||||
.intern(&ClipItemKey::rectangle(clip_region.main, ClipMode::Clip));
|
||||
.intern(&ClipItemKey::rectangle(clip_region.main, ClipMode::Clip), || {
|
||||
ClipItemSceneData {
|
||||
}
|
||||
});
|
||||
|
||||
parent_clip_chain_index = self
|
||||
.clip_store
|
||||
|
@ -1341,7 +1360,10 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
let handle = self
|
||||
.resources
|
||||
.clip_interner
|
||||
.intern(&ClipItemKey::image_mask(image_mask));
|
||||
.intern(&ClipItemKey::image_mask(image_mask), || {
|
||||
ClipItemSceneData {
|
||||
}
|
||||
});
|
||||
|
||||
parent_clip_chain_index = self
|
||||
.clip_store
|
||||
|
@ -1357,7 +1379,10 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
let handle = self
|
||||
.resources
|
||||
.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
|
||||
.clip_store
|
||||
|
@ -1514,7 +1539,13 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
);
|
||||
|
||||
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(
|
||||
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.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[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
|
||||
map: FastHashMap<S, Handle<M>>,
|
||||
/// List of free slots in the data store for re-use.
|
||||
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.
|
||||
updates: Vec<Update<S>>,
|
||||
/// The current epoch for the interner.
|
||||
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
|
||||
pub fn new() -> Self {
|
||||
Interner {
|
||||
map: FastHashMap::default(),
|
||||
free_list: Vec::new(),
|
||||
next_index: 0,
|
||||
updates: Vec::new(),
|
||||
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
|
||||
/// frame builder, and safely accessed via the data
|
||||
/// 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,
|
||||
data: &S,
|
||||
) -> Handle<M> {
|
||||
f: F,
|
||||
) -> Handle<M> where F: FnOnce() -> D {
|
||||
// Use get_mut rather than entry here to avoid
|
||||
// cloning the (sometimes large) key in the common
|
||||
// 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 {
|
||||
index: handle.index,
|
||||
kind: UpdateKind::UpdateEpoch,
|
||||
})
|
||||
});
|
||||
self.local_data[handle.index].epoch = self.current_epoch;
|
||||
}
|
||||
handle.epoch = self.current_epoch;
|
||||
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.
|
||||
let index = match self.free_list.pop() {
|
||||
Some(index) => index,
|
||||
None => {
|
||||
let index = self.next_index;
|
||||
self.next_index += 1;
|
||||
index
|
||||
}
|
||||
None => self.local_data.len(),
|
||||
};
|
||||
|
||||
// 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.
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -299,3 +313,13 @@ impl<S, M> Interner<S, M> where S: Eq + Hash + Clone + Debug, M: Copy + Debug {
|
|||
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 = "replay", derive(Deserialize))]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
|
@ -315,7 +328,7 @@ pub struct PrimitiveDataMarker;
|
|||
pub type PrimitiveDataStore = intern::DataStore<PrimitiveKey, PrimitiveTemplate, PrimitiveDataMarker>;
|
||||
pub type PrimitiveDataHandle = intern::Handle<PrimitiveDataMarker>;
|
||||
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
|
||||
// the color of a single primitive. This is an important optimization
|
||||
|
|
|
@ -1 +1 @@
|
|||
a8817b943a2fd0038307a7432fdf5cbccf4a943e
|
||||
a7052abfe8e41bcc8904cb5b3add99735fedcd1f
|
||||
|
|
Загрузка…
Ссылка в новой задаче