Bug 1471221 - Calculate intermediate surface bounds in advanced layers in pre-pass. r=mattwoodrow

Advanced layers was calculating incorrect visible regions for
container layers with intermediate surfaces, as it was not taking
async transform animations in to account. Rather than recursing the
depth of the tree for each layer to calculate this in
OnPrepareToRender, do a single pre-pass at the start of the frame.

Differential Revision: https://phabricator.services.mozilla.com/D4522
This commit is contained in:
Jamie Nicol
2018-08-30 00:26:08 +00:00
parent c9cc9cb27d
commit ddceaa2fe8
3 changed files with 43 additions and 46 deletions

View File

@@ -47,22 +47,6 @@ ContainerLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder)
return true; return true;
} }
if ((!mRenderTarget || mChildrenChanged) &&
gfxPrefs::AdvancedLayersEnableContainerResizing())
{
// Try to compute a more accurate visible region.
AL_LOG("Computing new surface size for container %p:\n", GetLayer());
Maybe<IntRect> bounds = ComputeIntermediateSurfaceBounds();
if (bounds) {
LayerIntRegion region = std::move(GetShadowVisibleRegion());
region.AndWith(LayerIntRect::FromUnknownRect(bounds.value()));
AL_LOG(" computed bounds: %s\n", Stringify(bounds.value()).c_str());
AL_LOG(" new visible: %s\n", Stringify(region).c_str());
SetShadowVisibleRegion(std::move(region));
}
}
mChildrenChanged = false; mChildrenChanged = false;
mTargetOffset = GetIntermediateSurfaceRect().TopLeft().ToUnknownPoint(); mTargetOffset = GetIntermediateSurfaceRect().TopLeft().ToUnknownPoint();
@@ -117,41 +101,45 @@ GetTransformedBounds(Layer* aLayer)
return bounds; return bounds;
} }
static Maybe<IntRect> /* static */ Maybe<IntRect>
FindVisibleBounds(Layer* aLayer, const Maybe<RenderTargetIntRect>& aClip) ContainerLayerMLGPU::FindVisibleBounds(Layer* aLayer, const Maybe<RenderTargetIntRect>& aClip)
{ {
AL_LOG(" visiting child %p\n", aLayer); AL_LOG(" visiting child %p\n", aLayer);
AL_LOG_IF(aClip, " parent clip: %s\n", Stringify(aClip.value()).c_str()); AL_LOG_IF(aClip, " parent clip: %s\n", Stringify(aClip.value()).c_str());
ContainerLayer* container = aLayer->AsContainerLayer(); ContainerLayer* container = aLayer->AsContainerLayer();
if (container && !container->UseIntermediateSurface()) { if (container) {
Maybe<IntRect> accumulated = Some(IntRect()); if (container->UseIntermediateSurface()) {
container->AsHostLayer()->AsLayerMLGPU()->AsContainerLayerMLGPU()->ComputeIntermediateSurfaceBounds();
} else {
Maybe<IntRect> accumulated = Some(IntRect());
// Traverse children. // Traverse children.
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) { for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
Maybe<RenderTargetIntRect> clip = aClip; Maybe<RenderTargetIntRect> clip = aClip;
if (const Maybe<ParentLayerIntRect>& childClip = child->AsHostLayer()->GetShadowClipRect()) { if (const Maybe<ParentLayerIntRect>& childClip = child->AsHostLayer()->GetShadowClipRect()) {
RenderTargetIntRect rtChildClip = RenderTargetIntRect rtChildClip =
TransformBy(ViewAs<ParentLayerToRenderTargetMatrix4x4>( TransformBy(ViewAs<ParentLayerToRenderTargetMatrix4x4>(
aLayer->GetEffectiveTransform(), aLayer->GetEffectiveTransform(),
PixelCastJustification::RenderTargetIsParentLayerForRoot), PixelCastJustification::RenderTargetIsParentLayerForRoot),
childClip.value()); childClip.value());
clip = IntersectMaybeRects(clip, Some(rtChildClip)); clip = IntersectMaybeRects(clip, Some(rtChildClip));
AL_LOG(" target clip: %s\n", Stringify(rtChildClip).c_str()); AL_LOG(" target clip: %s\n", Stringify(rtChildClip).c_str());
AL_LOG_IF(clip, " full clip: %s\n", Stringify(clip.value()).c_str()); AL_LOG_IF(clip, " full clip: %s\n", Stringify(clip.value()).c_str());
} }
Maybe<IntRect> childBounds = FindVisibleBounds(child, clip); Maybe<IntRect> childBounds = FindVisibleBounds(child, clip);
if (!childBounds) { if (!childBounds) {
return Nothing(); return Nothing();
} }
accumulated = accumulated->SafeUnion(childBounds.value()); accumulated = accumulated->SafeUnion(childBounds.value());
if (!accumulated) { if (!accumulated) {
return Nothing(); return Nothing();
}
} }
return accumulated;
} }
return accumulated;
} }
IntRect bounds = GetTransformedBounds(aLayer); IntRect bounds = GetTransformedBounds(aLayer);
@@ -164,7 +152,7 @@ FindVisibleBounds(Layer* aLayer, const Maybe<RenderTargetIntRect>& aClip)
return Some(bounds); return Some(bounds);
} }
Maybe<IntRect> void
ContainerLayerMLGPU::ComputeIntermediateSurfaceBounds() ContainerLayerMLGPU::ComputeIntermediateSurfaceBounds()
{ {
Maybe<IntRect> bounds = Some(IntRect()); Maybe<IntRect> bounds = Some(IntRect());
@@ -174,15 +162,16 @@ ContainerLayerMLGPU::ComputeIntermediateSurfaceBounds()
PixelCastJustification::RenderTargetIsParentLayerForRoot); PixelCastJustification::RenderTargetIsParentLayerForRoot);
Maybe<IntRect> childBounds = FindVisibleBounds(child, clip); Maybe<IntRect> childBounds = FindVisibleBounds(child, clip);
if (!childBounds) { if (!childBounds) {
return Nothing(); return;
} }
bounds = bounds->SafeUnion(childBounds.value()); bounds = bounds->SafeUnion(childBounds.value());
if (!bounds) { if (!bounds) {
return Nothing(); return;
} }
} }
return bounds;
SetShadowVisibleRegion(LayerIntRect::FromUnknownRect(bounds.value()));
} }
void void

View File

@@ -69,12 +69,15 @@ public:
mView = aView; mView = aView;
} }
void ComputeIntermediateSurfaceBounds();
protected: protected:
bool OnPrepareToRender(FrameBuilder* aBuilder) override; bool OnPrepareToRender(FrameBuilder* aBuilder) override;
void OnLayerManagerChange(LayerManagerMLGPU* aManager) override; void OnLayerManagerChange(LayerManagerMLGPU* aManager) override;
Maybe<gfx::IntRect> ComputeIntermediateSurfaceBounds();
private: private:
static Maybe<gfx::IntRect> FindVisibleBounds(Layer* aLayer, const Maybe<RenderTargetIntRect>& aClip);
RefPtr<MLGRenderTarget> mRenderTarget; RefPtr<MLGRenderTarget> mRenderTarget;
// We cache these since occlusion culling can change the visible region. // We cache these since occlusion culling can change the visible region.

View File

@@ -66,6 +66,11 @@ FrameBuilder::Build()
mWidgetRenderView = new RenderViewMLGPU(this, target, region); mWidgetRenderView = new RenderViewMLGPU(this, target, region);
// Traverse the layer tree and compute visible region for intermediate surfaces
if (ContainerLayerMLGPU* root = mRoot->AsLayerMLGPU()->AsContainerLayerMLGPU()) {
root->ComputeIntermediateSurfaceBounds();
}
// Traverse the layer tree and assign each layer to tiles. // Traverse the layer tree and assign each layer to tiles.
{ {
Maybe<gfx::Polygon> geometry; Maybe<gfx::Polygon> geometry;