Bug 1491442 - Support BasicCompositor OMTC rendering in the CoreAnimation path. r=mattwoodrow
authorMarkus Stange <mstange@themasta.com>
Fri, 16 Aug 2019 01:14:22 +0000
changeset 488412 24dbae685801b451fba51d0e3788a821038c9321
parent 488411 5aa5080461f8910b5b3e131f7164d236536aaf79
child 488413 a5ba7777641703116a83c6b4bbea66308fb6e816
push id113908
push userccoroiu@mozilla.com
push dateFri, 16 Aug 2019 09:57:53 +0000
treeherdermozilla-inbound@83fad6abe38a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1491442
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 1491442 - Support BasicCompositor OMTC rendering in the CoreAnimation path. r=mattwoodrow Now CoreAnimation supports all rendering paths. The BasicCompositor OMTC path is used when hardware acceleration is disabled, for example in safe mode or when the user manually disabled it. Differential Revision: https://phabricator.services.mozilla.com/D38758
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -20,16 +20,17 @@
 #include "nsCocoaUtils.h"
 #include "gfxQuartzSurface.h"
 #include "GLContextTypes.h"
 #include "mozilla/Mutex.h"
 #include "nsRegion.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/webrender/WebRenderTypes.h"
+#include "mozilla/gfx/MacIOSurface.h"
 
 #include "nsString.h"
 #include "nsIDragService.h"
 #include "ViewRegion.h"
 #include "CFTypeRefPtr.h"
 
 #import <Carbon/Carbon.h>
 #import <Cocoa/Cocoa.h>
@@ -672,16 +673,21 @@ class nsChildView final : public nsBaseW
 
   RefPtr<mozilla::layers::NativeLayerRootCA> mNativeLayerRoot;
 
   // The CoreAnimation layer that contains the rendering from Gecko. This is a
   // sublayer of mNativeLayerRoot's underlying wrapper layer.
   // Always null if StaticPrefs::gfx_core_animation_enabled_AtStartup() is false.
   RefPtr<mozilla::layers::NativeLayerCA> mContentLayer;
 
+  // Used in BasicCompositor OMTC mode.
+  // Non-null between calls to PreRender(Impl) and PostRender,
+  // if StaticPrefs::gfx_core_animation_enabled_AtStartup() is true.
+  RefPtr<MacIOSurface> mBasicCompositorIOSurface;
+
   mozilla::UniquePtr<mozilla::VibrancyManager> mVibrancyManager;
   RefPtr<mozilla::SwipeTracker> mSwipeTracker;
   mozilla::UniquePtr<mozilla::SwipeEventQueue> mSwipeEventQueue;
 
   // Only used for drawRect-based painting in popups.
   // Always null if StaticPrefs::gfx_core_animation_enabled_AtStartup() is true.
   RefPtr<mozilla::gfx::DrawTarget> mBackingSurface;
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -1927,17 +1927,26 @@ bool nsChildView::PreRenderImpl(WidgetRe
       }
       CFTypeRefPtr<IOSurfaceRef> surf = mContentLayer->NextSurface();
       if (!surf) {
         return false;
       }
       glContextCGL->UseRegisteredIOSurfaceForDefaultFramebuffer(surf.get());
       return true;
     }
-    return false;  // This will be fleshed out in upcoming patches.
+    // We're using BasicCompositor.
+    MOZ_RELEASE_ASSERT(!mBasicCompositorIOSurface);
+    mContentLayer->SetRect(GetBounds().ToUnknownRect());
+    mContentLayer->SetSurfaceIsFlipped(false);
+    CFTypeRefPtr<IOSurfaceRef> surf = mContentLayer->NextSurface();
+    if (!surf) {
+      return false;
+    }
+    mBasicCompositorIOSurface = new MacIOSurface(std::move(surf));
+    return true;
   }
 
   if (gl) {
     return [mView preRender:GLContextCGL::Cast(gl)->GetNSOpenGLContext()];
   }
 
   // BasicCompositor.
   MOZ_RELEASE_ASSERT(mGLPresenter, "Should have been set up in InitCompositor");
@@ -2453,16 +2462,28 @@ void nsChildView::TrackScrollEventAsSwip
 }
 
 void nsChildView::SwipeFinished() { mSwipeTracker = nullptr; }
 
 void nsChildView::UpdateBoundsFromView() { mBounds = CocoaPointsToDevPixels([mView frame]); }
 
 already_AddRefed<gfx::DrawTarget> nsChildView::StartRemoteDrawingInRegion(
     LayoutDeviceIntRegion& aInvalidRegion, BufferMode* aBufferMode) {
+  if (StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
+    MOZ_RELEASE_ASSERT(mBasicCompositorIOSurface,
+                       "Should have been set up by nsChildView::PreRender");
+
+    mContentLayer->InvalidateRegionThroughoutSwapchain(aInvalidRegion.ToUnknownRegion());
+    aInvalidRegion =
+        LayoutDeviceIntRegion::FromUnknownRegion(mContentLayer->CurrentSurfaceInvalidRegion());
+    *aBufferMode = BufferMode::BUFFER_NONE;
+    mBasicCompositorIOSurface->Lock(false);
+    return mBasicCompositorIOSurface->GetAsDrawTargetLocked(gfx::BackendType::SKIA);
+  }
+
   MOZ_RELEASE_ASSERT(mGLPresenter);
 
   LayoutDeviceIntRegion dirtyRegion(aInvalidRegion);
   LayoutDeviceIntSize renderSize = mBounds.Size();
 
   MOZ_RELEASE_ASSERT(mBasicCompositorImage, "Should have created this in PreRender.");
   RefPtr<gfx::DrawTarget> drawTarget = mBasicCompositorImage->BeginUpdate(renderSize, dirtyRegion);
 
@@ -2474,18 +2495,28 @@ already_AddRefed<gfx::DrawTarget> nsChil
 
   aInvalidRegion = mBasicCompositorImage->GetUpdateRegion();
   *aBufferMode = BufferMode::BUFFER_NONE;
 
   return drawTarget.forget();
 }
 
 void nsChildView::EndRemoteDrawing() {
-  mBasicCompositorImage->EndUpdate();
-  DoRemoteComposition(mBounds);
+  if (StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
+    MOZ_RELEASE_ASSERT(mBasicCompositorIOSurface);
+
+    // The DrawTarget we returned from StartRemoteDrawingInRegion, which
+    // referred to pixels in mBasicCompositorIOSurface, is no longer in use.
+    // We can unlock the surface and release our reference to it.
+    mBasicCompositorIOSurface->Unlock(false);
+    mBasicCompositorIOSurface = nullptr;
+  } else {
+    mBasicCompositorImage->EndUpdate();
+    DoRemoteComposition(mBounds);
+  }
 }
 
 void nsChildView::CleanupRemoteDrawing() {
   mBasicCompositorImage = nullptr;
   mCornerMaskImage = nullptr;
   mTitlebarImage = nullptr;
   mGLPresenter = nullptr;
 }