Bug 1574592 - Add CompositorWidget::GetOpaqueWidgetRegion. r=mattwoodrow
authorMarkus Stange <mstange@themasta.com>
Sun, 25 Aug 2019 21:41:58 +0000
changeset 553557 c6d52b09f158420ec69829adb7d3815073c85392
parent 553556 de0c56e1ffad7de4e606b77a1f7156772f857569
child 553558 a63deabe60b22eaa1e69d8bf7eb716d90bb3f9fe
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
bugs1574592
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 1574592 - Add CompositorWidget::GetOpaqueWidgetRegion. r=mattwoodrow This lets LayerManagerComposite and RendererOGL set the correct opaque region on the native layer. Differential Revision: https://phabricator.services.mozilla.com/D42401
widget/CompositorWidget.h
widget/InProcessCompositorWidget.cpp
widget/InProcessCompositorWidget.h
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
widget/nsBaseWidget.h
--- a/widget/CompositorWidget.h
+++ b/widget/CompositorWidget.h
@@ -247,16 +247,34 @@ class CompositorWidget {
   /**
    * Ensure end of composition to back buffer.
    *
    * Called by BasicCompositor on the compositor thread for OMTC drawing
    * after each composition to back buffer.
    */
   virtual already_AddRefed<gfx::SourceSurface> EndBackBufferDrawing();
 
+#ifdef XP_MACOSX
+  /**
+   * Return the opaque region of the widget. This is racy and can only be used
+   * on macOS, where the widget works around the raciness.
+   * Bug 1576491 tracks fixing this properly.
+   * The problem with this method is that it can return values "from the future"
+   * - the compositor might be working on frame N but the widget will return its
+   * opaque region from frame N + 1.
+   * It is believed that this won't lead to visible glitches on macOS due to the
+   * SuspendAsyncCATransactions call when the vibrant region changes or when the
+   * window resizes. Whenever the compositor uses an opaque region that's a
+   * frame ahead, the result it renders won't be shown on the screen; instead,
+   * the next composite will happen with the correct display list, and that's
+   * what's shown on the screen once the FlushRendering call completes.
+   */
+  virtual LayoutDeviceIntRegion GetOpaqueWidgetRegion() { return {}; }
+#endif
+
   /**
    * Observe or unobserve vsync.
    */
   virtual void ObserveVsync(VsyncObserver* aObserver) = 0;
 
   /**
    * Get the compositor options for the compositor associated with this
    * CompositorWidget.
--- a/widget/InProcessCompositorWidget.cpp
+++ b/widget/InProcessCompositorWidget.cpp
@@ -105,16 +105,22 @@ uint32_t InProcessCompositorWidget::GetG
 }
 
 uintptr_t InProcessCompositorWidget::GetWidgetKey() {
   return reinterpret_cast<uintptr_t>(mWidget);
 }
 
 nsIWidget* InProcessCompositorWidget::RealWidget() { return mWidget; }
 
+#ifdef XP_MACOSX
+LayoutDeviceIntRegion InProcessCompositorWidget::GetOpaqueWidgetRegion() {
+  return mWidget->GetOpaqueWidgetRegion();
+}
+#endif
+
 void InProcessCompositorWidget::ObserveVsync(VsyncObserver* aObserver) {
   if (RefPtr<CompositorVsyncDispatcher> cvd =
           mWidget->GetCompositorVsyncDispatcher()) {
     cvd->SetCompositorVsyncObserver(aObserver);
   }
 }
 
 }  // namespace widget
--- a/widget/InProcessCompositorWidget.h
+++ b/widget/InProcessCompositorWidget.h
@@ -33,16 +33,19 @@ class InProcessCompositorWidget : public
   virtual void EndRemoteDrawingInRegion(
       gfx::DrawTarget* aDrawTarget,
       const LayoutDeviceIntRegion& aInvalidRegion) override;
   virtual void CleanupRemoteDrawing() override;
   virtual void CleanupWindowEffects() override;
   virtual bool InitCompositor(layers::Compositor* aCompositor) override;
   virtual LayoutDeviceIntSize GetClientSize() override;
   virtual uint32_t GetGLFrameBufferFormat() override;
+#ifdef XP_MACOSX
+  virtual LayoutDeviceIntRegion GetOpaqueWidgetRegion() override;
+#endif
   virtual void ObserveVsync(VsyncObserver* aObserver) override;
   virtual uintptr_t GetWidgetKey() override;
 
   // If you can override this method, inherit from CompositorWidget instead.
   nsIWidget* RealWidget() override;
 
  protected:
   nsBaseWidget* mWidget;
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -563,16 +563,18 @@ class nsChildView final : public nsBaseW
                                                nsString& aCommitted) override;
 
   virtual void SetPluginFocused(bool& aFocused) override;
 
   bool IsPluginFocused() { return mPluginFocused; }
 
   virtual LayoutDeviceIntPoint GetClientOffset() override;
 
+  virtual LayoutDeviceIntRegion GetOpaqueWidgetRegion() override;
+
   void DispatchAPZWheelInputEvent(mozilla::InputData& aEvent, bool aCanTriggerSwipe);
   nsEventStatus DispatchAPZInputEvent(mozilla::InputData& aEvent);
 
   void SwipeFinished();
 
   nsresult SetPrefersReducedMotionOverrideForTest(bool aValue) override;
   nsresult ResetPrefersReducedMotionOverrideForTest() override;
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -1585,16 +1585,21 @@ LayoutDeviceIntPoint nsChildView::Widget
   FlipCocoaScreenCoordinate(origin);
 
   // convert to device pixels
   return CocoaPointsToDevPixels(origin);
 
   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(LayoutDeviceIntPoint(0, 0));
 }
 
+LayoutDeviceIntRegion nsChildView::GetOpaqueWidgetRegion() {
+  auto opaqueRegion = mOpaqueRegion.Lock();
+  return *opaqueRegion;
+}
+
 nsresult nsChildView::SetTitle(const nsAString& title) {
   // child views don't have titles
   return NS_OK;
 }
 
 nsresult nsChildView::GetAttention(int32_t aCycleCount) {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -471,16 +471,19 @@ class nsBaseWidget : public nsIWidget, p
   }
   virtual void CleanupRemoteDrawing() {}
   virtual void CleanupWindowEffects() {}
   virtual bool InitCompositor(mozilla::layers::Compositor* aCompositor) {
     return true;
   }
   virtual uint32_t GetGLFrameBufferFormat();
   virtual bool CompositorInitiallyPaused() { return false; }
+#ifdef XP_MACOSX
+  virtual LayoutDeviceIntRegion GetOpaqueWidgetRegion() { return {}; }
+#endif
 
  protected:
   void ResolveIconName(const nsAString& aIconName, const nsAString& aIconSuffix,
                        nsIFile** aResult);
   virtual void OnDestroy();
   void BaseCreate(nsIWidget* aParent, nsWidgetInitData* aInitData);
 
   virtual void ConfigureAPZCTreeManager();