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>
Mon, 13 Jul 2015 16:46:48 +0200
changeset 281650 0956814d7faf96534e426d38a5739badf28b65d1
parent 281649 f4c4b6599968254014c9faf9cda20623986c3528
child 281651 566ea532f5526f2890acb6e4a2bee37485f6e78b
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, lmandel
bugs1180688
milestone41.0a2
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
@@ -534,16 +534,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
@@ -2557,16 +2557,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;
     }
   }
 
@@ -2601,16 +2603,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
@@ -1201,16 +1201,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
@@ -44,16 +44,17 @@ class WritingMode;
 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;
@@ -1713,16 +1714,26 @@ class nsIWidget : public nsISupports {
      * after each composition.
      */
     virtual void EndRemoteDrawing() = 0;
     virtual void EndRemoteDrawingInRegion(mozilla::gfx::DrawTarget* aDrawTarget, nsIntRegion& aInvalidRegion) {
       EndRemoteDrawing();
     }
 
     /**
+     * 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;
 
     /**