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()
mFunctionsGL(nullptr),
mContext(nullptr),
mDummyPbuffer(0),
mUsesNewXDisplay(false),
mEGLDisplay(nullptr)
{
}
......@@ -67,6 +68,7 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
// the display specified by the DISPLAY environment variable.
if (xDisplay == EGL_DEFAULT_DISPLAY)
{
mUsesNewXDisplay = true;
xDisplay = XOpenDisplay(NULL);
if (!xDisplay)
{
......@@ -155,6 +157,8 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
mFunctionsGL = new FunctionsGLGLX(mGLX.getProc);
mFunctionsGL->initialize();
syncXCommands();
return DisplayGL::initialize(display);
}
......@@ -186,7 +190,7 @@ SurfaceImpl *DisplayGLX::createWindowSurface(const egl::Config *configuration,
ASSERT(configIdToGLXConfig.count(configuration->configID) > 0);
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,
......@@ -379,6 +383,14 @@ std::string DisplayGLX::getVendorString() const
return "";
}
void DisplayGLX::syncXCommands() const
{
if (mUsesNewXDisplay)
{
XSync(mGLX.getDisplay(), False);
}
}
const FunctionsGL *DisplayGLX::getFunctionsGL() const
{
return mFunctionsGL;
......
......@@ -53,6 +53,12 @@ class DisplayGLX : public DisplayGL
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:
const FunctionsGL *getFunctionsGL() const override;
......@@ -72,6 +78,8 @@ class DisplayGLX : public DisplayGL
// A pbuffer the context is current on during ANGLE initialization
GLXPbuffer mDummyPbuffer;
bool mUsesNewXDisplay;
FunctionsGLX mGLX;
egl::Display *mEGLDisplay;
};
......
......@@ -30,7 +30,6 @@ class FunctionsGLX : angle::NonCopyable
void terminate();
bool hasExtension(const char *extension) const;
int majorVersion;
int minorVersion;
......
......@@ -10,19 +10,22 @@
#include "common/debug.h"
#include "libANGLE/renderer/gl/glx/DisplayGLX.h"
#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
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(),
mGLX(glx),
mParent(window),
mWindow(0),
mDisplay(display),
mGLX(glx),
mGLXDisplay(glxDisplay),
mContext(context),
mFBConfig(fbConfig),
mWindow(0),
mGLXWindow(0)
{
}
......@@ -38,6 +41,8 @@ WindowSurfaceGLX::~WindowSurfaceGLX()
{
XDestroyWindow(mDisplay, mWindow);
}
mGLXDisplay.syncXCommands();
}
egl::Error WindowSurfaceGLX::initialize()
......@@ -84,6 +89,8 @@ egl::Error WindowSurfaceGLX::initialize()
XFree(visualInfo);
XFreeColormap(mDisplay, colormap);
mGLXDisplay.syncXCommands();
return egl::Error(EGL_SUCCESS);
}
......
......@@ -15,12 +15,14 @@
namespace rx
{
class DisplayGLX;
class FunctionsGLX;
class WindowSurfaceGLX : public SurfaceGL
{
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;
egl::Error initialize();
......@@ -38,12 +40,15 @@ class WindowSurfaceGLX : public SurfaceGL
EGLint isPostSubBufferSupported() const override;
private:
const FunctionsGLX &mGLX;
Window mParent;
Window mWindow;
Display *mDisplay;
const FunctionsGLX &mGLX;
const DisplayGLX &mGLXDisplay;
GLXContext mContext;
GLXFBConfig mFBConfig;
Window mWindow;
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