Bug 1287182 - log angle failureid via ANGLEPlatformInitialize. r=jrmuizel
authorBenoit Girard <b56girard@gmail.com>
Tue, 19 Jul 2016 11:48:08 -0400
changeset 345758 d7f56af6ddd22743c7cce4c9fdb2a72df3a16dea
parent 345757 786569c41cd1b791bfc17c39cf65357c577eebc3
child 345759 2475145b53b60a5294a5a624982004bf02132f90
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1287182
milestone50.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 1287182 - log angle failureid via ANGLEPlatformInitialize. r=jrmuizel MozReview-Commit-ID: 7Cg8AOVij1z
gfx/angle/moz.build
gfx/gl/GLLibraryEGL.cpp
gfx/gl/GLLibraryEGL.h
--- a/gfx/angle/moz.build
+++ b/gfx/angle/moz.build
@@ -158,17 +158,18 @@ DEFINES['EGLAPI'] = ""
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     DIRS += [ 'src/libANGLE', 'src/libGLESv2', 'src/libEGL' ]
 
 DEFINES['ANGLE_ENABLE_HLSL'] = "1"
 DEFINES['ANGLE_ENABLE_GLSL'] = "1"
 DEFINES['ANGLE_ENABLE_ESSL'] = "1"
 DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
 
-EXPORTS.angle += [ 'include/GLSLANG/ShaderLang.h', 'include/GLSLANG/ShaderVars.h' ]
+EXPORTS.angle += [ 'include/GLSLANG/ShaderLang.h', 'include/GLSLANG/ShaderVars.h', 'include/platform/Platform.h' ]
+
 EXPORTS.angle.KHR += [ 'include/KHR/khrplatform.h' ]
 
 LOCAL_INCLUDES += [ 'include', 'src', 'src/common/third_party/numerics' ]
 
 # We allow warnings for third-party code that can be updated from upstream.
 ALLOW_COMPILER_WARNINGS = True
 
 FINAL_LIBRARY = 'gkmedias'
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -1,20 +1,23 @@
 /* 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 "GLLibraryEGL.h"
 
+#include "angle/Platform.h"
 #include "gfxConfig.h"
 #include "gfxCrashReporterUtils.h"
 #include "gfxUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Telemetry.h"
+#include "mozilla/Tokenizer.h"
+#include "mozilla/ScopeExit.h"
 #include "mozilla/unused.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsIGfxInfo.h"
 #include "nsPrintfCString.h"
 #ifdef XP_WIN
 #include "nsWindowsHelpers.h"
 #endif
@@ -167,32 +170,75 @@ GetAndInitDisplay(GLLibraryEGL& egl, voi
         return EGL_NO_DISPLAY;
 
     if (!egl.fInitialize(display, nullptr, nullptr))
         return EGL_NO_DISPLAY;
 
     return display;
 }
 
+class AngleErrorReporting: public angle::Platform {
+public:
+    AngleErrorReporting(nsACString *aFailureId)
+        : mFailureId(aFailureId)
+    {}
+
+    void logError(const char *errorMessage) override
+    {
+        nsCString str(errorMessage);
+        Tokenizer tokenizer(str);
+
+        // Parse "ANGLE Display::initialize error " << error.getID() << ": "
+        //       << error.getMessage()
+        nsCString currWord;
+        Tokenizer::Token intToken;
+        if (tokenizer.CheckWord("ANGLE") &&
+            tokenizer.CheckWhite() &&
+            tokenizer.CheckWord("Display") &&
+            tokenizer.CheckChar(':') &&
+            tokenizer.CheckChar(':') &&
+            tokenizer.CheckWord("initialize") &&
+            tokenizer.CheckWhite() &&
+            tokenizer.CheckWord("error") &&
+            tokenizer.CheckWhite() &&
+            tokenizer.Check(Tokenizer::TOKEN_INTEGER, intToken)) {
+            *mFailureId = "FAILURE_ID_ANGLE_ID_";
+            mFailureId->AppendPrintf("%i", intToken.AsInteger());
+        } else {
+            *mFailureId = "FAILURE_ID_ANGLE_UNKNOWN";
+        }
+    }
+private:
+    nsACString* mFailureId;
+};
+
 static EGLDisplay
-GetAndInitDisplayForAccelANGLE(GLLibraryEGL& egl)
+GetAndInitDisplayForAccelANGLE(GLLibraryEGL& egl, nsACString* const out_failureId)
 {
     EGLDisplay ret = 0;
 
     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");
 
-    if (gfxConfig::IsForcedOnByUser(Feature::D3D11_HW_ANGLE))
+    AngleErrorReporting errorReporter(out_failureId);
+
+    egl.fANGLEPlatformInitialize(&errorReporter);
+    auto guardShutdown = mozilla::MakeScopeExit([&] {
+        egl.fANGLEPlatformShutdown();
+    });
+
+    if (gfxConfig::IsForcedOnByUser(Feature::D3D11_HW_ANGLE)) {
         return GetAndInitDisplay(egl, LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
+    }
 
     if (d3d11ANGLE.IsEnabled()) {
         ret = GetAndInitDisplay(egl, LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
     }
 
     if (!ret) {
         ret = GetAndInitDisplay(egl, EGL_DEFAULT_DISPLAY);
     }
@@ -367,17 +413,19 @@ GLLibraryEGL::EnsureInitialized(bool for
     InitClientExtensions();
 
     const auto lookupFunction =
         (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;
 
     // Client exts are ready. (But not display exts!)
     if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
         GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
-            { (PRFuncPtr*)&mSymbols.fGetPlatformDisplayEXT, { "eglGetPlatformDisplayEXT", nullptr } },
+            { (PRFuncPtr*)&mSymbols.fANGLEPlatformInitialize, { "ANGLEPlatformInitialize", nullptr } },
+            { (PRFuncPtr*)&mSymbols.fANGLEPlatformShutdown,   { "ANGLEPlatformShutdown", nullptr } },
+            { (PRFuncPtr*)&mSymbols.fGetPlatformDisplayEXT,   { "eglGetPlatformDisplayEXT", nullptr } },
             { nullptr, { nullptr } }
         };
 
         bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                     &d3dSymbols[0],
                                                     lookupFunction);
         if (!success) {
             NS_ERROR("EGL supports ANGLE_platform_angle_d3d without exposing its functions!");
@@ -419,17 +467,17 @@ GLLibraryEGL::EnsureInitialized(bool for
                 if (out_failureId->IsEmpty()) {
                     *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WARP_FALLBACK");
                 }
                 NS_ERROR("Fallback WARP ANGLE context failed to initialize.");
                 return false;
             }
 
             // Hardware accelerated ANGLE path
-            chosenDisplay = GetAndInitDisplayForAccelANGLE(*this);
+            chosenDisplay = GetAndInitDisplayForAccelANGLE(*this, out_failureId);
         }
     } else {
         chosenDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);
     }
 
     if (!chosenDisplay) {
         if (out_failureId->IsEmpty()) {
             *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_DISPLAY");
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -47,16 +47,20 @@
 #endif
 
 #if defined(MOZ_X11)
 #define EGL_DEFAULT_DISPLAY  ((EGLNativeDisplayType)mozilla::DefaultXDisplay())
 #else
 #define EGL_DEFAULT_DISPLAY  ((EGLNativeDisplayType)0)
 #endif
 
+namespace angle {
+class Platform;
+}
+
 namespace mozilla {
 
 namespace gfx {
 class DataSourceSurface;
 }
 
 namespace gl {
 
@@ -111,16 +115,18 @@ public:
           mEGLDisplay(EGL_NO_DISPLAY),
           mIsANGLE(false),
           mIsWARP(false)
     {
         ClearSymbols();
     }
 
     void ClearSymbols() {
+        mSymbols.fANGLEPlatformInitialize = nullptr;
+        mSymbols.fANGLEPlatformShutdown = nullptr;
         mSymbols.fGetDisplay = nullptr;
         mSymbols.fGetPlatformDisplayEXT = nullptr;
         mSymbols.fTerminate = nullptr;
         mSymbols.fGetCurrentSurface = nullptr;
         mSymbols.fGetCurrentContext = nullptr;
         mSymbols.fMakeCurrent = nullptr;
         mSymbols.fDestroyContext = nullptr;
         mSymbols.fCreateContext = nullptr;
@@ -493,16 +499,32 @@ public:
     {
         MOZ_ASSERT(mSymbols.fDupNativeFenceFDANDROID);
         BEFORE_GL_CALL;
         EGLint ret = mSymbols.fDupNativeFenceFDANDROID(dpy, sync);
         AFTER_GL_CALL;
         return ret;
     }
 
+    void fANGLEPlatformInitialize(angle::Platform* platform)
+    {
+        MOZ_ASSERT(mSymbols.fANGLEPlatformInitialize);
+        BEFORE_GL_CALL;
+        mSymbols.fANGLEPlatformInitialize(platform);
+        AFTER_GL_CALL;
+    }
+
+    void fANGLEPlatformShutdown()
+    {
+        MOZ_ASSERT(mSymbols.fANGLEPlatformShutdown);
+        BEFORE_GL_CALL;
+        mSymbols.fANGLEPlatformShutdown();
+        AFTER_GL_CALL;
+    }
+
     EGLDisplay Display() {
         MOZ_ASSERT(mInitialized);
         return mEGLDisplay;
     }
 
     bool IsANGLE() const {
         MOZ_ASSERT(mInitialized);
         return mIsANGLE;
@@ -617,16 +639,21 @@ public:
         typedef EGLBoolean (GLAPIENTRY * pfnDestroySync)(EGLDisplay dpy, EGLSync sync);
         pfnDestroySync fDestroySync;
         typedef EGLint (GLAPIENTRY * pfnClientWaitSync)(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
         pfnClientWaitSync fClientWaitSync;
         typedef EGLBoolean (GLAPIENTRY * pfnGetSyncAttrib)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint* value);
         pfnGetSyncAttrib fGetSyncAttrib;
         typedef EGLint (GLAPIENTRY * pfnDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSync sync);
         pfnDupNativeFenceFDANDROID fDupNativeFenceFDANDROID;
+
+        typedef void (GLAPIENTRY * pfnANGLEPlatformInitialize)(angle::Platform* platform);
+        pfnANGLEPlatformInitialize fANGLEPlatformInitialize;
+        typedef void (GLAPIENTRY * pfnANGLEPlatformShutdown)();
+        pfnANGLEPlatformShutdown fANGLEPlatformShutdown;
     } mSymbols;
 
 #ifdef DEBUG
     static void BeforeGLCall(const char* glFunction);
     static void AfterGLCall(const char* glFunction);
 #endif
 
 #ifdef MOZ_B2G