Commit cedb8ca2 by Corentin Wallez

Call XSync in the GLX EGL impl if we have a new X server connection

This prevents races between the application's connection and ANGLE's one that could lead to X errors crashing the program. BUG=angleproject:892 Change-Id: Ic09462e76724d1a32c35b32708de97258d99241c Reviewed-on: https://chromium-review.googlesource.com/271178Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 96748507
...@@ -49,6 +49,7 @@ DisplayGLX::DisplayGLX() ...@@ -49,6 +49,7 @@ DisplayGLX::DisplayGLX()
mFunctionsGL(nullptr), mFunctionsGL(nullptr),
mContext(nullptr), mContext(nullptr),
mDummyPbuffer(0), mDummyPbuffer(0),
mUsesNewXDisplay(false),
mEGLDisplay(nullptr) mEGLDisplay(nullptr)
{ {
} }
...@@ -67,6 +68,7 @@ egl::Error DisplayGLX::initialize(egl::Display *display) ...@@ -67,6 +68,7 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
// the display specified by the DISPLAY environment variable. // the display specified by the DISPLAY environment variable.
if (xDisplay == EGL_DEFAULT_DISPLAY) if (xDisplay == EGL_DEFAULT_DISPLAY)
{ {
mUsesNewXDisplay = true;
xDisplay = XOpenDisplay(NULL); xDisplay = XOpenDisplay(NULL);
if (!xDisplay) if (!xDisplay)
{ {
...@@ -155,6 +157,8 @@ egl::Error DisplayGLX::initialize(egl::Display *display) ...@@ -155,6 +157,8 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
mFunctionsGL = new FunctionsGLGLX(mGLX.getProc); mFunctionsGL = new FunctionsGLGLX(mGLX.getProc);
mFunctionsGL->initialize(); mFunctionsGL->initialize();
syncXCommands();
return DisplayGL::initialize(display); return DisplayGL::initialize(display);
} }
...@@ -186,7 +190,7 @@ SurfaceImpl *DisplayGLX::createWindowSurface(const egl::Config *configuration, ...@@ -186,7 +190,7 @@ SurfaceImpl *DisplayGLX::createWindowSurface(const egl::Config *configuration,
ASSERT(configIdToGLXConfig.count(configuration->configID) > 0); ASSERT(configIdToGLXConfig.count(configuration->configID) > 0);
GLXFBConfig fbConfig = configIdToGLXConfig[configuration->configID]; GLXFBConfig fbConfig = configIdToGLXConfig[configuration->configID];
return new WindowSurfaceGLX(mGLX, window, mGLX.getDisplay(), mContext, fbConfig); return new WindowSurfaceGLX(mGLX, *this, window, mGLX.getDisplay(), mContext, fbConfig);
} }
SurfaceImpl *DisplayGLX::createPbufferSurface(const egl::Config *configuration, SurfaceImpl *DisplayGLX::createPbufferSurface(const egl::Config *configuration,
...@@ -379,6 +383,14 @@ std::string DisplayGLX::getVendorString() const ...@@ -379,6 +383,14 @@ std::string DisplayGLX::getVendorString() const
return ""; return "";
} }
void DisplayGLX::syncXCommands() const
{
if (mUsesNewXDisplay)
{
XSync(mGLX.getDisplay(), False);
}
}
const FunctionsGL *DisplayGLX::getFunctionsGL() const const FunctionsGL *DisplayGLX::getFunctionsGL() const
{ {
return mFunctionsGL; return mFunctionsGL;
......
...@@ -53,6 +53,12 @@ class DisplayGLX : public DisplayGL ...@@ -53,6 +53,12 @@ class DisplayGLX : public DisplayGL
std::string getVendorString() const override; std::string getVendorString() const override;
// Synchronizes with the X server, if the display has been opened by ANGLE.
// Calling this is required at the end of every functions that does buffered
// X calls (not for glX calls) otherwise there might be race conditions
// between the application's display and ANGLE's one.
void syncXCommands() const;
private: private:
const FunctionsGL *getFunctionsGL() const override; const FunctionsGL *getFunctionsGL() const override;
...@@ -72,6 +78,8 @@ class DisplayGLX : public DisplayGL ...@@ -72,6 +78,8 @@ class DisplayGLX : public DisplayGL
// A pbuffer the context is current on during ANGLE initialization // A pbuffer the context is current on during ANGLE initialization
GLXPbuffer mDummyPbuffer; GLXPbuffer mDummyPbuffer;
bool mUsesNewXDisplay;
FunctionsGLX mGLX; FunctionsGLX mGLX;
egl::Display *mEGLDisplay; egl::Display *mEGLDisplay;
}; };
......
...@@ -30,7 +30,6 @@ class FunctionsGLX : angle::NonCopyable ...@@ -30,7 +30,6 @@ class FunctionsGLX : angle::NonCopyable
void terminate(); void terminate();
bool hasExtension(const char *extension) const; bool hasExtension(const char *extension) const;
int majorVersion; int majorVersion;
int minorVersion; int minorVersion;
......
...@@ -10,19 +10,22 @@ ...@@ -10,19 +10,22 @@
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/renderer/gl/glx/DisplayGLX.h"
#include "libANGLE/renderer/gl/glx/FunctionsGLX.h" #include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
namespace rx namespace rx
{ {
WindowSurfaceGLX::WindowSurfaceGLX(const FunctionsGLX &glx, EGLNativeWindowType window, Display *display, GLXContext context, GLXFBConfig fbConfig) WindowSurfaceGLX::WindowSurfaceGLX(const FunctionsGLX &glx, const DisplayGLX &glxDisplay, Window window, Display *display,
GLXContext context, GLXFBConfig fbConfig)
: SurfaceGL(), : SurfaceGL(),
mGLX(glx),
mParent(window), mParent(window),
mWindow(0),
mDisplay(display), mDisplay(display),
mGLX(glx),
mGLXDisplay(glxDisplay),
mContext(context), mContext(context),
mFBConfig(fbConfig), mFBConfig(fbConfig),
mWindow(0),
mGLXWindow(0) mGLXWindow(0)
{ {
} }
...@@ -38,6 +41,8 @@ WindowSurfaceGLX::~WindowSurfaceGLX() ...@@ -38,6 +41,8 @@ WindowSurfaceGLX::~WindowSurfaceGLX()
{ {
XDestroyWindow(mDisplay, mWindow); XDestroyWindow(mDisplay, mWindow);
} }
mGLXDisplay.syncXCommands();
} }
egl::Error WindowSurfaceGLX::initialize() egl::Error WindowSurfaceGLX::initialize()
...@@ -84,6 +89,8 @@ egl::Error WindowSurfaceGLX::initialize() ...@@ -84,6 +89,8 @@ egl::Error WindowSurfaceGLX::initialize()
XFree(visualInfo); XFree(visualInfo);
XFreeColormap(mDisplay, colormap); XFreeColormap(mDisplay, colormap);
mGLXDisplay.syncXCommands();
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
} }
......
...@@ -15,12 +15,14 @@ ...@@ -15,12 +15,14 @@
namespace rx namespace rx
{ {
class DisplayGLX;
class FunctionsGLX; class FunctionsGLX;
class WindowSurfaceGLX : public SurfaceGL class WindowSurfaceGLX : public SurfaceGL
{ {
public: public:
WindowSurfaceGLX(const FunctionsGLX &glx, Window window, Display *display, GLXContext context, GLXFBConfig fbConfig); WindowSurfaceGLX(const FunctionsGLX &glx, const DisplayGLX &glxDisplay, Window window, Display *display,
GLXContext context, GLXFBConfig fbConfig);
~WindowSurfaceGLX() override; ~WindowSurfaceGLX() override;
egl::Error initialize(); egl::Error initialize();
...@@ -38,12 +40,15 @@ class WindowSurfaceGLX : public SurfaceGL ...@@ -38,12 +40,15 @@ class WindowSurfaceGLX : public SurfaceGL
EGLint isPostSubBufferSupported() const override; EGLint isPostSubBufferSupported() const override;
private: private:
const FunctionsGLX &mGLX;
Window mParent; Window mParent;
Window mWindow;
Display *mDisplay; Display *mDisplay;
const FunctionsGLX &mGLX;
const DisplayGLX &mGLXDisplay;
GLXContext mContext; GLXContext mContext;
GLXFBConfig mFBConfig; GLXFBConfig mFBConfig;
Window mWindow;
GLXWindow mGLXWindow; GLXWindow mGLXWindow;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment