| author | Brindusan Cristian <cbrindusan@mozilla.com> |
| Fri, 24 Jan 2020 20:42:16 +0200 | |
| changeset 511705 | 65b1787817bdd4addf847582f564a68afabdb932 |
| parent 511704 | 519a3bf8de9403f05b526a501b1543e7eb52a0c2 |
| child 511706 | 3803b2403fa26a9726088bd66e043760b9915273 |
| push id | 37054 |
| push user | btara@mozilla.com |
| push date | Sat, 25 Jan 2020 09:45:27 +0000 |
| treeherder | mozilla-central@f7f534f08b48 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| bugs | 1558926 |
| milestone | 74.0a1 |
| backs out | 974bcab6b1bf3cea22595e23d06cd9457d302299 1865e6d29dcfdcc1ec7adb5a5fa8fa9df183083b 92b415dac733b24ce8013e2ba6dd629c25c7af5c 30481c41873ab75cb2b0c49860d6b67ad7e38bf5 a4d9a1af297af013b60da92594942f02c955a338 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -251,17 +251,16 @@ EXPORTS.mozilla.layers += [ 'SyncObject.h', 'TextureSourceProvider.h', 'TextureWrapperImage.h', 'TransactionIdAllocator.h', 'TreeTraversal.h', 'UpdateImageHelper.h', 'wr/AsyncImagePipelineManager.h', 'wr/ClipManager.h', - 'wr/DisplayItemCache.h', 'wr/IpcResourceUpdateQueue.h', 'wr/RenderRootBoundary.h', 'wr/RenderRootStateManager.h', 'wr/RenderRootTypes.h', 'wr/StackingContextHelper.h', 'wr/WebRenderBridgeChild.h', 'wr/WebRenderBridgeParent.h', 'wr/WebRenderCanvasRenderer.h', @@ -519,17 +518,16 @@ UNIFIED_SOURCES += [ 'ShareableCanvasRenderer.cpp', 'SourceSurfaceSharedData.cpp', 'SourceSurfaceVolatileData.cpp', 'SyncObject.cpp', 'TextureSourceProvider.cpp', 'TextureWrapperImage.cpp', 'wr/AsyncImagePipelineManager.cpp', 'wr/ClipManager.cpp', - 'wr/DisplayItemCache.cpp', 'wr/IpcResourceUpdateQueue.cpp', 'wr/RenderRootStateManager.cpp', 'wr/RenderRootTypes.cpp', 'wr/StackingContextHelper.cpp', 'wr/WebRenderBridgeChild.cpp', 'wr/WebRenderBridgeParent.cpp', 'wr/WebRenderCanvasRenderer.cpp', 'wr/WebRenderCommandBuilder.cpp',
deleted file mode 100644 --- a/gfx/layers/wr/DisplayItemCache.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "DisplayItemCache.h" - -namespace mozilla { -namespace layers { - -void DisplayItemCache::UpdateState(const bool aPartialDisplayListBuildFailed, - const wr::PipelineId& aPipelineId) { - if (!IsEnabled()) { - return; - } - - // Clear the cache if the partial display list build failed, or if the - // pipeline id changed. - const bool clearCache = - UpdatePipelineId(aPipelineId) || aPartialDisplayListBuildFailed; - - if (clearCache) { - memset(mCachedItemState.Elements(), 0, - mCachedItemState.Length() * sizeof(CacheEntry)); - mNextIndex = 0; - mFreeList.Clear(); - } - - PopulateFreeList(clearCache); -} - -void DisplayItemCache::PopulateFreeList(const bool aAddAll) { - uint16_t index = 0; - for (auto& state : mCachedItemState) { - if (aAddAll || (!state.mUsed && state.mCached)) { - // This entry contained a cached item, but was not used. - state.mCached = false; - mFreeList.AppendElement(index); - } - - state.mUsed = false; - index++; - } -} - -static bool CanCacheItem(const nsDisplayItem* aItem) { - // Only cache leaf display items that can be reused. - if (!aItem->CanBeReused()) { - return false; - } - - switch (aItem->GetType()) { - case DisplayItemType::TYPE_BACKGROUND_COLOR: - // case DisplayItemType::TYPE_TEXT: - MOZ_ASSERT(!aItem->HasChildren()); - return true; - default: - return false; - } -} - -void DisplayItemCache::MaybeStartCaching(nsPaintedDisplayItem* aItem, - wr::DisplayListBuilder& aBuilder) { - if (!IsEnabled()) { - return; - } - - Stats().AddTotal(); - - auto& index = aItem->CacheIndex(); - if (!index) { - if (!CanCacheItem(aItem)) { - // The item cannot be cached. - return; - } - - index = GetNextCacheIndex(); - if (!index) { - // The item does not fit in the cache. - return; - } - } - - // Update the current cache index, which is used by |MaybeEndCaching()| below. - MOZ_ASSERT(!mCurrentIndex); - mCurrentIndex = index; - - MOZ_ASSERT(CanCacheItem(aItem)); - MOZ_ASSERT(mCurrentIndex && CurrentCacheSize() > *mCurrentIndex); - - auto& state = mCachedItemState[*mCurrentIndex]; - MOZ_ASSERT(!state.mCached); - state.mCached = true; - MOZ_ASSERT(!state.mUsed); - state.mUsed = true; - state.mSpaceAndClip = aBuilder.CurrentSpaceAndClipChain(); - - Stats().AddCached(); - aBuilder.StartCachedItem(*mCurrentIndex); -} - -void DisplayItemCache::MaybeEndCaching(wr::DisplayListBuilder& aBuilder) { - if (IsEnabled() && mCurrentIndex) { - aBuilder.EndCachedItem(*mCurrentIndex); - mCurrentIndex = Nothing(); - } -} - -bool DisplayItemCache::ReuseItem(nsPaintedDisplayItem* aItem, - wr::DisplayListBuilder& aBuilder) { - if (!IsEnabled()) { - return false; - } - - auto& index = aItem->CacheIndex(); - if (!index) { - return false; - } - - auto& state = mCachedItemState[*index]; - if (!state.mCached) { - // The display item has a stale cache state. - return false; // Recache item. - } - - // Spatial id and clip id can change between display lists. - if (!(aBuilder.CurrentSpaceAndClipChain() == state.mSpaceAndClip)) { - // TODO(miko): Technically we might be able to update just the changed data - // here but it adds a lot of complexity. - // Mark the cache state false and recache the item. - state.mCached = false; - return false; - } - - Stats().AddReused(); - Stats().AddTotal(); - - state.mUsed = true; - aBuilder.ReuseItem(*index); - return true; -} - -} // namespace layers -} // namespace mozilla
deleted file mode 100644 --- a/gfx/layers/wr/DisplayItemCache.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef GFX_DISPLAY_ITEM_CACHE_H -#define GFX_DISPLAY_ITEM_CACHE_H - -#include "mozilla/webrender/WebRenderAPI.h" -#include "mozilla/Maybe.h" -#include "nsTArray.h" - -class nsPaintedDisplayItem; - -namespace mozilla { - -namespace wr { -class DisplayListBuilder; -} // namespace wr - -namespace layers { - -class CacheStats { - public: - CacheStats() = default; - - void Reset() { mCached = mReused = mTotal = 0; } - - void Print() { - printf("Cached: %zu, Reused: %zu, Total: %zu\n", mCached, mReused, mTotal); - } - - void AddCached() { mCached++; } - void AddReused() { mReused++; } - void AddTotal() { mTotal++; } - - private: - size_t mCached = 0; - size_t mReused = 0; - size_t mTotal = 0; -}; - -/** - * DisplayItemCache keeps track of which Gecko display items have already had - * their respective WebRender display items sent to WebRender backend. - * - * Ideally creating the WR display items for a Gecko display item would not - * depend on any external state. However currently pipeline id, clip id, and - * spatial id can change between display lists, even if the Gecko display items - * have not. This state is tracked by DisplayItemCache. - */ -class DisplayItemCache final { - public: - DisplayItemCache() : mMaxCacheSize(0), mNextIndex(0) {} - - bool IsEnabled() const { return mMaxCacheSize > 0; } - - /** - * Updates the cache state based on the given display list build information - * and pipeline id. - * - * This is necessary because Gecko display items can only be reused for the - * partial display list builds following a full display list build. - */ - void UpdateState(const bool aPartialDisplayListBuildFailed, - const wr::PipelineId& aPipelineId); - - /** - * Returns the current cache size. - */ - size_t CurrentCacheSize() const { - return IsEnabled() ? mCachedItemState.Length() : 0; - } - - /** - * Sets the initial and max cache size to given |aInitialSize| and |aMaxSize|. - * - * Currently the cache size is constant, but a good improvement would be to - * set the initial and maximum size based on the display list length. - */ - void SetCapacity(const size_t aInitialSize, const size_t aMaxSize) { - mMaxCacheSize = aMaxSize; - mCachedItemState.SetCapacity(aMaxSize); - mCachedItemState.SetLength(aInitialSize); - mFreeList.SetCapacity(aMaxSize); - } - - /** - * If the given display item |aItem| can be cached, update the cache state of - * the item and tell WR DisplayListBuilder |aBuilder| to cache WR display - * items until |EndCaching()| is called. - * - * If the display item cannot be cached, this function does nothing. - */ - void MaybeStartCaching(nsPaintedDisplayItem* aItem, - wr::DisplayListBuilder& aBuilder); - - /** - * Tell WR DisplayListBuilder |aBuilder| to stop caching WR display items. - * - * If the display item cannot be cached, this function does nothing. - */ - void MaybeEndCaching(wr::DisplayListBuilder& aBuilder); - - /** - * If the given |aItem| has been cached, tell WR DisplayListBuilder |aBuilder| - * to reuse it. - * Returns true if the item was reused, otherwise returns false. - */ - bool ReuseItem(nsPaintedDisplayItem* aItem, wr::DisplayListBuilder& aBuilder); - - CacheStats& Stats() { return mCacheStats; } - - private: - struct CacheEntry { - wr::WrSpaceAndClipChain mSpaceAndClip; - bool mCached; - bool mUsed; - }; - - Maybe<uint16_t> GetNextCacheIndex() { - if (mFreeList.IsEmpty()) { - return Nothing(); - } - - return Some(mFreeList.PopLastElement()); - } - - /** - * Iterates through |mCachedItemState| and adds unused entries to free list. - * If |aAddAll| is true, adds every entry regardless of the state. - */ - void PopulateFreeList(const bool aAddAll); - - /** - * Returns true if the given |aPipelineId| is different from the previous one, - * otherwise returns false. - */ - bool UpdatePipelineId(const wr::PipelineId& aPipelineId) { - const bool isSame = mPreviousPipelineId.refOr(aPipelineId) == aPipelineId; - mPreviousPipelineId = Some(aPipelineId); - return !isSame; - } - - nsTArray<CacheEntry> mCachedItemState; - nsTArray<uint16_t> mFreeList; - size_t mMaxCacheSize; - uint16_t mNextIndex; - Maybe<uint16_t> mCurrentIndex; - Maybe<wr::PipelineId> mPreviousPipelineId; - CacheStats mCacheStats; -}; - -} // namespace layers -} // namespace mozilla - -#endif /* GFX_DISPLAY_ITEM_CACHE_H */
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -1539,31 +1539,16 @@ void WebRenderCommandBuilder::DoGrouping .PostTranslate(residualOffset.x, residualOffset.y); group.mScale = scale; group.mScrollId = scrollId; g.ConstructGroups(aDisplayListBuilder, this, aBuilder, aResources, &group, aList, aSc); mCurrentClipManager->EndList(aSc); } -WebRenderCommandBuilder::WebRenderCommandBuilder( - WebRenderLayerManager* aManager) - : mManager(aManager), - mRootStackingContexts(nullptr), - mCurrentClipManager(nullptr), - mLastAsr(nullptr), - mDumpIndent(0), - mDoGrouping(false), - mContainsSVGGroup(false) { - if (XRE_IsContentProcess() && - StaticPrefs::gfx_webrender_enable_item_cache_AtStartup()) { - mDisplayItemCache.SetCapacity(10000, 10000); - } -} - void WebRenderCommandBuilder::Destroy() { mLastCanvasDatas.Clear(); ClearCachedResources(); } void WebRenderCommandBuilder::EmptyTransaction() { // We need to update canvases that might have changed. for (auto iter = mLastCanvasDatas.Iter(); !iter.Done(); iter.Next()) { @@ -1598,23 +1583,16 @@ void WebRenderCommandBuilder::BuildWebRe mBuilderDumpIndex[renderRoot] = 0; } MOZ_ASSERT(mLayerScrollDatas.IsEmpty()); mLastCanvasDatas.Clear(); mLastAsr = nullptr; mContainsSVGGroup = false; MOZ_ASSERT(mDumpIndent == 0); - if (mDisplayItemCache.IsEnabled()) { - mDisplayItemCache.UpdateState(aDisplayListBuilder->PartialBuildFailed(), - aBuilder.CurrentPipelineId()); - aBuilder.SetDisplayListCacheSize(mDisplayItemCache.CurrentCacheSize()); - // mDisplayItemCache.Stats().Reset(); - } - { nsPresContext* presContext = aDisplayListBuilder->RootReferenceFrame()->PresContext(); bool isTopLevelContent = presContext->Document()->IsTopLevelContentDocument(); wr::RenderRootArray<Maybe<StackingContextHelper>> pageRootScs; for (auto renderRoot : wr::kRenderRoots) { @@ -1674,62 +1652,27 @@ void WebRenderCommandBuilder::BuildWebRe mClipManagers[renderRoot].EndBuild(); } } mLayerScrollDatas.Clear(); // Remove the user data those are not displayed on the screen and // also reset the data to unused for next transaction. RemoveUnusedAndResetWebRenderUserData(); - - if (mDisplayItemCache.IsEnabled()) { - // mDisplayItemCache.Stats().Print(); - } } bool WebRenderCommandBuilder::ShouldDumpDisplayList( nsDisplayListBuilder* aBuilder) { return aBuilder != nullptr && aBuilder->IsInActiveDocShell() && ((XRE_IsParentProcess() && StaticPrefs::gfx_webrender_dl_dump_parent()) || (XRE_IsContentProcess() && StaticPrefs::gfx_webrender_dl_dump_content())); } -void WebRenderCommandBuilder::CreateWebRenderCommands( - nsDisplayItem* aItem, mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - nsDisplayListBuilder* aDisplayListBuilder) { - auto* item = aItem->AsPaintedDisplayItem(); - MOZ_RELEASE_ASSERT(item, "Tried to paint item that cannot be painted"); - - if (mDisplayItemCache.ReuseItem(item, aBuilder)) { - // No further processing should be needed, since the item was reused. - return; - } - - mDisplayItemCache.MaybeStartCaching(item, aBuilder); - - aItem->SetPaintRect(aItem->GetBuildingRect()); - RenderRootStateManager* manager = - mManager->GetRenderRootStateManager(aBuilder.GetRenderRoot()); - - // Note: this call to CreateWebRenderCommands can recurse back into - // this function if the |item| is a wrapper for a sublist. - const bool createdWRCommands = aItem->CreateWebRenderCommands( - aBuilder, aResources, aSc, manager, aDisplayListBuilder); - - if (!createdWRCommands) { - PushItemAsImage(aItem, aBuilder, aResources, aSc, aDisplayListBuilder); - } - - mDisplayItemCache.MaybeEndCaching(aBuilder); -} - void WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList( nsDisplayList* aDisplayList, nsDisplayItem* aWrappingItem, nsDisplayListBuilder* aDisplayListBuilder, const StackingContextHelper& aSc, wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources) { AutoRestore<ClipManager*> prevClipManager(mCurrentClipManager); mCurrentClipManager = &mClipManagers[aBuilder.GetRenderRoot()]; if (mDoGrouping) { MOZ_RELEASE_ASSERT( @@ -1821,18 +1764,26 @@ void WebRenderCommandBuilder::CreateWebR if (dumpEnabled) { std::stringstream ss; nsFrame::PrintDisplayItem(aDisplayListBuilder, item, ss, static_cast<uint32_t>(mDumpIndent)); printf_stderr("%s", ss.str().c_str()); } - CreateWebRenderCommands(item, aBuilder, aResources, aSc, - aDisplayListBuilder); + // Note: this call to CreateWebRenderCommands can recurse back into + // this function if the |item| is a wrapper for a sublist. + item->SetPaintRect(item->GetBuildingRect()); + RenderRootStateManager* manager = + mManager->GetRenderRootStateManager(aBuilder.GetRenderRoot()); + bool createdWRCommands = item->CreateWebRenderCommands( + aBuilder, aResources, aSc, manager, aDisplayListBuilder); + if (!createdWRCommands) { + PushItemAsImage(item, aBuilder, aResources, aSc, aDisplayListBuilder); + } if (dumpEnabled) { mBuilderDumpIndex[aBuilder.GetRenderRoot()] = aBuilder.Dump( mDumpIndent + 1, Some(mBuilderDumpIndex[aBuilder.GetRenderRoot()]), Nothing()); } }
--- a/gfx/layers/wr/WebRenderCommandBuilder.h +++ b/gfx/layers/wr/WebRenderCommandBuilder.h @@ -10,17 +10,16 @@ #include "mozilla/webrender/WebRenderAPI.h" #include "mozilla/layers/ClipManager.h" #include "mozilla/layers/RenderRootBoundary.h" #include "mozilla/layers/WebRenderMessages.h" #include "mozilla/layers/WebRenderScrollData.h" #include "mozilla/layers/WebRenderUserData.h" #include "nsDisplayList.h" #include "nsIFrame.h" -#include "DisplayItemCache.h" namespace mozilla { namespace layers { class CanvasLayer; class ImageClient; class ImageContainer; @@ -78,17 +77,24 @@ class WebRenderScrollDataCollection { }; class WebRenderCommandBuilder final { typedef nsTHashtable<nsRefPtrHashKey<WebRenderUserData>> WebRenderUserDataRefTable; typedef nsTHashtable<nsRefPtrHashKey<WebRenderCanvasData>> CanvasDataSet; public: - explicit WebRenderCommandBuilder(WebRenderLayerManager* aManager); + explicit WebRenderCommandBuilder(WebRenderLayerManager* aManager) + : mManager(aManager), + mRootStackingContexts(nullptr), + mCurrentClipManager(nullptr), + mLastAsr(nullptr), + mDumpIndent(0), + mDoGrouping(false), + mContainsSVGGroup(false) {} void Destroy(); void EmptyTransaction(); bool NeedsEmptyTransaction(); void BuildWebRenderCommands( @@ -222,21 +228,16 @@ class WebRenderCommandBuilder final { WebRenderCommandBuilder& mBuilder; RenderRootBoundary mBoundary; size_t mLayerCountBeforeRecursing; }; friend class ScrollDataBoundaryWrapper; private: RenderRootStateManager* GetRenderRootStateManager(wr::RenderRoot aRenderRoot); - void CreateWebRenderCommands(nsDisplayItem* aItem, - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - nsDisplayListBuilder* aDisplayListBuilder); wr::RenderRootArray<Maybe<StackingContextHelper>>* mRootStackingContexts; wr::RenderRootArray<ClipManager> mClipManagers; ClipManager* mCurrentClipManager; // We use this as a temporary data structure while building the mScrollData // inside a layers-free transaction. WebRenderScrollDataCollection mLayerScrollDatas; @@ -250,18 +251,16 @@ class WebRenderCommandBuilder final { WebRenderUserDataRefTable mWebRenderUserDatas; // Store of WebRenderCanvasData objects for use in empty transactions CanvasDataSet mLastCanvasDatas; wr::RenderRootArray<wr::usize> mBuilderDumpIndex; wr::usize mDumpIndent; - DisplayItemCache mDisplayItemCache; - public: // Whether consecutive inactive display items should be grouped into one // blob image. bool mDoGrouping; // True if the most recently build display list contained an svg that // we did grouping for. bool mContainsSVGGroup;
--- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -1390,32 +1390,16 @@ void DisplayListBuilder::PushBoxShadow( const wr::BorderRadius& aBorderRadius, const wr::BoxShadowClipMode& aClipMode) { wr_dp_push_box_shadow(mWrState, aRect, MergeClipLeaf(aClip), aIsBackfaceVisible, &mCurrentSpaceAndClipChain, aBoxBounds, aOffset, aColor, aBlurRadius, aSpreadRadius, aBorderRadius, aClipMode); } -void DisplayListBuilder::ReuseItem(wr::ItemKey aKey) { - wr_dp_push_reuse_item(mWrState, aKey); -} - -void DisplayListBuilder::StartCachedItem(wr::ItemKey aKey) { - wr_dp_start_cached_item(mWrState, aKey); -} - -void DisplayListBuilder::EndCachedItem(wr::ItemKey aKey) { - wr_dp_end_cached_item(mWrState, aKey); -} - -void DisplayListBuilder::SetDisplayListCacheSize(const size_t aCacheSize) { - wr_dp_set_cache_size(mWrState, aCacheSize); -} - Maybe<layers::ScrollableLayerGuid::ViewID> DisplayListBuilder::GetContainingFixedPosScrollTarget( const ActiveScrolledRoot* aAsr) { return mActiveFixedPosTracker ? mActiveFixedPosTracker->GetScrollTargetForASR(aAsr) : Nothing(); }
--- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -395,17 +395,16 @@ class DisplayListBuilder final { RenderRoot aRenderRoot = RenderRoot::Default); DisplayListBuilder(DisplayListBuilder&&) = default; ~DisplayListBuilder(); void Save(); void Restore(); void ClearSave(); - usize Dump(usize aIndent, const Maybe<usize>& aStart, const Maybe<usize>& aEnd); void Finalize(wr::LayoutSize& aOutContentSizes, wr::BuiltDisplayList& aOutDisplayList); void Finalize(layers::RenderRootDisplayListData& aOutTransaction); RenderRoot GetRenderRoot() const { return mRenderRoot; } @@ -574,31 +573,20 @@ class DisplayListBuilder final { void PushBoxShadow(const wr::LayoutRect& aRect, const wr::LayoutRect& aClip, bool aIsBackfaceVisible, const wr::LayoutRect& aBoxBounds, const wr::LayoutVector2D& aOffset, const wr::ColorF& aColor, const float& aBlurRadius, const float& aSpreadRadius, const wr::BorderRadius& aBorderRadius, const wr::BoxShadowClipMode& aClipMode); - void StartCachedItem(wr::ItemKey aKey); - void EndCachedItem(wr::ItemKey aKey); - void ReuseItem(wr::ItemKey aKey); - void SetDisplayListCacheSize(const size_t aCacheSize); - uint64_t CurrentClipChainId() const { return mCurrentSpaceAndClipChain.clip_chain; } - const wr::WrSpaceAndClipChain& CurrentSpaceAndClipChain() const { - return mCurrentSpaceAndClipChain; - } - - const wr::PipelineId& CurrentPipelineId() const { return mPipelineId; } - // Checks to see if the innermost enclosing fixed pos item has the same // ASR. If so, it returns the scroll target for that fixed-pos item. // Otherwise, it returns Nothing(). Maybe<layers::ScrollableLayerGuid::ViewID> GetContainingFixedPosScrollTarget( const ActiveScrolledRoot* aAsr); Maybe<SideBits> GetContainingFixedPosSideBits(const ActiveScrolledRoot* aAsr);
--- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -2287,32 +2287,30 @@ impl WebRenderFrameBuilder { } } pub struct WrState { pipeline_id: WrPipelineId, frame_builder: WebRenderFrameBuilder, current_tag: Option<ItemTag>, - current_item_key: Option<ItemKey>, } #[no_mangle] pub extern "C" fn wr_state_new(pipeline_id: WrPipelineId, content_size: LayoutSize, capacity: usize) -> *mut WrState { assert!(unsafe { !is_in_render_thread() }); let state = Box::new(WrState { pipeline_id: pipeline_id, frame_builder: WebRenderFrameBuilder::with_capacity(pipeline_id, content_size, capacity), current_tag: None, - current_item_key: None, }); Box::into_raw(state) } #[no_mangle] pub extern "C" fn wr_state_delete(state: *mut WrState) { assert!(unsafe { !is_in_render_thread() }); @@ -2673,17 +2671,16 @@ pub extern "C" fn wr_dp_push_rect(state: // NB: the damp-e10s talos-test will frequently crash on startup if we // early-return here for empty rects. I couldn't figure out why, but // it's pretty harmless to feed these through, so, uh, we do? clip_rect: clip_rect.unwrap_or(LayoutRect::zero()), clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_rect( &prim_info, color, ); } @@ -2704,17 +2701,16 @@ pub extern "C" fn wr_dp_push_rect_with_p if clip_rect.is_none() { return; } let prim_info = CommonItemProperties { clip_rect: clip_rect.unwrap(), clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_rect( &prim_info, color, ); } @@ -2757,17 +2753,16 @@ pub extern "C" fn wr_dp_push_backdrop_fi if clip_rect.is_none() { return; } let prim_info = CommonItemProperties { clip_rect: clip_rect.unwrap(), clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_backdrop_filter( &prim_info, &filters, &filter_datas, &[], ); @@ -2786,17 +2781,16 @@ pub extern "C" fn wr_dp_push_clear_rect( if clip_rect.is_none() { return; } let prim_info = CommonItemProperties { clip_rect: clip_rect.unwrap(), clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(true), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_clear_rect( &prim_info, ); } #[no_mangle] @@ -2813,17 +2807,16 @@ pub extern "C" fn wr_dp_push_hit_test(st if clip_rect.is_none() { return; } let prim_info = CommonItemProperties { clip_rect: clip_rect.unwrap(), clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_hit_test( &prim_info, ); } #[no_mangle] @@ -2841,17 +2834,16 @@ pub extern "C" fn wr_dp_push_clear_rect_ if clip_rect.is_none() { return; } let prim_info = CommonItemProperties { clip_rect: clip_rect.unwrap(), clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(true), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_clear_rect( &prim_info, ); } #[no_mangle] @@ -2869,17 +2861,16 @@ pub extern "C" fn wr_dp_push_image(state let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; let alpha_type = if premultiplied_alpha { AlphaType::PremultipliedAlpha } else { AlphaType::Alpha }; @@ -2910,17 +2901,16 @@ pub extern "C" fn wr_dp_push_repeating_i let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; let alpha_type = if premultiplied_alpha { AlphaType::PremultipliedAlpha } else { AlphaType::Alpha }; @@ -2955,17 +2945,16 @@ pub extern "C" fn wr_dp_push_yuv_planar_ let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder .dl_builder .push_yuv_image(&prim_info, bounds, YuvData::PlanarYCbCr(image_key_0, image_key_1, image_key_2), color_depth, @@ -2992,17 +2981,16 @@ pub extern "C" fn wr_dp_push_yuv_NV12_im let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder .dl_builder .push_yuv_image(&prim_info, bounds, YuvData::NV12(image_key_0, image_key_1), color_depth, @@ -3028,17 +3016,16 @@ pub extern "C" fn wr_dp_push_yuv_interle let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder .dl_builder .push_yuv_image(&prim_info, bounds, YuvData::InterleavedYCbCr(image_key_0), color_depth, @@ -3064,18 +3051,17 @@ pub extern "C" fn wr_dp_push_text(state: let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, spatial_id: space_and_clip.spatial_id, clip_id: space_and_clip.clip_id, flags: prim_flags(is_backface_visible), - hit_info: state.current_tag, - item_key: state.current_item_key, + hit_info: state.current_tag }; state.frame_builder .dl_builder .push_text(&prim_info, bounds, &glyph_slice, font_key, @@ -3122,17 +3108,16 @@ pub extern "C" fn wr_dp_push_line(state: let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: *clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder .dl_builder .push_line(&prim_info, bounds, wavy_line_thickness, orientation, @@ -3168,17 +3153,16 @@ pub extern "C" fn wr_dp_push_border(stat let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder .dl_builder .push_border(&prim_info, rect, widths, border_details); @@ -3218,17 +3202,16 @@ pub extern "C" fn wr_dp_push_border_imag let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_border( &prim_info, rect, params.widths, border_details, ); @@ -3277,17 +3260,16 @@ pub extern "C" fn wr_dp_push_border_grad let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_border( &prim_info, rect, widths.into(), border_details, ); @@ -3340,17 +3322,16 @@ pub extern "C" fn wr_dp_push_border_radi let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_border( &prim_info, rect, widths.into(), border_details, ); @@ -3384,17 +3365,16 @@ pub extern "C" fn wr_dp_push_linear_grad let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_gradient( &prim_info, rect, gradient, tile_size.into(), tile_spacing.into(), @@ -3429,17 +3409,16 @@ pub extern "C" fn wr_dp_push_radial_grad let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder.dl_builder.push_radial_gradient( &prim_info, rect, gradient, tile_size, tile_spacing); @@ -3463,70 +3442,31 @@ pub extern "C" fn wr_dp_push_box_shadow( let space_and_clip = parent.to_webrender(state.pipeline_id); let prim_info = CommonItemProperties { clip_rect: clip, clip_id: space_and_clip.clip_id, spatial_id: space_and_clip.spatial_id, flags: prim_flags(is_backface_visible), hit_info: state.current_tag, - item_key: state.current_item_key, }; state.frame_builder .dl_builder .push_box_shadow(&prim_info, box_bounds, offset, color, blur_radius, spread_radius, border_radius, clip_mode); } #[no_mangle] -pub extern "C" fn wr_dp_start_cached_item(state: &mut WrState, - key: ItemKey) { - debug_assert!(state.current_item_key.is_none(), "Nested item keys"); - state.current_item_key = Some(key); - - state.frame_builder.dl_builder.start_extra_data_chunk(); -} - -#[no_mangle] -pub extern "C" fn wr_dp_end_cached_item(state: &mut WrState, - key: ItemKey) { - // Avoid pushing reuse item marker when no extra data was written. - if state.frame_builder.dl_builder.end_extra_data_chunk() > 0 { - state.frame_builder.dl_builder.push_reuse_item(key); - } - - debug_assert!(state.current_item_key.is_some(), "Nested item keys"); - state.current_item_key = None; -} - -#[no_mangle] -pub extern "C" fn wr_dp_push_reuse_item(state: &mut WrState, - key: ItemKey) { - state.frame_builder - .dl_builder - .push_reuse_item(key); -} - -#[no_mangle] -pub extern "C" fn wr_dp_set_cache_size(state: &mut WrState, - cache_size: usize) { - state.frame_builder - .dl_builder - .set_cache_size(cache_size); -} - - -#[no_mangle] pub extern "C" fn wr_dump_display_list(state: &mut WrState, indent: usize, start: *const usize, end: *const usize) -> usize { let start = unsafe { start.as_ref().cloned() }; let end = unsafe { end.as_ref().cloned() }; let range = Range { start, end }; let mut sink = Cursor::new(Vec::new());
--- a/gfx/wr/webrender/src/scene.rs +++ b/gfx/wr/webrender/src/scene.rs @@ -1,13 +1,13 @@ /* 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/. */ -use api::{BuiltDisplayList, DisplayItemCache, ColorF, DynamicProperties, Epoch, FontRenderMode}; +use api::{BuiltDisplayList, ColorF, DynamicProperties, Epoch, FontRenderMode}; use api::{PipelineId, PropertyBinding, PropertyBindingId, MixBlendMode, StackingContext}; use api::units::*; use crate::composite::CompositorKind; use crate::clip::{ClipStore, ClipDataStore}; use crate::clip_scroll_tree::{ClipScrollTree, SpatialNodeIndex}; use crate::frame_builder::{ChasePrimitive, FrameBuilderConfig}; use crate::hit_test::{HitTester, HitTestingScene, HitTestingSceneStats}; use crate::internal_types::{FastHashMap, FastHashSet}; @@ -122,28 +122,29 @@ impl SceneProperties { pub fn float_properties(&self) -> &FastHashMap<PropertyBindingId, f32> { &self.float_properties } } /// A representation of the layout within the display port for a given document or iframe. #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] +#[derive(Clone)] pub struct ScenePipeline { pub pipeline_id: PipelineId, pub viewport_size: LayoutSize, pub content_size: LayoutSize, pub background_color: Option<ColorF>, pub display_list: BuiltDisplayList, - pub display_list_cache: DisplayItemCache, } /// A complete representation of the layout bundling visible pipelines together. #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] +#[derive(Clone)] pub struct Scene { pub root_pipeline_id: Option<PipelineId>, pub pipelines: FastHashMap<PipelineId, ScenePipeline>, pub pipeline_epochs: FastHashMap<PipelineId, Epoch>, } impl Scene { pub fn new() -> Self { @@ -162,30 +163,22 @@ impl Scene { &mut self, pipeline_id: PipelineId, epoch: Epoch, display_list: BuiltDisplayList, background_color: Option<ColorF>, viewport_size: LayoutSize, content_size: LayoutSize, ) { - let pipeline = self.pipelines.remove(&pipeline_id); - let mut display_list_cache = pipeline.map_or(Default::default(), |p| { - p.display_list_cache - }); - - display_list_cache.update(&display_list); - let new_pipeline = ScenePipeline { pipeline_id, viewport_size, content_size, background_color, display_list, - display_list_cache, }; self.pipelines.insert(pipeline_id, new_pipeline); self.pipeline_epochs.insert(pipeline_id, epoch); } pub fn remove_pipeline(&mut self, pipeline_id: PipelineId) { if self.root_pipeline_id == Some(pipeline_id) {
--- a/gfx/wr/webrender/src/scene_builder_thread.rs +++ b/gfx/wr/webrender/src/scene_builder_thread.rs @@ -250,17 +250,16 @@ pub struct SceneBuilderThread { documents: FastHashMap<DocumentId, Document>, rx: Receiver<SceneBuilderRequest>, tx: Sender<SceneBuilderResult>, api_tx: MsgSender<ApiMsg>, config: FrameBuilderConfig, size_of_ops: Option<MallocSizeOfOps>, hooks: Option<Box<dyn SceneBuilderHooks + Send>>, simulate_slow_ms: u32, - removed_pipelines: FastHashSet<PipelineId> } pub struct SceneBuilderThreadChannels { rx: Receiver<SceneBuilderRequest>, tx: Sender<SceneBuilderResult>, api_tx: MsgSender<ApiMsg>, } @@ -295,17 +294,16 @@ impl SceneBuilderThread { documents: Default::default(), rx, tx, api_tx, config, size_of_ops, hooks, simulate_slow_ms: 0, - removed_pipelines: FastHashSet::default(), } } /// Send a message to the render backend thread. /// /// We first put something in the result queue and then send a wake-up /// message to the api queue that the render backend is blocking on. pub fn send(&self, msg: SceneBuilderResult) { @@ -526,45 +524,38 @@ impl SceneBuilderThread { let scene_build_start_time = precise_time_ns(); let doc = self.documents .entry(txn.document_id) .or_insert_with(|| Document::new(Scene::new())); let scene = &mut doc.scene; - for &(pipeline_id, epoch) in &txn.epoch_updates { - scene.update_epoch(pipeline_id, epoch); - } - - if let Some(id) = txn.set_root_pipeline { - scene.set_root_pipeline_id(id); - } - - for &(pipeline_id, _) in &txn.removed_pipelines { - scene.remove_pipeline(pipeline_id); - self.removed_pipelines.insert(pipeline_id); - } - for update in txn.display_list_updates.drain(..) { - if self.removed_pipelines.contains(&update.pipeline_id) { - continue; - } - scene.set_display_list( update.pipeline_id, update.epoch, update.built_display_list, update.background, update.viewport_size, update.content_size, ); } - self.removed_pipelines.clear(); + for &(pipeline_id, epoch) in &txn.epoch_updates { + scene.update_epoch(pipeline_id, epoch); + } + + if let Some(id) = txn.set_root_pipeline { + scene.set_root_pipeline_id(id); + } + + for &(pipeline_id, _) in &txn.removed_pipelines { + scene.remove_pipeline(pipeline_id) + } let mut built_scene = None; let mut interner_updates = None; if scene.has_root_pipeline() { if let Some(request) = txn.request_scene_build.take() { let built = SceneBuilder::build( &scene, request.font_instances,
--- a/gfx/wr/webrender/src/scene_building.rs +++ b/gfx/wr/webrender/src/scene_building.rs @@ -444,19 +444,18 @@ impl<'a> SceneBuilder<'a> { /* create_tile_cache = */ false, ROOT_SPATIAL_NODE_INDEX, ClipChainId::NONE, RasterSpace::Screen, /* is_backdrop_root = */ true, device_pixel_scale, ); - let cache = &root_pipeline.display_list_cache; builder.build_items( - &mut root_pipeline.display_list.iter_with_cache(cache), + &mut root_pipeline.display_list.iter(), root_pipeline.pipeline_id, true, ); builder.pop_stacking_context(); debug_assert!(builder.sc_stack.is_empty()); @@ -683,64 +682,40 @@ impl<'a> SceneBuilder<'a> { fn build_items( &mut self, traversal: &mut BuiltDisplayListIter<'a>, pipeline_id: PipelineId, apply_pipeline_clip: bool, ) { loop { - let item = match traversal.next() { - Some(item) => item, - None => break, - }; - - let subtraversal = match item.item() { - DisplayItem::PushStackingContext(ref info) => { - let space = self.get_space(&info.spatial_id); - let mut subtraversal = item.sub_iter(); - self.build_stacking_context( - &mut subtraversal, - pipeline_id, - &info.stacking_context, - space, - info.origin, - item.filters(), - &item.filter_datas(), - item.filter_primitives(), - info.prim_flags, - apply_pipeline_clip, - ); - Some(subtraversal) + let subtraversal = { + let item = match traversal.next() { + Some(item) => item, + None => break, + }; + + match item.item() { + DisplayItem::PopReferenceFrame | + DisplayItem::PopStackingContext => return, + _ => (), } - DisplayItem::PushReferenceFrame(ref info) => { - let parent_space = self.get_space(&info.parent_spatial_id); - let mut subtraversal = item.sub_iter(); - self.build_reference_frame( - &mut subtraversal, - pipeline_id, - parent_space, - info.origin, - &info.reference_frame, - apply_pipeline_clip, - ); - Some(subtraversal) - } - DisplayItem::PopReferenceFrame | - DisplayItem::PopStackingContext => return, - _ => None, + + self.build_item( + item, + pipeline_id, + apply_pipeline_clip, + ) }; // If build_item created a sub-traversal, we need `traversal` to have the // same state as the completed subtraversal, so we reinitialize it here. if let Some(mut subtraversal) = subtraversal { subtraversal.merge_debug_stats_from(traversal); *traversal = subtraversal; - } else { - self.build_item(item, pipeline_id, apply_pipeline_clip); } } // TODO: factor this out to be part of capture if cfg!(feature = "display_list_stats") { let stats = traversal.debug_stats(); let total_bytes: usize = stats.iter().map(|(_, stats)| stats.num_bytes).sum(); println!("item, total count, total bytes, % of DL bytes, bytes per item"); @@ -978,20 +953,18 @@ impl<'a> SceneBuilder<'a> { &content_size, ScrollSensitivity::ScriptAndInputEvents, ScrollFrameKind::PipelineRoot, LayoutVector2D::zero(), ); self.rf_mapper.push_scope(); self.iframe_depth += 1; - - let cache = &pipeline.display_list_cache; self.build_items( - &mut pipeline.display_list.iter_with_cache(cache), + &mut pipeline.display_list.iter(), pipeline.pipeline_id, true, ); self.iframe_depth -= 1; self.rf_mapper.pop_scope(); self.pipeline_clip_chain_stack.pop(); } @@ -1083,20 +1056,20 @@ impl<'a> SceneBuilder<'a> { target_spatial_node, &self.clip_scroll_tree ); snap_to_device.snap_rect(rect) } fn build_item<'b>( &'b mut self, - item: DisplayItemRef, + item: DisplayItemRef<'a, 'b>, pipeline_id: PipelineId, apply_pipeline_clip: bool, - ) { + ) -> Option<BuiltDisplayListIter<'a>> { match *item.item() { DisplayItem::Image(ref info) => { let (layout, _, clip_and_scroll) = self.process_common_properties_with_bounds( &info.common, &info.bounds, apply_pipeline_clip, ); @@ -1321,16 +1294,46 @@ impl<'a> SceneBuilder<'a> { self.add_border( clip_and_scroll, &layout, info, item.gradient_stops(), ); } + DisplayItem::PushStackingContext(ref info) => { + let space = self.get_space(&info.spatial_id); + let mut subtraversal = item.sub_iter(); + self.build_stacking_context( + &mut subtraversal, + pipeline_id, + &info.stacking_context, + space, + info.origin, + item.filters(), + item.filter_datas(), + item.filter_primitives(), + info.prim_flags, + apply_pipeline_clip, + ); + return Some(subtraversal); + } + DisplayItem::PushReferenceFrame(ref info) => { + let parent_space = self.get_space(&info.parent_spatial_id); + let mut subtraversal = item.sub_iter(); + self.build_reference_frame( + &mut subtraversal, + pipeline_id, + parent_space, + info.origin, + &info.reference_frame, + apply_pipeline_clip, + ); + return Some(subtraversal); + } DisplayItem::Iframe(ref info) => { let space = self.get_space(&info.space_and_clip.spatial_id); self.build_iframe( info, space, ); } DisplayItem::Clip(ref info) => { @@ -1448,41 +1451,35 @@ impl<'a> SceneBuilder<'a> { } // Do nothing; these are dummy items for the display list parser DisplayItem::SetGradientStops | DisplayItem::SetFilterOps | DisplayItem::SetFilterData | DisplayItem::SetFilterPrimitives => {} - // Special items that are handled in the parent method - DisplayItem::PushStackingContext(..) | - DisplayItem::PushReferenceFrame(..) | DisplayItem::PopReferenceFrame | DisplayItem::PopStackingContext => { unreachable!("Should have returned in parent method.") } - - DisplayItem::ReuseItem(..) => { - unreachable!("Iterator logic error") - } - DisplayItem::PushShadow(info) => { let clip_and_scroll = self.get_clip_and_scroll( &info.space_and_clip.clip_id, &info.space_and_clip.spatial_id, apply_pipeline_clip ); self.push_shadow(info.shadow, clip_and_scroll, info.should_inflate); } DisplayItem::PopAllShadows => { self.pop_all_shadows(); } } + + None } // Given a list of clip sources, a positioning node and // a parent clip chain, return a new clip chain entry. // If the supplied list of clip sources is empty, then // just return the parent clip chain id directly. fn build_clip_chain( &mut self,
--- a/gfx/wr/webrender_api/src/display_item.rs +++ b/gfx/wr/webrender_api/src/display_item.rs @@ -28,20 +28,16 @@ pub const MAX_BLUR_RADIUS: f32 = 300.; /// is missing then the item doesn't take part in hit testing at all. This /// is composed of two numbers. In Servo, the first is an identifier while the /// second is used to select the cursor that should be used during mouse /// movement. In Gecko, the first is a scrollframe identifier, while the second /// is used to store various flags that APZ needs to properly process input /// events. pub type ItemTag = (u64, u16); -/// An identifier used to refer to previously sent display items. Currently it -/// refers to individual display items, but this may change later. -pub type ItemKey = u16; - bitflags! { #[repr(C)] #[derive(Deserialize, MallocSizeOf, Serialize, PeekPoke)] pub struct PrimitiveFlags: u8 { /// The CSS backface-visibility property (yes, it can be really granular) const IS_BACKFACE_VISIBLE = 1 << 0; /// If set, this primitive represents a scroll bar container const IS_SCROLLBAR_CONTAINER = 1 << 1; @@ -73,33 +69,30 @@ pub struct CommonItemProperties { /// The coordinate-space the item is in (yes, it can be really granular) pub spatial_id: SpatialId, /// Opaque bits for our clients to use for hit-testing. This is the most /// dubious "common" field, but because it's an Option, it usually only /// wastes a single byte (for None). pub hit_info: Option<ItemTag>, /// Various flags describing properties of this primitive. pub flags: PrimitiveFlags, - /// The unique id of this display item. - pub item_key: Option<ItemKey> } impl CommonItemProperties { /// Convenience for tests. pub fn new( clip_rect: LayoutRect, space_and_clip: SpaceAndClipInfo, ) -> Self { Self { clip_rect, spatial_id: space_and_clip.spatial_id, clip_id: space_and_clip.clip_id, hit_info: None, flags: PrimitiveFlags::default(), - item_key: None, } } } /// Per-primitive information about the nodes in the clip tree and /// the spatial tree that the primitive belongs to. /// /// Note: this is a separate struct from `PrimitiveInfo` because @@ -158,18 +151,16 @@ pub enum DisplayItem { SetFilterOps, SetFilterData, SetFilterPrimitives, // These marker items terminate a scope introduced by a previous item. PopReferenceFrame, PopStackingContext, PopAllShadows, - - ReuseItem(ItemKey), } /// This is a "complete" version of the DisplayItem, with all implicit trailing /// arrays included, for debug serialization (captures). #[cfg(any(feature = "serialize", feature = "deserialize"))] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))] pub enum DebugDisplayItem { @@ -200,18 +191,16 @@ pub enum DebugDisplayItem { SetGradientStops(Vec<GradientStop>), SetFilterOps(Vec<FilterOp>), SetFilterData(FilterData), SetFilterPrimitives(Vec<FilterPrimitive>), PopReferenceFrame, PopStackingContext, PopAllShadows, - - ReuseItem(ItemKey), } #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)] pub struct ClipDisplayItem { pub id: ClipId, pub parent_space_and_clip: SpaceAndClipInfo, pub clip_rect: LayoutRect, pub image_mask: Option<ImageMask>, @@ -1475,17 +1464,16 @@ impl DisplayItem { DisplayItem::PushStackingContext(..) => "push_stacking_context", DisplayItem::SetFilterOps => "set_filter_ops", DisplayItem::SetFilterData => "set_filter_data", DisplayItem::SetFilterPrimitives => "set_filter_primitives", DisplayItem::RadialGradient(..) => "radial_gradient", DisplayItem::Rectangle(..) => "rectangle", DisplayItem::ScrollFrame(..) => "scroll_frame", DisplayItem::SetGradientStops => "set_gradient_stops", - DisplayItem::ReuseItem(..) => "reuse_item", DisplayItem::StickyFrame(..) => "sticky_frame", DisplayItem::Text(..) => "text", DisplayItem::YuvImage(..) => "yuv_image", DisplayItem::BackdropFilter(..) => "backdrop_filter", } } }
deleted file mode 100644 --- a/gfx/wr/webrender_api/src/display_item_cache.rs +++ /dev/null @@ -1,106 +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/. */ - -use crate::display_item::*; -use crate::display_list::*; - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -pub struct CachedDisplayItem { - item: DisplayItem, - data: Vec<u8>, -} - -impl CachedDisplayItem { - pub fn item(&self) -> &DisplayItem { - &self.item - } - - pub fn data_as_item_range<T>(&self) -> ItemRange<T> { - ItemRange::new(&self.data) - } -} - -impl From<DisplayItemRef<'_, '_>> for CachedDisplayItem { - fn from (item_ref: DisplayItemRef) -> Self { - let item = item_ref.item(); - - match item { - DisplayItem::Text(..) => CachedDisplayItem { - item: *item, - data: item_ref.glyphs().bytes().to_vec(), - }, - DisplayItem::Rectangle(..) | - DisplayItem::Image(..) => CachedDisplayItem { - item: *item, - data: Vec::new(), - }, - _ => { unimplemented!("Unsupported display item type"); } - } - } -} - -#[derive(Default, Deserialize, Serialize)] -pub struct DisplayItemCache { - items: Vec<Option<CachedDisplayItem>> -} - -impl DisplayItemCache { - fn grow_if_needed( - &mut self, - capacity: usize - ) { - if capacity > self.items.len() { - self.items.resize_with(capacity, || None::<CachedDisplayItem>); - // println!("Current cache size: {:?}", - // mem::size_of::<CachedDisplayItem>() * capacity); - } - } - - pub fn add_item( - &mut self, - key: Option<ItemKey>, - item: DisplayItemRef - ) { - let index = usize::from(key.expect("Cached item without key")); - self.items[index] = Some(CachedDisplayItem::from(item)); - } - - pub fn get_item( - &self, - key: ItemKey - ) -> Option<&CachedDisplayItem> { - self.items[key as usize].as_ref() - } - - pub fn update( - &mut self, - display_list: &BuiltDisplayList - ) { - self.grow_if_needed(display_list.cache_size()); - - let mut iter = display_list.extra_data_iter(); - - loop { - let item = match iter.next() { - Some(item) => item, - None => break, - }; - - match item.item() { - DisplayItem::Rectangle(ref info) => { - self.add_item(info.common.item_key, item); - } - DisplayItem::Text(ref info) => { - self.add_item(info.common.item_key, item); - } - DisplayItem::Image(ref info) => { - self.add_item(info.common.item_key, item); - } - item @ _ => { - unimplemented!("Unexpected item in extra data: {:?}", item); - } - } - } - } -}
--- a/gfx/wr/webrender_api/src/display_list.rs +++ b/gfx/wr/webrender_api/src/display_list.rs @@ -13,17 +13,16 @@ use serde::{Deserialize, Serialize}; use std::io::{stdout, Write}; use std::marker::PhantomData; use std::ops::Range; use std::mem; use std::collections::HashMap; use time::precise_time_ns; // local imports use crate::display_item as di; -use crate::display_item_cache::*; use crate::api::{PipelineId, PropertyBinding}; use crate::gradient_builder::GradientBuilder; use crate::color::ColorF; use crate::font::{FontInstanceKey, GlyphInstance, GlyphOptions}; use crate::image::{ColorDepth, ImageKey}; use crate::units::*; @@ -58,31 +57,20 @@ impl<'a, T> Default for ItemRange<'a, T> ItemRange { bytes: Default::default(), _boo: PhantomData, } } } impl<'a, T> ItemRange<'a, T> { - pub fn new(bytes: &'a [u8]) -> Self { - Self { - bytes, - _boo: PhantomData - } - } - pub fn is_empty(&self) -> bool { // Nothing more than space for a length (0). self.bytes.len() <= mem::size_of::<usize>() } - - pub fn bytes(&self) -> &[u8] { - &self.bytes - } } impl<'a, T: Default> ItemRange<'a, T> { pub fn iter(&self) -> AuxIter<'a, T> { AuxIter::new(T::default(), self.bytes) } } @@ -126,28 +114,21 @@ pub struct BuiltDisplayListDescriptor { /// The second IPC time stamp: after serialization builder_finish_time: u64, /// The third IPC time stamp: just before sending send_start_time: u64, /// The amount of clipping nodes created while building this display list. total_clip_nodes: usize, /// The amount of spatial nodes created while building this display list. total_spatial_nodes: usize, - /// The size of the cache for this display list. - cache_size: usize, - /// The offset for additional display list data. - extra_data_offset: usize, } -impl BuiltDisplayListDescriptor {} - pub struct BuiltDisplayListIter<'a> { list: &'a BuiltDisplayList, data: &'a [u8], - cache: Option<&'a DisplayItemCache>, cur_item: di::DisplayItem, cur_stops: ItemRange<'a, di::GradientStop>, cur_glyphs: ItemRange<'a, GlyphInstance>, cur_filters: ItemRange<'a, di::FilterOp>, cur_filter_data: Vec<TempFilterData<'a>>, cur_filter_primitives: ItemRange<'a, di::FilterPrimitive>, cur_clip_chain_items: ItemRange<'a, di::ClipId>, cur_complex_clip: ItemRange<'a, di::ComplexClipRegion>, @@ -218,68 +199,16 @@ pub struct ItemStats { /// How many instances of this kind of item we deserialized pub total_count: usize, /// How many bytes we processed for this kind of item pub num_bytes: usize, } pub struct DisplayItemRef<'a: 'b, 'b> { iter: &'b BuiltDisplayListIter<'a>, - cached_item: Option<&'a CachedDisplayItem>, -} - -// Some of these might just become ItemRanges -impl<'a, 'b> DisplayItemRef<'a, 'b> { - fn cached_or_iter_data<T>( - &self, - data: ItemRange<'a, T> - ) -> ItemRange<'a, T> { - self.cached_item.map_or(data, |i| i.data_as_item_range()) - } - - pub fn display_list(&self) -> &BuiltDisplayList { - self.iter.display_list() - } - - // Creates a new iterator where this element's iterator is, to hack around borrowck. - pub fn sub_iter(&self) -> BuiltDisplayListIter<'a> { - BuiltDisplayListIter::new(self.iter.list, self.iter.data, self.iter.cache) - } - - pub fn item(&self) -> &di::DisplayItem { - self.cached_item.map_or(&self.iter.cur_item, |i| i.item()) - } - - pub fn clip_chain_items(&self) -> ItemRange<di::ClipId> { - self.iter.cur_clip_chain_items - } - - pub fn complex_clip(&self) -> ItemRange<di::ComplexClipRegion> { - self.iter.cur_complex_clip - } - - pub fn glyphs(&self) -> ItemRange<GlyphInstance> { - self.cached_or_iter_data(self.iter.cur_glyphs) - } - - pub fn gradient_stops(&self) -> ItemRange<di::GradientStop> { - self.cached_or_iter_data(self.iter.cur_stops) - } - - pub fn filters(&self) -> ItemRange<di::FilterOp> { - self.iter.cur_filters - } - - pub fn filter_datas(&self) -> &Vec<TempFilterData> { - &self.iter.cur_filter_data - } - - pub fn filter_primitives(&self) -> ItemRange<di::FilterPrimitive> { - self.iter.cur_filter_primitives - } } #[derive(PartialEq)] enum Peek { StartPeeking, IsPeeking, NotPeeking, } @@ -287,36 +216,35 @@ enum Peek { #[derive(Clone)] pub struct AuxIter<'a, T> { item: T, data: &'a [u8], size: usize, // _boo: PhantomData<T>, } +impl BuiltDisplayListDescriptor {} + impl BuiltDisplayList { pub fn from_data(data: Vec<u8>, descriptor: BuiltDisplayListDescriptor) -> Self { BuiltDisplayList { data, descriptor } } pub fn into_data(mut self) -> (Vec<u8>, BuiltDisplayListDescriptor) { self.descriptor.send_start_time = precise_time_ns(); (self.data, self.descriptor) } pub fn data(&self) -> &[u8] { &self.data[..] } + // Currently redundant with data, but may be useful if we add extra data to dl pub fn item_slice(&self) -> &[u8] { - &self.data[..self.descriptor.extra_data_offset] - } - - pub fn extra_slice(&self) -> &[u8] { - &self.data[self.descriptor.extra_data_offset..] + &self.data[..] } pub fn descriptor(&self) -> &BuiltDisplayListDescriptor { &self.descriptor } pub fn times(&self) -> (u64, u64, u64) { ( @@ -330,32 +258,17 @@ impl BuiltDisplayList { self.descriptor.total_clip_nodes } pub fn total_spatial_nodes(&self) -> usize { self.descriptor.total_spatial_nodes } pub fn iter(&self) -> BuiltDisplayListIter { - BuiltDisplayListIter::new(self, self.item_slice(), None) - } - - pub fn extra_data_iter(&self) -> BuiltDisplayListIter { - BuiltDisplayListIter::new(self, self.extra_slice(), None) - } - - pub fn iter_with_cache<'a>( - &'a self, - cache: &'a DisplayItemCache - ) -> BuiltDisplayListIter<'a> { - BuiltDisplayListIter::new(self, self.item_slice(), Some(cache)) - } - - pub fn cache_size(&self) -> usize { - self.descriptor.cache_size + BuiltDisplayListIter::new(self) } } /// Returns the byte-range the slice occupied. fn skip_slice<'a, T: peek_poke::Peek>(data: &mut &'a [u8]) -> ItemRange<'a, T> { let mut skip_offset = 0usize; *data = peek_from_slice(data, &mut skip_offset); let (skip, rest) = data.split_at(skip_offset); @@ -365,25 +278,24 @@ fn skip_slice<'a, T: peek_poke::Peek>(da ItemRange { bytes: skip, _boo: PhantomData, } } impl<'a> BuiltDisplayListIter<'a> { - pub fn new( - list: &'a BuiltDisplayList, - data: &'a [u8], - cache: Option<&'a DisplayItemCache>, - ) -> Self { - Self { + pub fn new(list: &'a BuiltDisplayList) -> Self { + Self::new_with_list_and_data(list, list.item_slice()) + } + + pub fn new_with_list_and_data(list: &'a BuiltDisplayList, data: &'a [u8]) -> Self { + BuiltDisplayListIter { list, data, - cache, cur_item: di::DisplayItem::PopStackingContext, cur_stops: ItemRange::default(), cur_glyphs: ItemRange::default(), cur_filters: ItemRange::default(), cur_filter_data: Vec::new(), cur_filter_primitives: ItemRange::default(), cur_clip_chain_items: ItemRange::default(), cur_complex_clip: ItemRange::default(), @@ -504,28 +416,17 @@ impl<'a> BuiltDisplayListIter<'a> { } _ => { /* do nothing */ } } Some(self.as_ref()) } pub fn as_ref<'b>(&'b self) -> DisplayItemRef<'a, 'b> { - let cached_item = match self.cur_item { - di::DisplayItem::ReuseItem(key) => { - debug_assert!(self.cache.is_some(), "Cache marker without cache!"); - self.cache.and_then(|c| c.get_item(key)) - } - _ => None - }; - - DisplayItemRef { - iter: self, - cached_item - } + DisplayItemRef { iter: self } } pub fn skip_current_stacking_context(&mut self) { let mut depth = 0; while let Some(item) = self.next() { match *item.item() { di::DisplayItem::PushStackingContext(..) => depth += 1, di::DisplayItem::PopStackingContext if depth == 0 => return, @@ -575,16 +476,60 @@ impl<'a> BuiltDisplayListIter<'a> { fn log_item_stats(&mut self) { self.debug_stats.log_item(self.data, &self.cur_item); } #[cfg(not(feature = "display_list_stats"))] fn log_item_stats(&mut self) { /* no-op */ } } +// Some of these might just become ItemRanges +impl<'a, 'b> DisplayItemRef<'a, 'b> { + pub fn item(&self) -> &di::DisplayItem { + &self.iter.cur_item + } + + pub fn complex_clip(&self) -> ItemRange<di::ComplexClipRegion> { + self.iter.cur_complex_clip + } + + pub fn gradient_stops(&self) -> ItemRange<di::GradientStop> { + self.iter.cur_stops + } + + pub fn glyphs(&self) -> ItemRange<GlyphInstance> { + self.iter.cur_glyphs + } + + pub fn filters(&self) -> ItemRange<di::FilterOp> { + self.iter.cur_filters + } + + pub fn filter_datas(&self) -> &Vec<TempFilterData> { + &self.iter.cur_filter_data + } + + pub fn filter_primitives(&self) -> ItemRange<di::FilterPrimitive> { + self.iter.cur_filter_primitives + } + + pub fn clip_chain_items(&self) -> ItemRange<di::ClipId> { + self.iter.cur_clip_chain_items + } + + pub fn display_list(&self) -> &BuiltDisplayList { + self.iter.display_list() + } + + // Creates a new iterator where this element's iterator is, to hack around borrowck. + pub fn sub_iter(&self) -> BuiltDisplayListIter<'a> { + BuiltDisplayListIter::new_with_list_and_data(self.iter.list, self.iter.data) + } +} + impl<'a, T> AuxIter<'a, T> { pub fn new(item: T, mut data: &'a [u8]) -> Self { let mut size = 0usize; if !data.is_empty() { data = peek_from_slice(data, &mut size); }; AuxIter { @@ -688,17 +633,16 @@ impl Serialize for BuiltDisplayList { Real::PushReferenceFrame(v) => Debug::PushReferenceFrame(v), Real::PushStackingContext(v) => Debug::PushStackingContext(v), Real::PushShadow(v) => Debug::PushShadow(v), Real::BackdropFilter(v) => Debug::BackdropFilter(v), Real::PopReferenceFrame => Debug::PopReferenceFrame, Real::PopStackingContext => Debug::PopStackingContext, Real::PopAllShadows => Debug::PopAllShadows, - Real::ReuseItem(k) => Debug::ReuseItem(k), }; seq.serialize_element(&serial_di)? } seq.end() } } // The purpose of this implementation is to deserialize @@ -792,17 +736,16 @@ impl<'de> Deserialize<'de> for BuiltDisp Debug::RadialGradient(v) => Real::RadialGradient(v), Debug::PushStackingContext(v) => Real::PushStackingContext(v), Debug::PushShadow(v) => Real::PushShadow(v), Debug::BackdropFilter(v) => Real::BackdropFilter(v), Debug::PopStackingContext => Real::PopStackingContext, Debug::PopReferenceFrame => Real::PopReferenceFrame, Debug::PopAllShadows => Real::PopAllShadows, - Debug::ReuseItem(k) => Real::ReuseItem(k), }; poke_into_vec(&item, &mut data); // the aux data is serialized after the item, hence the temporary data.extend(temp.drain(..)); } // Add `DisplayItem::max_size` zone of zeroes to the end of display list // so there is at least this amount available in the display list during @@ -829,32 +772,25 @@ pub struct SaveState { next_spatial_index: usize, next_clip_chain_id: u64, } #[derive(Clone)] pub struct DisplayListBuilder { pub data: Vec<u8>, pub pipeline_id: PipelineId, - - extra_data: Vec<u8>, - extra_data_chunk_len: usize, - writing_extra_data_chunk: bool, - next_clip_index: usize, next_spatial_index: usize, next_clip_chain_id: u64, builder_start_time: u64, /// The size of the content of this display list. This is used to allow scrolling /// outside the bounds of the display list items themselves. content_size: LayoutSize, save_state: Option<SaveState>, - - cache_size: usize, } impl DisplayListBuilder { pub fn new(pipeline_id: PipelineId, content_size: LayoutSize) -> Self { Self::with_capacity(pipeline_id, content_size, 0) } pub fn with_capacity( @@ -862,28 +798,22 @@ impl DisplayListBuilder { content_size: LayoutSize, capacity: usize, ) -> Self { let start_time = precise_time_ns(); DisplayListBuilder { data: Vec::with_capacity(capacity), pipeline_id, - - extra_data: Vec::new(), - extra_data_chunk_len: 0, - writing_extra_data_chunk: false, - next_clip_index: FIRST_CLIP_NODE_INDEX, next_spatial_index: FIRST_SPATIAL_NODE_INDEX, next_clip_chain_id: 0, builder_start_time: start_time, content_size, save_state: None, - cache_size: 0, } } /// Return the content size for this display list pub fn content_size(&self) -> LayoutSize { self.content_size } @@ -945,45 +875,37 @@ impl DisplayListBuilder { where W: Write { let mut temp = BuiltDisplayList::default(); mem::swap(&mut temp.data, &mut self.data); let mut index: usize = 0; { - let mut iter = temp.iter(); + let mut iter = BuiltDisplayListIter::new(&temp); while let Some(item) = iter.next_raw() { if index >= range.start.unwrap_or(0) && range.end.map_or(true, |e| index < e) { writeln!(sink, "{}{:?}", " ".repeat(indent), item.item()).unwrap(); } index += 1; } } self.data = temp.data; index } - fn active_buffer(&mut self) -> &mut Vec<u8> { - if self.writing_extra_data_chunk { - &mut self.extra_data - } else { - &mut self.data - } - } - /// Add an item to the display list. /// /// NOTE: It is usually preferable to use the specialized methods to push /// display items. Pushing unexpected or invalid items here may /// result in WebRender panicking or behaving in unexpected ways. #[inline] pub fn push_item(&mut self, item: &di::DisplayItem) { - poke_into_vec(item, self.active_buffer()); + poke_into_vec(item, &mut self.data); } fn push_iter_impl<I>(data: &mut Vec<u8>, iter_source: I) where I: IntoIterator, I::IntoIter: ExactSizeIterator, I::Item: Poke, { @@ -1019,17 +941,17 @@ impl DisplayListBuilder { /// NOTE: Pushing unexpected or invalid items to the display list /// may result in panic and confusion. pub fn push_iter<I>(&mut self, iter: I) where I: IntoIterator, I::IntoIter: ExactSizeIterator, I::Item: Poke, { - Self::push_iter_impl(self.active_buffer(), iter); + Self::push_iter_impl(&mut self.data, iter); } pub fn push_rect( &mut self, common: &di::CommonItemProperties, color: ColorF, ) { let item = di::DisplayItem::Rectangle(di::RectangleDisplayItem { @@ -1608,68 +1530,34 @@ impl DisplayListBuilder { }); self.push_item(&item); } pub fn pop_all_shadows(&mut self) { self.push_item(&di::DisplayItem::PopAllShadows); } - pub fn start_extra_data_chunk(&mut self) { - self.writing_extra_data_chunk = true; - self.extra_data_chunk_len = self.extra_data.len(); - } - - // Returns the amount of bytes written to extra data buffer. - pub fn end_extra_data_chunk(&mut self) -> usize { - self.writing_extra_data_chunk = false; - self.extra_data.len() - self.extra_data_chunk_len - } - - pub fn push_reuse_item( - &mut self, - key: di::ItemKey, - ) { - let item = di::DisplayItem::ReuseItem(key); - self.push_item(&item); - } - - pub fn set_cache_size( - &mut self, - cache_size: usize, - ) { - self.cache_size = cache_size; - } - pub fn finalize(mut self) -> (PipelineId, LayoutSize, BuiltDisplayList) { assert!(self.save_state.is_none(), "Finalized DisplayListBuilder with a pending save"); // Add `DisplayItem::max_size` zone of zeroes to the end of display list // so there is at least this amount available in the display list during // serialization. ensure_red_zone::<di::DisplayItem>(&mut self.data); - let extra_data_offset = self.data.len(); + let end_time = precise_time_ns(); - if self.extra_data.len() > 0 { - ensure_red_zone::<di::DisplayItem>(&mut self.extra_data); - self.data.extend(self.extra_data); - } - - let end_time = precise_time_ns(); ( self.pipeline_id, self.content_size, BuiltDisplayList { descriptor: BuiltDisplayListDescriptor { builder_start_time: self.builder_start_time, builder_finish_time: end_time, send_start_time: 0, total_clip_nodes: self.next_clip_index, total_spatial_nodes: self.next_spatial_index, - cache_size: self.cache_size, - extra_data_offset, }, data: self.data, }, ) } }
--- a/gfx/wr/webrender_api/src/lib.rs +++ b/gfx/wr/webrender_api/src/lib.rs @@ -39,23 +39,21 @@ extern crate time; extern crate malloc_size_of; extern crate peek_poke; mod api; pub mod channel; mod color; mod display_item; -mod display_item_cache; mod display_list; mod font; mod gradient_builder; mod image; pub mod units; pub use crate::api::*; pub use crate::color::*; pub use crate::display_item::*; -pub use crate::display_item_cache::DisplayItemCache; pub use crate::display_list::*; pub use crate::font::*; pub use crate::gradient_builder::*; pub use crate::image::*;
--- a/layout/painting/RetainedDisplayListBuilder.cpp +++ b/layout/painting/RetainedDisplayListBuilder.cpp @@ -1444,17 +1444,16 @@ PartialUpdateResult RetainedDisplayListB nsRect modifiedDirty; AnimatedGeometryRoot* modifiedAGR = nullptr; PartialUpdateResult result = PartialUpdateResult::NoChange; if (!shouldBuildPartial || !ComputeRebuildRegion(modifiedFrames.Frames(), &modifiedDirty, &modifiedAGR, framesWithProps.Frames()) || !PreProcessDisplayList(&mList, modifiedAGR, result)) { - mBuilder.SetPartialBuildFailed(true); mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), nullptr); mList.DeleteAll(&mBuilder); return PartialUpdateResult::Failed; } // This is normally handled by EnterPresShell, but we skipped it so that we // didn't call MarkFrameForDisplayIfVisible before ComputeRebuildRegion. nsIScrollableFrame* sf = mBuilder.RootReferenceFrame() @@ -1469,31 +1468,31 @@ PartialUpdateResult RetainedDisplayListB } modifiedDirty.IntersectRect( modifiedDirty, mBuilder.RootReferenceFrame()->GetVisualOverflowRectRelativeToSelf()); mBuilder.SetDirtyRect(modifiedDirty); mBuilder.SetPartialUpdate(true); - mBuilder.SetPartialBuildFailed(false); nsDisplayList modifiedDL; mBuilder.RootReferenceFrame()->BuildDisplayListForStackingContext( &mBuilder, &modifiedDL); if (!modifiedDL.IsEmpty()) { nsLayoutUtils::AddExtraBackgroundItems( &mBuilder, &modifiedDL, mBuilder.RootReferenceFrame(), nsRect(nsPoint(0, 0), mBuilder.RootReferenceFrame()->GetSize()), mBuilder.RootReferenceFrame()->GetVisualOverflowRectRelativeToSelf(), aBackstop); } mBuilder.SetPartialUpdate(false); if (mBuilder.PartialBuildFailed()) { + mBuilder.SetPartialBuildFailed(false); mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), nullptr); mList.DeleteAll(&mBuilder); modifiedDL.DeleteAll(&mBuilder); Metrics()->mPartialUpdateFailReason = PartialUpdateFailReason::Content; return PartialUpdateResult::Failed; } if (aChecker) {
--- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -3208,34 +3208,31 @@ class nsPaintedDisplayItem : public nsDi /** * Paint this item to some rendering context. */ virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) { // TODO(miko): Make this a pure virtual function to force implementation. MOZ_ASSERT_UNREACHABLE("Paint() is not implemented!"); } - Maybe<uint16_t>& CacheIndex() { return mCacheIndex; } - protected: nsPaintedDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : nsDisplayItem(aBuilder, aFrame) {} nsPaintedDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const ActiveScrolledRoot* aActiveScrolledRoot) : nsDisplayItem(aBuilder, aFrame, aActiveScrolledRoot) {} nsPaintedDisplayItem(nsDisplayListBuilder* aBuilder, const nsPaintedDisplayItem& aOther) : nsDisplayItem(aBuilder, aOther) {} private: mozilla::DisplayItemData* mDisplayItemData = nullptr; mozilla::layers::LayerManager* mDisplayItemDataLayerManager = nullptr; - mozilla::Maybe<uint16_t> mCacheIndex; }; /** * Manages a singly-linked list of display list items. * * mSentinel is the sentinel list value, the first value in the null-terminated * linked list of items. mTop is the last item in the list (whose 'above' * pointer is null). This class has no virtual methods. So list objects are just
--- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -3863,21 +3863,16 @@ type: bool #ifdef DEBUG value: true #else value: false #endif mirror: once -- name: gfx.webrender.enable-item-cache - type: bool - value: false - mirror: once - #ifdef NIGHTLY_BUILD # Keep this pref hidden on non-nightly builds to avoid people accidentally # turning it on. - name: gfx.webrender.panic-on-gl-error type: bool value: false mirror: once #endif