From 8dbe82a76f9ef29eb3f7df4f6f612af6e44b4b6c Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Fri, 17 Jun 2011 11:49:27 -0400 Subject: [PATCH] Bug 659842 - [topcrash] release the GL context before calling glXDestroyContext - r=karlt See the glXDestroyContext man page: If GLX rendering context ctx is not current to any thread, glXDestroyContext destroys it immediately. Otherwise, ctx is destroyed when it becomes not current to any thread. In either case, the resource ID referenced by ctx is freed immediately. In other words, if we want glXDestroyContext to have the well-defined semantics of destroying the context before future X commands take effect, we must first release the GL context before calling it. We were failing to do that, but we were destroying the drawable immediately after that call, and as a result, the context was outliving its underlying drawable. This eventually resulted in X_GLXMakeCurrent: GLXBadContextTag X errors on subsequent glXMakeCurrent calls. --- gfx/thebes/GLContextProviderGLX.cpp | 5 +++++ toolkit/xre/glxtest.cpp | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gfx/thebes/GLContextProviderGLX.cpp b/gfx/thebes/GLContextProviderGLX.cpp index 8ecc337899b..de3661b0e25 100644 --- a/gfx/thebes/GLContextProviderGLX.cpp +++ b/gfx/thebes/GLContextProviderGLX.cpp @@ -403,6 +403,11 @@ TRY_AGAIN_NO_SHARING: { MarkDestroyed(); + // see bug 659842 comment 76 + bool success = sGLXLibrary.xMakeCurrent(mDisplay, None, nsnull); + NS_ABORT_IF_FALSE(success, + "glXMakeCurrent failed to release GL context before we call glXDestroyContext!"); + sGLXLibrary.xDestroyContext(mDisplay, mContext); if (mDeleteDrawable) { diff --git a/toolkit/xre/glxtest.cpp b/toolkit/xre/glxtest.cpp index f471c87c360..0023366bf3e 100644 --- a/toolkit/xre/glxtest.cpp +++ b/toolkit/xre/glxtest.cpp @@ -212,8 +212,8 @@ static void glxtest() ///// Clean up. Indeed, the parent process might fail to kill us (e.g. if it doesn't need to check GL info) ///// so we might be staying alive for longer than expected, so it's important to consume as little memory as - ///// possible. - glXDestroyContext(dpy, context); + ///// possible. Also we want to check that we're able to do that too without generating X errors. + glXMakeCurrent(dpy, None, NULL); // must release the GL context before destroying it glXDestroyPixmap(dpy, glxpixmap); XFreePixmap(dpy, pixmap); XCloseDisplay(dpy);