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;
}
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;
mTargetOffset = GetIntermediateSurfaceRect().TopLeft().ToUnknownPoint();
@@ -117,41 +101,45 @@ GetTransformedBounds(Layer* aLayer)
return bounds;
}
static Maybe<IntRect>
FindVisibleBounds(Layer* aLayer, const Maybe<RenderTargetIntRect>& aClip)
/* static */ Maybe<IntRect>
ContainerLayerMLGPU::FindVisibleBounds(Layer* aLayer, const Maybe<RenderTargetIntRect>& aClip)
{
AL_LOG(" visiting child %p\n", aLayer);
AL_LOG_IF(aClip, " parent clip: %s\n", Stringify(aClip.value()).c_str());
ContainerLayer* container = aLayer->AsContainerLayer();
if (container && !container->UseIntermediateSurface()) {
Maybe<IntRect> accumulated = Some(IntRect());
if (container) {
if (container->UseIntermediateSurface()) {
container->AsHostLayer()->AsLayerMLGPU()->AsContainerLayerMLGPU()->ComputeIntermediateSurfaceBounds();
} else {
Maybe<IntRect> accumulated = Some(IntRect());
// Traverse children.
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
Maybe<RenderTargetIntRect> clip = aClip;
if (const Maybe<ParentLayerIntRect>& childClip = child->AsHostLayer()->GetShadowClipRect()) {
RenderTargetIntRect rtChildClip =
TransformBy(ViewAs<ParentLayerToRenderTargetMatrix4x4>(
aLayer->GetEffectiveTransform(),
PixelCastJustification::RenderTargetIsParentLayerForRoot),
childClip.value());
clip = IntersectMaybeRects(clip, Some(rtChildClip));
AL_LOG(" target clip: %s\n", Stringify(rtChildClip).c_str());
AL_LOG_IF(clip, " full clip: %s\n", Stringify(clip.value()).c_str());
}
// Traverse children.
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
Maybe<RenderTargetIntRect> clip = aClip;
if (const Maybe<ParentLayerIntRect>& childClip = child->AsHostLayer()->GetShadowClipRect()) {
RenderTargetIntRect rtChildClip =
TransformBy(ViewAs<ParentLayerToRenderTargetMatrix4x4>(
aLayer->GetEffectiveTransform(),
PixelCastJustification::RenderTargetIsParentLayerForRoot),
childClip.value());
clip = IntersectMaybeRects(clip, Some(rtChildClip));
AL_LOG(" target clip: %s\n", Stringify(rtChildClip).c_str());
AL_LOG_IF(clip, " full clip: %s\n", Stringify(clip.value()).c_str());
}
Maybe<IntRect> childBounds = FindVisibleBounds(child, clip);
if (!childBounds) {
return Nothing();
}
Maybe<IntRect> childBounds = FindVisibleBounds(child, clip);
if (!childBounds) {
return Nothing();
}
accumulated = accumulated->SafeUnion(childBounds.value());
if (!accumulated) {
return Nothing();
accumulated = accumulated->SafeUnion(childBounds.value());
if (!accumulated) {
return Nothing();
}
}
return accumulated;
}
return accumulated;
}
IntRect bounds = GetTransformedBounds(aLayer);
@@ -164,7 +152,7 @@ FindVisibleBounds(Layer* aLayer, const Maybe<RenderTargetIntRect>& aClip)
return Some(bounds);
}
Maybe<IntRect>
void
ContainerLayerMLGPU::ComputeIntermediateSurfaceBounds()
{
Maybe<IntRect> bounds = Some(IntRect());
@@ -174,15 +162,16 @@ ContainerLayerMLGPU::ComputeIntermediateSurfaceBounds()
PixelCastJustification::RenderTargetIsParentLayerForRoot);
Maybe<IntRect> childBounds = FindVisibleBounds(child, clip);
if (!childBounds) {
return Nothing();
return;
}
bounds = bounds->SafeUnion(childBounds.value());
if (!bounds) {
return Nothing();
return;
}
}
return bounds;
SetShadowVisibleRegion(LayerIntRect::FromUnknownRect(bounds.value()));
}
void