mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-14 22:13:31 +00:00
Bug 1409446 - Modify the extra-clip flag to instead track more useful information. r=ethlin,mstange
Instead of just keeping a count of how many "extra clips" (aka out-of-band clips) we have pushed, track more complex information for each clip. In particular, track the display item's normal clip chain, as well as the clip id of the extra clip that was pushed. This will be needed to override clip cache information in the next patch. MozReview-Commit-ID: AWKDTkelhyL --HG-- extra : rebase_source : 379e38550cf45d54862850f6c4aad0ac488f6ca9
This commit is contained in:
parent
54e570d116
commit
eae58bd759
@ -631,7 +631,6 @@ WebRenderAPI::RunOnRenderThread(UniquePtr<RendererEvent> aEvent)
|
||||
DisplayListBuilder::DisplayListBuilder(PipelineId aId,
|
||||
const wr::LayoutSize& aContentSize,
|
||||
size_t aCapacity)
|
||||
: mExtraClipCount(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(DisplayListBuilder);
|
||||
mWrState = wr_state_new(aId, aContentSize, aCapacity);
|
||||
@ -720,30 +719,47 @@ DisplayListBuilder::DefineClip(const Maybe<layers::FrameMetrics::ViewID>& aAnces
|
||||
}
|
||||
|
||||
void
|
||||
DisplayListBuilder::PushClip(const wr::WrClipId& aClipId, bool aExtra)
|
||||
DisplayListBuilder::PushClip(const wr::WrClipId& aClipId,
|
||||
const DisplayItemClipChain* aParent)
|
||||
{
|
||||
wr_dp_push_clip(mWrState, aClipId.id);
|
||||
WRDL_LOG("PushClip id=%" PRIu64 "\n", mWrState, aClipId.id);
|
||||
if (!aExtra) {
|
||||
if (!aParent) {
|
||||
mClipStack.push_back(wr::ScrollOrClipId(aClipId));
|
||||
} else {
|
||||
mExtraClipCount++;
|
||||
auto it = mCacheOverride.insert({ aParent, std::vector<wr::WrClipId>() });
|
||||
it.first->second.push_back(aClipId);
|
||||
WRDL_LOG("Pushing override %p -> %" PRIu64 "\n", mWrState, aParent, aClipId.id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DisplayListBuilder::PopClip(bool aExtra)
|
||||
DisplayListBuilder::PopClip(const DisplayItemClipChain* aParent)
|
||||
{
|
||||
WRDL_LOG("PopClip\n", mWrState);
|
||||
if (!aExtra) {
|
||||
if (!aParent) {
|
||||
MOZ_ASSERT(mClipStack.back().is<wr::WrClipId>());
|
||||
mClipStack.pop_back();
|
||||
} else {
|
||||
mExtraClipCount--;
|
||||
auto it = mCacheOverride.find(aParent);
|
||||
MOZ_ASSERT(it != mCacheOverride.end());
|
||||
MOZ_ASSERT(!(it->second.empty()));
|
||||
WRDL_LOG("Popping override %p -> %" PRIu64 "\n", mWrState, aParent, it->second.back().id);
|
||||
it->second.pop_back();
|
||||
if (it->second.empty()) {
|
||||
mCacheOverride.erase(it);
|
||||
}
|
||||
}
|
||||
wr_dp_pop_clip(mWrState);
|
||||
}
|
||||
|
||||
Maybe<wr::WrClipId>
|
||||
DisplayListBuilder::GetCacheOverride(const DisplayItemClipChain* aParent)
|
||||
{
|
||||
auto it = mCacheOverride.find(aParent);
|
||||
return it == mCacheOverride.end() ? Nothing() : Some(it->second.back());
|
||||
}
|
||||
|
||||
wr::WrStickyId
|
||||
DisplayListBuilder::DefineStickyFrame(const wr::LayoutRect& aContentRect,
|
||||
const wr::StickySideConstraint* aTop,
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
struct DisplayItemClipChain;
|
||||
|
||||
namespace widget {
|
||||
class CompositorWidget;
|
||||
}
|
||||
@ -234,8 +236,9 @@ public:
|
||||
const wr::LayoutRect& aClipRect,
|
||||
const nsTArray<wr::ComplexClipRegion>* aComplex = nullptr,
|
||||
const wr::WrImageMask* aMask = nullptr);
|
||||
void PushClip(const wr::WrClipId& aClipId, bool aExtra = false);
|
||||
void PopClip(bool aExtra = false);
|
||||
void PushClip(const wr::WrClipId& aClipId, const DisplayItemClipChain* aParent = nullptr);
|
||||
void PopClip(const DisplayItemClipChain* aParent = nullptr);
|
||||
Maybe<wr::WrClipId> GetCacheOverride(const DisplayItemClipChain* aParent);
|
||||
|
||||
wr::WrStickyId DefineStickyFrame(const wr::LayoutRect& aContentRect,
|
||||
const wr::StickySideConstraint* aTop,
|
||||
@ -407,7 +410,7 @@ public:
|
||||
wr::WrState* Raw() { return mWrState; }
|
||||
|
||||
// Return true if the current clip stack has any extra clip.
|
||||
bool HasExtraClip() { return mExtraClipCount > 0; }
|
||||
bool HasExtraClip() { return !mCacheOverride.empty(); }
|
||||
|
||||
protected:
|
||||
wr::WrState* mWrState;
|
||||
@ -422,8 +425,20 @@ protected:
|
||||
// as that results in undefined behaviour in WR.
|
||||
std::unordered_set<layers::FrameMetrics::ViewID> mScrollIdsDefined;
|
||||
|
||||
// The number of extra clips that are in the stack.
|
||||
uint32_t mExtraClipCount;
|
||||
// A map that holds the cache overrides creates by "out of band" clips, i.e.
|
||||
// clips that are generated by display items but that ScrollingLayersHelper
|
||||
// doesn't know about. These are called "cache overrides" because while we're
|
||||
// inside one of these clips, the WR clip stack is different from what
|
||||
// ScrollingLayersHelper thinks it actually is (because of the out-of-band
|
||||
// clip that was pushed onto the stack) and so ScrollingLayersHelper cannot
|
||||
// use its clip cache as-is. Instead, any time ScrollingLayersHelper wants
|
||||
// to define a new clip as a child of clip X, it should first check the
|
||||
// cache overrides to see if there is an out-of-band clip Y that is already a
|
||||
// child of X, and then define its clip as a child of Y instead. This map
|
||||
// stores X -> ClipId of Y, which allows ScrollingLayersHelper to do the
|
||||
// necessary lookup. Note that there theoretically might be multiple
|
||||
// different "Y" clips which is why we need a vector.
|
||||
std::unordered_map<const DisplayItemClipChain*, std::vector<wr::WrClipId>> mCacheOverride;
|
||||
|
||||
friend class WebRenderAPI;
|
||||
};
|
||||
|
@ -383,7 +383,7 @@ nsDisplayButtonBorder::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder&
|
||||
visible,
|
||||
mFrame,
|
||||
buttonRect);
|
||||
mBorderRenderer->CreateWebRenderCommands(aBuilder, aResources, aSc);
|
||||
mBorderRenderer->CreateWebRenderCommands(this, aBuilder, aResources, aSc);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -551,7 +551,7 @@ nsDisplayButtonForeground::CreateWebRenderCommands(mozilla::wr::DisplayListBuild
|
||||
return false;
|
||||
}
|
||||
|
||||
mBorderRenderer->CreateWebRenderCommands(aBuilder, aResources, aSc);
|
||||
mBorderRenderer->CreateWebRenderCommands(this, aBuilder, aResources, aSc);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ nsDisplayColumnRule::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aB
|
||||
}
|
||||
|
||||
for (auto iter = mBorderRenderers.begin(); iter != mBorderRenderers.end(); iter++) {
|
||||
iter->CreateWebRenderCommands(aBuilder, aResources, aSc);
|
||||
iter->CreateWebRenderCommands(this, aBuilder, aResources, aSc);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -719,7 +719,7 @@ nsCSSRendering::CreateWebRenderCommandsForBorder(nsDisplayItem* aItem,
|
||||
if (!br->CanCreateWebRenderCommands()) {
|
||||
return false;
|
||||
}
|
||||
br->CreateWebRenderCommands(aBuilder, aResources, aSc);
|
||||
br->CreateWebRenderCommands(aItem, aBuilder, aResources, aSc);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -3602,7 +3602,8 @@ nsCSSBorderRenderer::CanCreateWebRenderCommands()
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSBorderRenderer::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
|
||||
nsCSSBorderRenderer::CreateWebRenderCommands(nsDisplayItem* aItem,
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
wr::IpcResourceUpdateQueue& aResources,
|
||||
const layers::StackingContextHelper& aSc)
|
||||
{
|
||||
@ -3622,7 +3623,7 @@ nsCSSBorderRenderer::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
|
||||
LayoutDeviceRect clip = LayoutDeviceRect::FromUnknownRect(mLocalClip.value());
|
||||
wr::LayoutRect clipRect = aSc.ToRelativeLayoutRect(clip);
|
||||
wr::WrClipId clipId = aBuilder.DefineClip(Nothing(), Nothing(), clipRect);
|
||||
aBuilder.PushClip(clipId, true);
|
||||
aBuilder.PushClip(clipId, aItem->GetClipChain());
|
||||
}
|
||||
|
||||
Range<const wr::BorderSide> wrsides(side, 4);
|
||||
@ -3634,7 +3635,7 @@ nsCSSBorderRenderer::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
|
||||
borderRadius);
|
||||
|
||||
if (mLocalClip) {
|
||||
aBuilder.PopClip(true);
|
||||
aBuilder.PopClip(aItem->GetClipChain());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,8 @@ public:
|
||||
void DrawBorders();
|
||||
|
||||
bool CanCreateWebRenderCommands();
|
||||
void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
void CreateWebRenderCommands(nsDisplayItem* aItem,
|
||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
const mozilla::layers::StackingContextHelper& aSc);
|
||||
|
||||
|
@ -4731,7 +4731,7 @@ nsDisplayOutline::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuil
|
||||
return false;
|
||||
}
|
||||
|
||||
mBorderRenderer->CreateWebRenderCommands(aBuilder, aResources, aSc);
|
||||
mBorderRenderer->CreateWebRenderCommands(this, aBuilder, aResources, aSc);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -9413,13 +9413,13 @@ nsDisplayMask::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder
|
||||
// Don't record this clip push in aBuilder's internal clip stack, because
|
||||
// otherwise any nested ScrollingLayersHelper instances that are created
|
||||
// will get confused about which clips are pushed.
|
||||
aBuilder.PushClip(clipId, /*aMask*/ true);
|
||||
aBuilder.PushClip(clipId, GetClipChain());
|
||||
}
|
||||
|
||||
nsDisplaySVGEffects::CreateWebRenderCommands(aBuilder, aResources, aSc, aManager, aDisplayListBuilder);
|
||||
|
||||
if (mask) {
|
||||
aBuilder.PopClip(/*aMask*/ true);
|
||||
aBuilder.PopClip(GetClipChain());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user