Bug 1574745 - Get everything ready for rendering into multiple native layers. r=mattwoodrow
authorMarkus Stange <mstange@themasta.com>
Fri, 30 Aug 2019 21:52:32 +0000
changeset 554769 56928dc94586cba272761f8af49e67795baab0bf
parent 554768 1db2a705c75c28805a054c2023401860fad803df
child 554770 da6f33b8403d6e2a56a836714d97bb29f6a9d8e3
push id2165
push userffxbld-merge
push dateMon, 14 Oct 2019 16:30:58 +0000
treeherdermozilla-release@0eae18af659f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1574745, 1574586
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1574745 - Get everything ready for rendering into multiple native layers. r=mattwoodrow This change breaks the draw-fps overlay when using native layers. I'll try to fix that in a new bug soon. The do { } while(0) loop looks a bit odd, but it'll get replaced with a proper loop in bug 1574586. Differential Revision: https://phabricator.services.mozilla.com/D43879
gfx/layers/composite/LayerManagerComposite.cpp
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -970,37 +970,29 @@ bool LayerManagerComposite::Render(const
   LayerMetricsWrapper wrapper = GetRootContentLayer();
   if (wrapper) {
     mCompositor->SetClearColor(wrapper.Metadata().GetBackgroundColor());
   } else {
     mCompositor->SetClearColorToDefault();
   }
 #endif
 
-  if (mNativeLayerForEntireWindow) {
-    mNativeLayerForEntireWindow->SetRect(mRenderBounds);
-#ifdef XP_MACOSX
-    mNativeLayerForEntireWindow->SetOpaqueRegion(
-        mCompositor->GetWidget()->GetOpaqueWidgetRegion().ToUnknownRegion());
-#endif
-  }
-
   Maybe<IntRect> rootLayerClip = mRoot->GetClipRect().map(
       [](const ParentLayerIntRect& r) { return r.ToUnknownRect(); });
   Maybe<IntRect> maybeBounds;
+  bool usingNativeLayers = false;
   if (mTarget) {
     maybeBounds = mCompositor->BeginFrameForTarget(
         aInvalidRegion, rootLayerClip, mRenderBounds, aOpaqueRegion, mTarget,
         mTargetBounds);
-  } else if (mNativeLayerForEntireWindow) {
+  } else if (mNativeLayerRoot) {
     if (aInvalidRegion.Intersects(mRenderBounds)) {
       mCompositor->BeginFrameForNativeLayers();
-      maybeBounds = mCompositor->BeginRenderingToNativeLayer(
-          aInvalidRegion, rootLayerClip, aOpaqueRegion,
-          mNativeLayerForEntireWindow);
+      maybeBounds = Some(mRenderBounds);
+      usingNativeLayers = true;
     }
   } else {
     maybeBounds = mCompositor->BeginFrameForWindow(
         aInvalidRegion, rootLayerClip, mRenderBounds, aOpaqueRegion);
   }
 
   if (!maybeBounds) {
     mProfilerScreenshotGrabber.NotifyEmptyFrame();
@@ -1026,39 +1018,73 @@ bool LayerManagerComposite::Render(const
   {
     Diagnostics::Record record(mRenderStartTime);
     RootLayer()->Prepare(RenderTargetIntRect::FromUnknownRect(clipRect));
     if (record.Recording()) {
       mDiagnostics->RecordPrepareTime(record.Duration());
     }
   }
 
-  {
-    Diagnostics::Record record;
+  auto RenderOnce = [&](const IntRect& aClipRect) {
     RefPtr<CompositingRenderTarget> previousTarget;
     if (haveLayerEffects) {
       previousTarget = PushGroupForLayerEffects();
     } else {
       mTwoPassTmpTarget = nullptr;
     }
 
     // Execute draw commands.
-    RootLayer()->RenderLayer(clipRect, Nothing());
+    RootLayer()->RenderLayer(aClipRect, Nothing());
 
     if (mTwoPassTmpTarget) {
       MOZ_ASSERT(haveLayerEffects);
-      PopGroupForLayerEffects(previousTarget, clipRect, grayscaleVal, invertVal,
-                              contrastVal);
+      PopGroupForLayerEffects(previousTarget, aClipRect, grayscaleVal,
+                              invertVal, contrastVal);
     }
     if (!mRegionToClear.IsEmpty()) {
       for (auto iter = mRegionToClear.RectIter(); !iter.Done(); iter.Next()) {
         mCompositor->ClearRect(Rect(iter.Get()));
       }
     }
     mCompositor->NormalDrawingDone();
+  };
+
+  {
+    Diagnostics::Record record;
+
+    if (usingNativeLayers) {
+      mNativeLayerForEntireWindow->SetRect(mRenderBounds);
+#ifdef XP_MACOSX
+      IntRegion opaqueRegion =
+          mCompositor->GetWidget()->GetOpaqueWidgetRegion().ToUnknownRegion();
+      opaqueRegion.AndWith(mRenderBounds);
+      mNativeLayerForEntireWindow->SetOpaqueRegion(
+          opaqueRegion.MovedBy(-mRenderBounds.TopLeft());
+#endif
+
+      do {
+        Maybe<IntRect> maybeLayerRect =
+            mCompositor->BeginRenderingToNativeLayer(
+                aInvalidRegion, rootLayerClip, aOpaqueRegion,
+                mNativeLayerForEntireWindow);
+        if (!maybeLayerRect) {
+          continue;
+        }
+
+        if (rootLayerClip) {
+          RenderOnce(rootLayerClip->Intersect(*maybeLayerRect));
+        } else {
+          RenderOnce(*maybeLayerRect);
+        }
+        mCompositor->EndRenderingToNativeLayer();
+      } while (0);
+    } else {
+      RenderOnce(clipRect);
+    }
+
     if (record.Recording()) {
       mDiagnostics->RecordCompositeTime(record.Duration());
     }
   }
 
   RootLayer()->Cleanup();
 
   mProfilerScreenshotGrabber.MaybeGrabScreenshot(mCompositor);
@@ -1072,39 +1098,44 @@ bool LayerManagerComposite::Render(const
     if (hasContentPaint) {
       if (RefPtr<RecordedFrame> frame =
               mCompositor->RecordFrame(TimeStamp::Now())) {
         mCompositionRecorder->RecordFrame(frame);
       }
     }
   }
 
-  // Allow widget to render a custom foreground.
-  mCompositor->GetWidget()->DrawWindowOverlay(
-      &widgetContext, LayoutDeviceIntRect::FromUnknownRect(bounds));
+  if (!usingNativeLayers) {
+    // Allow widget to render a custom foreground.
+    mCompositor->GetWidget()->DrawWindowOverlay(
+        &widgetContext, LayoutDeviceIntRect::FromUnknownRect(bounds));
 
 #if defined(MOZ_WIDGET_ANDROID)
-  // Depending on the content shift the toolbar may be rendered on top of
-  // some of the content so it must be rendered after the content.
-  if (jni::IsFennec()) {
-    RenderToolbar();
-  }
-  HandlePixelsTarget();
+    // Depending on the content shift the toolbar may be rendered on top of
+    // some of the content so it must be rendered after the content.
+    if (jni::IsFennec()) {
+      RenderToolbar();
+    }
+    HandlePixelsTarget();
 #endif  // defined(MOZ_WIDGET_ANDROID)
 
-  // Debugging
-  RenderDebugOverlay(bounds);
+    // Debugging
+    // FIXME: We should render the debug overlay when using native layers, too.
+    // But we can't split the debug overlay rendering into multiple tiles
+    // because of a cyclic dependency: We want to display stats about the
+    // rendering of the entire window, but at the time when we render into the
+    // native layers, we do not know all the information about this frame yet.
+    // So we need to render the debug layer into an additional native layer on
+    // top, probably.
+    RenderDebugOverlay(bounds);
+  }
 
   {
     AUTO_PROFILER_LABEL("LayerManagerComposite::Render:EndFrame", GRAPHICS);
 
-    if (mNativeLayerForEntireWindow) {
-      mCompositor->EndRenderingToNativeLayer();
-    }
-
     mCompositor->EndFrame();
   }
 
   mCompositor->GetWidget()->PostRender(&widgetContext);
 
   mProfilerScreenshotGrabber.MaybeProcessQueue();
 
   RecordFrame();