Don't use Direct2D if CompositorD3D11::Initialize fails. (bug 1208638, r=jrmuizel)
authorDavid Anderson <danderson@mozilla.com>
Thu, 01 Oct 2015 23:06:43 -0700
changeset 299075 17da3f535e295d8f104e17ac035c3ff176cdbd54
parent 299074 69e9851fe871c816bf37fe80497c78dc25777487
child 299076 590404aac3573ac8def5d8caf2af61f013b79338
push id5392
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:08:23 +0000
treeherdermozilla-beta@16ce8562a975 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1208638
milestone44.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
Don't use Direct2D if CompositorD3D11::Initialize fails. (bug 1208638, r=jrmuizel)
dom/svg/nsSVGPathGeometryElement.cpp
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/d3d11/TextureD3D11.cpp
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxPlatformGtk.h
gfx/thebes/gfxWindowsPlatform.cpp
gfx/thebes/gfxWindowsPlatform.h
--- a/dom/svg/nsSVGPathGeometryElement.cpp
+++ b/dom/svg/nsSVGPathGeometryElement.cpp
@@ -76,17 +76,17 @@ nsSVGPathGeometryElement::GetMarkPoints(
 }
 
 already_AddRefed<Path>
 nsSVGPathGeometryElement::GetOrBuildPath(const DrawTarget& aDrawTarget,
                                          FillRule aFillRule)
 {
   // We only cache the path if it matches the backend used for screen painting:
   bool cacheable  = aDrawTarget.GetBackendType() ==
-                      gfxPlatform::GetPlatform()->GetContentBackend();
+                    gfxPlatform::GetPlatform()->GetDefaultContentBackend();
 
   // Checking for and returning mCachedPath before checking the pref means
   // that the pref is only live on page reload (or app restart for SVG in
   // chrome). The benefit is that we avoid causing a CPU memory cache miss by
   // looking at the global variable that the pref's stored in.
   if (cacheable && mCachedPath) {
     if (aDrawTarget.GetBackendType() == mCachedPath->GetBackendType()) {
       RefPtr<Path> path(mCachedPath);
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -69,17 +69,17 @@ public:
 
 BasicCompositor::BasicCompositor(nsIWidget *aWidget)
   : mWidget(aWidget)
 {
   MOZ_COUNT_CTOR(BasicCompositor);
   SetBackend(LayersBackend::LAYERS_BASIC);
 
   mMaxTextureSize =
-    Factory::GetMaxSurfaceSize(gfxPlatform::GetPlatform()->GetContentBackend());
+    Factory::GetMaxSurfaceSize(gfxPlatform::GetPlatform()->GetContentBackendFor(LayersBackend::LAYERS_BASIC));
 }
 
 BasicCompositor::~BasicCompositor()
 {
   MOZ_COUNT_DTOR(BasicCompositor);
 }
 
 bool
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -338,48 +338,48 @@ CreateBufferTextureClient(ISurfaceAlloca
   }
   RefPtr<BufferTextureClient> result = new ShmemTextureClient(aAllocator, aFormat,
                                                               aMoz2DBackend,
                                                               aTextureFlags);
   return result.forget();
 }
 
 static inline gfx::BackendType
-BackendTypeForBackendSelector(BackendSelector aSelector)
+BackendTypeForBackendSelector(LayersBackend aLayersBackend, BackendSelector aSelector)
 {
   switch (aSelector) {
     case BackendSelector::Canvas:
       return gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
     case BackendSelector::Content:
-      return gfxPlatform::GetPlatform()->GetContentBackend();
+      return gfxPlatform::GetPlatform()->GetContentBackendFor(aLayersBackend);
     default:
       MOZ_ASSERT_UNREACHABLE("Unknown backend selector");
       return gfx::BackendType::NONE;
   }
 };
 
 // static
 already_AddRefed<TextureClient>
 TextureClient::CreateForDrawing(ISurfaceAllocator* aAllocator,
                                 gfx::SurfaceFormat aFormat,
                                 gfx::IntSize aSize,
                                 BackendSelector aSelector,
                                 TextureFlags aTextureFlags,
                                 TextureAllocationFlags aAllocFlags)
 {
-  gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(aSelector);
+  LayersBackend parentBackend = aAllocator->GetCompositorBackendType();
+  gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(parentBackend, aSelector);
 
   RefPtr<TextureClient> texture;
 
 #if defined(MOZ_WIDGET_GONK) || defined(XP_WIN)
   int32_t maxTextureSize = aAllocator->GetMaxTextureSize();
 #endif
 
 #ifdef XP_WIN
-  LayersBackend parentBackend = aAllocator->GetCompositorBackendType();
   if (parentBackend == LayersBackend::LAYERS_D3D11 &&
       (moz2DBackend == gfx::BackendType::DIRECT2D ||
        moz2DBackend == gfx::BackendType::DIRECT2D1_1) &&
       aSize.width <= maxTextureSize &&
       aSize.height <= maxTextureSize)
   {
     texture = new TextureClientD3D11(aAllocator, aFormat, aTextureFlags);
   }
@@ -402,17 +402,16 @@ TextureClient::CreateForDrawing(ISurface
       texture = new TextureClientMemoryDIB(aAllocator, aFormat, aTextureFlags);
     } else {
       texture = new TextureClientShmemDIB(aAllocator, aFormat, aTextureFlags);
     }
   }
 #endif
 
 #ifdef MOZ_X11
-  LayersBackend parentBackend = aAllocator->GetCompositorBackendType();
   gfxSurfaceType type =
     gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType();
 
   if (parentBackend == LayersBackend::LAYERS_BASIC &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       type == gfxSurfaceType::Xlib)
   {
     texture = new TextureClientX11(aAllocator, aFormat, aTextureFlags);
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -574,17 +574,18 @@ TextureClientD3D11::AllocateForSurface(g
     return false;
   }
 
   gfxWindowsPlatform* windowsPlatform = gfxWindowsPlatform::GetPlatform();
   ID3D11Device* d3d11device = windowsPlatform->GetD3D11DeviceForCurrentThread();
 
   // When we're not on the main thread we're not going to be using Direct2D
   // to access the contents of this texture client so we will always use D3D11.
-  bool haveD3d11Backend = windowsPlatform->GetContentBackend() == BackendType::DIRECT2D1_1 || !NS_IsMainThread();
+  BackendType backend = windowsPlatform->GetContentBackendFor(LayersBackend::LAYERS_D3D11);
+  bool haveD3d11Backend = (backend == BackendType::DIRECT2D1_1) || !NS_IsMainThread();
 
   if (haveD3d11Backend) {
     if (!AllocateD3D11Surface(d3d11device, aSize)) {
       return false;
     }
   } else {
     ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
 
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -266,17 +266,26 @@ public:
     virtual void GetAzureBackendInfo(mozilla::widget::InfoObject &aObj) {
       aObj.DefineProperty("AzureCanvasBackend", GetBackendName(mPreferredCanvasBackend));
       aObj.DefineProperty("AzureSkiaAccelerated", UseAcceleratedSkiaCanvas());
       aObj.DefineProperty("AzureFallbackCanvasBackend", GetBackendName(mFallbackCanvasBackend));
       aObj.DefineProperty("AzureContentBackend", GetBackendName(mContentBackend));
     }
     void GetApzSupportInfo(mozilla::widget::InfoObject& aObj);
 
-    mozilla::gfx::BackendType GetContentBackend() {
+    // Get the default content backend that will be used with the default
+    // compositor. If the compositor is known when calling this function,
+    // GetContentBackendFor() should be called instead.
+    mozilla::gfx::BackendType GetDefaultContentBackend() {
+      return mContentBackend;
+    }
+
+    // Return the best content backend available that is compatible with the
+    // given layers backend.
+    virtual mozilla::gfx::BackendType GetContentBackendFor(mozilla::layers::LayersBackend aLayers) {
       return mContentBackend;
     }
 
     mozilla::gfx::BackendType GetPreferredCanvasBackend() {
       return mPreferredCanvasBackend;
     }
     mozilla::gfx::BackendType GetFallbackCanvasBackend() {
       return mFallbackCanvasBackend;
--- a/gfx/thebes/gfxPlatformGtk.h
+++ b/gfx/thebes/gfxPlatformGtk.h
@@ -94,18 +94,18 @@ public:
     static GdkDrawable *GetGdkDrawable(cairo_surface_t *target);
 #endif
 
     static int32_t GetDPI();
     static double  GetDPIScale();
 
     bool UseXRender() {
 #if defined(MOZ_X11)
-        if (GetContentBackend() != mozilla::gfx::BackendType::NONE &&
-            GetContentBackend() != mozilla::gfx::BackendType::CAIRO)
+        if (GetDefaultContentBackend() != mozilla::gfx::BackendType::NONE &&
+            GetDefaultContentBackend() != mozilla::gfx::BackendType::CAIRO)
             return false;
 
         return sUseXRender;
 #else
         return false;
 #endif
     }
 
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -507,22 +507,24 @@ gfxWindowsPlatform::HandleDeviceReset()
 
   // Since we got a device reset, we must ask the parent process for an updated
   // list of which devices to create.
   UpdateDeviceInitData();
   InitializeDevices();
   return true;
 }
 
+static const BackendType SOFTWARE_BACKEND = BackendType::CAIRO;
+
 void
 gfxWindowsPlatform::UpdateBackendPrefs()
 {
-  uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO);
-  uint32_t contentMask = BackendTypeBit(BackendType::CAIRO);
-  BackendType defaultBackend = BackendType::CAIRO;
+  uint32_t canvasMask = BackendTypeBit(SOFTWARE_BACKEND);
+  uint32_t contentMask = BackendTypeBit(SOFTWARE_BACKEND);
+  BackendType defaultBackend = SOFTWARE_BACKEND;
   if (GetD2DStatus() == FeatureStatus::Available) {
     mRenderMode = RENDER_DIRECT2D;
     canvasMask |= BackendTypeBit(BackendType::DIRECT2D);
     contentMask |= BackendTypeBit(BackendType::DIRECT2D);
     if (GetD2D1Status() == FeatureStatus::Available) {
       contentMask |= BackendTypeBit(BackendType::DIRECT2D1_1);
       canvasMask |= BackendTypeBit(BackendType::DIRECT2D1_1);
       defaultBackend = BackendType::DIRECT2D1_1;
@@ -545,16 +547,27 @@ gfxWindowsPlatform::UpdateRenderMode()
   UpdateBackendPrefs();
 
   if (didReset) {
     mScreenReferenceDrawTarget =
       CreateOffscreenContentDrawTarget(IntSize(1, 1), SurfaceFormat::B8G8R8A8);
   }
 }
 
+mozilla::gfx::BackendType
+gfxWindowsPlatform::GetContentBackendFor(mozilla::layers::LayersBackend aLayers)
+{
+  if (aLayers == LayersBackend::LAYERS_D3D11) {
+    return gfxPlatform::GetDefaultContentBackend();
+  }
+
+  // If we're not accelerated with D3D11, never use D2D.
+  return SOFTWARE_BACKEND;
+}
+
 #ifdef CAIRO_HAS_D2D_SURFACE
 HRESULT
 gfxWindowsPlatform::CreateDevice(nsRefPtr<IDXGIAdapter1> &adapter1,
                                  int featureLevelIndex)
 {
   nsModuleHandle d3d10module(LoadLibrarySystem32(L"d3d10_1.dll"));
   if (!d3d10module)
     return E_FAIL;
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -209,16 +209,18 @@ public:
 
     /**
      * Check whether format is supported on a platform or not (if unclear, returns true)
      */
     virtual bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags);
 
     virtual bool DidRenderingDeviceReset(DeviceResetReason* aResetReason = nullptr);
 
+    mozilla::gfx::BackendType GetContentBackendFor(mozilla::layers::LayersBackend aLayers) override;
+
     // ClearType is not always enabled even when available (e.g. Windows XP)
     // if either of these prefs are enabled and apply, use ClearType rendering
     bool UseClearTypeForDownloadableFonts();
     bool UseClearTypeAlways();
 
     static void GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion);
 
     // returns ClearType tuning information for each display