XQuartz: xpr: The dri.c code for pixmaps was wrong in several ways. They weren't

being exported correctly by Xplugin.

This should fix a bug with the surface for a window, when an export fails.
Before the export could fail and leave behind an invalid (freed) pointer in the dix privates.

I have an idea of how to fix the GLXPixmaps now without using CGLSetOffScreen.

This work is a step towards that.  The Xplugin will need a small patch to fix an
issue that this change brought forth.
(cherry picked from commit 58c4116c47)
This commit is contained in:
George Staplin 2009-02-06 12:55:09 -07:00 committed by Jeremy Huddleston
parent b17d6bed97
commit d229ba7068

View File

@ -406,7 +406,7 @@ CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr)
return pDRIDrawablePriv;
}
/* Return FALSE if an error occurs. */
/* Return NULL if an error occurs. */
static DRIDrawablePrivPtr
CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
DRIDrawablePrivPtr pDRIDrawablePriv;
@ -415,7 +415,6 @@ CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
if (pDRIDrawablePriv == NULL) {
xp_error err;
xp_window_changes wc;
/* allocate a DRI Window Private record */
if (!(pDRIDrawablePriv = xcalloc(1, sizeof(*pDRIDrawablePriv)))) {
@ -437,18 +436,10 @@ CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
return NULL;
}
wc.x = 0;
wc.y = 0;
wc.width = pPix->drawable.width;
wc.height = pPix->drawable.height;
err = xp_configure_surface(pDRIDrawablePriv->sid, XP_BOUNDS, &wc);
if(err != Success) {
xp_destroy_surface(pDRIDrawablePriv->sid);
xfree(pDRIDrawablePriv);
return NULL;
}
/*
* The DRIUpdateSurface will be called to resize the surface
* after this function, if the export is successful.
*/
/* save private off of preallocated index */
dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey,
@ -489,21 +480,39 @@ DRICreateSurface(ScreenPtr pScreen, Drawable id,
/* NOT_DONE */
return FALSE;
}
/* Finish initialization of new surfaces */
if (pDRIDrawablePriv->refCount == 0) {
unsigned int key[2] = {0};
xp_error err;
/* try to give the client access to the surface */
if (client_id != 0 && wid != 0) {
if (client_id != 0) {
/*
* Xplugin accepts a 0 wid if the surface id is offscreen, such
* as for a pixmap.
*/
err = xp_export_surface(wid, pDRIDrawablePriv->sid,
client_id, key);
if (err != Success) {
xp_destroy_surface(pDRIDrawablePriv->sid);
xfree(pDRIDrawablePriv);
/*
* Now set the dix privates to NULL that were previously set.
* This prevents reusing an invalid pointer.
*/
if(pDrawable->type == DRAWABLE_WINDOW) {
WindowPtr pWin = (WindowPtr)pDrawable;
dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
} else if(pDrawable->type == DRAWABLE_PIXMAP) {
PixmapPtr pPix = (PixmapPtr)pDrawable;
dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
}
return FALSE;
}
}