From 2ef785bda12566ed17fc68b6f5927156a1e7ff0a Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 3 Mar 2019 21:14:49 +0000 Subject: [PATCH] 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 --- gfx/wr/webrender/src/batch.rs | 2 +- gfx/wr/webrender/src/box_shadow.rs | 7 +- gfx/wr/webrender/src/clip.rs | 12 +- .../webrender/src/display_list_flattener.rs | 73 ++++---- gfx/wr/webrender/src/filterdata.rs | 10 +- gfx/wr/webrender/src/intern.rs | 161 ++++++++---------- gfx/wr/webrender/src/intern_types.rs | 114 ------------- gfx/wr/webrender/src/lib.rs | 1 - gfx/wr/webrender/src/picture.rs | 2 +- gfx/wr/webrender/src/prim_store/borders.rs | 78 ++++----- gfx/wr/webrender/src/prim_store/gradient.rs | 89 +++++----- gfx/wr/webrender/src/prim_store/image.rs | 103 +++++------ gfx/wr/webrender/src/prim_store/interned.rs | 12 ++ gfx/wr/webrender/src/prim_store/line_dec.rs | 44 +++-- gfx/wr/webrender/src/prim_store/mod.rs | 120 ++++++------- gfx/wr/webrender/src/prim_store/picture.rs | 44 +++-- gfx/wr/webrender/src/prim_store/text_run.rs | 59 ++++--- gfx/wr/webrender/src/profiler.rs | 5 +- gfx/wr/webrender/src/render_backend.rs | 8 +- gfx/wr/webrender/src/scene_builder.rs | 54 ++---- gfx/wr/webrender_api/src/api.rs | 44 +++-- 21 files changed, 442 insertions(+), 600 deletions(-) delete mode 100644 gfx/wr/webrender/src/intern_types.rs create mode 100644 gfx/wr/webrender/src/prim_store/interned.rs diff --git a/gfx/wr/webrender/src/batch.rs b/gfx/wr/webrender/src/batch.rs index 850d81914da5..3816513e1ab0 100644 --- a/gfx/wr/webrender/src/batch.rs +++ b/gfx/wr/webrender/src/batch.rs @@ -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 | diff --git a/gfx/wr/webrender/src/box_shadow.rs b/gfx/wr/webrender/src/box_shadow.rs index 75ab8b8d0cb1..1257c0cb5ab8 100644 --- a/gfx/wr/webrender/src/box_shadow.rs +++ b/gfx/wr/webrender/src/box_shadow.rs @@ -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; diff --git a/gfx/wr/webrender/src/clip.rs b/gfx/wr/webrender/src/clip.rs index d31d7821684a..ecbfa1d1256b 100644 --- a/gfx/wr/webrender/src/clip.rs +++ b/gfx/wr/webrender/src/clip.rs @@ -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; +type ClipDataHandle = intern::Handle; // 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))] diff --git a/gfx/wr/webrender/src/display_list_flattener.rs b/gfx/wr/webrender/src/display_list_flattener.rs index 7e52fb90714e..2d2a9bf4589f 100644 --- a/gfx/wr/webrender/src/display_list_flattener.rs +++ b/gfx/wr/webrender/src/display_list_flattener.rs @@ -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, - P::Source: AsInstanceKind> + InternDebug, - Interners: InternerMut

, + P: InternablePrimitive, + Interners: AsMut>, { // 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 + IsVisible, - P::Source: AsInstanceKind> + InternDebug, - Interners: InternerMut

, + P: InternablePrimitive + IsVisible, + Interners: AsMut>, { 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 + IsVisible, - P::Source: AsInstanceKind> + InternDebug, - Interners: InternerMut

, + P: InternablePrimitive + IsVisible, + Interners: AsMut>, ShadowItem: From> { // If a shadow context is not active, then add the primitive @@ -1290,9 +1288,8 @@ impl<'a> DisplayListFlattener<'a> { prim: P, ) where - P: Internable, - P::Source: AsInstanceKind> + InternDebug, - Interners: InternerMut

, + P: InternablePrimitive, + Interners: AsMut>, { 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, ) where - P: Internable + CreateShadow, - P::Source: AsInstanceKind> + InternDebug, - Interners: InternerMut

, + P: InternablePrimitive + CreateShadow, + Interners: AsMut>, { // 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

, ) where - P: Internable + IsVisible, - P::Source: AsInstanceKind> + InternDebug, - Interners: InternerMut

, + P: InternablePrimitive + IsVisible, + Interners: AsMut>, { // 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 { - 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; diff --git a/gfx/wr/webrender/src/filterdata.rs b/gfx/wr/webrender/src/filterdata.rs index 89912138ab14..69e8112d1fc0 100644 --- a/gfx/wr/webrender/src/filterdata.rs +++ b/gfx/wr/webrender/src/filterdata.rs @@ -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; #[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, diff --git a/gfx/wr/webrender/src/intern.rs b/gfx/wr/webrender/src/intern.rs index a42597bf1b13..fe8d7c61ea4f 100644 --- a/gfx/wr/webrender/src/intern.rs +++ b/gfx/wr/webrender/src/intern.rs @@ -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 { +#[derive(Debug, MallocSizeOf)] +pub struct Handle { index: u32, epoch: Epoch, uid: ItemUid, - _marker: PhantomData, + _marker: PhantomData, } -impl Handle where M: Copy { +impl Clone for Handle { + fn clone(&self) -> Self { + Handle { + index: self.index, + epoch: self.epoch, + uid: self.uid, + _marker: self._marker, + } + } +} + +impl Copy for Handle {} + +impl Handle { 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 { - items: Vec>, - _source: PhantomData, - _marker: PhantomData, +pub struct DataStore { + items: Vec>, } -impl ::std::default::Default for DataStore -where - S: Debug + MallocSizeOf, - T: From + MallocSizeOf, - M: Debug -{ +impl Default for DataStore { fn default() -> Self { DataStore { items: Vec::new(), - _source: PhantomData, - _marker: PhantomData, } } } -impl DataStore -where - S: Debug + MallocSizeOf, - T: From + MallocSizeOf, - M: Debug -{ +impl DataStore { /// Apply any updates from the scene builder thread to /// this data store. pub fn apply_updates( &mut self, - update_list: UpdateList, + update_list: UpdateList, 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::() + mem::size_of::(); + let per_item_size = mem::size_of::() + mem::size_of::(); 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 ops::Index> for DataStore -where - S: MallocSizeOf, - T: MallocSizeOf, - M: Copy -{ - type Output = T; - fn index(&self, handle: Handle) -> &T { +impl ops::Index> for DataStore { + type Output = I::StoreData; + fn index(&self, handle: Handle) -> &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 ops::IndexMut> for DataStore -where - S: MallocSizeOf, - T: MallocSizeOf, - M: Copy -{ - fn index_mut(&mut self, handle: Handle) -> &mut T { +impl ops::IndexMut> for DataStore { + fn index_mut(&mut self, handle: Handle) -> &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 -where - S: Eq + Hash + Clone + Debug + MallocSizeOf, - D: MallocSizeOf, - M: Copy + MallocSizeOf, -{ +pub struct Interner { /// Uniquely map an interning key to a handle - map: FastHashMap>, + map: FastHashMap>, /// List of free slots in the data store for re-use. free_list: Vec, /// Pending list of updates that need to be applied. updates: Vec, /// Pending new data to insert. - update_data: Vec, + update_data: Vec, /// 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, + local_data: Vec, } -impl ::std::default::Default for Interner -where - S: Eq + Hash + Clone + Debug + MallocSizeOf, - D: MallocSizeOf, - M: Copy + Debug + MallocSizeOf, -{ +impl Default for Interner { fn default() -> Self { Interner { map: FastHashMap::default(), @@ -245,12 +225,7 @@ where } } -impl Interner -where - S: Eq + Hash + Clone + Debug + InternDebug + MallocSizeOf, - D: MallocSizeOf, - M: Copy + Debug + MallocSizeOf -{ +impl Interner { /// 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( &mut self, - data: &S, - f: F, - ) -> Handle where F: FnOnce() -> D { + data: &I::Key, + fun: F, + ) -> Handle 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 { + pub fn end_frame_and_get_pending_updates(&mut self) -> UpdateList { 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 ops::Index> for Interner -where - S: Eq + Clone + Hash + Debug + MallocSizeOf, - D: MallocSizeOf, - M: Copy + Debug + MallocSizeOf -{ - type Output = D; - fn index(&self, handle: Handle) -> &D { +impl ops::Index> for Interner { + type Output = I::InternData; + fn index(&self, handle: Handle) -> &I::InternData { &self.local_data[handle.index as usize] } } -/// Implement `Internable` for a type that wants participate in interning. -/// -/// see DisplayListFlattener::add_interned_primitive

-pub trait Internable { - type Marker: Copy + Debug + MallocSizeOf; - type Source: Eq + Hash + Clone + Debug + MallocSizeOf; - type StoreData: From + 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 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 + MallocSizeOf + InternSerialize + for<'a> InternDeserialize<'a>; + type InternData: MallocSizeOf + InternSerialize + for<'a> InternDeserialize<'a>; } diff --git a/gfx/wr/webrender/src/intern_types.rs b/gfx/wr/webrender/src/intern_types.rs deleted file mode 100644 index bdeca9c356e9..000000000000 --- a/gfx/wr/webrender/src/intern_types.rs +++ /dev/null @@ -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; - ) -} - -pub mod clip { -common!(); -use ::clip::{ClipItemKey, ClipNode}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod prim { -common!(); -use ::prim_store::{PrimitiveKey, PrimitiveTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod normal_border { -common!(); -use ::prim_store::borders::{NormalBorderKey, NormalBorderTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod image_border { -common!(); -use ::prim_store::borders::{ImageBorderKey, ImageBorderTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod image { -common!(); -use ::prim_store::image::{ImageKey, ImageTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod yuv_image { -common!(); -use ::prim_store::image::{YuvImageKey, YuvImageTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod line_decoration { -use ::prim_store::line_dec::{LineDecorationKey, LineDecorationTemplate}; -common!(); -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod linear_grad { -common!(); -use ::prim_store::gradient::{LinearGradientKey, LinearGradientTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod radial_grad { -common!(); -use ::prim_store::gradient::{RadialGradientKey, RadialGradientTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod picture { -common!(); -use ::prim_store::picture::{PictureKey, PictureTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod text_run { -common!(); -use ::prim_store::text_run::{TextRunKey, TextRunTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - -pub mod filterdata { -common!(); -use ::filterdata::{SFilterDataKey, SFilterDataTemplate}; -pub type Store = intern::DataStore; -pub type UpdateList = intern::UpdateList; -pub type Interner = intern::Interner; -} - - diff --git a/gfx/wr/webrender/src/lib.rs b/gfx/wr/webrender/src/lib.rs index d790c333a421..9f6fb79807d0 100644 --- a/gfx/wr/webrender/src/lib.rs +++ b/gfx/wr/webrender/src/lib.rs @@ -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; diff --git a/gfx/wr/webrender/src/picture.rs b/gfx/wr/webrender/src/picture.rs index 90105a35d35b..4f883d4ac73a 100644 --- a/gfx/wr/webrender/src/picture.rs +++ b/gfx/wr/webrender/src/picture.rs @@ -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( diff --git a/gfx/wr/webrender/src/prim_store/borders.rs b/gfx/wr/webrender/src/prim_store/borders.rs index 089278a19634..d0d2d712b83e 100644 --- a/gfx/wr/webrender/src/prim_store/borders.rs +++ b/gfx/wr/webrender/src/prim_store/borders.rs @@ -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 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 for NormalBorderTemplate { } } -pub use intern_types::normal_border::Handle as NormalBorderDataHandle; +pub type NormalBorderDataHandle = intern::Handle; 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 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 for ImageBorderTemplate { } } -pub use intern_types::image_border::Handle as ImageBorderDataHandle; +pub type ImageBorderDataHandle = intern::Handle; 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 { diff --git a/gfx/wr/webrender/src/prim_store/gradient.rs b/gfx/wr/webrender/src/prim_store/gradient.rs index af0383489a16..8064fed6a715 100644 --- a/gfx/wr/webrender/src/prim_store/gradient.rs +++ b/gfx/wr/webrender/src/prim_store/gradient.rs @@ -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 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; +#[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 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; +#[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 { diff --git a/gfx/wr/webrender/src/prim_store/image.rs b/gfx/wr/webrender/src/prim_store/image.rs index 32df6901c9a6..9c55117ab25e 100644 --- a/gfx/wr/webrender/src/prim_store/image.rs +++ b/gfx/wr/webrender/src/prim_store/image.rs @@ -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 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 for ImageTemplate { } } -pub use intern_types::image::Handle as ImageDataHandle; +pub type ImageDataHandle = InternHandle; 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 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 for YuvImageTemplate { } } -pub use intern_types::yuv_image::Handle as YuvImageDataHandle; +pub type YuvImageDataHandle = InternHandle; 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 { diff --git a/gfx/wr/webrender/src/prim_store/interned.rs b/gfx/wr/webrender/src/prim_store/interned.rs new file mode 100644 index 000000000000..3ae38d38a7c9 --- /dev/null +++ b/gfx/wr/webrender/src/prim_store/interned.rs @@ -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; diff --git a/gfx/wr/webrender/src/prim_store/line_dec.rs b/gfx/wr/webrender/src/prim_store/line_dec.rs index 27ba95b9cdce..c314d830366e 100644 --- a/gfx/wr/webrender/src/prim_store/line_dec.rs +++ b/gfx/wr/webrender/src/prim_store/line_dec.rs @@ -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 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 for LineDecorationTemplate { } } -pub use intern_types::line_decoration::Handle as LineDecorationDataHandle; +pub type LineDecorationDataHandle = intern::Handle; 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 { diff --git a/gfx/wr/webrender/src/prim_store/mod.rs b/gfx/wr/webrender/src/prim_store/mod.rs index c279618e9ffa..be9d5605ec11 100644 --- a/gfx/wr/webrender/src/prim_store/mod.rs +++ b/gfx/wr/webrender/src/prim_store/mod.rs @@ -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 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 for PrimitiveTemplateKind { + fn from(kind: PrimitiveKeyKind) -> Self { + match kind { PrimitiveKeyKind::Clear => { PrimitiveTemplateKind::Clear } @@ -746,10 +705,10 @@ impl ops::DerefMut for PrimitiveTemplate { impl From 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; + 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

+pub trait InternablePrimitive: intern::Internable + 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, + prim_store: &mut PrimitiveStore, + reference_frame_relative_offset: LayoutVector2D, + ) -> PrimitiveInstanceKind; +} + + #[test] #[cfg(target_pointer_width = "64")] fn test_struct_sizes() { diff --git a/gfx/wr/webrender/src/prim_store/picture.rs b/gfx/wr/webrender/src/prim_store/picture.rs index 2051fb6ba760..fd40faa171f6 100644 --- a/gfx/wr/webrender/src/prim_store/picture.rs +++ b/gfx/wr/webrender/src/prim_store/picture.rs @@ -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 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 for PictureTemplate { } } -pub use intern_types::picture::Handle as PictureDataHandle; +pub type PictureDataHandle = InternHandle; 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 { diff --git a/gfx/wr/webrender/src/prim_store/text_run.rs b/gfx/wr/webrender/src/prim_store/text_run.rs index 501a8ac80dad..3c17df39f331 100644 --- a/gfx/wr/webrender/src/prim_store/text_run.rs +++ b/gfx/wr/webrender/src/prim_store/text_run.rs @@ -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 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; +#[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>, 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 { diff --git a/gfx/wr/webrender/src/profiler.rs b/gfx/wr/webrender/src/profiler.rs index fdc53fbfe860..7b35341c9664 100644 --- a/gfx/wr/webrender/src/profiler.rs +++ b/gfx/wr/webrender/src/profiler.rs @@ -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"), }, } } diff --git a/gfx/wr/webrender/src/render_backend.rs b/gfx/wr/webrender/src/render_backend.rs index 43ca4c91a38a..f0e0a9e8ebbe 100644 --- a/gfx/wr/webrender/src/render_backend.rs +++ b/gfx/wr/webrender/src/render_backend.rs @@ -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>, )+ } diff --git a/gfx/wr/webrender/src/scene_builder.rs b/gfx/wr/webrender/src/scene_builder.rs index 0398335db66a..412dcea77f2d 100644 --- a/gfx/wr/webrender/src/scene_builder.rs +++ b/gfx/wr/webrender/src/scene_builder.rs @@ -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> 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 -{ - fn interner_mut(&mut self) -> &mut Interner; -} - -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 diff --git a/gfx/wr/webrender_api/src/api.rs b/gfx/wr/webrender_api/src/api.rs index d7a29c754f9c..ee4880a59ace 100644 --- a/gfx/wr/webrender_api/src/api.rs +++ b/gfx/wr/webrender_api/src/api.rs @@ -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 {