Bug 1245747 - Terminate the EGL display on context loss - r=jgilbert
☠☠ backed out by 137df01eff02 ☠ ☠
authorEdwin Flores <edwin@mozilla.com>
Tue, 26 Jul 2016 13:31:22 +0100
changeset 331781 c5b0b62fc39ea439f997b3c180872ad93e509322
parent 331780 08079892bec5cb1744ae48316bc2cd4378a679db
child 331782 137df01eff02fcb191f47b81077f1fb0c621fac5
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs1245747
milestone50.0a1
Bug 1245747 - Terminate the EGL display on context loss - r=jgilbert
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLLibraryEGL.cpp
gfx/gl/GLLibraryEGL.h
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -336,16 +336,19 @@ GLContextEGL::SetEGLSurfaceOverride(EGLS
     DebugOnly<bool> ok = MakeCurrent(true);
     MOZ_ASSERT(ok);
 }
 
 bool
 GLContextEGL::MakeCurrentImpl(bool aForce) {
     bool succeeded = true;
 
+    if (IsContextLost())
+        return false;
+
     // Assume that EGL has the same problem as WGL does,
     // where MakeCurrent with an already-current context is
     // still expensive.
     bool hasDifferentContext = false;
     if (sEGLLibrary.CachedCurrentContext() != mContext) {
         // even if the cached context doesn't match the current one
         // might still
         if (sEGLLibrary.fGetCurrentContext() != mContext) {
@@ -363,29 +366,35 @@ GLContextEGL::MakeCurrentImpl(bool aForc
             return false;
         }
         succeeded = sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
                                               surface, surface,
                                               mContext);
         if (!succeeded) {
             int eglError = sEGLLibrary.fGetError();
             if (eglError == LOCAL_EGL_CONTEXT_LOST) {
+                sEGLLibrary.SetDeviceLost();
                 mContextLost = true;
                 NS_WARNING("EGL context has been lost.");
             } else {
                 NS_WARNING("Failed to make GL context current!");
 #ifdef DEBUG
                 printf_stderr("EGL Error: 0x%04x\n", eglError);
 #endif
             }
         } else {
             sEGLLibrary.SetCachedCurrentContext(mContext);
         }
     } else {
         MOZ_ASSERT(sEGLLibrary.CachedCurrentContextMatches());
+
+        if (sEGLLibrary.HasRobustness() && fGetGraphicsResetStatus() != NO_ERROR) {
+            sEGLLibrary.SetDeviceLost();
+            mContextLost = true;
+        }
     }
 
     return succeeded;
 }
 
 bool
 GLContextEGL::IsCurrent() {
     return sEGLLibrary.fGetCurrentContext() == mContext;
@@ -505,16 +514,18 @@ GLContextEGL::CreateGLContext(CreateCont
     if (flags & CreateContextFlags::PREFER_ES3)
         contextAttribs.AppendElement(3);
     else
         contextAttribs.AppendElement(2);
 
     if (sEGLLibrary.HasRobustness()) {
 //    contextAttribs.AppendElement(LOCAL_EGL_CONTEXT_ROBUST_ACCESS_EXT);
 //    contextAttribs.AppendElement(LOCAL_EGL_TRUE);
+      contextAttribs.AppendElement(LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT);
+      contextAttribs.AppendElement(LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT);
     }
 
     for (size_t i = 0; i < MOZ_ARRAY_LENGTH(gTerminationAttribs); i++) {
       contextAttribs.AppendElement(gTerminationAttribs[i]);
     }
 
     EGLContext context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
                                                     config,
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -284,16 +284,24 @@ GLLibraryEGL::ReadbackEGLImage(EGLImage 
                                                              out_surface->GetFormat());
     int shaderConfig = config.mFeatures;
     mReadbackGL->ReadTexImageHelper()->ReadTexImage(out_surface, 0, target,
                                                     out_surface->GetSize(), shaderConfig);
 
     return true;
 }
 
+void
+GLLibraryEGL::SetDeviceLost()
+{
+    fTerminate(mEGLDisplay);
+    mEGLDisplay = nullptr;
+    mInitialized = false;
+}
+
 bool
 GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString* const out_failureId)
 {
     if (mInitialized) {
         return true;
     }
 
     mozilla::ScopedGfxFeatureReporter reporter("EGL");
--- a/gfx/gl/GLLibraryEGL.h
+++ b/gfx/gl/GLLibraryEGL.h
@@ -552,16 +552,17 @@ public:
     }
 
     bool HasRobustness() const {
         return IsExtensionSupported(EXT_create_context_robustness);
     }
 
     bool ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surface);
 
+    void SetDeviceLost();
     bool EnsureInitialized(bool forceAccel, nsACString* const out_failureId);
 
     void DumpEGLConfig(EGLConfig cfg);
     void DumpEGLConfigs();
 
     struct {
         typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void* display_id);
         pfnGetDisplay fGetDisplay;