Bug 1531930 - Interneration refactoring r=gw

Remove the intern_types module in favor of the associated Internable types that we already have.
The only bit of magic I had to do is around serialization bounds, and it's nicely isolated.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Dzmitry Malyshau 2019-03-03 21:14:49 +00:00
Родитель b709cc9b5d
Коммит 2ef785bda1
21 изменённых файлов: 442 добавлений и 600 удалений

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

@ -1464,7 +1464,7 @@ impl AlphaBatchBuilder {
.expect("bug: surface must be allocated by now");
let filter_data = &ctx.data_stores.filterdata[handle];
let filter_data = &ctx.data_stores.filter_data[handle];
let filter_mode : i32 = 13 |
((filter_data.data.r_func.to_int() << 28 |
filter_data.data.g_func.to_int() << 24 |

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

@ -2,13 +2,14 @@
* 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::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, DeviceIntSize, LayoutPrimitiveInfo};
use api::{LayoutRect, LayoutSize, LayoutVector2D, MAX_BLUR_RADIUS};
use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, LayoutPrimitiveInfo, PrimitiveKeyKind};
use api::MAX_BLUR_RADIUS;
use api::units::*;
use clip::ClipItemKey;
use display_list_flattener::DisplayListFlattener;
use gpu_cache::GpuCacheHandle;
use gpu_types::BoxShadowStretchMode;
use prim_store::{ScrollNodeAndClipChain, PrimitiveKeyKind};
use prim_store::ScrollNodeAndClipChain;
use render_task::RenderTaskCacheEntryHandle;
use util::RectHelpers;

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

@ -6,7 +6,7 @@ use api::{BorderRadius, ClipMode, ComplexClipRegion, DeviceIntRect, DevicePixelS
use api::{ImageRendering, LayoutRect, LayoutSize, LayoutPoint, LayoutVector2D};
use api::{BoxShadowClipMode, LayoutToWorldScale, PicturePixel, WorldPixel};
use api::{PictureRect, LayoutPixel, WorldPoint, WorldSize, WorldRect, LayoutToWorldTransform};
use api::{ImageKey};
use api::{ClipIntern, ImageKey};
use app_units::Au;
use border::{ensure_no_corner_overlap, BorderRadiusAu};
use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowClipSource, BoxShadowCacheKey};
@ -104,8 +104,8 @@ use util::{extract_inner_rect_safe, project_rect, ScaleOffset};
// Type definitions for interning clip nodes.
pub use intern_types::clip::Store as ClipDataStore;
use intern_types::clip::Handle as ClipDataHandle;
pub type ClipDataStore = intern::DataStore<ClipIntern>;
type ClipDataHandle = intern::Handle<ClipIntern>;
// Result of comparing a clip node instance against a local rect.
#[derive(Debug)]
@ -847,6 +847,12 @@ impl ClipItemKey {
impl intern::InternDebug for ClipItemKey {}
impl intern::Internable for ClipIntern {
type Key = ClipItemKey;
type StoreData = ClipNode;
type InternData = ();
}
#[derive(Debug, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]

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

@ -3,15 +3,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter};
use api::{ClipId, ColorF, ComplexClipRegion, DeviceIntPoint, DeviceIntRect, DeviceIntSize};
use api::{DisplayItemRef, ExtendMode, ExternalScrollId, AuHelpers};
use api::{FilterOp, FontInstanceKey, GlyphInstance, GlyphOptions, RasterSpace, GradientStop};
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, LayoutPoint, ColorDepth};
use api::{LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
use api::{ClipId, ColorF, ComplexClipRegion, RasterSpace};
use api::{DisplayItemRef, ExtendMode, ExternalScrollId};
use api::{FilterOp, FontInstanceKey, GlyphInstance, GlyphOptions, GradientStop};
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, ColorDepth};
use api::{LayoutPrimitiveInfo, LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
use api::{PropertyBinding, ReferenceFrame, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity};
use api::{Shadow, SpaceAndClipInfo, SpatialId, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect};
use api::{ClipMode, TransformStyle, YuvColorSpace, YuvData, TempFilterData};
use api::{Shadow, SpaceAndClipInfo, SpatialId, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem};
use api::{ClipMode, PrimitiveKeyKind, TransformStyle, YuvColorSpace, YuvData, TempFilterData};
use api::units::*;
use app_units::Au;
use clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore};
use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex};
@ -19,13 +19,14 @@ use frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig};
use glyph_rasterizer::FontInstance;
use hit_test::{HitTestingItem, HitTestingRun};
use image::simplify_repeated_primitive;
use intern::{Handle, Internable, InternDebug};
use intern::Interner;
use internal_types::{FastHashMap, FastHashSet};
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureOptions};
use picture::{BlitReason, OrderedPictureChild, PrimitiveList, TileCache};
use prim_store::{PrimitiveInstance, PrimitiveKeyKind, PrimitiveSceneData};
use prim_store::{PrimitiveInstance, PrimitiveSceneData};
use prim_store::{PrimitiveInstanceKind, NinePatchDescriptor, PrimitiveStore};
use prim_store::{PrimitiveStoreStats, ScrollNodeAndClipChain, PictureIndex};
use prim_store::InternablePrimitive;
use prim_store::{register_prim_chase_id, get_line_decoration_sizes};
use prim_store::borders::{ImageBorder, NormalBorderPrim};
use prim_store::gradient::{GradientStopKey, LinearGradient, RadialGradient, RadialGradientParams};
@ -36,7 +37,7 @@ use prim_store::text_run::TextRun;
use render_backend::{DocumentView};
use resource_cache::{FontInstanceMap, ImageRequest};
use scene::{Scene, StackingContextHelpers};
use scene_builder::{InternerMut, Interners};
use scene_builder::Interners;
use spatial_node::{StickyFrameInfo, ScrollFrameKind, SpatialNodeType};
use std::{f32, mem, usize};
use std::collections::vec_deque::VecDeque;
@ -1148,16 +1149,14 @@ impl<'a> DisplayListFlattener<'a> {
prim: P,
) -> PrimitiveInstance
where
P: Internable<InternData=PrimitiveSceneData>,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
Interners: InternerMut<P>,
P: InternablePrimitive,
Interners: AsMut<Interner<P>>,
{
// Build a primitive key.
let prim_key = prim.build_key(info);
let prim_key = prim.into_key(info);
let interner = self.interners.interner_mut();
let prim_data_handle =
interner
let interner = self.interners.as_mut();
let prim_data_handle = interner
.intern(&prim_key, || {
PrimitiveSceneData {
prim_size: info.rect.size,
@ -1167,7 +1166,8 @@ impl<'a> DisplayListFlattener<'a> {
let current_offset = self.rf_mapper.current_offset();
let instance_kind = prim_key.as_instance_kind(
let instance_kind = P::make_instance_kind(
prim_key,
prim_data_handle,
&mut self.prim_store,
current_offset,
@ -1228,9 +1228,8 @@ impl<'a> DisplayListFlattener<'a> {
prim: P,
)
where
P: Internable<InternData = PrimitiveSceneData> + IsVisible,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
Interners: InternerMut<P>,
P: InternablePrimitive + IsVisible,
Interners: AsMut<Interner<P>>,
{
if prim.is_visible() {
let clip_chain_id = self.build_clip_chain(
@ -1255,9 +1254,8 @@ impl<'a> DisplayListFlattener<'a> {
prim: P,
)
where
P: Internable<InternData = PrimitiveSceneData> + IsVisible,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
Interners: InternerMut<P>,
P: InternablePrimitive + IsVisible,
Interners: AsMut<Interner<P>>,
ShadowItem: From<PendingPrimitive<P>>
{
// If a shadow context is not active, then add the primitive
@ -1290,9 +1288,8 @@ impl<'a> DisplayListFlattener<'a> {
prim: P,
)
where
P: Internable<InternData = PrimitiveSceneData>,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
Interners: InternerMut<P>,
P: InternablePrimitive,
Interners: AsMut<Interner<P>>,
{
let prim_instance = self.create_primitive(
info,
@ -1606,7 +1603,7 @@ impl<'a> DisplayListFlattener<'a> {
};
let handle = self.interners
.filterdata
.filter_data
.intern(&filter_data_key, || ());
PictureCompositeMode::ComponentTransferFilter(handle)
}
@ -2129,9 +2126,8 @@ impl<'a> DisplayListFlattener<'a> {
prims: &mut Vec<PrimitiveInstance>,
)
where
P: Internable<InternData=PrimitiveSceneData> + CreateShadow,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
Interners: InternerMut<P>,
P: InternablePrimitive + CreateShadow,
Interners: AsMut<Interner<P>>,
{
// Offset the local rect and clip rect by the shadow offset.
let mut info = pending_primitive.info.clone();
@ -2156,9 +2152,8 @@ impl<'a> DisplayListFlattener<'a> {
&mut self,
pending_primitive: PendingPrimitive<P>,
) where
P: Internable<InternData = PrimitiveSceneData> + IsVisible,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug,
Interners: InternerMut<P>,
P: InternablePrimitive + IsVisible,
Interners: AsMut<Interner<P>>,
{
// For a normal primitive, if it has alpha > 0, then we add this
// as a normal primitive to the parent picture.
@ -2681,14 +2676,6 @@ impl<'a> DisplayListFlattener<'a> {
}
}
pub trait AsInstanceKind<H> {
fn as_instance_kind(
&self,
data_handle: H,
prim_store: &mut PrimitiveStore,
reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind;
}
pub trait CreateShadow {
fn create_shadow(&self, shadow: &Shadow) -> Self;

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

@ -7,10 +7,10 @@ use gpu_cache::{GpuCacheHandle};
use frame_builder::FrameBuildingState;
use gpu_cache::GpuDataRequest;
use intern;
use api::{ComponentTransferFuncType};
use api::{FilterDataIntern, ComponentTransferFuncType};
pub use intern_types::filterdata::Handle as FilterDataHandle;
pub type FilterDataHandle = intern::Handle<FilterDataIntern>;
#[derive(Debug, Clone, MallocSizeOf, PartialEq)]
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -144,6 +144,12 @@ impl SFilterDataTemplate {
}
}
impl intern::Internable for FilterDataIntern {
type Key = SFilterDataKey;
type StoreData = SFilterDataTemplate;
type InternData = ();
}
fn push_component_transfer_data(
func_comp: &SFilterDataComponent,
request: &mut GpuDataRequest,

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

@ -33,7 +33,6 @@
//! stored inside each handle. This is then used for
//! cache invalidation.
use api::{LayoutPrimitiveInfo};
use internal_types::FastHashMap;
use malloc_size_of::MallocSizeOf;
use profiler::ResourceProfileCounter;
@ -79,15 +78,28 @@ impl ItemUid {
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Copy, Clone, MallocSizeOf)]
pub struct Handle<M: Copy> {
#[derive(Debug, MallocSizeOf)]
pub struct Handle<I> {
index: u32,
epoch: Epoch,
uid: ItemUid,
_marker: PhantomData<M>,
_marker: PhantomData<I>,
}
impl <M> Handle<M> where M: Copy {
impl<I> Clone for Handle<I> {
fn clone(&self) -> Self {
Handle {
index: self.index,
epoch: self.epoch,
uid: self.uid,
_marker: self._marker,
}
}
}
impl<I> Copy for Handle<I> {}
impl<I> Handle<I> {
pub fn uid(&self) -> ItemUid {
self.uid
}
@ -118,46 +130,34 @@ pub trait InternDebug {
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)]
pub struct DataStore<S, T: MallocSizeOf, M> {
items: Vec<Option<T>>,
_source: PhantomData<S>,
_marker: PhantomData<M>,
pub struct DataStore<I: Internable> {
items: Vec<Option<I::StoreData>>,
}
impl<S, T, M> ::std::default::Default for DataStore<S, T, M>
where
S: Debug + MallocSizeOf,
T: From<S> + MallocSizeOf,
M: Debug
{
impl<I: Internable> Default for DataStore<I> {
fn default() -> Self {
DataStore {
items: Vec::new(),
_source: PhantomData,
_marker: PhantomData,
}
}
}
impl<S, T, M> DataStore<S, T, M>
where
S: Debug + MallocSizeOf,
T: From<S> + MallocSizeOf,
M: Debug
{
impl<I: Internable> DataStore<I> {
/// Apply any updates from the scene builder thread to
/// this data store.
pub fn apply_updates(
&mut self,
update_list: UpdateList<S>,
update_list: UpdateList<I::Key>,
profile_counter: &mut ResourceProfileCounter,
) {
let mut data_iter = update_list.data.into_iter();
for update in update_list.updates {
match update.kind {
UpdateKind::Insert => {
self.items.entry(update.index).
set(Some(T::from(data_iter.next().unwrap())));
let value = data_iter.next().unwrap().into();
self.items
.entry(update.index)
.set(Some(value));
}
UpdateKind::Remove => {
self.items[update.index] = None;
@ -165,7 +165,7 @@ where
}
}
let per_item_size = mem::size_of::<S>() + mem::size_of::<T>();
let per_item_size = mem::size_of::<I::Key>() + mem::size_of::<I::StoreData>();
profile_counter.set(self.items.len(), per_item_size * self.items.len());
debug_assert!(data_iter.next().is_none());
@ -173,27 +173,17 @@ where
}
/// Retrieve an item from the store via handle
impl<S, T, M> ops::Index<Handle<M>> for DataStore<S, T, M>
where
S: MallocSizeOf,
T: MallocSizeOf,
M: Copy
{
type Output = T;
fn index(&self, handle: Handle<M>) -> &T {
impl<I: Internable> ops::Index<Handle<I>> for DataStore<I> {
type Output = I::StoreData;
fn index(&self, handle: Handle<I>) -> &I::StoreData {
self.items[handle.index as usize].as_ref().expect("Bad datastore lookup")
}
}
/// Retrieve a mutable item from the store via handle
/// Retrieve an item from the store via handle
impl<S, T, M> ops::IndexMut<Handle<M>> for DataStore<S, T, M>
where
S: MallocSizeOf,
T: MallocSizeOf,
M: Copy
{
fn index_mut(&mut self, handle: Handle<M>) -> &mut T {
impl<I: Internable> ops::IndexMut<Handle<I>> for DataStore<I> {
fn index_mut(&mut self, handle: Handle<I>) -> &mut I::StoreData {
self.items[handle.index as usize].as_mut().expect("Bad datastore lookup")
}
}
@ -206,33 +196,23 @@ where
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)]
pub struct Interner<S, D, M>
where
S: Eq + Hash + Clone + Debug + MallocSizeOf,
D: MallocSizeOf,
M: Copy + MallocSizeOf,
{
pub struct Interner<I: Internable> {
/// Uniquely map an interning key to a handle
map: FastHashMap<S, Handle<M>>,
map: FastHashMap<I::Key, Handle<I>>,
/// List of free slots in the data store for re-use.
free_list: Vec<usize>,
/// Pending list of updates that need to be applied.
updates: Vec<Update>,
/// Pending new data to insert.
update_data: Vec<S>,
update_data: Vec<I::Key>,
/// 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<D>,
local_data: Vec<I::InternData>,
}
impl<S, D, M> ::std::default::Default for Interner<S, D, M>
where
S: Eq + Hash + Clone + Debug + MallocSizeOf,
D: MallocSizeOf,
M: Copy + Debug + MallocSizeOf,
{
impl<I: Internable> Default for Interner<I> {
fn default() -> Self {
Interner {
map: FastHashMap::default(),
@ -245,12 +225,7 @@ where
}
}
impl<S, D, M> Interner<S, D, M>
where
S: Eq + Hash + Clone + Debug + InternDebug + MallocSizeOf,
D: MallocSizeOf,
M: Copy + Debug + MallocSizeOf
{
impl<I: Internable> Interner<I> {
/// Intern a data structure, and return a handle to
/// that data. The handle can then be stored in the
/// frame builder, and safely accessed via the data
@ -260,9 +235,9 @@ where
/// key isn't already interned.
pub fn intern<F>(
&mut self,
data: &S,
f: F,
) -> Handle<M> where F: FnOnce() -> D {
data: &I::Key,
fun: F,
) -> Handle<I> where F: FnOnce() -> I::InternData {
// 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.
@ -303,7 +278,7 @@ where
// Create the local data for this item that is
// being interned.
self.local_data.entry(index).set(f());
self.local_data.entry(index).set(fun());
handle
}
@ -311,7 +286,7 @@ where
/// Retrieve the pending list of updates for an interner
/// that need to be applied to the data store. Also run
/// a GC step that removes old entries.
pub fn end_frame_and_get_pending_updates(&mut self) -> UpdateList<S> {
pub fn end_frame_and_get_pending_updates(&mut self) -> UpdateList<I::Key> {
let mut updates = self.updates.take_and_preallocate();
let data = self.update_data.take_and_preallocate();
@ -354,30 +329,36 @@ where
}
/// 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 + MallocSizeOf,
D: MallocSizeOf,
M: Copy + Debug + MallocSizeOf
{
type Output = D;
fn index(&self, handle: Handle<M>) -> &D {
impl<I: Internable> ops::Index<Handle<I>> for Interner<I> {
type Output = I::InternData;
fn index(&self, handle: Handle<I>) -> &I::InternData {
&self.local_data[handle.index as usize]
}
}
/// Implement `Internable` for a type that wants participate in interning.
///
/// see DisplayListFlattener::add_interned_primitive<P>
pub trait Internable {
type Marker: Copy + Debug + MallocSizeOf;
type Source: Eq + Hash + Clone + Debug + MallocSizeOf;
type StoreData: From<Self::Source> + MallocSizeOf;
type InternData: MallocSizeOf;
/// Build a new key from self with `info`.
fn build_key(
self,
info: &LayoutPrimitiveInfo,
) -> Self::Source;
// The trick to make trait bounds configurable by features.
mod dummy {
#[cfg(not(feature = "capture"))]
pub trait Serialize {}
#[cfg(not(feature = "capture"))]
impl<T> Serialize for T {}
#[cfg(not(feature = "replay"))]
pub trait Deserialize<'a> {}
#[cfg(not(feature = "replay"))]
impl<'a, T> Deserialize<'a> for T {}
}
#[cfg(feature = "capture")]
use serde::Serialize as InternSerialize;
#[cfg(not(feature = "capture"))]
use self::dummy::Serialize as InternSerialize;
#[cfg(feature = "replay")]
use serde::Deserialize as InternDeserialize;
#[cfg(not(feature = "replay"))]
use self::dummy::Deserialize as InternDeserialize;
/// Implement `Internable` for a type that wants to participate in interning.
pub trait Internable: MallocSizeOf {
type Key: Eq + Hash + Clone + Debug + MallocSizeOf + InternDebug + InternSerialize + for<'a> InternDeserialize<'a>;
type StoreData: From<Self::Key> + MallocSizeOf + InternSerialize + for<'a> InternDeserialize<'a>;
type InternData: MallocSizeOf + InternSerialize + for<'a> InternDeserialize<'a>;
}

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

@ -1,114 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
macro_rules! common {
() => (
use ::intern;
#[allow(unused_imports)]
use ::prim_store::PrimitiveSceneData;
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
pub struct Marker;
pub type Handle = intern::Handle<Marker>;
)
}
pub mod clip {
common!();
use ::clip::{ClipItemKey, ClipNode};
pub type Store = intern::DataStore<ClipItemKey, ClipNode, Marker>;
pub type UpdateList = intern::UpdateList<ClipItemKey>;
pub type Interner = intern::Interner<ClipItemKey, (), Marker>;
}
pub mod prim {
common!();
use ::prim_store::{PrimitiveKey, PrimitiveTemplate};
pub type Store = intern::DataStore<PrimitiveKey, PrimitiveTemplate, Marker>;
pub type UpdateList = intern::UpdateList<PrimitiveKey>;
pub type Interner = intern::Interner<PrimitiveKey, PrimitiveSceneData, Marker>;
}
pub mod normal_border {
common!();
use ::prim_store::borders::{NormalBorderKey, NormalBorderTemplate};
pub type Store = intern::DataStore<NormalBorderKey, NormalBorderTemplate, Marker>;
pub type UpdateList = intern::UpdateList<NormalBorderKey>;
pub type Interner = intern::Interner<NormalBorderKey, PrimitiveSceneData, Marker>;
}
pub mod image_border {
common!();
use ::prim_store::borders::{ImageBorderKey, ImageBorderTemplate};
pub type Store = intern::DataStore<ImageBorderKey, ImageBorderTemplate, Marker>;
pub type UpdateList = intern::UpdateList<ImageBorderKey>;
pub type Interner = intern::Interner<ImageBorderKey, PrimitiveSceneData, Marker>;
}
pub mod image {
common!();
use ::prim_store::image::{ImageKey, ImageTemplate};
pub type Store = intern::DataStore<ImageKey, ImageTemplate, Marker>;
pub type UpdateList = intern::UpdateList<ImageKey>;
pub type Interner = intern::Interner<ImageKey, PrimitiveSceneData, Marker>;
}
pub mod yuv_image {
common!();
use ::prim_store::image::{YuvImageKey, YuvImageTemplate};
pub type Store = intern::DataStore<YuvImageKey, YuvImageTemplate, Marker>;
pub type UpdateList = intern::UpdateList<YuvImageKey>;
pub type Interner = intern::Interner<YuvImageKey, PrimitiveSceneData, Marker>;
}
pub mod line_decoration {
use ::prim_store::line_dec::{LineDecorationKey, LineDecorationTemplate};
common!();
pub type Store = intern::DataStore<LineDecorationKey, LineDecorationTemplate, Marker>;
pub type UpdateList = intern::UpdateList<LineDecorationKey>;
pub type Interner = intern::Interner<LineDecorationKey, PrimitiveSceneData, Marker>;
}
pub mod linear_grad {
common!();
use ::prim_store::gradient::{LinearGradientKey, LinearGradientTemplate};
pub type Store = intern::DataStore<LinearGradientKey, LinearGradientTemplate, Marker>;
pub type UpdateList = intern::UpdateList<LinearGradientKey>;
pub type Interner = intern::Interner<LinearGradientKey, PrimitiveSceneData, Marker>;
}
pub mod radial_grad {
common!();
use ::prim_store::gradient::{RadialGradientKey, RadialGradientTemplate};
pub type Store = intern::DataStore<RadialGradientKey, RadialGradientTemplate, Marker>;
pub type UpdateList = intern::UpdateList<RadialGradientKey>;
pub type Interner = intern::Interner<RadialGradientKey, PrimitiveSceneData, Marker>;
}
pub mod picture {
common!();
use ::prim_store::picture::{PictureKey, PictureTemplate};
pub type Store = intern::DataStore<PictureKey, PictureTemplate, Marker>;
pub type UpdateList = intern::UpdateList<PictureKey>;
pub type Interner = intern::Interner<PictureKey, PrimitiveSceneData, Marker>;
}
pub mod text_run {
common!();
use ::prim_store::text_run::{TextRunKey, TextRunTemplate};
pub type Store = intern::DataStore<TextRunKey, TextRunTemplate, Marker>;
pub type UpdateList = intern::UpdateList<TextRunKey>;
pub type Interner = intern::Interner<TextRunKey, PrimitiveSceneData, Marker>;
}
pub mod filterdata {
common!();
use ::filterdata::{SFilterDataKey, SFilterDataTemplate};
pub type Store = intern::DataStore<SFilterDataKey, SFilterDataTemplate, Marker>;
pub type UpdateList = intern::UpdateList<SFilterDataKey>;
pub type Interner = intern::Interner<SFilterDataKey, (), Marker>;
}

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

@ -104,7 +104,6 @@ mod gpu_types;
mod hit_test;
mod image;
mod intern;
mod intern_types;
mod internal_types;
mod picture;
mod prim_store;

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

@ -3114,7 +3114,7 @@ impl PicturePrimitive {
PictureSurface::RenderTask(render_task_id)
}
PictureCompositeMode::ComponentTransferFilter(handle) => {
let filter_data = &mut data_stores.filterdata[handle];
let filter_data = &mut data_stores.filter_data[handle];
filter_data.update(frame_state);
let uv_rect_kind = calculate_uv_rect_kind(

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

@ -9,16 +9,15 @@ use api::{
};
use border::create_border_segments;
use border::NormalBorderAu;
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible};
use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState};
use gpu_cache::GpuDataRequest;
use intern;
use intern_types;
use prim_store::{
BorderSegmentInfo, BrushSegment, NinePatchDescriptor, PrimKey,
PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,
PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData,
PrimitiveStore
PrimitiveStore, InternablePrimitive,
};
use resource_cache::ImageRequest;
use storage;
@ -49,22 +48,6 @@ impl NormalBorderKey {
impl intern::InternDebug for NormalBorderKey {}
impl AsInstanceKind<NormalBorderDataHandle> for NormalBorderKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: NormalBorderDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::NormalBorder {
data_handle,
cache_handles: storage::Range::empty(),
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)]
@ -160,16 +143,16 @@ impl From<NormalBorderKey> for NormalBorderTemplate {
}
}
pub use intern_types::normal_border::Handle as NormalBorderDataHandle;
pub type NormalBorderDataHandle = intern::Handle<NormalBorderPrim>;
impl intern::Internable for NormalBorderPrim {
type Marker = intern_types::normal_border::Marker;
type Source = NormalBorderKey;
type Key = NormalBorderKey;
type StoreData = NormalBorderTemplate;
type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`.
fn build_key(
impl InternablePrimitive for NormalBorderPrim {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> NormalBorderKey {
@ -178,6 +161,18 @@ impl intern::Internable for NormalBorderPrim {
self,
)
}
fn make_instance_kind(
_key: NormalBorderKey,
data_handle: NormalBorderDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::NormalBorder {
data_handle,
cache_handles: storage::Range::empty(),
}
}
}
impl CreateShadow for NormalBorderPrim {
@ -225,20 +220,6 @@ impl ImageBorderKey {
impl intern::InternDebug for ImageBorderKey {}
impl AsInstanceKind<ImageBorderDataHandle> for ImageBorderKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: ImageBorderDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::ImageBorder {
data_handle
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
@ -330,16 +311,16 @@ impl From<ImageBorderKey> for ImageBorderTemplate {
}
}
pub use intern_types::image_border::Handle as ImageBorderDataHandle;
pub type ImageBorderDataHandle = intern::Handle<ImageBorder>;
impl intern::Internable for ImageBorder {
type Marker = intern_types::image_border::Marker;
type Source = ImageBorderKey;
type Key = ImageBorderKey;
type StoreData = ImageBorderTemplate;
type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`.
fn build_key(
impl InternablePrimitive for ImageBorder {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> ImageBorderKey {
@ -348,6 +329,17 @@ impl intern::Internable for ImageBorder {
self,
)
}
fn make_instance_kind(
_key: ImageBorderKey,
data_handle: ImageBorderDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::ImageBorder {
data_handle
}
}
}
impl IsVisible for ImageBorder {

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

@ -6,15 +6,14 @@ use api::{
ColorF, ColorU,ExtendMode, GradientStop, LayoutPoint, LayoutSize,
LayoutPrimitiveInfo, PremultipliedColorF, LayoutVector2D,
};
use display_list_flattener::{AsInstanceKind, IsVisible};
use display_list_flattener::IsVisible;
use frame_builder::FrameBuildingState;
use gpu_cache::{GpuCacheHandle, GpuDataRequest};
use intern::{Internable, InternDebug};
use intern_types;
use intern::{Internable, InternDebug, Handle as InternHandle};
use prim_store::{BrushSegment, GradientTileRange};
use prim_store::{PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData};
use prim_store::{PrimKeyCommonData, PrimTemplateCommonData, PrimitiveStore};
use prim_store::{NinePatchDescriptor, PointKey, SizeKey};
use prim_store::{NinePatchDescriptor, PointKey, SizeKey, InternablePrimitive};
use std::{hash, ops::{Deref, DerefMut}, mem};
use util::pack_as_float;
@ -77,22 +76,6 @@ impl LinearGradientKey {
impl InternDebug for LinearGradientKey {}
impl AsInstanceKind<LinearGradientDataHandle> for LinearGradientKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: LinearGradientDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::LinearGradient {
data_handle,
visible_tiles_range: GradientTileRange::empty(),
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)]
@ -227,8 +210,11 @@ impl LinearGradientTemplate {
}
}
pub type LinearGradientDataHandle = intern_types::linear_grad::Handle;
pub type LinearGradientDataHandle = InternHandle<LinearGradient>;
#[derive(Debug, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct LinearGradient {
pub extend_mode: ExtendMode,
pub start_point: PointKey,
@ -241,13 +227,13 @@ pub struct LinearGradient {
}
impl Internable for LinearGradient {
type Marker = intern_types::linear_grad::Marker;
type Source = LinearGradientKey;
type Key = LinearGradientKey;
type StoreData = LinearGradientTemplate;
type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`.
fn build_key(
impl InternablePrimitive for LinearGradient {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> LinearGradientKey {
@ -257,6 +243,18 @@ impl Internable for LinearGradient {
self
)
}
fn make_instance_kind(
_key: LinearGradientKey,
data_handle: LinearGradientDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::LinearGradient {
data_handle,
visible_tiles_range: GradientTileRange::empty(),
}
}
}
impl IsVisible for LinearGradient {
@ -326,22 +324,6 @@ impl RadialGradientKey {
impl InternDebug for RadialGradientKey {}
impl AsInstanceKind<RadialGradientDataHandle> for RadialGradientKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: RadialGradientDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::RadialGradient {
data_handle,
visible_tiles_range: GradientTileRange::empty(),
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)]
@ -447,8 +429,11 @@ impl RadialGradientTemplate {
}
}
pub type RadialGradientDataHandle = intern_types::radial_grad::Handle;
pub type RadialGradientDataHandle = InternHandle<RadialGradient>;
#[derive(Debug, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct RadialGradient {
pub extend_mode: ExtendMode,
pub center: PointKey,
@ -460,13 +445,13 @@ pub struct RadialGradient {
}
impl Internable for RadialGradient {
type Marker = intern_types::radial_grad::Marker;
type Source = RadialGradientKey;
type Key = RadialGradientKey;
type StoreData = RadialGradientTemplate;
type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`.
fn build_key(
impl InternablePrimitive for RadialGradient {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> RadialGradientKey {
@ -476,6 +461,18 @@ impl Internable for RadialGradient {
self,
)
}
fn make_instance_kind(
_key: RadialGradientKey,
data_handle: RadialGradientDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::RadialGradient {
data_handle,
visible_tiles_range: GradientTileRange::empty(),
}
}
}
impl IsVisible for RadialGradient {

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

@ -8,16 +8,15 @@ use api::{
PremultipliedColorF, Shadow, TileOffset, YuvColorSpace, YuvFormat, LayoutVector2D,
};
use api::ImageKey as ApiImageKey;
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible};
use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::FrameBuildingState;
use gpu_cache::{GpuDataRequest};
use intern::{Internable, InternDebug};
use intern_types;
use intern::{Internable, InternDebug, Handle as InternHandle};
use prim_store::{
EdgeAaSegmentMask, OpacityBindingIndex, PrimitiveInstanceKind,
PrimitiveOpacity, PrimitiveSceneData, PrimKey, PrimKeyCommonData,
PrimTemplate, PrimTemplateCommonData, PrimitiveStore, SegmentInstanceIndex,
SizeKey
SizeKey, InternablePrimitive,
};
use render_task::{
BlitSource, RenderTask, RenderTaskCacheEntryHandle, RenderTaskCacheKey,
@ -101,31 +100,6 @@ impl ImageKey {
impl InternDebug for ImageKey {}
impl AsInstanceKind<ImageDataHandle> for ImageKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: ImageDataHandle,
prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
// TODO(gw): Refactor this to not need a separate image
// instance (see ImageInstance struct).
let image_instance_index = prim_store.images.push(ImageInstance {
opacity_binding_index: OpacityBindingIndex::INVALID,
segment_instance_index: SegmentInstanceIndex::INVALID,
tight_local_clip_rect: LayoutRect::zero(),
visible_tiles: Vec::new(),
});
PrimitiveInstanceKind::Image {
data_handle,
image_instance_index,
}
}
}
// Where to find the texture data for an image primitive.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
@ -338,16 +312,16 @@ impl From<ImageKey> for ImageTemplate {
}
}
pub use intern_types::image::Handle as ImageDataHandle;
pub type ImageDataHandle = InternHandle<Image>;
impl Internable for Image {
type Marker = intern_types::image::Marker;
type Source = ImageKey;
type Key = ImageKey;
type StoreData = ImageTemplate;
type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`.
fn build_key(
impl InternablePrimitive for Image {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> ImageKey {
@ -357,6 +331,27 @@ impl Internable for Image {
self
)
}
fn make_instance_kind(
_key: ImageKey,
data_handle: ImageDataHandle,
prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
// TODO(gw): Refactor this to not need a separate image
// instance (see ImageInstance struct).
let image_instance_index = prim_store.images.push(ImageInstance {
opacity_binding_index: OpacityBindingIndex::INVALID,
segment_instance_index: SegmentInstanceIndex::INVALID,
tight_local_clip_rect: LayoutRect::zero(),
visible_tiles: Vec::new(),
});
PrimitiveInstanceKind::Image {
data_handle,
image_instance_index,
}
}
}
impl CreateShadow for Image {
@ -413,22 +408,6 @@ impl YuvImageKey {
impl InternDebug for YuvImageKey {}
impl AsInstanceKind<YuvImageDataHandle> for YuvImageKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: YuvImageDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::YuvImage {
data_handle,
segment_instance_index: SegmentInstanceIndex::INVALID
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)]
@ -505,25 +484,37 @@ impl From<YuvImageKey> for YuvImageTemplate {
}
}
pub use intern_types::yuv_image::Handle as YuvImageDataHandle;
pub type YuvImageDataHandle = InternHandle<YuvImage>;
impl Internable for YuvImage {
type Marker = intern_types::yuv_image::Marker;
type Source = YuvImageKey;
type Key = YuvImageKey;
type StoreData = YuvImageTemplate;
type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`.
fn build_key(
impl InternablePrimitive for YuvImage {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> YuvImageKey {
YuvImageKey::new(
info.is_backface_visible,
info.rect.size,
self
self,
)
}
fn make_instance_kind(
_key: YuvImageKey,
data_handle: YuvImageDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::YuvImage {
data_handle,
segment_instance_index: SegmentInstanceIndex::INVALID
}
}
}
impl IsVisible for YuvImage {

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

@ -0,0 +1,12 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
// list of all interned primitives to match enumerate_interners!
pub use prim_store::borders::{ImageBorder, NormalBorderPrim};
pub use prim_store::image::{Image, YuvImage};
pub use prim_store::line_dec::{LineDecoration};
pub use prim_store::gradient::{LinearGradient, RadialGradient};
pub use prim_store::picture::Picture;
pub use prim_store::text_run::TextRun;

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

@ -7,17 +7,17 @@ use api::{
LineOrientation, LineStyle, PremultipliedColorF, Shadow,
};
use app_units::Au;
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible};
use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState};
use gpu_cache::GpuDataRequest;
use intern;
use intern_types;
use prim_store::{
PrimKey, PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,
PrimitiveSceneData, PrimitiveStore,
InternablePrimitive, PrimitiveSceneData, PrimitiveStore,
};
use prim_store::PrimitiveInstanceKind;
#[derive(Clone, Debug, Hash, MallocSizeOf, PartialEq, Eq)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
@ -59,22 +59,6 @@ impl LineDecorationKey {
impl intern::InternDebug for LineDecorationKey {}
impl AsInstanceKind<LineDecorationDataHandle> for LineDecorationKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: LineDecorationDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::LineDecoration {
data_handle,
cache_handle: None,
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)]
@ -135,16 +119,16 @@ impl From<LineDecorationKey> for LineDecorationTemplate {
}
}
pub use intern_types::line_decoration::Handle as LineDecorationDataHandle;
pub type LineDecorationDataHandle = intern::Handle<LineDecoration>;
impl intern::Internable for LineDecoration {
type Marker = intern_types::line_decoration::Marker;
type Source = LineDecorationKey;
type Key = LineDecorationKey;
type StoreData = LineDecorationTemplate;
type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`.
fn build_key(
impl InternablePrimitive for LineDecoration {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> LineDecorationKey {
@ -153,6 +137,18 @@ impl intern::Internable for LineDecoration {
self,
)
}
fn make_instance_kind(
_key: LineDecorationKey,
data_handle: LineDecorationDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::LineDecoration {
data_handle,
cache_handle: None,
}
}
}
impl CreateShadow for LineDecoration {

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

@ -2,15 +2,12 @@
* 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::{BorderRadius, ClipMode, ColorF, PictureRect, ColorU, LayoutVector2D};
use api::{DeviceIntRect, DevicePixelScale, DeviceRect, WorldVector2D};
use api::{BorderRadius, ClipMode, ColorF};
use api::{FilterOp, ImageRendering, TileOffset, RepeatMode, WorldPoint, WorldSize};
use api::{LayoutPoint, LayoutRect, LayoutSideOffsets, LayoutSize, PicturePoint};
use api::{PremultipliedColorF, PropertyBinding, Shadow, DeviceVector2D};
use api::{WorldPixel, BoxShadowClipMode, WorldRect, LayoutToWorldScale};
use api::{PicturePixel, RasterPixel, LineStyle, LineOrientation, AuHelpers};
use api::{LayoutPrimitiveInfo};
use api::DevicePoint;
use api::{PremultipliedColorF, PropertyBinding, Shadow};
use api::{BoxShadowClipMode, LineStyle, LineOrientation, AuHelpers};
use api::{LayoutPrimitiveInfo, PrimitiveKeyKind};
use api::units::*;
use border::{get_max_scale_for_border, build_border_instances};
use border::BorderSegmentCacheKey;
use clip::{ClipStore};
@ -18,7 +15,7 @@ use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex
use clip::{ClipDataStore, ClipNodeFlags, ClipChainId, ClipChainInstance, ClipItem};
use debug_colors;
use debug_render::DebugItem;
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible};
use display_list_flattener::{CreateShadow, IsVisible};
use euclid::{SideOffsets2D, TypedTransform3D, TypedRect, TypedScale, TypedSize2D};
use frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState};
use frame_builder::{PrimitiveContext, FrameVisibilityContext, FrameVisibilityState};
@ -60,6 +57,7 @@ pub mod image;
pub mod line_dec;
pub mod picture;
pub mod text_run;
pub mod interned;
/// Counter for unique primitive IDs for debug tracing.
#[cfg(debug_assertions)]
@ -329,19 +327,6 @@ pub struct PrimitiveSceneData {
pub is_backface_visible: bool,
}
/// Information specific to a primitive type that
/// uniquely identifies a primitive template by key.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)]
pub enum PrimitiveKeyKind {
/// Clear an existing rect, used for special effects on some platforms.
Clear,
Rectangle {
color: ColorU,
},
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Clone, MallocSizeOf, PartialEq)]
@ -634,32 +619,6 @@ impl PrimitiveKey {
impl intern::InternDebug for PrimitiveKey {}
impl AsInstanceKind<PrimitiveDataHandle> for PrimitiveKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: PrimitiveDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
match self.kind {
PrimitiveKeyKind::Clear => {
PrimitiveInstanceKind::Clear {
data_handle
}
}
PrimitiveKeyKind::Rectangle { .. } => {
PrimitiveInstanceKind::Rectangle {
data_handle,
opacity_binding_index: OpacityBindingIndex::INVALID,
segment_instance_index: SegmentInstanceIndex::INVALID,
}
}
}
}
}
/// The shared information for a given primitive. This is interned and retained
/// both across frames and display lists, by comparing the matching PrimitiveKey.
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -675,9 +634,9 @@ pub enum PrimitiveTemplateKind {
/// Construct the primitive template data from a primitive key. This
/// is invoked when a primitive key is created and the interner
/// doesn't currently contain a primitive with this key.
impl PrimitiveKeyKind {
fn into_template(self) -> PrimitiveTemplateKind {
match self {
impl From<PrimitiveKeyKind> for PrimitiveTemplateKind {
fn from(kind: PrimitiveKeyKind) -> Self {
match kind {
PrimitiveKeyKind::Clear => {
PrimitiveTemplateKind::Clear
}
@ -746,10 +705,10 @@ impl ops::DerefMut for PrimitiveTemplate {
impl From<PrimitiveKey> for PrimitiveTemplate {
fn from(item: PrimitiveKey) -> Self {
let common = PrimTemplateCommonData::with_key_common(item.common);
let kind = item.kind.into_template();
PrimitiveTemplate { common, kind, }
PrimitiveTemplate {
common: PrimTemplateCommonData::with_key_common(item.common),
kind: item.kind.into(),
}
}
}
@ -795,13 +754,16 @@ impl PrimitiveTemplate {
}
}
type PrimitiveDataHandle = intern::Handle<PrimitiveKeyKind>;
impl intern::Internable for PrimitiveKeyKind {
type Marker = ::intern_types::prim::Marker;
type Source = PrimitiveKey;
type Key = PrimitiveKey;
type StoreData = PrimitiveTemplate;
type InternData = PrimitiveSceneData;
}
fn build_key(
impl InternablePrimitive for PrimitiveKeyKind {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> PrimitiveKey {
@ -811,9 +773,29 @@ impl intern::Internable for PrimitiveKeyKind {
self,
)
}
}
use intern_types::prim::Handle as PrimitiveDataHandle;
fn make_instance_kind(
key: PrimitiveKey,
data_handle: PrimitiveDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
match key.kind {
PrimitiveKeyKind::Clear => {
PrimitiveInstanceKind::Clear {
data_handle
}
}
PrimitiveKeyKind::Rectangle { .. } => {
PrimitiveInstanceKind::Rectangle {
data_handle,
opacity_binding_index: OpacityBindingIndex::INVALID,
segment_instance_index: SegmentInstanceIndex::INVALID,
}
}
}
}
}
// Maintains a list of opacity bindings that have been collapsed into
// the color of a single primitive. This is an important optimization
@ -3706,6 +3688,24 @@ fn update_opacity_binding(
}
}
/// Trait for primitives that are directly internable.
/// see DisplayListFlattener::add_primitive<P>
pub trait InternablePrimitive: intern::Internable<InternData = PrimitiveSceneData> + Sized {
/// Build a new key from self with `info`.
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> Self::Key;
fn make_instance_kind(
key: Self::Key,
data_handle: intern::Handle<Self>,
prim_store: &mut PrimitiveStore,
reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind;
}
#[test]
#[cfg(target_pointer_width = "64")]
fn test_struct_sizes() {

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

@ -8,13 +8,13 @@ use api::{
};
use intern::ItemUid;
use app_units::Au;
use display_list_flattener::{AsInstanceKind, IsVisible};
use intern::{Internable, InternDebug};
use intern_types;
use display_list_flattener::IsVisible;
use intern::{Internable, InternDebug, Handle as InternHandle};
use picture::PictureCompositeMode;
use prim_store::{
PrimKey, PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,
PrimitiveInstanceKind, PrimitiveSceneData, PrimitiveStore, VectorKey,
InternablePrimitive,
};
/// Represents a hashable description of how a picture primitive
@ -161,21 +161,6 @@ impl PictureKey {
impl InternDebug for PictureKey {}
impl AsInstanceKind<PictureDataHandle> for PictureKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
_: PictureDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
// Should never be hit as this method should not be
// called for pictures.
unreachable!();
}
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)]
@ -194,25 +179,36 @@ impl From<PictureKey> for PictureTemplate {
}
}
pub use intern_types::picture::Handle as PictureDataHandle;
pub type PictureDataHandle = InternHandle<Picture>;
impl Internable for Picture {
type Marker = intern_types::picture::Marker;
type Source = PictureKey;
type Key = PictureKey;
type StoreData = PictureTemplate;
type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`.
fn build_key(
impl InternablePrimitive for Picture {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> PictureKey {
PictureKey::new(
info.is_backface_visible,
info.rect.size,
self
self,
)
}
fn make_instance_kind(
_key: PictureKey,
_: PictureDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
// Should never be hit as this method should not be
// called for pictures.
unreachable!();
}
}
impl IsVisible for Picture {

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

@ -5,20 +5,19 @@
use api::{ColorF, DevicePixelScale, GlyphInstance, LayoutPrimitiveInfo};
use api::{LayoutToWorldTransform, RasterSpace};
use api::{LayoutVector2D, Shadow};
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible};
use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState, PictureContext};
use glyph_rasterizer::{FontInstance, FontTransform, GlyphKey, FONT_SIZE_LIMIT};
use gpu_cache::GpuCache;
use gpu_types::RasterizationSpace;
use intern;
use intern_types;
use prim_store::{PrimitiveOpacity, PrimitiveSceneData, PrimitiveScratchBuffer};
use prim_store::{PrimitiveStore, PrimKeyCommonData, PrimTemplateCommonData};
use render_task::{RenderTaskTree};
use renderer::{MAX_VERTEX_TEXTURE_WIDTH};
use resource_cache::{ResourceCache};
use util::{MatrixHelpers};
use prim_store::PrimitiveInstanceKind;
use prim_store::{InternablePrimitive, PrimitiveInstanceKind};
use std::ops;
use std::sync::Arc;
use storage;
@ -53,28 +52,6 @@ impl TextRunKey {
impl intern::InternDebug for TextRunKey {}
impl AsInstanceKind<TextRunDataHandle> for TextRunKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: TextRunDataHandle,
prim_store: &mut PrimitiveStore,
reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
let run_index = prim_store.text_runs.push(TextRunPrimitive {
used_font: self.font.clone(),
glyph_keys_range: storage::Range::empty(),
reference_frame_relative_offset,
shadow: self.shadow,
raster_space: RasterizationSpace::Screen,
inverse_raster_scale: 1.0,
});
PrimitiveInstanceKind::TextRun{ data_handle, run_index }
}
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)]
@ -157,22 +134,26 @@ impl TextRunTemplate {
}
}
pub use intern_types::text_run::Handle as TextRunDataHandle;
pub type TextRunDataHandle = intern::Handle<TextRun>;
#[derive(Debug, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct TextRun {
pub font: FontInstance,
#[ignore_malloc_size_of = "Measured via PrimaryArc"]
pub glyphs: Arc<Vec<GlyphInstance>>,
pub shadow: bool,
}
impl intern::Internable for TextRun {
type Marker = intern_types::text_run::Marker;
type Source = TextRunKey;
type Key = TextRunKey;
type StoreData = TextRunTemplate;
type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`.
fn build_key(
impl InternablePrimitive for TextRun {
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> TextRunKey {
@ -181,6 +162,24 @@ impl intern::Internable for TextRun {
self,
)
}
fn make_instance_kind(
key: TextRunKey,
data_handle: TextRunDataHandle,
prim_store: &mut PrimitiveStore,
reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
let run_index = prim_store.text_runs.push(TextRunPrimitive {
used_font: key.font.clone(),
glyph_keys_range: storage::Range::empty(),
reference_frame_relative_offset,
shadow: key.shadow,
raster_space: RasterizationSpace::Screen,
inverse_raster_scale: 1.0,
});
PrimitiveInstanceKind::TextRun{ data_handle, run_index }
}
}
impl CreateShadow for TextRun {

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

@ -453,7 +453,7 @@ pub struct IpcProfileCounters {
}
macro_rules! declare_intern_profile_counters {
( $( $name: ident, )+ ) => {
( $( $name:ident : $ty:ty, )+ ) => {
#[derive(Clone)]
pub struct InternProfileCounters {
$(
@ -522,6 +522,7 @@ impl BackendProfileCounters {
total_time: TimeProfileCounter::new("Total Display List Time", false),
display_lists: ResourceProfileCounter::new("Display Lists Sent"),
},
//TODO: generate this by a macro
intern: InternProfileCounters {
prim: ResourceProfileCounter::new("Interned primitives"),
image: ResourceProfileCounter::new("Interned images"),
@ -534,7 +535,7 @@ impl BackendProfileCounters {
text_run: ResourceProfileCounter::new("Interned text runs"),
yuv_image: ResourceProfileCounter::new("Interned YUV images"),
clip: ResourceProfileCounter::new("Interned clips"),
filterdata: ResourceProfileCounter::new("Interned filterdata"),
filter_data: ResourceProfileCounter::new("Interned filter data"),
},
}
}

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

@ -15,6 +15,7 @@ use api::{DocumentId, DocumentLayer, ExternalScrollId, FrameMsg, HitTestFlags, H
use api::{IdNamespace, MemoryReport, PipelineId, RenderNotifier, SceneMsg, ScrollClamping};
use api::{ScrollLocation, ScrollNodeState, TransactionMsg, ResourceUpdate, BlobImageKey};
use api::{NotificationRequest, Checkpoint};
use api::{ClipIntern, FilterDataIntern, PrimitiveKeyKind};
use api::units::*;
use api::channel::{MsgReceiver, MsgSender, Payload};
#[cfg(feature = "capture")]
@ -28,12 +29,13 @@ use frame_builder::{FrameBuilder, FrameBuilderConfig};
use glyph_rasterizer::{FontInstance};
use gpu_cache::GpuCache;
use hit_test::{HitTest, HitTester};
use intern_types;
use intern::DataStore;
use internal_types::{DebugOutput, FastHashMap, FastHashSet, RenderedDocument, ResultMsg};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use picture::RetainedTiles;
use prim_store::{PrimitiveScratchBuffer, PrimitiveInstance};
use prim_store::{PrimitiveInstanceKind, PrimTemplateCommonData};
use prim_store::interned::*;
use profiler::{BackendProfileCounters, IpcProfileCounters, ResourceProfileCounters};
use record::ApiRecordingReceiver;
use render_task::RenderTaskTreeCounters;
@ -210,7 +212,7 @@ impl FrameStamp {
}
macro_rules! declare_data_stores {
( $( $name: ident, )+ ) => {
( $( $name:ident : $ty:ty, )+ ) => {
/// A collection of resources that are shared by clips, primitives
/// between display lists.
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -218,7 +220,7 @@ macro_rules! declare_data_stores {
#[derive(Default)]
pub struct DataStores {
$(
pub $name: intern_types::$name::Store,
pub $name: DataStore<$ty>,
)+
}

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

@ -5,18 +5,16 @@
use api::{AsyncBlobImageRasterizer, BlobImageRequest, BlobImageParams, BlobImageResult};
use api::{DocumentId, PipelineId, ApiMsg, FrameMsg, ResourceUpdate, ExternalEvent, Epoch};
use api::{BuiltDisplayList, ColorF, LayoutSize, NotificationRequest, Checkpoint, IdNamespace};
use api::{MemoryReport};
use api::{ClipIntern, FilterDataIntern, MemoryReport, PrimitiveKeyKind};
use api::channel::MsgSender;
#[cfg(feature = "capture")]
use capture::CaptureConfig;
use frame_builder::{FrameBuilderConfig, FrameBuilder};
use clip_scroll_tree::ClipScrollTree;
use display_list_flattener::DisplayListFlattener;
use intern::{Internable, Interner};
use intern_types;
use intern::{Internable, Interner, UpdateList};
use internal_types::{FastHashMap, FastHashSet};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use prim_store::{PrimitiveKeyKind};
use prim_store::PrimitiveStoreStats;
use prim_store::borders::{ImageBorder, NormalBorderPrim};
use prim_store::gradient::{LinearGradient, RadialGradient};
@ -35,6 +33,7 @@ use util::drain_filter;
use std::thread;
use std::time::Duration;
/// Represents the work associated to a transaction before scene building.
pub struct Transaction {
pub document_id: DocumentId,
@ -170,7 +169,7 @@ pub enum SceneSwapResult {
}
macro_rules! declare_interners {
( $( $name: ident, )+ ) => {
( $( $name:ident : $ty:ident, )+ ) => {
/// This struct contains all items that can be shared between
/// display lists. We want to intern and share the same clips,
/// primitives and other things between display lists so that:
@ -182,13 +181,21 @@ macro_rules! declare_interners {
#[derive(Default)]
pub struct Interners {
$(
pub $name: intern_types::$name::Interner,
pub $name: Interner<$ty>,
)+
}
$(
impl AsMut<Interner<$ty>> for Interners {
fn as_mut(&mut self) -> &mut Interner<$ty> {
&mut self.$name
}
}
)+
pub struct InternerUpdates {
$(
pub $name: intern_types::$name::UpdateList,
pub $name: UpdateList<<$ty as Internable>::Key>,
)+
}
@ -217,39 +224,6 @@ macro_rules! declare_interners {
enumerate_interners!(declare_interners);
// Access to `Interners` interners by `Internable`
pub trait InternerMut<I: Internable>
{
fn interner_mut(&mut self) -> &mut Interner<I::Source, I::InternData, I::Marker>;
}
macro_rules! impl_interner_mut {
($($ty:ident: $mem:ident,)*) => {
$(impl InternerMut<$ty> for Interners {
fn interner_mut(&mut self) -> &mut Interner<
<$ty as Internable>::Source,
<$ty as Internable>::InternData,
<$ty as Internable>::Marker
> {
&mut self.$mem
}
})*
}
}
impl_interner_mut! {
Image: image,
ImageBorder: image_border,
LineDecoration: line_decoration,
LinearGradient: linear_grad,
NormalBorderPrim: normal_border,
Picture: picture,
PrimitiveKeyKind: prim,
RadialGradient: radial_grad,
TextRun: text_run,
YuvImage: yuv_image,
}
// A document in the scene builder contains the current scene,
// as well as a persistent clip interner. This allows clips
// to be de-duplicated, and persisted in the GPU cache between

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

@ -15,7 +15,7 @@ use std::sync::Arc;
use std::u32;
// local imports
use {display_item as di, font};
use color::ColorF;
use color::{ColorU, ColorF};
use display_list::{BuiltDisplayList, BuiltDisplayListDescriptor};
use image::{BlobImageData, BlobImageKey, ImageData, ImageDescriptor, ImageKey};
use units::*;
@ -813,6 +813,22 @@ impl PipelineId {
}
}
#[derive(Copy, Clone, Debug, MallocSizeOf, Serialize, Deserialize)]
pub enum ClipIntern {}
#[derive(Copy, Clone, Debug, MallocSizeOf, Serialize, Deserialize)]
pub enum FilterDataIntern {}
/// Information specific to a primitive type that
/// uniquely identifies a primitive template by key.
#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash, Serialize, Deserialize)]
pub enum PrimitiveKeyKind {
/// Clear an existing rect, used for special effects on some platforms.
Clear,
Rectangle {
color: ColorU,
},
}
/// Meta-macro to enumerate the various interner identifiers and types.
///
/// IMPORTANT: Keep this synchronized with the list in mozilla-central located at
@ -823,24 +839,24 @@ impl PipelineId {
macro_rules! enumerate_interners {
($macro_name: ident) => {
$macro_name! {
clip,
prim,
normal_border,
image_border,
image,
yuv_image,
line_decoration,
linear_grad,
radial_grad,
picture,
text_run,
filterdata,
clip: ClipIntern,
prim: PrimitiveKeyKind,
normal_border: NormalBorderPrim,
image_border: ImageBorder,
image: Image,
yuv_image: YuvImage,
line_decoration: LineDecoration,
linear_grad: LinearGradient,
radial_grad: RadialGradient,
picture: Picture,
text_run: TextRun,
filter_data: FilterDataIntern,
}
}
}
macro_rules! declare_interning_memory_report {
( $( $name: ident, )+ ) => {
( $( $name:ident : $ty:ident, )+ ) => {
#[repr(C)]
#[derive(AddAssign, Clone, Debug, Default, Deserialize, Serialize)]
pub struct InternerSubReport {