Bug 1296911 - Use a separate X display on the GLX VSync thread. r?lsalzman
This reverts commit cce8e136869d313e999fdd0b98c88dfa3603c3de.
--- 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.