Bug 1571253 - Persist the layers damage region in mInvalidRegion if the frame has been aborted. r=mattwoodrow

An alternative approach, which I would have preferred, would be to keep the old
mClonedLayerTreeProperties around, so that future frames can compare to the
last non-aborted mClonedLayerTreeProperties. However, that doesn't work in the
current world because mClonedLayerTreeProperties->ComputeDifferences has side-
effects.

Differential Revision: https://phabricator.services.mozilla.com/D40558

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Markus Stange 2019-08-04 20:37:06 +00:00
parent 259d8d43ed
commit 901919b119
2 changed files with 24 additions and 19 deletions

View File

@ -553,42 +553,39 @@ void LayerManagerComposite::UpdateAndRender() {
nsIntRegion opaque; nsIntRegion opaque;
PostProcessLayers(opaque); PostProcessLayers(opaque);
nsIntRegion changed;
if (mClonedLayerTreeProperties) { if (mClonedLayerTreeProperties) {
// We need to compute layer tree differences even if we're not going to // We need to compute layer tree differences even if we're not going to
// immediately use the resulting damage area, since ComputeDifferences // immediately use the resulting damage area, since ComputeDifferences
// is also responsible for invalidates intermediate surfaces in // is also responsible for invalidates intermediate surfaces in
// ContainerLayers. // ContainerLayers.
nsIntRegion changed;
const bool overflowed = !mClonedLayerTreeProperties->ComputeDifferences( const bool overflowed = !mClonedLayerTreeProperties->ComputeDifferences(
mRoot, changed, nullptr); mRoot, changed, nullptr);
if (overflowed) { if (overflowed) {
changed = mTarget ? mTargetBounds : mRenderBounds; changed = mTarget ? mTargetBounds : mRenderBounds;
} }
mInvalidRegion.Or(mInvalidRegion, changed);
} }
nsIntRegion invalid; nsIntRegion invalid;
if (mTarget) { if (mTarget) {
// Since we're composing to an external target, we're not going to use // Since we're composing to an external target, we're not going to use
// the damage region from layers changes - we want to composite // the damage region from layers changes - we want to composite
// everything in the target bounds. Instead we accumulate the layers // everything in the target bounds. The layers damage region has been
// damage region for the next window composite. // stored in mInvalidRegion and will be picked up by the next window
mInvalidRegion.Or(mInvalidRegion, changed); // composite.
invalid = mTargetBounds; invalid = mTargetBounds;
} else { } else {
if (mClonedLayerTreeProperties) { if (!mClonedLayerTreeProperties) {
invalid = std::move(changed);
} else {
// If we didn't have a previous layer tree, invalidate the entire render // If we didn't have a previous layer tree, invalidate the entire render
// area. // area.
invalid = mRenderBounds; mInvalidRegion = mRenderBounds;
} }
// Add any additional invalid rects from the window manager or previous invalid = mInvalidRegion;
// damage computed during ComposeToTarget().
invalid.Or(invalid, mInvalidRegion);
mInvalidRegion.SetEmpty();
} }
if (invalid.IsEmpty() && !mWindowOverlayChanged) { if (invalid.IsEmpty() && !mWindowOverlayChanged) {
@ -601,11 +598,15 @@ void LayerManagerComposite::UpdateAndRender() {
// so we will invalidate after we've decided if something changed. // so we will invalidate after we've decided if something changed.
InvalidateDebugOverlay(invalid, mRenderBounds); InvalidateDebugOverlay(invalid, mRenderBounds);
Render(invalid, opaque); bool rendered = Render(invalid, opaque);
#if defined(MOZ_WIDGET_ANDROID) #if defined(MOZ_WIDGET_ANDROID)
RenderToPresentationSurface(); RenderToPresentationSurface();
#endif #endif
mWindowOverlayChanged = false;
if (!mTarget && rendered) {
mInvalidRegion.SetEmpty();
mWindowOverlayChanged = false;
}
// Update cached layer tree information. // Update cached layer tree information.
mClonedLayerTreeProperties = LayerProperties::CloneFrom(GetRoot()); mClonedLayerTreeProperties = LayerProperties::CloneFrom(GetRoot());
@ -893,13 +894,13 @@ class ScopedCompositorRenderOffset {
}; };
#endif // defined(MOZ_WIDGET_ANDROID) #endif // defined(MOZ_WIDGET_ANDROID)
void LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion, bool LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion,
const nsIntRegion& aOpaqueRegion) { const nsIntRegion& aOpaqueRegion) {
AUTO_PROFILER_LABEL("LayerManagerComposite::Render", GRAPHICS); AUTO_PROFILER_LABEL("LayerManagerComposite::Render", GRAPHICS);
if (mDestroyed || !mCompositor || mCompositor->IsDestroyed()) { if (mDestroyed || !mCompositor || mCompositor->IsDestroyed()) {
NS_WARNING("Call on destroyed layer manager"); NS_WARNING("Call on destroyed layer manager");
return; return false;
} }
mCompositor->RequestAllowFrameRecording(!!mCompositionRecorder); mCompositor->RequestAllowFrameRecording(!!mCompositionRecorder);
@ -943,7 +944,7 @@ void LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion,
AUTO_PROFILER_LABEL("LayerManagerComposite::Render:Prerender", GRAPHICS); AUTO_PROFILER_LABEL("LayerManagerComposite::Render:Prerender", GRAPHICS);
if (!mCompositor->GetWidget()->PreRender(&widgetContext)) { if (!mCompositor->GetWidget()->PreRender(&widgetContext)) {
return; return false;
} }
} }
@ -985,7 +986,7 @@ void LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion,
if (actualBounds.IsEmpty()) { if (actualBounds.IsEmpty()) {
mProfilerScreenshotGrabber.NotifyEmptyFrame(); mProfilerScreenshotGrabber.NotifyEmptyFrame();
mCompositor->GetWidget()->PostRender(&widgetContext); mCompositor->GetWidget()->PostRender(&widgetContext);
return; return true;
} }
// Allow widget to render a custom background. // Allow widget to render a custom background.
@ -1086,6 +1087,8 @@ void LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion,
mPayload.Clear(); mPayload.Clear();
mCompositor->WaitForGPU(); mCompositor->WaitForGPU();
return true;
} }
#if defined(MOZ_WIDGET_ANDROID) #if defined(MOZ_WIDGET_ANDROID)

View File

@ -414,8 +414,10 @@ class LayerManagerComposite final : public HostLayerManager {
/** /**
* Render the current layer tree to the active target. * Render the current layer tree to the active target.
* Returns true if the current invalid region can be cleared, false if
* rendering was canceled.
*/ */
void Render(const nsIntRegion& aInvalidRegion, bool Render(const nsIntRegion& aInvalidRegion,
const nsIntRegion& aOpaqueRegion); const nsIntRegion& aOpaqueRegion);
#if defined(MOZ_WIDGET_ANDROID) #if defined(MOZ_WIDGET_ANDROID)
void RenderToPresentationSurface(); void RenderToPresentationSurface();