Bug 912196 - Fixes for D3D11 ANGLE. - r=kamidphish
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 08 Oct 2014 16:32:50 -0700
changeset 212597 942e71d1f271f59951d5970875e039f5d2b9cbbc
parent 212596 f9105d35ba70fe45f391f6ee291f9458c05c10e6
child 212598 51926ef0c382e859d8c9fe047c701d345c493f88
push id27721
push usercbook@mozilla.com
push dateTue, 28 Oct 2014 14:55:05 +0000
treeherdermozilla-central@c0ddb1b098ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskamidphish
bugs912196
milestone36.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 912196 - Fixes for D3D11 ANGLE. - r=kamidphish
dom/canvas/WebGLContext.cpp
gfx/gl/GLConsts.h
gfx/gl/GLContext.cpp
gfx/gl/GLDefs.h
gfx/gl/GLLibraryEGL.cpp
gfx/gl/GLLibraryEGL.h
gfx/gl/SharedSurfaceGL.cpp
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -1253,22 +1253,20 @@ void
 WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributes> &retval)
 {
     retval.SetNull();
     if (IsContextLost())
         return;
 
     dom::WebGLContextAttributes& result = retval.SetValue();
 
-    const PixelBufferFormat& format = gl->GetPixelFormat();
-
-    result.mAlpha.Construct(format.alpha > 0);
-    result.mDepth = format.depth > 0;
-    result.mStencil = format.stencil > 0;
-    result.mAntialias = format.samples > 1;
+    result.mAlpha.Construct(mOptions.alpha);
+    result.mDepth = mOptions.depth;
+    result.mStencil = mOptions.stencil;
+    result.mAntialias = mOptions.antialias;
     result.mPremultipliedAlpha = mOptions.premultipliedAlpha;
     result.mPreserveDrawingBuffer = mOptions.preserveDrawingBuffer;
 }
 
 /* [noscript] DOMString mozGetUnderlyingParamString(in GLenum pname); */
 NS_IMETHODIMP
 WebGLContext::MozGetUnderlyingParamString(uint32_t pname, nsAString& retval)
 {
--- a/gfx/gl/GLConsts.h
+++ b/gfx/gl/GLConsts.h
@@ -5182,18 +5182,16 @@
 #define LOCAL_EGL_CONTEXT_PRIORITY_MEDIUM_IMG                0x3102
 #define LOCAL_EGL_CORE_NATIVE_ENGINE                         0x305B
 #define LOCAL_EGL_COVERAGE_BUFFERS_NV                        0x30E0
 #define LOCAL_EGL_COVERAGE_SAMPLES_NV                        0x30E1
 #define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV         0x3132
 #define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV            0x3133
 #define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_NV                 0x3131
 #define LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE          0x3200
-#define LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE              ((EGLNativeDisplayType)-2)
-#define LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE                   ((EGLNativeDisplayType)-3)
 #define LOCAL_EGL_DEFAULT_DISPLAY                            ((EGLNativeDisplayType)0)
 #define LOCAL_EGL_DEPTH_ENCODING_NONE_NV                     0
 #define LOCAL_EGL_DEPTH_ENCODING_NONLINEAR_NV                0x30E3
 #define LOCAL_EGL_DEPTH_ENCODING_NV                          0x30E2
 #define LOCAL_EGL_DEPTH_SIZE                                 0x3025
 #define LOCAL_EGL_DISCARD_SAMPLES_ARM                        0x3286
 #define LOCAL_EGL_DISPLAY_SCALING                            10000
 #define LOCAL_EGL_DMA_BUF_PLANE0_FD_EXT                      0x3272
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -1807,16 +1807,25 @@ GLContext::ChooseGLFormats(const Surface
             formats.color_rbFormat  = LOCAL_GL_RGBA8;
         } else {
             formats.color_texInternalFormat = IsGLES() ? LOCAL_GL_RGB : LOCAL_GL_RGB8;
             formats.color_texFormat = LOCAL_GL_RGB;
             formats.color_rbFormat  = LOCAL_GL_RGB8;
         }
     }
 
+    if (WorkAroundDriverBugs() &&
+        IsANGLE() &&
+        formats.color_rbFormat == LOCAL_GL_RGBA8)
+    {
+        formats.color_texInternalFormat = LOCAL_GL_BGRA;
+        formats.color_texFormat = LOCAL_GL_BGRA;
+        formats.color_rbFormat = LOCAL_GL_BGRA8_EXT;
+    }
+
     uint32_t msaaLevel = gfxPrefs::MSAALevel();
     GLsizei samples = msaaLevel * msaaLevel;
     samples = std::min(samples, mMaxSamples);
 
     // Bug 778765.
     if (WorkAroundDriverBugs() && samples == 1) {
         samples = 0;
     }
--- a/gfx/gl/GLDefs.h
+++ b/gfx/gl/GLDefs.h
@@ -50,9 +50,13 @@
 
 #define LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
 #define LOCAL_GL_CONTEXT_LOST                           0x9242
 #define LOCAL_GL_CONTEXT_FLAGS_ARB                      0x2094
 #define LOCAL_GL_CONTEXT_CORE_PROFILE_BIT_ARB           0x00000001
 #define LOCAL_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB  0x00000002
 #define LOCAL_GL_CONTEXT_ROBUST_ACCESS_BIT_ARB          0x00000004
 
+
+#define LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE         ((EGLNativeDisplayType)-2)
+#define LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE              ((EGLNativeDisplayType)-3)
+
 #endif
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -94,16 +94,29 @@ LoadLibraryForEGLOnWindows(const nsAStri
         nsPrintfCString msg("Failed to load %s - Expect EGL initialization to fail",
                             NS_LossyConvertUTF16toASCII(filename).get());
         NS_WARNING(msg.get());
     }
     return lib;
 }
 #endif // XP_WIN
 
+static EGLDisplay
+GetAndInitDisplay(GLLibraryEGL& egl, void* displayType)
+{
+    EGLDisplay display = egl.fGetDisplay(displayType);
+    if (display == EGL_NO_DISPLAY)
+        return EGL_NO_DISPLAY;
+
+    if (!egl.fInitialize(display, nullptr, nullptr))
+        return EGL_NO_DISPLAY;
+
+    return display;
+}
+
 bool
 GLLibraryEGL::EnsureInitialized()
 {
     if (mInitialized) {
         return true;
     }
 
     mozilla::ScopedGfxFeatureReporter reporter("EGL");
@@ -180,16 +193,17 @@ GLLibraryEGL::EnsureInitialized()
 
 #endif // !Windows
 
 #define SYMBOL(name) \
 { (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } }
 
     GLLibraryLoader::SymLoadStruct earlySymbols[] = {
         SYMBOL(GetDisplay),
+        SYMBOL(Terminate),
         SYMBOL(GetCurrentSurface),
         SYMBOL(GetCurrentContext),
         SYMBOL(MakeCurrent),
         SYMBOL(DestroyContext),
         SYMBOL(CreateContext),
         SYMBOL(DestroySurface),
         SYMBOL(CreateWindowSurface),
         SYMBOL(CreatePbufferSurface),
@@ -227,45 +241,51 @@ GLLibraryEGL::EnsureInitialized()
 
     GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0]);
 
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
     MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
                        "Couldn't find eglQueryStringImplementationANDROID");
 #endif
 
-    mEGLDisplay = nullptr;
+    mEGLDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);
 
-#ifdef XP_WIN
-    // XXX we have no way of knowing if this is ANGLE, or if we're just using
-    // a native EGL on windows.  We don't really do the latter right now, so
-    // let's assume it is ANGLE, and try our special types.
-
-    // D3D11 ANGLE only works with OMTC; there's a bug in the non-OMTC layer
-    // manager, and it's pointless to try to fix it.  We also don't try D3D11
-    // ANGLE if the layer manager is prefering D3D9 (hrm, do we care?)
-    if (gfxPrefs::LayersOffMainThreadCompositionEnabled() &&
-        !gfxPrefs::LayersPreferD3D9())
+    const char* vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
+    if (vendor && (strstr(vendor, "TransGaming") != 0 ||
+                   strstr(vendor, "Google Inc.") != 0))
     {
-        if (gfxPrefs::WebGLANGLEForceD3D11()) {
-            mEGLDisplay = fGetDisplay(LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
-        } else if (gfxPrefs::WebGLANGLETryD3D11()) {
-            mEGLDisplay = fGetDisplay(LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
-        }
+        mIsANGLE = true;
     }
-#endif
+
+    if (mIsANGLE) {
+        EGLDisplay newDisplay = EGL_NO_DISPLAY;
 
-    if (!mEGLDisplay)
-        mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
-    if (!fInitialize(mEGLDisplay, nullptr, nullptr))
-        return false;
+        // D3D11 ANGLE only works with OMTC; there's a bug in the non-OMTC layer
+        // manager, and it's pointless to try to fix it.  We also don't try
+        // D3D11 ANGLE if the layer manager is prefering D3D9 (hrm, do we care?)
+        if (gfxPrefs::LayersOffMainThreadCompositionEnabled() &&
+            !gfxPrefs::LayersPreferD3D9())
+        {
+            if (gfxPrefs::WebGLANGLEForceD3D11()) {
+                newDisplay = GetAndInitDisplay(*this,
+                                               LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
+            } else if (gfxPrefs::WebGLANGLETryD3D11()) {
+                newDisplay = GetAndInitDisplay(*this,
+                                               LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
+            }
+        }
 
-    const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
-    if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
-        mIsANGLE = true;
+        if (newDisplay != EGL_NO_DISPLAY) {
+            DebugOnly<EGLBoolean> success = fTerminate(mEGLDisplay);
+            MOZ_ASSERT(success == LOCAL_EGL_TRUE);
+
+            mEGLDisplay = newDisplay;
+
+            vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
+        }
     }
 
     InitExtensions();
 
     GLLibraryLoader::PlatformLookupFunction lookupFunction =
             (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;
 
     if (IsExtensionSupported(KHR_lock_surface)) {
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -99,17 +99,17 @@ namespace gl {
 #define BEFORE_GL_CALL
 #endif
 #define AFTER_GL_CALL
 #endif
 
 class GLLibraryEGL
 {
 public:
-    GLLibraryEGL() 
+    GLLibraryEGL()
         : mInitialized(false),
           mEGLLibrary(nullptr),
           mIsANGLE(false)
     {
     }
 
     void InitExtensions();
 
@@ -149,16 +149,24 @@ public:
     EGLDisplay fGetDisplay(void* display_id)
     {
         BEFORE_GL_CALL;
         EGLDisplay disp = mSymbols.fGetDisplay(display_id);
         AFTER_GL_CALL;
         return disp;
     }
 
+    EGLBoolean fTerminate(EGLDisplay display)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean ret = mSymbols.fTerminate(display);
+        AFTER_GL_CALL;
+        return ret;
+    }
+
     EGLSurface fGetCurrentSurface(EGLint id)
     {
         BEFORE_GL_CALL;
         EGLSurface surf = mSymbols.fGetCurrentSurface(id);
         AFTER_GL_CALL;
         return surf;
     }
 
@@ -464,16 +472,18 @@ public:
     bool EnsureInitialized();
 
     void DumpEGLConfig(EGLConfig cfg);
     void DumpEGLConfigs();
 
     struct {
         typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void *display_id);
         pfnGetDisplay fGetDisplay;
+        typedef EGLBoolean (GLAPIENTRY * pfnTerminate)(EGLDisplay dpy);
+        pfnTerminate fTerminate;
         typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint);
         pfnGetCurrentSurface fGetCurrentSurface;
         typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void);
         pfnGetCurrentContext fGetCurrentContext;
         typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
         pfnMakeCurrent fMakeCurrent;
         typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
         pfnDestroyContext fDestroyContext;
--- a/gfx/gl/SharedSurfaceGL.cpp
+++ b/gfx/gl/SharedSurfaceGL.cpp
@@ -43,16 +43,18 @@ SharedSurface_Basic::Create(GLContext* g
     case LOCAL_GL_RGB8:
         if (formats.color_texType == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
             format = SurfaceFormat::R5G6B5;
         else
             format = SurfaceFormat::B8G8R8X8;
         break;
     case LOCAL_GL_RGBA:
     case LOCAL_GL_RGBA8:
+    case LOCAL_GL_BGRA:
+    case LOCAL_GL_BGRA8_EXT:
         format = SurfaceFormat::B8G8R8A8;
         break;
     default:
         MOZ_CRASH("Unhandled Tex format.");
     }
 
     ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, format, tex) );
     return Move(ret);