WindowSurfaceGLX: ignore X11 when destroying windows

Chromium seems to destroy the parent window before calling asking to
destroy the EGL surface. We don't want to generate a BadWindow X11
error in this case so we ignore errors when calling XDestroyWindow.

BUG=angleproject:1281

Change-Id: Ie63d188b6206c0ff3b5ac6a5a874e7d6018489e4
Reviewed-on: https://chromium-review.googlesource.com/322361
Tryjob-Request: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp b/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp
index b4c5fd6..08fb520 100644
--- a/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp
+++ b/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp
@@ -16,6 +16,11 @@
 namespace rx
 {
 
+static int IgnoreX11Errors(Display *, XErrorEvent *)
+{
+    return 0;
+}
+
 WindowSurfaceGLX::WindowSurfaceGLX(const FunctionsGLX &glx,
                                    DisplayGLX *glxDisplay,
                                    RendererGL *renderer,
@@ -44,7 +49,14 @@
 
     if (mWindow)
     {
+        // When destroying the window, it may happen that the window has already been
+        // destroyed by the application (this happens in Chromium). There is no way to
+        // atomically check that a window exists and to destroy it so instead we call
+        // XDestroyWindow, ignoring any errors.
+        auto oldErrorHandler = XSetErrorHandler(IgnoreX11Errors);
         XDestroyWindow(mDisplay, mWindow);
+        XSync(mDisplay, False);
+        XSetErrorHandler(oldErrorHandler);
     }
 
     mGLXDisplay->syncXCommands();