|
|
485e329 |
From 69cbca0b83a86ad1ab266314e76304ca4e35f57b Mon Sep 17 00:00:00 2001
|
|
|
cb51bc2 |
From: Owen Taylor <otaylor@redhat.com>
|
|
|
cb51bc2 |
Date: Fri, 30 Apr 2010 13:17:18 -0400
|
|
|
da36744 |
Subject: [PATCH] Merge fixes for DRI drawable handling from master
|
|
|
cb51bc2 |
MIME-Version: 1.0
|
|
|
cb51bc2 |
Content-Type: text/plain; charset=UTF-8
|
|
|
cb51bc2 |
Content-Transfer-Encoding: 8bit
|
|
|
a54aedc |
|
|
|
cb51bc2 |
commit a92b2c2c8dd1e86ee852168146f01bdf72bfe2d0
|
|
|
cb51bc2 |
Author: Kristian Høgsberg <krh@bitplanet.net>
|
|
|
cb51bc2 |
Date: Fri Apr 16 05:55:35 2010 -0400
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
glx: Drop DestroyWindow hook
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
Now that glx doesn't call DRI2DestroyDrawable anymore, we don't need to
|
|
|
cb51bc2 |
force a specific resource destruction order in the DestroyWindow hook.
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
Signed-off-by: Kristian Høgsberg <krh@bitplanet.net>
|
|
|
cb51bc2 |
Reviewed-by: Michel Dänzer <michel@daenzer.net>
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
https://bugs.freedesktop.org/show_bug.cgi?id=26394
|
|
|
cb51bc2 |
Signed-off-by: Keith Packard <keithp@keithp.com>
|
|
|
cb51bc2 |
|
|
|
485e329 |
commit 2b3f755254675933475b068ff20bd322ffb8631f
|
|
|
cb51bc2 |
Author: Kristian Høgsberg <krh@bitplanet.net>
|
|
|
cb51bc2 |
Date: Thu, 29 Apr 2010 16:36:10 -0400
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
dri2: Take an XID for tracking the DRI2 drawable
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
Some pixmaps (window pixmaps and scratch pixmaps) don't have the
|
|
|
cb51bc2 |
drawable->id set and thus DRI2 gets confused when using that field
|
|
|
cb51bc2 |
for looking up the DRI2 drawable. Go back to using privates for getting
|
|
|
cb51bc2 |
at the DRI2 drawable from a DrawablePtr. We need to keep the resource
|
|
|
cb51bc2 |
tracking in place so we can remove the DRI2 drawable when the X resource
|
|
|
cb51bc2 |
it was created for goes away. Additionally, we also now track the DRI2
|
|
|
cb51bc2 |
drawable using a client XID so we can reclaim the DRI2 drawable even if
|
|
|
cb51bc2 |
the client goes before the drawable and doesn't destroy the DRI2 drawable.
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
commit 1da1f33f2dd5b437dd56cd9f5d6782de4ad5a1bc
|
|
|
cb51bc2 |
Author: Kristian Høgsberg <krh@bitplanet.net>
|
|
|
cb51bc2 |
Date: Fri Apr 16 05:55:34 2010 -0400
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
DRI2: Track DRI2 drawables as resources, not privates
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
The main motivation here is to have the resource system clean up the
|
|
|
cb51bc2 |
DRI2 drawable automatically so glx doesn't have to. Right now, the
|
|
|
cb51bc2 |
glx drawable resource must be destroyed before the X drawable, so that
|
|
|
cb51bc2 |
calling DRI2DestroyDrawable doesn't crash. By making the DRI2
|
|
|
cb51bc2 |
drawable a resource, GLX doesn't have to worry about that and the
|
|
|
cb51bc2 |
resource destruction order becomes irrelevant.
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
https://bugs.freedesktop.org/show_bug.cgi?id=26394
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
Signed-off-by: Kristian Høgsberg <krh@bitplanet.net>
|
|
|
cb51bc2 |
Signed-off-by: Keith Packard <keithp@keithp.com>
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
commit f0006aa58f6cf7552a239e169ff6e7e4fda532f4
|
|
|
cb51bc2 |
Author: Kristian Høgsberg <krh@bitplanet.net>
|
|
|
cb51bc2 |
Date: Fri Apr 16 05:55:32 2010 -0400
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
glx: Track GLX 1.3 style GLX drawables under their X drawable ID as well
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
This ensures that the DrawableGone callback gets called as necessary
|
|
|
cb51bc2 |
when the X drawable goes away. Otherwise, using a GLX drawable
|
|
|
cb51bc2 |
(say, glXSwapBuffers) in indirect mode after the X drawable has been
|
|
|
cb51bc2 |
destroyed will crash the server.
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
Signed-off-by: Kristian Høgsberg <krh@bitplanet.net>
|
|
|
cb51bc2 |
Reviewed-by: Michel Dänzer <michel@daenzer.net>
|
|
|
cb51bc2 |
Signed-off-by: Keith Packard <keithp@keithp.com>
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
commit 22da7aa9d743deee198aaf6df5d370a446db9763
|
|
|
cb51bc2 |
Author: Kristian Høgsberg <krh@bitplanet.net>
|
|
|
cb51bc2 |
Date: Fri Apr 16 05:55:33 2010 -0400
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
glx: Let the resource system destroy pixmaps
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
GLX pbuffers are implemented using a pixmap allocated by the server.
|
|
|
cb51bc2 |
With the change to DRI2 to track DRI2 drawables as resources, we need to make
|
|
|
cb51bc2 |
sure that every drawable we create a DRI2 drawable for has an XID. By
|
|
|
cb51bc2 |
using the XID of the pbuffer, the resource system will automatically
|
|
|
cb51bc2 |
reclaim the hidden pixmap and the DRI2 drawable when the pbuffer is
|
|
|
cb51bc2 |
destroyed or the client exits.
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
Signed-off-by: Kristian Høgsberg <krh@bitplanet.net>
|
|
|
cb51bc2 |
Signed-off-by: Keith Packard <keithp@keithp.com>
|
|
|
a54aedc |
---
|
|
|
485e329 |
glx/glxcmds.c | 60 ++++++++-----
|
|
|
cb51bc2 |
glx/glxdri.c | 8 +-
|
|
|
cb51bc2 |
glx/glxdri2.c | 17 ++--
|
|
|
cb51bc2 |
glx/glxdriswrast.c | 8 +-
|
|
|
cb51bc2 |
glx/glxext.c | 11 +++
|
|
|
da36744 |
glx/glxscreens.c | 28 ------
|
|
|
cb51bc2 |
glx/glxscreens.h | 7 +-
|
|
|
485e329 |
hw/xfree86/dri2/dri2.c | 215 +++++++++++++++++++++++++++------------------
|
|
|
cb51bc2 |
hw/xfree86/dri2/dri2.h | 3 +-
|
|
|
cb51bc2 |
hw/xfree86/dri2/dri2ext.c | 24 +-----
|
|
|
cb51bc2 |
include/list.h | 6 ++
|
|
|
485e329 |
11 files changed, 209 insertions(+), 178 deletions(-)
|
|
|
a54aedc |
|
|
|
a54aedc |
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
|
|
|
485e329 |
index 77afbf4..ec3bbe6 100644
|
|
|
a54aedc |
--- a/glx/glxcmds.c
|
|
|
a54aedc |
+++ b/glx/glxcmds.c
|
|
|
a54aedc |
@@ -161,7 +161,11 @@ validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
|
|
|
a54aedc |
return FALSE;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
a54aedc |
+ /* If the ID of the glx drawable we looked up doesn't match the id
|
|
|
a54aedc |
+ * we looked for, it's because we looked it up under the X
|
|
|
a54aedc |
+ * drawable ID (see DoCreateGLXDrawable). */
|
|
|
a54aedc |
if (rc == BadValue ||
|
|
|
a54aedc |
+ (*drawable)->drawId != id ||
|
|
|
a54aedc |
(type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
|
|
|
a54aedc |
client->errorValue = id;
|
|
|
a54aedc |
switch (type) {
|
|
|
cb51bc2 |
@@ -508,8 +512,9 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
|
|
|
cb51bc2 |
if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
|
|
|
cb51bc2 |
return NULL;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
- pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
|
|
|
cb51bc2 |
- pDraw, GLX_DRAWABLE_WINDOW,
|
|
|
cb51bc2 |
+ pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
|
|
|
cb51bc2 |
+ pDraw, drawId,
|
|
|
cb51bc2 |
+ GLX_DRAWABLE_WINDOW,
|
|
|
cb51bc2 |
drawId, glxc->config);
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
/* since we are creating the drawablePrivate, drawId should be new */
|
|
|
cb51bc2 |
@@ -1097,28 +1102,20 @@ __glXDrawableInit(__GLXdrawable *drawable,
|
|
|
a54aedc |
void
|
|
|
a54aedc |
__glXDrawableRelease(__GLXdrawable *drawable)
|
|
|
a54aedc |
{
|
|
|
a54aedc |
- ScreenPtr pScreen = drawable->pDraw->pScreen;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- switch (drawable->type) {
|
|
|
a54aedc |
- case GLX_DRAWABLE_PIXMAP:
|
|
|
a54aedc |
- case GLX_DRAWABLE_PBUFFER:
|
|
|
a54aedc |
- (*pScreen->DestroyPixmap)((PixmapPtr) drawable->pDraw);
|
|
|
a54aedc |
- break;
|
|
|
a54aedc |
- }
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
a54aedc |
static int
|
|
|
cb51bc2 |
-DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
|
|
|
cb51bc2 |
- DrawablePtr pDraw, XID glxDrawableId, int type)
|
|
|
cb51bc2 |
+DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen,
|
|
|
cb51bc2 |
+ __GLXconfig *config, DrawablePtr pDraw, XID drawableId,
|
|
|
cb51bc2 |
+ XID glxDrawableId, int type)
|
|
|
a54aedc |
{
|
|
|
a54aedc |
__GLXdrawable *pGlxDraw;
|
|
|
a54aedc |
|
|
|
a54aedc |
- LEGAL_NEW_RESOURCE(glxDrawableId, client);
|
|
|
a54aedc |
-
|
|
|
a54aedc |
if (pGlxScreen->pScreen != pDraw->pScreen)
|
|
|
a54aedc |
return BadMatch;
|
|
|
a54aedc |
|
|
|
cb51bc2 |
- pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
|
|
|
cb51bc2 |
+ pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
|
|
|
cb51bc2 |
+ drawableId, type,
|
|
|
cb51bc2 |
glxDrawableId, config);
|
|
|
cb51bc2 |
if (pGlxDraw == NULL)
|
|
|
cb51bc2 |
return BadAlloc;
|
|
|
cb51bc2 |
@@ -1128,6 +1125,15 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf
|
|
|
a54aedc |
return BadAlloc;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
a54aedc |
+ /* Add the glx drawable under the XID of the underlying X drawable
|
|
|
a54aedc |
+ * too. That way we'll get a callback in DrawableGone and can
|
|
|
a54aedc |
+ * clean up properly when the drawable is destroyed. */
|
|
|
485e329 |
+ if (drawableId != glxDrawableId &&
|
|
|
a54aedc |
+ !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
|
|
|
a54aedc |
+ pGlxDraw->destroy (pGlxDraw);
|
|
|
a54aedc |
+ return BadAlloc;
|
|
|
a54aedc |
+ }
|
|
|
a54aedc |
+
|
|
|
a54aedc |
return Success;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
cb51bc2 |
@@ -1138,6 +1144,8 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config
|
|
|
a54aedc |
DrawablePtr pDraw;
|
|
|
a54aedc |
int err;
|
|
|
a54aedc |
|
|
|
a54aedc |
+ LEGAL_NEW_RESOURCE(glxDrawableId, client);
|
|
|
a54aedc |
+
|
|
|
a54aedc |
err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess);
|
|
|
a54aedc |
if (err != Success) {
|
|
|
a54aedc |
client->errorValue = drawableId;
|
|
|
cb51bc2 |
@@ -1148,12 +1156,9 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config
|
|
|
cb51bc2 |
return BadPixmap;
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
- err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw,
|
|
|
cb51bc2 |
+ err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
|
|
|
a54aedc |
glxDrawableId, GLX_DRAWABLE_PIXMAP);
|
|
|
a54aedc |
|
|
|
a54aedc |
- if (err == Success)
|
|
|
a54aedc |
- ((PixmapPtr) pDraw)->refcnt++;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
return err;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
cb51bc2 |
@@ -1294,6 +1299,8 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
|
|
|
a54aedc |
PixmapPtr pPixmap;
|
|
|
a54aedc |
int err;
|
|
|
a54aedc |
|
|
|
a54aedc |
+ LEGAL_NEW_RESOURCE(glxDrawableId, client);
|
|
|
a54aedc |
+
|
|
|
a54aedc |
if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
|
|
|
a54aedc |
return err;
|
|
|
a54aedc |
if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
|
|
|
cb51bc2 |
@@ -1304,8 +1311,16 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
|
|
|
a54aedc |
width, height, config->rgbBits, 0);
|
|
|
a54aedc |
__glXleaveServer(GL_FALSE);
|
|
|
a54aedc |
|
|
|
a54aedc |
+ /* Assign the pixmap the same id as the pbuffer and add it as a
|
|
|
a54aedc |
+ * resource so it and the DRI2 drawable will be reclaimed when the
|
|
|
a54aedc |
+ * pbuffer is destroyed. */
|
|
|
a54aedc |
+ pPixmap->drawable.id = glxDrawableId;
|
|
|
a54aedc |
+ if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap))
|
|
|
a54aedc |
+ return BadAlloc;
|
|
|
a54aedc |
+
|
|
|
a54aedc |
return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
|
|
|
cb51bc2 |
- glxDrawableId, GLX_DRAWABLE_PBUFFER);
|
|
|
cb51bc2 |
+ glxDrawableId, glxDrawableId,
|
|
|
cb51bc2 |
+ GLX_DRAWABLE_PBUFFER);
|
|
|
a54aedc |
}
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
|
|
|
cb51bc2 |
@@ -1411,6 +1426,8 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
|
|
|
a54aedc |
DrawablePtr pDraw;
|
|
|
a54aedc |
int err;
|
|
|
a54aedc |
|
|
|
a54aedc |
+ LEGAL_NEW_RESOURCE(req->glxwindow, client);
|
|
|
a54aedc |
+
|
|
|
a54aedc |
if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
|
|
|
a54aedc |
return err;
|
|
|
a54aedc |
if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
|
|
|
cb51bc2 |
@@ -1426,7 +1443,8 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
|
|
|
cb51bc2 |
return err;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
return DoCreateGLXDrawable(client, pGlxScreen, config,
|
|
|
cb51bc2 |
- pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW);
|
|
|
cb51bc2 |
+ pDraw, req->window,
|
|
|
cb51bc2 |
+ req->glxwindow, GLX_DRAWABLE_WINDOW);
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
|
|
|
cb51bc2 |
diff --git a/glx/glxdri.c b/glx/glxdri.c
|
|
|
da36744 |
index 30b820c..51b602d 100644
|
|
|
cb51bc2 |
--- a/glx/glxdri.c
|
|
|
cb51bc2 |
+++ b/glx/glxdri.c
|
|
|
cb51bc2 |
@@ -682,10 +682,12 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
static __GLXdrawable *
|
|
|
cb51bc2 |
-__glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|
|
cb51bc2 |
+__glXDRIscreenCreateDrawable(ClientPtr client,
|
|
|
cb51bc2 |
+ __GLXscreen *screen,
|
|
|
cb51bc2 |
DrawablePtr pDraw,
|
|
|
cb51bc2 |
- int type,
|
|
|
cb51bc2 |
XID drawId,
|
|
|
cb51bc2 |
+ int type,
|
|
|
cb51bc2 |
+ XID glxDrawId,
|
|
|
cb51bc2 |
__GLXconfig *glxConfig)
|
|
|
cb51bc2 |
{
|
|
|
cb51bc2 |
__GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
|
|
|
cb51bc2 |
@@ -699,7 +701,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|
|
cb51bc2 |
return NULL;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
if (!__glXDrawableInit(&private->base, screen,
|
|
|
cb51bc2 |
- pDraw, type, drawId, glxConfig)) {
|
|
|
cb51bc2 |
+ pDraw, type, glxDrawId, glxConfig)) {
|
|
|
cb51bc2 |
xfree(private);
|
|
|
cb51bc2 |
return NULL;
|
|
|
cb51bc2 |
}
|
|
|
a54aedc |
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
|
|
|
da36744 |
index bc37285..5bdeedb 100644
|
|
|
a54aedc |
--- a/glx/glxdri2.c
|
|
|
a54aedc |
+++ b/glx/glxdri2.c
|
|
|
a54aedc |
@@ -105,11 +105,6 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
|
|
|
a54aedc |
|
|
|
a54aedc |
(*core->destroyDrawable)(private->driDrawable);
|
|
|
a54aedc |
|
|
|
a54aedc |
- /* If the X window was destroyed, the dri DestroyWindow hook will
|
|
|
a54aedc |
- * aready have taken care of this, so only call if pDraw isn't NULL. */
|
|
|
a54aedc |
- if (drawable->pDraw != NULL)
|
|
|
a54aedc |
- DRI2DestroyDrawable(drawable->pDraw);
|
|
|
a54aedc |
-
|
|
|
a54aedc |
__glXDrawableRelease(drawable);
|
|
|
a54aedc |
|
|
|
a54aedc |
xfree(private);
|
|
|
cb51bc2 |
@@ -435,10 +430,12 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
static __GLXdrawable *
|
|
|
cb51bc2 |
-__glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|
|
cb51bc2 |
+__glXDRIscreenCreateDrawable(ClientPtr client,
|
|
|
cb51bc2 |
+ __GLXscreen *screen,
|
|
|
cb51bc2 |
DrawablePtr pDraw,
|
|
|
cb51bc2 |
- int type,
|
|
|
cb51bc2 |
XID drawId,
|
|
|
cb51bc2 |
+ int type,
|
|
|
cb51bc2 |
+ XID glxDrawId,
|
|
|
cb51bc2 |
__GLXconfig *glxConfig)
|
|
|
cb51bc2 |
{
|
|
|
cb51bc2 |
__GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
|
|
|
cb51bc2 |
@@ -451,7 +448,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
private->screen = driScreen;
|
|
|
cb51bc2 |
if (!__glXDrawableInit(&private->base, screen,
|
|
|
cb51bc2 |
- pDraw, type, drawId, glxConfig)) {
|
|
|
cb51bc2 |
+ pDraw, type, glxDrawId, glxConfig)) {
|
|
|
cb51bc2 |
xfree(private);
|
|
|
cb51bc2 |
return NULL;
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
@@ -462,7 +459,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|
|
cb51bc2 |
private->base.waitGL = __glXDRIdrawableWaitGL;
|
|
|
cb51bc2 |
private->base.waitX = __glXDRIdrawableWaitX;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
- if (DRI2CreateDrawable(pDraw)) {
|
|
|
cb51bc2 |
+ if (DRI2CreateDrawable(client, pDraw, drawId)) {
|
|
|
cb51bc2 |
xfree(private);
|
|
|
cb51bc2 |
return NULL;
|
|
|
cb51bc2 |
}
|
|
|
da36744 |
@@ -725,7 +722,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
|
|
|
cb51bc2 |
screen->core = (const __DRIcoreExtension *) extensions[i];
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 &&
|
|
|
cb51bc2 |
- extensions[i]->version >= __DRI_DRI2_VERSION) {
|
|
|
cb51bc2 |
+ extensions[i]->version >= 1) {
|
|
|
cb51bc2 |
screen->dri2 = (const __DRIdri2Extension *) extensions[i];
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
|
|
|
cb51bc2 |
index c647d83..6a34393 100644
|
|
|
cb51bc2 |
--- a/glx/glxdriswrast.c
|
|
|
cb51bc2 |
+++ b/glx/glxdriswrast.c
|
|
|
cb51bc2 |
@@ -301,10 +301,12 @@ glxChangeGC(GCPtr gc, BITS32 mask, CARD32 val)
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
static __GLXdrawable *
|
|
|
cb51bc2 |
-__glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|
|
cb51bc2 |
+__glXDRIscreenCreateDrawable(ClientPtr client,
|
|
|
cb51bc2 |
+ __GLXscreen *screen,
|
|
|
cb51bc2 |
DrawablePtr pDraw,
|
|
|
cb51bc2 |
- int type,
|
|
|
cb51bc2 |
XID drawId,
|
|
|
cb51bc2 |
+ int type,
|
|
|
cb51bc2 |
+ XID glxDrawId,
|
|
|
cb51bc2 |
__GLXconfig *glxConfig)
|
|
|
cb51bc2 |
{
|
|
|
cb51bc2 |
__GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
|
|
|
cb51bc2 |
@@ -319,7 +321,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
private->screen = driScreen;
|
|
|
cb51bc2 |
if (!__glXDrawableInit(&private->base, screen,
|
|
|
cb51bc2 |
- pDraw, type, drawId, glxConfig)) {
|
|
|
cb51bc2 |
+ pDraw, type, glxDrawId, glxConfig)) {
|
|
|
cb51bc2 |
xfree(private);
|
|
|
cb51bc2 |
return NULL;
|
|
|
cb51bc2 |
}
|
|
|
a54aedc |
diff --git a/glx/glxext.c b/glx/glxext.c
|
|
|
a54aedc |
index 59bcfbe..89e58b0 100644
|
|
|
a54aedc |
--- a/glx/glxext.c
|
|
|
a54aedc |
+++ b/glx/glxext.c
|
|
|
a54aedc |
@@ -126,6 +126,17 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
|
|
|
a54aedc |
{
|
|
|
a54aedc |
__GLXcontext *c;
|
|
|
a54aedc |
|
|
|
a54aedc |
+ /* If this drawable was created using glx 1.3 drawable
|
|
|
a54aedc |
+ * constructors, we added it as a glx drawable resource under both
|
|
|
a54aedc |
+ * its glx drawable ID and it X drawable ID. Remove the other
|
|
|
a54aedc |
+ * resource now so we don't a callback for freed memory. */
|
|
|
a54aedc |
+ if (glxPriv->drawId != glxPriv->pDraw->id) {
|
|
|
a54aedc |
+ if (xid == glxPriv->drawId)
|
|
|
a54aedc |
+ FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE);
|
|
|
a54aedc |
+ else
|
|
|
a54aedc |
+ FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE);
|
|
|
a54aedc |
+ }
|
|
|
a54aedc |
+
|
|
|
a54aedc |
for (c = glxAllContexts; c; c = c->next) {
|
|
|
a54aedc |
if (c->isCurrent && (c->drawPriv == glxPriv || c->readPriv == glxPriv)) {
|
|
|
a54aedc |
int i;
|
|
|
a54aedc |
diff --git a/glx/glxscreens.c b/glx/glxscreens.c
|
|
|
da36744 |
index 58d8ee0..b75aea6 100644
|
|
|
a54aedc |
--- a/glx/glxscreens.c
|
|
|
a54aedc |
+++ b/glx/glxscreens.c
|
|
|
a54aedc |
@@ -215,7 +215,6 @@ glxCloseScreen (int index, ScreenPtr pScreen)
|
|
|
a54aedc |
__GLXscreen *pGlxScreen = glxGetScreen(pScreen);
|
|
|
a54aedc |
|
|
|
a54aedc |
pScreen->CloseScreen = pGlxScreen->CloseScreen;
|
|
|
a54aedc |
- pScreen->DestroyWindow = pGlxScreen->DestroyWindow;
|
|
|
a54aedc |
|
|
|
a54aedc |
pGlxScreen->destroy(pGlxScreen);
|
|
|
a54aedc |
|
|
|
a54aedc |
@@ -347,31 +346,6 @@ pickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual)
|
|
|
a54aedc |
return best;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
a54aedc |
-static Bool
|
|
|
a54aedc |
-glxDestroyWindow(WindowPtr pWin)
|
|
|
a54aedc |
-{
|
|
|
a54aedc |
- ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
|
a54aedc |
- __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
|
|
|
a54aedc |
- Bool retval = TRUE;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- FreeResource(pWin->drawable.id, FALSE);
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- /* call lower wrapped functions */
|
|
|
a54aedc |
- if (pGlxScreen->DestroyWindow) {
|
|
|
a54aedc |
- /* unwrap */
|
|
|
a54aedc |
- pScreen->DestroyWindow = pGlxScreen->DestroyWindow;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- /* call lower layers */
|
|
|
a54aedc |
- retval = (*pScreen->DestroyWindow)(pWin);
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- /* rewrap */
|
|
|
a54aedc |
- pGlxScreen->DestroyWindow = pScreen->DestroyWindow;
|
|
|
a54aedc |
- pScreen->DestroyWindow = glxDestroyWindow;
|
|
|
a54aedc |
- }
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- return retval;
|
|
|
a54aedc |
-}
|
|
|
a54aedc |
-
|
|
|
a54aedc |
void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
|
|
|
a54aedc |
{
|
|
|
a54aedc |
__GLXconfig *m;
|
|
|
a54aedc |
@@ -394,8 +368,6 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
|
|
|
a54aedc |
|
|
|
a54aedc |
pGlxScreen->CloseScreen = pScreen->CloseScreen;
|
|
|
a54aedc |
pScreen->CloseScreen = glxCloseScreen;
|
|
|
a54aedc |
- pGlxScreen->DestroyWindow = pScreen->DestroyWindow;
|
|
|
a54aedc |
- pScreen->DestroyWindow = glxDestroyWindow;
|
|
|
a54aedc |
|
|
|
a54aedc |
i = 0;
|
|
|
a54aedc |
for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
|
|
|
a54aedc |
diff --git a/glx/glxscreens.h b/glx/glxscreens.h
|
|
|
cb51bc2 |
index bff4363..861e03c 100644
|
|
|
a54aedc |
--- a/glx/glxscreens.h
|
|
|
a54aedc |
+++ b/glx/glxscreens.h
|
|
|
cb51bc2 |
@@ -134,10 +134,12 @@ struct __GLXscreen {
|
|
|
cb51bc2 |
__GLXconfig *modes,
|
|
|
cb51bc2 |
__GLXcontext *shareContext);
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
- __GLXdrawable *(*createDrawable)(__GLXscreen *context,
|
|
|
cb51bc2 |
+ __GLXdrawable *(*createDrawable)(ClientPtr client,
|
|
|
cb51bc2 |
+ __GLXscreen *context,
|
|
|
cb51bc2 |
DrawablePtr pDraw,
|
|
|
cb51bc2 |
- int type,
|
|
|
cb51bc2 |
XID drawId,
|
|
|
cb51bc2 |
+ int type,
|
|
|
cb51bc2 |
+ XID glxDrawId,
|
|
|
cb51bc2 |
__GLXconfig *modes);
|
|
|
cb51bc2 |
int (*swapInterval) (__GLXdrawable *drawable,
|
|
|
cb51bc2 |
int interval);
|
|
|
cb51bc2 |
@@ -173,7 +175,6 @@ struct __GLXscreen {
|
|
|
a54aedc |
/*@}*/
|
|
|
a54aedc |
|
|
|
a54aedc |
Bool (*CloseScreen)(int index, ScreenPtr pScreen);
|
|
|
a54aedc |
- Bool (*DestroyWindow)(WindowPtr pWindow);
|
|
|
a54aedc |
};
|
|
|
a54aedc |
|
|
|
a54aedc |
|
|
|
a54aedc |
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
|
|
|
485e329 |
index 2bdb733..11442d0 100644
|
|
|
a54aedc |
--- a/hw/xfree86/dri2/dri2.c
|
|
|
a54aedc |
+++ b/hw/xfree86/dri2/dri2.c
|
|
|
cb51bc2 |
@@ -37,6 +37,7 @@
|
|
|
cb51bc2 |
#include <errno.h>
|
|
|
cb51bc2 |
#include <xf86drm.h>
|
|
|
cb51bc2 |
#include "xf86Module.h"
|
|
|
cb51bc2 |
+#include "list.h"
|
|
|
cb51bc2 |
#include "scrnintstr.h"
|
|
|
cb51bc2 |
#include "windowstr.h"
|
|
|
cb51bc2 |
#include "dixstruct.h"
|
|
|
da36744 |
@@ -48,15 +49,20 @@
|
|
|
cb51bc2 |
CARD8 dri2_major; /* version of DRI2 supported by DDX */
|
|
|
cb51bc2 |
CARD8 dri2_minor;
|
|
|
a54aedc |
|
|
|
a54aedc |
-static int dri2ScreenPrivateKeyIndex;
|
|
|
a54aedc |
+static int dri2ScreenPrivateKeyIndex;
|
|
|
a54aedc |
static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
|
|
|
da36744 |
static int dri2WindowPrivateKeyIndex;
|
|
|
da36744 |
static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
|
|
|
da36744 |
static int dri2PixmapPrivateKeyIndex;
|
|
|
da36744 |
static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
|
|
|
a54aedc |
+static RESTYPE dri2DrawableRes;
|
|
|
a54aedc |
+
|
|
|
a54aedc |
+typedef struct _DRI2Screen *DRI2ScreenPtr;
|
|
|
a54aedc |
|
|
|
a54aedc |
typedef struct _DRI2Drawable {
|
|
|
a54aedc |
- unsigned int refCount;
|
|
|
a54aedc |
+ DRI2ScreenPtr dri2_screen;
|
|
|
cb51bc2 |
+ DrawablePtr drawable;
|
|
|
cb51bc2 |
+ struct list reference_list;
|
|
|
a54aedc |
int width;
|
|
|
a54aedc |
int height;
|
|
|
a54aedc |
DRI2BufferPtr *buffers;
|
|
|
da36744 |
@@ -73,9 +79,9 @@ typedef struct _DRI2Drawable {
|
|
|
a54aedc |
int swap_limit; /* for N-buffering */
|
|
|
a54aedc |
} DRI2DrawableRec, *DRI2DrawablePtr;
|
|
|
a54aedc |
|
|
|
a54aedc |
-typedef struct _DRI2Screen *DRI2ScreenPtr;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
typedef struct _DRI2Screen {
|
|
|
a54aedc |
+ ScreenPtr screen;
|
|
|
cb51bc2 |
+ int refcnt;
|
|
|
a54aedc |
unsigned int numDrivers;
|
|
|
a54aedc |
const char **driverNames;
|
|
|
a54aedc |
const char *deviceName;
|
|
|
da36744 |
@@ -101,45 +107,33 @@ DRI2GetScreen(ScreenPtr pScreen)
|
|
|
a54aedc |
static DRI2DrawablePtr
|
|
|
a54aedc |
DRI2GetDrawable(DrawablePtr pDraw)
|
|
|
a54aedc |
{
|
|
|
a54aedc |
- WindowPtr pWin;
|
|
|
a54aedc |
- PixmapPtr pPixmap;
|
|
|
da36744 |
+ WindowPtr pWin;
|
|
|
da36744 |
+ PixmapPtr pPixmap;
|
|
|
a54aedc |
|
|
|
a54aedc |
- if (!pDraw)
|
|
|
da36744 |
- return NULL;
|
|
|
da36744 |
-
|
|
|
a54aedc |
- if (pDraw->type == DRAWABLE_WINDOW)
|
|
|
a54aedc |
- {
|
|
|
da36744 |
+ if (pDraw->type == DRAWABLE_WINDOW) {
|
|
|
da36744 |
pWin = (WindowPtr) pDraw;
|
|
|
da36744 |
return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
|
|
|
a54aedc |
- }
|
|
|
a54aedc |
- else
|
|
|
a54aedc |
- {
|
|
|
da36744 |
+ } else {
|
|
|
da36744 |
pPixmap = (PixmapPtr) pDraw;
|
|
|
da36744 |
return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
|
|
|
da36744 |
}
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
cb51bc2 |
-int
|
|
|
cb51bc2 |
-DRI2CreateDrawable(DrawablePtr pDraw)
|
|
|
cb51bc2 |
+static DRI2DrawablePtr
|
|
|
cb51bc2 |
+DRI2AllocateDrawable(DrawablePtr pDraw)
|
|
|
a54aedc |
{
|
|
|
cb51bc2 |
DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
|
|
|
a54aedc |
- WindowPtr pWin;
|
|
|
a54aedc |
- PixmapPtr pPixmap;
|
|
|
a54aedc |
DRI2DrawablePtr pPriv;
|
|
|
cb51bc2 |
CARD64 ust;
|
|
|
da36744 |
-
|
|
|
a54aedc |
- pPriv = DRI2GetDrawable(pDraw);
|
|
|
a54aedc |
- if (pPriv != NULL)
|
|
|
a54aedc |
- {
|
|
|
a54aedc |
- pPriv->refCount++;
|
|
|
a54aedc |
- return Success;
|
|
|
a54aedc |
- }
|
|
|
da36744 |
+ WindowPtr pWin;
|
|
|
da36744 |
+ PixmapPtr pPixmap;
|
|
|
da36744 |
|
|
|
a54aedc |
pPriv = xalloc(sizeof *pPriv);
|
|
|
a54aedc |
if (pPriv == NULL)
|
|
|
cb51bc2 |
- return BadAlloc;
|
|
|
cb51bc2 |
+ return NULL;
|
|
|
a54aedc |
|
|
|
a54aedc |
- pPriv->refCount = 1;
|
|
|
cb51bc2 |
+ pPriv->dri2_screen = ds;
|
|
|
cb51bc2 |
+ pPriv->drawable = pDraw;
|
|
|
a54aedc |
pPriv->width = pDraw->width;
|
|
|
a54aedc |
pPriv->height = pDraw->height;
|
|
|
a54aedc |
pPriv->buffers = NULL;
|
|
|
485e329 |
@@ -157,44 +151,131 @@ DRI2CreateDrawable(DrawablePtr pDraw)
|
|
|
a54aedc |
pPriv->swap_limit = 1; /* default to double buffering */
|
|
|
cb51bc2 |
pPriv->last_swap_msc = 0;
|
|
|
cb51bc2 |
pPriv->last_swap_ust = 0;
|
|
|
cb51bc2 |
+ list_init(&pPriv->reference_list);
|
|
|
a54aedc |
|
|
|
a54aedc |
- if (pDraw->type == DRAWABLE_WINDOW)
|
|
|
a54aedc |
- {
|
|
|
da36744 |
+ if (pDraw->type == DRAWABLE_WINDOW) {
|
|
|
da36744 |
pWin = (WindowPtr) pDraw;
|
|
|
da36744 |
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
|
|
|
a54aedc |
- }
|
|
|
a54aedc |
- else
|
|
|
a54aedc |
- {
|
|
|
da36744 |
+ } else {
|
|
|
da36744 |
pPixmap = (PixmapPtr) pDraw;
|
|
|
da36744 |
dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
|
|
|
da36744 |
}
|
|
|
da36744 |
|
|
|
cb51bc2 |
+ return pPriv;
|
|
|
cb51bc2 |
+}
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+typedef struct DRI2DrawableRefRec {
|
|
|
cb51bc2 |
+ XID id;
|
|
|
cb51bc2 |
+ XID dri2_id;
|
|
|
cb51bc2 |
+ struct list link;
|
|
|
cb51bc2 |
+} DRI2DrawableRefRec, *DRI2DrawableRefPtr;
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+static DRI2DrawableRefPtr
|
|
|
da36744 |
+DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id)
|
|
|
cb51bc2 |
+{
|
|
|
cb51bc2 |
+ DRI2DrawableRefPtr ref;
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ list_for_each_entry(ref, &pPriv->reference_list, link) {
|
|
|
da36744 |
+ if (ref->id == id)
|
|
|
cb51bc2 |
+ return ref;
|
|
|
da36744 |
+ }
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ return NULL;
|
|
|
cb51bc2 |
+}
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+static int
|
|
|
cb51bc2 |
+DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id)
|
|
|
cb51bc2 |
+{
|
|
|
cb51bc2 |
+ DRI2DrawableRefPtr ref;
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ ref = malloc(sizeof *ref);
|
|
|
cb51bc2 |
+ if (ref == NULL)
|
|
|
cb51bc2 |
+ return BadAlloc;
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ if (!AddResource(dri2_id, dri2DrawableRes, pPriv))
|
|
|
a54aedc |
+ return BadAlloc;
|
|
|
da36744 |
+ if (!DRI2LookupDrawableRef(pPriv, id))
|
|
|
cb51bc2 |
+ if (!AddResource(id, dri2DrawableRes, pPriv))
|
|
|
cb51bc2 |
+ return BadAlloc;
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ ref->id = id;
|
|
|
cb51bc2 |
+ ref->dri2_id = dri2_id;
|
|
|
cb51bc2 |
+ list_add(&ref->link, &pPriv->reference_list);
|
|
|
da36744 |
+
|
|
|
a54aedc |
return Success;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
a54aedc |
-static void
|
|
|
a54aedc |
-DRI2FreeDrawable(DrawablePtr pDraw)
|
|
|
cb51bc2 |
+int
|
|
|
cb51bc2 |
+DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id)
|
|
|
a54aedc |
{
|
|
|
cb51bc2 |
DRI2DrawablePtr pPriv;
|
|
|
a54aedc |
- WindowPtr pWin;
|
|
|
a54aedc |
- PixmapPtr pPixmap;
|
|
|
cb51bc2 |
+ XID dri2_id;
|
|
|
cb51bc2 |
+ int rc;
|
|
|
a54aedc |
|
|
|
cb51bc2 |
pPriv = DRI2GetDrawable(pDraw);
|
|
|
cb51bc2 |
if (pPriv == NULL)
|
|
|
a54aedc |
- return;
|
|
|
cb51bc2 |
+ pPriv = DRI2AllocateDrawable(pDraw);
|
|
|
cb51bc2 |
+ if (pPriv == NULL)
|
|
|
cb51bc2 |
+ return BadAlloc;
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ dri2_id = FakeClientID(client->index);
|
|
|
cb51bc2 |
+ rc = DRI2AddDrawableRef(pPriv, id, dri2_id);
|
|
|
cb51bc2 |
+ if (rc != Success)
|
|
|
cb51bc2 |
+ return rc;
|
|
|
a54aedc |
|
|
|
cb51bc2 |
- xfree(pPriv);
|
|
|
cb51bc2 |
+ return Success;
|
|
|
cb51bc2 |
+}
|
|
|
a54aedc |
|
|
|
a54aedc |
- if (pDraw->type == DRAWABLE_WINDOW)
|
|
|
a54aedc |
- {
|
|
|
cb51bc2 |
+static int DRI2DrawableGone(pointer p, XID id)
|
|
|
cb51bc2 |
+{
|
|
|
cb51bc2 |
+ DRI2DrawablePtr pPriv = p;
|
|
|
cb51bc2 |
+ DRI2ScreenPtr ds = pPriv->dri2_screen;
|
|
|
cb51bc2 |
+ DRI2DrawableRefPtr ref, next;
|
|
|
da36744 |
+ WindowPtr pWin;
|
|
|
da36744 |
+ PixmapPtr pPixmap;
|
|
|
da36744 |
+ DrawablePtr pDraw;
|
|
|
cb51bc2 |
+ int i;
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) {
|
|
|
cb51bc2 |
+ if (ref->dri2_id == id) {
|
|
|
cb51bc2 |
+ list_del(&ref->link);
|
|
|
cb51bc2 |
+ /* If this was the last ref under this X drawable XID,
|
|
|
cb51bc2 |
+ * unregister the X drawable resource. */
|
|
|
da36744 |
+ if (!DRI2LookupDrawableRef(pPriv, ref->id))
|
|
|
cb51bc2 |
+ FreeResourceByType(ref->id, dri2DrawableRes, TRUE);
|
|
|
485e329 |
+ free(ref);
|
|
|
cb51bc2 |
+ break;
|
|
|
cb51bc2 |
+ }
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ if (ref->id == id) {
|
|
|
cb51bc2 |
+ list_del(&ref->link);
|
|
|
cb51bc2 |
+ FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE);
|
|
|
cb51bc2 |
+ free(ref);
|
|
|
cb51bc2 |
+ }
|
|
|
da36744 |
+ }
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ if (!list_is_empty(&pPriv->reference_list))
|
|
|
cb51bc2 |
+ return Success;
|
|
|
cb51bc2 |
+
|
|
|
da36744 |
+ pDraw = pPriv->drawable;
|
|
|
da36744 |
+ if (pDraw->type == DRAWABLE_WINDOW) {
|
|
|
da36744 |
pWin = (WindowPtr) pDraw;
|
|
|
da36744 |
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
|
|
|
da36744 |
- }
|
|
|
da36744 |
- else
|
|
|
da36744 |
- {
|
|
|
da36744 |
+ } else {
|
|
|
da36744 |
pPixmap = (PixmapPtr) pDraw;
|
|
|
da36744 |
dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
|
|
|
da36744 |
}
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ if (pPriv->buffers != NULL) {
|
|
|
cb51bc2 |
+ for (i = 0; i < pPriv->bufferCount; i++)
|
|
|
da36744 |
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ xfree(pPriv->buffers);
|
|
|
da36744 |
+ }
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
+ xfree(pPriv);
|
|
|
cb51bc2 |
+
|
|
|
a54aedc |
+ return Success;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
a54aedc |
static int
|
|
|
485e329 |
@@ -505,10 +586,6 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
|
|
|
a54aedc |
|
|
|
cb51bc2 |
pPriv->blockedClient = NULL;
|
|
|
cb51bc2 |
pPriv->blockedOnMsc = FALSE;
|
|
|
cb51bc2 |
-
|
|
|
cb51bc2 |
- /* If there's still a swap pending, let DRI2SwapComplete free it */
|
|
|
cb51bc2 |
- if (pPriv->refCount == 0 && pPriv->swapsPending == 0)
|
|
|
a54aedc |
- DRI2FreeDrawable(pDraw);
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
static void
|
|
|
485e329 |
@@ -576,13 +653,6 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
|
|
|
cb51bc2 |
pPriv->last_swap_ust = ust;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
|
|
|
a54aedc |
-
|
|
|
cb51bc2 |
- /*
|
|
|
cb51bc2 |
- * It's normal for the app to have exited with a swap outstanding, but
|
|
|
cb51bc2 |
- * don't free the drawable until they're all complete.
|
|
|
cb51bc2 |
- */
|
|
|
cb51bc2 |
- if (pPriv->swapsPending == 0 && pPriv->refCount == 0)
|
|
|
cb51bc2 |
- DRI2FreeDrawable(pDraw);
|
|
|
cb51bc2 |
}
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
Bool
|
|
|
485e329 |
@@ -750,7 +820,7 @@ DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
|
|
|
cb51bc2 |
Bool ret;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
pPriv = DRI2GetDrawable(pDraw);
|
|
|
cb51bc2 |
- if (pPriv == NULL || pPriv->refCount == 0)
|
|
|
cb51bc2 |
+ if (pPriv == NULL)
|
|
|
cb51bc2 |
return BadDrawable;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
/* Old DDX just completes immediately */
|
|
|
485e329 |
@@ -774,7 +844,7 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
|
|
|
cb51bc2 |
DRI2DrawablePtr pPriv;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
pPriv = DRI2GetDrawable(pDraw);
|
|
|
cb51bc2 |
- if (pPriv == NULL || pPriv->refCount == 0)
|
|
|
cb51bc2 |
+ if (pPriv == NULL)
|
|
|
cb51bc2 |
return BadDrawable;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
/* target_sbc == 0 means to block until all pending swaps are
|
|
|
485e329 |
@@ -800,36 +870,6 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
|
|
|
a54aedc |
return Success;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
a54aedc |
-void
|
|
|
a54aedc |
-DRI2DestroyDrawable(DrawablePtr pDraw)
|
|
|
a54aedc |
-{
|
|
|
a54aedc |
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
|
|
|
a54aedc |
- DRI2DrawablePtr pPriv;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- pPriv = DRI2GetDrawable(pDraw);
|
|
|
a54aedc |
- if (pPriv == NULL)
|
|
|
a54aedc |
- return;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- pPriv->refCount--;
|
|
|
a54aedc |
- if (pPriv->refCount > 0)
|
|
|
a54aedc |
- return;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- if (pPriv->buffers != NULL) {
|
|
|
a54aedc |
- int i;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- for (i = 0; i < pPriv->bufferCount; i++)
|
|
|
a54aedc |
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- xfree(pPriv->buffers);
|
|
|
a54aedc |
- }
|
|
|
a54aedc |
-
|
|
|
cb51bc2 |
- /* If the window is destroyed while we have a swap or wait pending, don't
|
|
|
a54aedc |
- * actually free the priv yet. We'll need it in the DRI2SwapComplete()
|
|
|
a54aedc |
- * callback and we'll free it there once we're done. */
|
|
|
cb51bc2 |
- if (!pPriv->swapsPending && !pPriv->blockedClient)
|
|
|
a54aedc |
- DRI2FreeDrawable(pDraw);
|
|
|
a54aedc |
-}
|
|
|
a54aedc |
-
|
|
|
a54aedc |
Bool
|
|
|
cb51bc2 |
DRI2HasSwapControl(ScreenPtr pScreen)
|
|
|
cb51bc2 |
{
|
|
|
485e329 |
@@ -890,6 +930,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
|
|
|
a54aedc |
if (!ds)
|
|
|
a54aedc |
return FALSE;
|
|
|
a54aedc |
|
|
|
a54aedc |
+ ds->screen = pScreen;
|
|
|
a54aedc |
ds->fd = info->fd;
|
|
|
a54aedc |
ds->deviceName = info->deviceName;
|
|
|
cb51bc2 |
dri2_major = 1;
|
|
|
485e329 |
@@ -961,6 +1002,8 @@ DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
|
|
|
a54aedc |
{
|
|
|
a54aedc |
static Bool setupDone = FALSE;
|
|
|
a54aedc |
|
|
|
a54aedc |
+ dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
|
|
|
a54aedc |
+
|
|
|
a54aedc |
if (!setupDone)
|
|
|
a54aedc |
{
|
|
|
a54aedc |
setupDone = TRUE;
|
|
|
cb51bc2 |
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
|
|
|
cb51bc2 |
index ce8a5df..5415a0b 100644
|
|
|
cb51bc2 |
--- a/hw/xfree86/dri2/dri2.h
|
|
|
cb51bc2 |
+++ b/hw/xfree86/dri2/dri2.h
|
|
|
cb51bc2 |
@@ -198,7 +198,8 @@ extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen,
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic);
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
-extern _X_EXPORT int DRI2CreateDrawable(DrawablePtr pDraw);
|
|
|
cb51bc2 |
+extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
|
|
|
cb51bc2 |
+ DrawablePtr pDraw, XID id);
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
|
|
|
cb51bc2 |
|
|
|
a54aedc |
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
|
|
|
cb51bc2 |
index 094d54d..58eaa10 100644
|
|
|
a54aedc |
--- a/hw/xfree86/dri2/dri2ext.c
|
|
|
a54aedc |
+++ b/hw/xfree86/dri2/dri2ext.c
|
|
|
a54aedc |
@@ -51,7 +51,6 @@
|
|
|
a54aedc |
#include "xf86Module.h"
|
|
|
a54aedc |
|
|
|
a54aedc |
static ExtensionEntry *dri2Extension;
|
|
|
a54aedc |
-static RESTYPE dri2DrawableRes;
|
|
|
a54aedc |
|
|
|
a54aedc |
static Bool
|
|
|
a54aedc |
validDrawable(ClientPtr client, XID drawable, Mask access_mode,
|
|
|
cb51bc2 |
@@ -168,15 +167,10 @@ ProcDRI2CreateDrawable(ClientPtr client)
|
|
|
cb51bc2 |
&pDrawable, &status))
|
|
|
cb51bc2 |
return status;
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
- status = DRI2CreateDrawable(pDrawable);
|
|
|
cb51bc2 |
+ status = DRI2CreateDrawable(client, pDrawable, stuff->drawable);
|
|
|
a54aedc |
if (status != Success)
|
|
|
a54aedc |
return status;
|
|
|
a54aedc |
|
|
|
a54aedc |
- if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) {
|
|
|
a54aedc |
- DRI2DestroyDrawable(pDrawable);
|
|
|
a54aedc |
- return BadAlloc;
|
|
|
a54aedc |
- }
|
|
|
a54aedc |
-
|
|
|
a54aedc |
return client->noClientException;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
a54aedc |
@@ -192,8 +186,6 @@ ProcDRI2DestroyDrawable(ClientPtr client)
|
|
|
a54aedc |
&pDrawable, &status))
|
|
|
a54aedc |
return status;
|
|
|
a54aedc |
|
|
|
a54aedc |
- FreeResourceByType(stuff->drawable, dri2DrawableRes, FALSE);
|
|
|
a54aedc |
-
|
|
|
a54aedc |
return client->noClientException;
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
cb51bc2 |
@@ -627,25 +619,11 @@ SProcDRI2Dispatch (ClientPtr client)
|
|
|
a54aedc |
}
|
|
|
a54aedc |
}
|
|
|
a54aedc |
|
|
|
a54aedc |
-static int DRI2DrawableGone(pointer p, XID id)
|
|
|
a54aedc |
-{
|
|
|
a54aedc |
- DrawablePtr pDrawable = p;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- DRI2DestroyDrawable(pDrawable);
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- return Success;
|
|
|
a54aedc |
-}
|
|
|
a54aedc |
-
|
|
|
a54aedc |
int DRI2EventBase;
|
|
|
a54aedc |
|
|
|
a54aedc |
static void
|
|
|
a54aedc |
DRI2ExtensionInit(void)
|
|
|
a54aedc |
{
|
|
|
a54aedc |
- dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
|
|
|
a54aedc |
-
|
|
|
a54aedc |
- if (!dri2DrawableRes)
|
|
|
a54aedc |
- return;
|
|
|
a54aedc |
-
|
|
|
a54aedc |
dri2Extension = AddExtension(DRI2_NAME,
|
|
|
a54aedc |
DRI2NumberEvents,
|
|
|
a54aedc |
DRI2NumberErrors,
|
|
|
cb51bc2 |
diff --git a/include/list.h b/include/list.h
|
|
|
cb51bc2 |
index a126a65..89dc29d 100644
|
|
|
cb51bc2 |
--- a/include/list.h
|
|
|
cb51bc2 |
+++ b/include/list.h
|
|
|
cb51bc2 |
@@ -94,4 +94,10 @@ list_is_empty(struct list *head)
|
|
|
cb51bc2 |
&pos->member != (head); \
|
|
|
cb51bc2 |
pos = __container_of(pos->member.next, pos, member))
|
|
|
cb51bc2 |
|
|
|
cb51bc2 |
+#define list_for_each_entry_safe(pos, next, head, member) \
|
|
|
cb51bc2 |
+ for (pos = __container_of((head)->next, pos, member), \
|
|
|
cb51bc2 |
+ next = __container_of(pos->member.next, pos, member); \
|
|
|
cb51bc2 |
+ &pos->member != (head); \
|
|
|
cb51bc2 |
+ pos = next, next = __container_of(next->member.next, next, member))
|
|
|
cb51bc2 |
+
|
|
|
cb51bc2 |
#endif
|
|
|
a54aedc |
--
|
|
|
cb51bc2 |
1.7.0.1
|
|
|
a54aedc |
|