Bug 1323316 - Use ANGLE for WebRender on Windows. r=jrmuizel,kats
authorSotaro Ikeda <sikeda@mozilla.com>
Wed, 29 Mar 2017 10:14:19 -0400
changeset 553343 69a8dd0935e25869d9f33440d92f317535843e09
parent 553342 2cdfeef068e14815b5c675cfb485e16ea3718804
child 553344 4c7c05a49f3ce40aa0969beccb397380a8907f4a
child 553347 03d8c5461924c7dd15b6d9fc19061e85fb57fd37
child 553356 4054e9c37e66422bfc19c965dad4a30212e81bde
push id51601
push userfelipc@gmail.com
push dateWed, 29 Mar 2017 21:00:13 +0000
reviewersjrmuizel, kats
bugs1323316
milestone55.0a1
Bug 1323316 - Use ANGLE for WebRender on Windows. r=jrmuizel,kats MozReview-Commit-ID: Fg5GEWNRtIu
gfx/config/gfxVars.h
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLLibraryEGL.cpp
gfx/ipc/GraphicsMessages.ipdlh
gfx/thebes/gfxPlatform.cpp
gfx/webrender_bindings/WebRenderAPI.cpp
modules/libpref/init/all.js
--- a/gfx/config/gfxVars.h
+++ b/gfx/config/gfxVars.h
@@ -29,16 +29,19 @@ class gfxVarReceiver;
   _(UseXRender,                 bool,             false)                \
   _(OffscreenFormat,            gfxImageFormat,   mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32) \
   _(RequiresAcceleratedGLContextForCompositorOGL, bool, false)          \
   _(CanUseHardwareVideoDecoding, bool,            false)                \
   _(PDMWMFDisableD3D11Dlls,     nsCString,        nsCString())          \
   _(PDMWMFDisableD3D9Dlls,      nsCString,        nsCString())          \
   _(DXInterop2Blocked,          bool,             false)                \
   _(UseWebRender,               bool,             false)                \
+  _(UseWebRenderANGLE,          bool,             false)                \
+  _(ScreenDepth,                int32_t,          0)                    \
+  _(GREDirectory,               nsCString,        nsCString())          \
 
   /* Add new entries above this line. */
 
 // Some graphics settings are computed on the UI process and must be
 // communicated to content and GPU processes. gfxVars helps facilitate
 // this. Its function is similar to gfxPrefs, except rather than hold
 // user preferences, it holds dynamically computed values.
 //
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -6,32 +6,36 @@
 #if defined(MOZ_WIDGET_GTK)
     #include <gdk/gdkx.h>
     // we're using default display for now
     #define GET_NATIVE_WINDOW_FROM_REAL_WIDGET(aWidget) ((EGLNativeWindowType)GDK_WINDOW_XID((GdkWindow*)aWidget->GetNativeData(NS_NATIVE_WINDOW)))
     #define GET_NATIVE_WINDOW_FROM_COMPOSITOR_WIDGET(aWidget) ((EGLNativeWindowType)GDK_WINDOW_XID((GdkWindow*)aWidget->RealWidget()->GetNativeData(NS_NATIVE_WINDOW)))
 #elif defined(MOZ_WIDGET_ANDROID)
     #define GET_NATIVE_WINDOW_FROM_REAL_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_JAVA_SURFACE))
     #define GET_NATIVE_WINDOW_FROM_COMPOSITOR_WIDGET(aWidget) (aWidget->AsAndroid()->GetEGLNativeWindow())
+#elif defined(XP_WIN)
+    #define GET_NATIVE_WINDOW_FROM_REAL_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
+    #define GET_NATIVE_WINDOW_FROM_COMPOSITOR_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->AsWindows()->GetHwnd())
 #else
     #define GET_NATIVE_WINDOW_FROM_REAL_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
     #define GET_NATIVE_WINDOW_FROM_COMPOSITOR_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->RealWidget()->GetNativeData(NS_NATIVE_WINDOW))
 #endif
 
 #if defined(XP_UNIX)
     #ifdef MOZ_WIDGET_ANDROID
         #include <android/native_window.h>
         #include <android/native_window_jni.h>
         #include "mozilla/widget/AndroidCompositorWidget.h"
     #endif
 
     #define GLES2_LIB "libGLESv2.so"
     #define GLES2_LIB2 "libGLESv2.so.2"
 
 #elif defined(XP_WIN)
+    #include "mozilla/widget/WinCompositorWidget.h"
     #include "nsIFile.h"
 
     #define GLES2_LIB "libGLESv2.dll"
 
     #ifndef WIN32_LEAN_AND_MEAN
         #define WIN32_LEAN_AND_MEAN 1
     #endif
 
@@ -46,16 +50,17 @@
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
 #include "GLBlitHelper.h"
 #include "GLContextEGL.h"
 #include "GLContextProvider.h"
 #include "GLLibraryEGL.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/gfx/gfxVars.h"
 #include "mozilla/layers/CompositorOptions.h"
 #include "mozilla/widget/CompositorWidget.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
 #include "nsThreadUtils.h"
 #include "ScopedGLHelpers.h"
 #include "TextureImageEGL.h"
 
@@ -688,17 +693,17 @@ CreateConfig(EGLConfig* aConfig, int32_t
 // Return true if a suitable EGLConfig was found and pass it out
 // through aConfig.  Return false otherwise.
 //
 // NB: It's entirely legal for the returned EGLConfig to be valid yet
 // have the value null.
 static bool
 CreateConfig(EGLConfig* aConfig)
 {
-    int32_t depth = gfxPlatform::GetPlatform()->GetScreenDepth();
+    int32_t depth = gfxVars::ScreenDepth();
     if (!CreateConfig(aConfig, depth)) {
 #ifdef MOZ_WIDGET_ANDROID
         // Bug 736005
         // Android doesn't always support 16 bit so also try 24 bit
         if (depth == 16) {
             return CreateConfig(aConfig, 24);
         }
         // Bug 970096
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -19,16 +19,17 @@
 #include "nsDirectoryServiceUtils.h"
 #include "nsIGfxInfo.h"
 #include "nsPrintfCString.h"
 #ifdef XP_WIN
 #include "nsWindowsHelpers.h"
 #endif
 #include "OGLShaderProgram.h"
 #include "prenv.h"
+#include "prsystem.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "gfxPrefs.h"
 #include "ScopedGLHelpers.h"
 
 namespace mozilla {
 namespace gl {
 
@@ -96,30 +97,24 @@ static PRLibrary* LoadApitraceLibrary()
 
 #endif // ANDROID
 
 #ifdef XP_WIN
 // see the comment in GLLibraryEGL::EnsureInitialized() for the rationale here.
 static PRLibrary*
 LoadLibraryForEGLOnWindows(const nsAString& filename)
 {
-    nsCOMPtr<nsIFile> file;
-    nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(file));
-    if (NS_FAILED(rv))
-        return nullptr;
+    nsAutoCString path(gfx::gfxVars::GREDirectory());
+    path.Append(PR_GetDirectorySeparator());
+    path.Append(ToNewUTF8String(filename));
 
-    file->Append(filename);
-    PRLibrary* lib = nullptr;
-    rv = file->Load(&lib);
-    if (NS_FAILED(rv)) {
-        nsPrintfCString msg("Failed to load %s - Expect EGL initialization to fail",
-                            NS_LossyConvertUTF16toASCII(filename).get());
-        NS_WARNING(msg.get());
-    }
-    return lib;
+    PRLibSpec lspec;
+    lspec.type = PR_LibSpec_Pathname;
+    lspec.value.pathname = path.get();
+    return PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
 }
 
 #endif // XP_WIN
 
 static EGLDisplay
 GetAndInitWARPDisplay(GLLibraryEGL& egl, void* displayType)
 {
     EGLint attrib_list[] = {  LOCAL_EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
@@ -236,16 +231,20 @@ private:
 
 AngleErrorReporting gAngleErrorReporter;
 
 static EGLDisplay
 GetAndInitDisplayForAccelANGLE(GLLibraryEGL& egl, nsACString* const out_failureId)
 {
     EGLDisplay ret = 0;
 
+    if (wr::RenderThread::IsInRenderThread()) {
+        return GetAndInitDisplay(egl, LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
+    }
+
     FeatureState& d3d11ANGLE = gfxConfig::GetFeature(Feature::D3D11_HW_ANGLE);
 
     if (!gfxPrefs::WebGLANGLETryD3D11())
         d3d11ANGLE.UserDisable("User disabled D3D11 ANGLE by pref",
                                NS_LITERAL_CSTRING("FAILURE_ID_ANGLE_PREF"));
 
     if (gfxPrefs::WebGLANGLEForceD3D11())
         d3d11ANGLE.UserForceEnable("User force-enabled D3D11 ANGLE on disabled hardware");
--- a/gfx/ipc/GraphicsMessages.ipdlh
+++ b/gfx/ipc/GraphicsMessages.ipdlh
@@ -68,16 +68,17 @@ struct GPUDeviceData
 
 union GfxVarValue
 {
   BackendType;
   bool;
   gfxImageFormat;
   IntSize;
   nsCString;
+  int32_t;
 };
 
 struct GfxVarUpdate
 {
   size_t index;
   GfxVarValue value;
 };
 
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -616,16 +616,26 @@ gfxPlatform::Init()
 
       if (Preferences::GetBool("media.wmf.skip-blacklist")) {
         gfxVars::SetPDMWMFDisableD3D11Dlls(nsCString());
         gfxVars::SetPDMWMFDisableD3D9Dlls(nsCString());
       } else {
         gfxVars::SetPDMWMFDisableD3D11Dlls(Preferences::GetCString("media.wmf.disable-d3d11-for-dlls"));
         gfxVars::SetPDMWMFDisableD3D9Dlls(Preferences::GetCString("media.wmf.disable-d3d9-for-dlls"));
       }
+
+      nsCOMPtr<nsIFile> file;
+      nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(file));
+      if (NS_FAILED(rv)) {
+        gfxVars::SetGREDirectory(nsCString());
+      } else {
+        nsAutoCString nativePath;
+        file->GetNativePath(nativePath);
+        gfxVars::SetGREDirectory(nsCString(nativePath));
+      }
     }
 
     // Drop a note in the crash report if we end up forcing an option that could
     // destabilize things.  New items should be appended at the end (of an existing
     // or in a new section), so that we don't have to know the version to interpret
     // these cryptic strings.
     {
       nsAutoCString forcedPrefs;
@@ -1249,16 +1259,19 @@ gfxPlatform::PopulateScreenInfo()
   nsCOMPtr<nsIScreen> screen;
   manager->GetPrimaryScreen(getter_AddRefs(screen));
   if (!screen) {
     // This can happen in xpcshell, for instance
     return;
   }
 
   screen->GetColorDepth(&mScreenDepth);
+  if (XRE_IsParentProcess()) {
+    gfxVars::SetScreenDepth(mScreenDepth);
+  }
 
   int left, top;
   screen->GetRect(&left, &top, &mScreenSize.width, &mScreenSize.height);
 }
 
 bool
 gfxPlatform::SupportsAzureContentForDrawTarget(DrawTarget* aTarget)
 {
@@ -2322,16 +2335,29 @@ gfxPlatform::InitWebRenderConfig()
 
 #ifndef MOZ_BUILD_WEBRENDER
   featureWebRender.ForceDisable(
     FeatureStatus::Unavailable,
     "Build doesn't include WebRender",
     NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_WEBRENDER"));
 #endif
 
+#ifdef XP_WIN
+  if (Preferences::GetBool("gfx.webrender.force-angle", false)) {
+    if (!gfxConfig::IsEnabled(Feature::D3D11_HW_ANGLE)) {
+      featureWebRender.ForceDisable(
+        FeatureStatus::Unavailable,
+        "ANGLE is disabled",
+        NS_LITERAL_CSTRING("FEATURE_FAILURE_ANGLE_DISABLED"));
+    } else {
+      gfxVars::SetUseWebRenderANGLE(gfxConfig::IsEnabled(Feature::WEBRENDER));
+    }
+  }
+#endif
+
   // gfxFeature is not usable in the GPU process, so we use gfxVars to transmit this feature
   if (gfxConfig::IsEnabled(Feature::WEBRENDER)) {
     gfxVars::SetUseWebRender(true);
     reporter.SetSuccessful();
   }
 }
 
 bool
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebRenderAPI.h"
 #include "mozilla/webrender/RendererOGL.h"
+#include "mozilla/gfx/gfxVars.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/widget/CompositorWidget.h"
 #include "mozilla/widget/CompositorWidget.h"
 #include "mozilla/layers/SynchronousTask.h"
 
 namespace mozilla {
 namespace wr {
 
@@ -39,17 +40,27 @@ public:
   {
     MOZ_COUNT_DTOR(NewRenderer);
   }
 
   virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
   {
     layers::AutoCompleteTask complete(mTask);
 
-    RefPtr<gl::GLContext> gl = gl::GLContextProvider::CreateForCompositorWidget(mCompositorWidget, true);
+    RefPtr<gl::GLContext> gl;
+    if (gfxVars::UseWebRenderANGLE()) {
+      gl = gl::GLContextProviderEGL::CreateForCompositorWidget(mCompositorWidget, true);
+      if (!gl || !gl->IsANGLE()) {
+        gfxCriticalNote << "Failed ANGLE GL context creation for WebRender: " << hexa(gl.get());
+        return;
+      }
+    }
+    if (!gl) {
+      gl = gl::GLContextProvider::CreateForCompositorWidget(mCompositorWidget, true);
+    }
     if (!gl || !gl->MakeCurrent()) {
       gfxCriticalNote << "Failed GL context creation for WebRender: " << hexa(gl.get());
       return;
     }
 
     gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, mMaxTextureSize);
     *mUseANGLE = gl->IsANGLE();
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -820,16 +820,19 @@ pref("gfx.logging.peak-texture-usage.ena
 
 pref("gfx.ycbcr.accurate-conversion", false);
 
 #ifdef MOZ_ENABLE_WEBRENDER
 pref("gfx.webrender.enabled", true);
 #else
 pref("gfx.webrender.enabled", false);
 #endif
+#ifdef XP_WIN
+pref("gfx.webrender.force-angle", true);
+#endif
 
 pref("accessibility.browsewithcaret", false);
 pref("accessibility.warn_on_browsewithcaret", true);
 
 pref("accessibility.browsewithcaret_shortcut.enabled", true);
 
 #ifndef XP_MACOSX
 // Tab focus model bit field: