From 422d7967dca0c803e0e56be58b0b126fc861d04c Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 2 Jun 2015 16:34:28 -0700 Subject: [PATCH] Fix PostprocessRetainedLayers to not test occlusion with asynchronous clips. (bug 1148582 part 5, r=tn) --- gfx/layers/Layers.cpp | 21 +++++++++++++++++++++ gfx/layers/Layers.h | 6 ++++++ layout/base/FrameLayerBuilder.cpp | 13 +++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index a65864055907..2bc32d814ed5 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -929,6 +929,27 @@ Layer::GetVisibleRegionRelativeToRootLayer(nsIntRegion& aResult, return true; } +Maybe +Layer::GetCombinedClipRect() const +{ + Maybe clip = GetClipRect(); + + for (size_t i = 0; i < mFrameMetrics.Length(); i++) { + if (!mFrameMetrics[i].HasClipRect()) { + continue; + } + + const ParentLayerIntRect& other = mFrameMetrics[i].ClipRect(); + if (clip) { + clip = Some(clip.value().Intersect(other)); + } else { + clip = Some(other); + } + } + + return clip; +} + ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData) : Layer(aManager, aImplData), mFirstChild(nullptr), diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 46eb73524c47..c76bfd6c460d 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1255,6 +1255,12 @@ public: bool IsScrollbarContainer() { return mIsScrollbarContainer; } Layer* GetMaskLayer() const { return mMaskLayer; } + /* + * Get the combined clip rect of the Layer clip and all clips on FrameMetrics. + * This is intended for use in Layout. The compositor needs to apply async + * transforms to find the combined clip. + */ + Maybe GetCombinedClipRect() const; /** * Retrieve the root level visible region for |this| taking into account diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 1dc91bb8c396..57cfe1dab490 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -4408,6 +4408,15 @@ InvalidateVisibleBoundsChangesForScrolledLayer(PaintedLayer* aLayer) } } +static inline const Maybe& +GetStationaryClipInContainer(Layer* aLayer) +{ + if (size_t metricsCount = aLayer->GetFrameMetricsCount()) { + return aLayer->GetFrameMetrics(metricsCount - 1).GetClipRect(); + } + return aLayer->GetClipRect(); +} + void ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer) { @@ -4434,7 +4443,7 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer if (hideAll) { e->mVisibleRegion.SetEmpty(); } else if (!e->mLayer->IsScrollbarContainer()) { - const Maybe& clipRect = e->mLayer->GetClipRect(); + const Maybe& clipRect = GetStationaryClipInContainer(e->mLayer); if (clipRect && opaqueRegionForContainer >= 0 && opaqueRegions[opaqueRegionForContainer].mOpaqueRegion.Contains(ParentLayerIntRect::ToUntyped(*clipRect))) { e->mVisibleRegion.SetEmpty(); @@ -4474,7 +4483,7 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer } nsIntRegion clippedOpaque = e->mOpaqueRegion; - const Maybe& clipRect = e->mLayer->GetClipRect(); + Maybe clipRect = e->mLayer->GetCombinedClipRect(); if (clipRect) { clippedOpaque.AndWith(ParentLayerIntRect::ToUntyped(*clipRect)); }