Bug 1491442 - Render accelerated windows into mContentLayer, using OMTC. r=mattwoodrow
authorMarkus Stange <mstange@themasta.com>
Fri, 16 Aug 2019 01:13:52 +0000
changeset 488411 5aa5080461f8910b5b3e131f7164d236536aaf79
parent 488410 7711755e979e4ef6a37d0fec4bf3de41e8e4d148
child 488412 24dbae685801b451fba51d0e3788a821038c9321
push id36443
push userccoroiu@mozilla.com
push dateFri, 16 Aug 2019 09:48:15 +0000
treeherdermozilla-central@5d4cbfe103bb [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 - Render accelerated windows into mContentLayer, using OMTC. r=mattwoodrow This makes windows that render using CompositorOGL or WebRender show content. Differential Revision: https://phabricator.services.mozilla.com/D40517
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -479,16 +479,17 @@ class nsChildView final : public nsBaseW
 
   virtual void AddWindowOverlayWebRenderCommands(
       mozilla::layers::WebRenderBridgeChild* aWrBridge, mozilla::wr::DisplayListBuilder& aBuilder,
       mozilla::wr::IpcResourceUpdateQueue& aResourceUpdates) override;
 
   virtual bool PreRender(mozilla::widget::WidgetRenderingContext* aContext) override;
   bool PreRenderImpl(mozilla::widget::WidgetRenderingContext* aContext);
   virtual void PostRender(mozilla::widget::WidgetRenderingContext* aContext) override;
+  virtual void DoCompositorCleanup() override;
   virtual void DrawWindowOverlay(mozilla::widget::WidgetRenderingContext* aManager,
                                  LayoutDeviceIntRect aRect) override;
 
   virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) override;
 
   virtual void UpdateWindowDraggingRegion(const LayoutDeviceIntRegion& aRegion) override;
   LayoutDeviceIntRegion GetNonDraggableRegion() { return mNonDraggableRegion.Region(); }
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -1447,16 +1447,22 @@ void nsChildView::PaintWindowInContentLa
 
 void nsChildView::HandleMainThreadCATransaction() {
   WillPaintWindow();
 
   if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) {
     // We're in BasicLayers mode, i.e. main thread software compositing.
     // Composite the window into our layer's surface.
     PaintWindowInContentLayer();
+  } else {
+    // Trigger a synchronous OMTC composite. This will call NextSurface and
+    // NotifySurfaceReady on the compositor thread to update mContentLayer's
+    // surface, and the main thread (this thread) will wait inside PaintWindow
+    // during that time.
+    PaintWindow(LayoutDeviceIntRegion(GetBounds()));
   }
 
   // Apply the changes from mContentLayer to its underlying CALayer. Now is a
   // good time to call this because we know we're currently inside a main thread
   // CATransaction.
   mNativeLayerRoot->ApplyChanges();
 }
 
@@ -1883,21 +1889,54 @@ bool nsChildView::PreRender(WidgetRender
 
   if (!canComposite) {
     mViewTearDownLock.Unlock();
     return false;
   }
   return true;
 }
 
+class SurfaceRegistryWrapperAroundGLContextCGL : public layers::IOSurfaceRegistry {
+ public:
+  explicit SurfaceRegistryWrapperAroundGLContextCGL(gl::GLContextCGL* aContext)
+      : mContext(aContext) {}
+  void RegisterSurface(CFTypeRefPtr<IOSurfaceRef> aSurface) override {
+    mContext->RegisterIOSurface(aSurface.get());
+  }
+  void UnregisterSurface(CFTypeRefPtr<IOSurfaceRef> aSurface) override {
+    mContext->UnregisterIOSurface(aSurface.get());
+  }
+  RefPtr<gl::GLContextCGL> mContext;
+};
+
 bool nsChildView::PreRenderImpl(WidgetRenderingContext* aContext) {
   UniquePtr<GLManager> manager(GLManager::CreateGLManager(aContext->mLayerManager));
   gl::GLContext* gl = manager ? manager->gl() : aContext->mGL;
 
   if (StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
+    if (gl) {
+      auto glContextCGL = GLContextCGL::Cast(gl);
+      mContentLayer->SetRect(GetBounds().ToUnknownRect());
+      mContentLayer->SetSurfaceIsFlipped(true);
+      RefPtr<layers::IOSurfaceRegistry> currentRegistry = mContentLayer->GetSurfaceRegistry();
+      if (!currentRegistry) {
+        mContentLayer->SetSurfaceRegistry(
+            MakeAndAddRef<SurfaceRegistryWrapperAroundGLContextCGL>(glContextCGL));
+      } else {
+        MOZ_RELEASE_ASSERT(
+            static_cast<SurfaceRegistryWrapperAroundGLContextCGL*>(currentRegistry.get())
+                ->mContext == glContextCGL);
+      }
+      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.
   }
 
   if (gl) {
     return [mView preRender:GLContextCGL::Cast(gl)->GetNSOpenGLContext()];
   }
 
   // BasicCompositor.
@@ -1908,24 +1947,39 @@ bool nsChildView::PreRenderImpl(WidgetRe
 
   if (!mBasicCompositorImage) {
     mBasicCompositorImage = MakeUnique<RectTextureImage>();
   }
   return true;
 }
 
 void nsChildView::PostRender(WidgetRenderingContext* aContext) {
-  UniquePtr<GLManager> manager(GLManager::CreateGLManager(aContext->mLayerManager));
-  gl::GLContext* gl = manager ? manager->gl() : aContext->mGL;
-  NSOpenGLContext* glContext =
-      gl ? GLContextCGL::Cast(gl)->GetNSOpenGLContext() : mGLPresenter->GetNSOpenGLContext();
-  [mView postRender:glContext];
+  if (StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
+    mContentLayer->NotifySurfaceReady();
+
+    // Force a CoreAnimation layer tree update from this thread.
+    [CATransaction begin];
+    mNativeLayerRoot->ApplyChanges();
+    [CATransaction commit];
+  } else {
+    UniquePtr<GLManager> manager(GLManager::CreateGLManager(aContext->mLayerManager));
+    GLContext* gl = manager ? manager->gl() : aContext->mGL;
+    NSOpenGLContext* glContext =
+        gl ? GLContextCGL::Cast(gl)->GetNSOpenGLContext() : mGLPresenter->GetNSOpenGLContext();
+    [mView postRender:glContext];
+  }
   mViewTearDownLock.Unlock();
 }
 
+void nsChildView::DoCompositorCleanup() {
+  if (mContentLayer) {
+    mContentLayer->SetSurfaceRegistry(nullptr);
+  }
+}
+
 void nsChildView::DrawWindowOverlay(WidgetRenderingContext* aContext, LayoutDeviceIntRect aRect) {
   mozilla::UniquePtr<GLManager> manager(GLManager::CreateGLManager(aContext->mLayerManager));
   if (manager) {
     DrawWindowOverlay(manager.get(), aRect);
   }
 }
 
 void nsChildView::DrawWindowOverlay(GLManager* aManager, LayoutDeviceIntRect aRect) {