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:
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user