Problem with new Xorg, radeon & compiz/Kwin revisited

matt sendtomatt at gmail.com
Thu Aug 16 05:22:25 UTC 2012


On 08/07/12 22:35, matt wrote:
> On 08/07/12 19:15, matt wrote:
>>
>> A while back, I was having a strange issue with the new Xorg and compiz.
>> In a nutshell, closing certain windows caused Xorg to exit on nasty
>> signals. At the same time, a few users with Radeon cards were having
>> issues with Kwin disabling opengl for no apparent reason.
>>
>> After some research, I had posted a patch seen in a debian mailing list
>> as a possible solution, and it did indeed solve the immediate problem of
>> crashing Xorg (and later I found out Kwin worked with OpenGL effects
>> when the patch is applied).
>>
>> It was requested I file a PR but first investigate what issues such a
>> patch might cause. I'm glad I waited, because there are a few. The
>> medicine is a little worse than the disease. First, with Compiz & Xfce4,
>> if X was told to shutdown while the previously affected programs
>> (xfce4-terminal running under compiz & xfce4 was obvious), the machine
>> would immediately reboot. This is obviously not good. So usually I would
>> only logout after closing all windows (except Xfce4-panel and the root
>> window). This would work, and the machine could be shut down from the 
>> TTY.
>>
>> Recently, I installed KDE4. I was so impressed that I was trying to use
>> it as my "daily desktop". OpenGL Kwin was working fine. However,
>> engaging the screen lock would reboot the machine, as well as the
>> machine occasionally spontaneously rebooting. This was much worse than
>> the above issue.
>>
>> The patch had one other odd effect, which was that Dri2 was disabled for
>> some reason.
>>
>> I reverted the patch to xorg-server I had been running, and now Kwin
>> will not start OpenGL mode, because it can't find an ARGBGLX visual. If
>> Kwin is started alone, OpenGL suprisingly works. Xfce4+compiz crashes
>> Xorg as before, however Dri2 is now enabled. The signal is a segfault at
>> 0x0. AIGLX on/off have no effect.
>>
>> Here was the patch (I applied it manually looking at the file, the
>> offsets are wrong for us):
>>
>> diff --git a/glx/glxdri.c b/glx/glxdri.c
>> index 326f539..f6ef784 100644
>> --- a/glx/glxdri.c
>> +++ b/glx/glxdri.c
>> @@ -230,7 +230,7 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
>>
>>      /* If the X window was destroyed, the dri DestroyWindow hook will
>>       * aready have taken care of this, so only call if pDraw isn't
>> NULL. */
>> -    if (drawable->pDraw != NULL) {
>> +    if (drawable->pDraw != NULL&& drawable->pDraw->type ==
>> DRAWABLE_WINDOW) {
>>      screen = (__GLXDRIscreen *) glxGetScreen(drawable->pDraw->pScreen);
>> (*screen->core->destroyDrawable)(private->driDrawable);
>>
>> It seems like this shouldn't be having as much effect as it does. I can
>> only guess the reboots are from memory problems resulting from lingering
>> drawables? I can't explain the Dri2 interaction, nor can I explain
>> Kwin's behavior (fairly new to KDE, last time I used it was last century
>> :) ).
>>
>> For what it's worth, my driver is xf86-video-ati on a Radeon HD4650.
>> I'm thoroughly confused by this problem and I'd welcome some help trying
>> to solve the bug. Anyone else seeing problems with RV710 radeons and
>> OpenGL compositing?
>>
>> Matt
>>
>>
>>
>>
> A quick follow up...dri2 issue was something else, it works with the 
> patch. I've tried base gcc as well as gcc47 no difference for 
> xorg-server and the above behavior. The initial check for pDraw != 
> NULL was to prevent a double free, and the patch adds a check to 
> prevent an instance. My best guess now is that there is a double free 
> situation that passes the DRAWABLE_WINDOW check.
>
> Matt
I fixed the issues for radeon using WITH_NEW_XORG (at least for me)

1. The attached patch from Andriy Gaipon fixes an issue with refcounting 
when releasing pixmaps
2. Apply the other patch that checks for pDraw->type == DRAWABLE_WINDOW 
that I posted before

This has been stable with both KWin and compiz.

Was Gaipon's patch previously applied in FreeBSD's xorg?

Matt
-------------- next part --------------
--- glx/glxdrawable.h.orig	2011-06-11 19:55:47.000000000 +0300
+++ glx/glxdrawable.h	2011-07-30 14:52:16.730791751 +0300
@@ -53,6 +53,7 @@ struct __GLXdrawable {
 
     DrawablePtr pDraw;
     XID drawId;
+    XID otherId; /* for glx1.3 we need to track the original Drawable as well */
 
     /*
     ** Either GLX_DRAWABLE_PIXMAP, GLX_DRAWABLE_WINDOW or
--- glx/glxcmds.c.orig	2011-06-11 19:55:47.000000000 +0300
+++ glx/glxcmds.c	2011-07-30 14:51:33.374788616 +0300
@@ -1095,6 +1095,7 @@ __glXDrawableInit(__GLXdrawable *drawabl
     drawable->pDraw = pDraw;
     drawable->type = type;
     drawable->drawId = drawId;
+    drawable->otherId = 0;
     drawable->config = config;
     drawable->eventMask = 0;
 
@@ -1131,10 +1132,13 @@ DoCreateGLXDrawable(ClientPtr client, __
      * Windows aren't refcounted, so track both the X and the GLX window
      * so we get called regardless of destruction order.
      */
-    if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW &&
-	!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
-	pGlxDraw->destroy (pGlxDraw);
-	return BadAlloc;
+    if (drawableId != glxDrawableId &&
+        (type == GLX_DRAWABLE_WINDOW || type == GLX_DRAWABLE_PIXMAP)) {
+        if (!AddResource(drawableId, __glXDrawableRes, pGlxDraw)) {
+	    pGlxDraw->destroy (pGlxDraw);
+	    return BadAlloc;
+	}
+	pGlxDraw->otherId = drawableId;
     }
 
     return Success;
--- glx/glxext.c.orig	2011-06-11 19:55:47.000000000 +0300
+++ glx/glxext.c	2011-07-30 14:51:03.306788511 +0300
@@ -124,14 +124,16 @@ static Bool DrawableGone(__GLXdrawable *
 {
     __GLXcontext *c, *next;
 
-    if (glxPriv->type == GLX_DRAWABLE_WINDOW) {
+    if (glxPriv->type == GLX_DRAWABLE_WINDOW || glxPriv->type == GLX_DRAWABLE_PIXMAP) {
         /* If this was created by glXCreateWindow, free the matching resource */
-        if (glxPriv->drawId != glxPriv->pDraw->id) {
-            if (xid == glxPriv->drawId)
-                FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE);
-            else
-                FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE);
-        }
+        if (glxPriv->otherId) {
+            XID other = glxPriv->otherId;
+            glxPriv->otherId = 0;
+            if (xid == other)
+                FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE);
+            else
+                FreeResourceByType(other, __glXDrawableRes, TRUE);
+        }
         /* otherwise this window was implicitly created by MakeCurrent */
     }
 


More information about the freebsd-x11 mailing list