Bug 1180688 - Detect whether the widget will be able to present frames with BasicCompositor on Mac. r=mstange, a=lmandel
authorNicolas Silva <nsilva@mozilla.com>
Thu, 23 Jul 2015 18:09:53 -0400
changeset 273915 5657e76d4ee58ed4eb1117529784352d3d51bb27
parent 273914 f05ed00c482dfeea6ccae77bfe12792c4015649b
child 273916 d3bcdf6eba958fd19954b0e2a27d250311618a06
child 273920 26c44dd74c2298cbbe754327635c2eed73a00f10
push id4902
push userryanvm@gmail.com
push dateThu, 23 Jul 2015 22:09:58 +0000
treeherdermozilla-beta@5657e76d4ee5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, lmandel
bugs1180688
milestone40.0
Bug 1180688 - Detect whether the widget will be able to present frames with BasicCompositor on Mac. r=mstange, a=lmandel
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/basic/BasicCompositor.h
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d9/CompositorD3D9.cpp
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
widget/nsBaseWidget.cpp
widget/nsIWidget.h
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -77,16 +77,22 @@ BasicCompositor::BasicCompositor(nsIWidg
     Factory::GetMaxSurfaceSize(gfxPlatform::GetPlatform()->GetContentBackend());
 }
 
 BasicCompositor::~BasicCompositor()
 {
   MOZ_COUNT_DTOR(BasicCompositor);
 }
 
+bool
+BasicCompositor::Initialize()
+{
+  return mWidget ? mWidget->InitCompositor(this) : false;
+};
+
 int32_t
 BasicCompositor::GetMaxTextureSize() const
 {
   return mMaxTextureSize;
 }
 
 void
 BasicCompositingRenderTarget::BindRenderTarget()
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -41,17 +41,17 @@ class BasicCompositor : public Composito
 {
 public:
   explicit BasicCompositor(nsIWidget *aWidget);
 
 protected:
   virtual ~BasicCompositor();
 
 public:
-  virtual bool Initialize() override { return true; };
+  virtual bool Initialize() override;
 
   virtual void Destroy() override;
 
   virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() override
   {
     return TextureFactoryIdentifier(LayersBackend::LAYERS_BASIC,
                                     XRE_GetProcessType(),
                                     GetMaxTextureSize());
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -386,16 +386,20 @@ CompositorD3D11::Initialize()
      return false;
     }
 
     // We need this because we don't want DXGI to respond to Alt+Enter.
     dxgiFactory->MakeWindowAssociation(swapDesc.OutputWindow,
                                        DXGI_MWA_NO_WINDOW_CHANGES);
   }
 
+  if (!mWidget->InitCompositor(this)) {
+    return false;
+  }
+
   reporter.SetSuccessful();
   return true;
 }
 
 TemporaryRef<DataTextureSource>
 CompositorD3D11::CreateDataTextureSource(TextureFlags aFlags)
 {
   RefPtr<DataTextureSource> result = new DataTextureSourceD3D11(gfx::SurfaceFormat::UNKNOWN,
--- a/gfx/layers/d3d9/CompositorD3D9.cpp
+++ b/gfx/layers/d3d9/CompositorD3D9.cpp
@@ -57,16 +57,20 @@ CompositorD3D9::Initialize()
 
   mSwapChain = mDeviceManager->
     CreateSwapChain((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW));
 
   if (!mSwapChain) {
     return false;
   }
 
+  if (!mWidget->InitCompositor(this)) {
+    return false;
+  }
+
   reporter.SetSuccessful();
   return true;
 }
 
 TextureFactoryIdentifier
 CompositorD3D9::GetTextureFactoryIdentifier()
 {
   TextureFactoryIdentifier ident;
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -535,16 +535,17 @@ public:
   }
   NSRect            DevPixelsToCocoaPoints(const nsIntRect& aRect) const {
     return nsCocoaUtils::DevPixelsToCocoaPoints(aRect, BackingScaleFactor());
   }
 
   mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing() override;
   void EndRemoteDrawing() override;
   void CleanupRemoteDrawing() override;
+  bool InitCompositor(mozilla::layers::Compositor* aCompositor) override;
 
   APZCTreeManager* APZCTM() { return mAPZC ; }
 
   NS_IMETHOD StartPluginIME(const mozilla::WidgetKeyboardEvent& aKeyboardEvent,
                             int32_t aPanelX, int32_t aPanelY,
                             nsString& aCommitted) override;
 
   NS_IMETHOD SetPluginFocused(bool& aFocused) override;
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -2582,16 +2582,18 @@ nsChildView::EnsureVibrancyManager()
     mVibrancyManager = MakeUnique<VibrancyManager>(*this, mView);
   }
   return *mVibrancyManager;
 }
 
 TemporaryRef<gfx::DrawTarget>
 nsChildView::StartRemoteDrawing()
 {
+  // should have created the GLPresenter in InitCompositor.
+  MOZ_ASSERT(mGLPresenter);
   if (!mGLPresenter) {
     mGLPresenter = GLPresenter::CreateForWindow(this);
 
     if (!mGLPresenter) {
       return nullptr;
     }
   }
 
@@ -2626,16 +2628,29 @@ nsChildView::CleanupRemoteDrawing()
 {
   mBasicCompositorImage = nullptr;
   mCornerMaskImage = nullptr;
   mResizerImage = nullptr;
   mTitlebarImage = nullptr;
   mGLPresenter = nullptr;
 }
 
+bool
+nsChildView::InitCompositor(Compositor* aCompositor)
+{
+  if (aCompositor->GetBackendType() == LayersBackend::LAYERS_BASIC) {
+    if (!mGLPresenter) {
+      mGLPresenter = GLPresenter::CreateForWindow(this);
+    }
+
+    return !!mGLPresenter;
+  }
+  return true;
+}
+
 void
 nsChildView::DoRemoteComposition(const nsIntRect& aRenderRect)
 {
   if (![(ChildView*)mView preRender:mGLPresenter->GetNSOpenGLContext()]) {
     return;
   }
   mGLPresenter->BeginFrame(aRenderRect.Size());
 
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1164,16 +1164,20 @@ void nsBaseWidget::CreateCompositor(int 
       backendHints, 0, &textureFactoryIdentifier, &success);
   }
 
   ShadowLayerForwarder* lf = lm->AsShadowForwarder();
 
   if (!success || !lf) {
     NS_WARNING("Failed to create an OMT compositor.");
     DestroyCompositor();
+    mLayerManager = nullptr;
+    mCompositorChild = nullptr;
+    mCompositorParent = nullptr;
+    mCompositorVsyncDispatcher = nullptr;
     return;
   }
 
   lf->SetShadowManager(shadowManager);
   lf->IdentifyTextureHost(textureFactoryIdentifier);
   ImageBridgeChild::IdentifyCompositorTextureHost(textureFactoryIdentifier);
   WindowUsesOMTC();
 
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -41,16 +41,17 @@ class CompositorVsyncDispatcher;
 namespace dom {
 class TabChild;
 }
 namespace plugins {
 class PluginWidgetChild;
 }
 namespace layers {
 class Composer2D;
+class Compositor;
 class CompositorChild;
 class LayerManager;
 class LayerManagerComposite;
 class PLayerTransactionChild;
 struct ScrollableLayerGuid;
 }
 namespace gfx {
 class DrawTarget;
@@ -1653,16 +1654,26 @@ class nsIWidget : public nsISupports {
      * StartRemoteDrawing reaches the screen.
      *
      * Called by BasicCompositor on the compositor thread for OMTC drawing
      * after each composition.
      */
     virtual void EndRemoteDrawing() = 0;
 
     /**
+     * A hook for the widget to prepare a Compositor, during the latter's initialization.
+     *
+     * If this method returns true, it means that the widget will be able to
+     * present frames from the compoositor.
+     * Returning false will cause the compositor's initialization to fail, and
+     * a different compositor backend will be used (if any).
+     */
+    virtual bool InitCompositor(mozilla::layers::Compositor*) { return true; }
+
+    /**
      * Clean up any resources used by Start/EndRemoteDrawing.
      *
      * Called by BasicCompositor on the compositor thread for OMTC drawing
      * when the compositor is destroyed.
      */
     virtual void CleanupRemoteDrawing() = 0;
 
     /**