Bug 1296911 - Use a separate X display on the GLX VSync thread. r?lsalzman draft
authorAndrew Comminos <andrew@comminos.com>
Mon, 22 Aug 2016 14:44:54 -0400
changeset 404053 21b67d114862938b1bf27c05a72fbdf7ed35e17c
parent 404025 78b89cc4c3d3f09f73077d02cb6cae7bae0e07c3
child 529074 ca818539a6b7538d5e1c33a26606fab75e316db3
push id27089
push userbmo:andrew@comminos.com
push dateMon, 22 Aug 2016 18:45:36 +0000
reviewerslsalzman
bugs1296911
milestone51.0a1
Bug 1296911 - Use a separate X display on the GLX VSync thread. r?lsalzman This reverts commit cce8e136869d313e999fdd0b98c88dfa3603c3de.
gfx/thebes/gfxPlatformGtk.cpp
--- a/gfx/thebes/gfxPlatformGtk.cpp
+++ b/gfx/thebes/gfxPlatformGtk.cpp
@@ -668,16 +668,17 @@ public:
   }
 
   class GLXDisplay final : public VsyncSource::Display
   {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLXDisplay)
 
   public:
     GLXDisplay() : mGLContext(nullptr)
+                 , mXDisplay(nullptr)
                  , mSetupLock("GLXVsyncSetupLock")
                  , mVsyncThread("GLXVsyncThread")
                  , mVsyncTask(nullptr)
                  , mVsyncEnabledLock("GLXVsyncEnabledLock")
                  , mVsyncEnabled(false)
     {
     }
 
@@ -700,36 +701,43 @@ public:
 
     // Called on the Vsync thread to setup the GL context.
     void SetupGLContext()
     {
         MonitorAutoLock lock(mSetupLock);
         MOZ_ASSERT(!NS_IsMainThread());
         MOZ_ASSERT(!mGLContext, "GLContext already setup!");
 
-        _XDisplay* display = gfxPlatformGtk::GetPlatform()->GetCompositorDisplay();
+        // Create video sync timer on a separate Display to prevent locking the
+        // main thread X display.
+        mXDisplay = XOpenDisplay(nullptr);
+        if (!mXDisplay) {
+          lock.NotifyAll();
+          return;
+        }
+
         // Most compositors wait for vsync events on the root window.
-        Window root = DefaultRootWindow(display);
-        int screen = DefaultScreen(display);
+        Window root = DefaultRootWindow(mXDisplay);
+        int screen = DefaultScreen(mXDisplay);
 
         ScopedXFree<GLXFBConfig> cfgs;
         GLXFBConfig config;
         int visid;
-        if (!gl::GLContextGLX::FindFBConfigForWindow(display, screen, root,
+        if (!gl::GLContextGLX::FindFBConfigForWindow(mXDisplay, screen, root,
                                                      &cfgs, &config, &visid)) {
           lock.NotifyAll();
           return;
         }
 
         mGLContext = gl::GLContextGLX::CreateGLContext(
             gl::CreateContextFlags::NONE,
             gl::SurfaceCaps::Any(),
             nullptr,
             false,
-            display,
+            mXDisplay,
             root,
             config,
             false);
 
         if (!mGLContext) {
           lock.NotifyAll();
           return;
         }
@@ -841,20 +849,22 @@ public:
         NotifyVsync(lastVsync);
       }
     }
 
     void Cleanup() {
       MOZ_ASSERT(!NS_IsMainThread());
 
       mGLContext = nullptr;
+      XCloseDisplay(mXDisplay);
     }
 
     // Owned by the vsync thread.
     RefPtr<gl::GLContextGLX> mGLContext;
+    _XDisplay* mXDisplay;
     Monitor mSetupLock;
     base::Thread mVsyncThread;
     RefPtr<Runnable> mVsyncTask;
     Monitor mVsyncEnabledLock;
     bool mVsyncEnabled;
   };
 private:
   // We need a refcounted VsyncSource::Display to use chromium IPC runnables.