xserver: Branch 'glucose-2'
Alan Hourihane
alanh at kemper.freedesktop.org
Tue Mar 27 15:30:15 EEST 2007
hw/xfree86/dri/dri.c | 186 +++++++++++++++++++++++++++++++++++++++++----
hw/xfree86/dri/dristruct.h | 2
2 files changed, 173 insertions(+), 15 deletions(-)
New commits:
diff-tree 71ee3e7c4849ee971a1f2a80531559f0b1d02e5a (from bd07acb187c391fc3263081771b9c67690661bde)
Author: Alan Hourihane <alanh at fairlite.demon.co.uk>
Date: Tue Mar 27 13:30:14 2007 +0100
Hack the DRI module to accept PIXMAPs.
For glucose use only.
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 7bd07c0..cef5ef3 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -79,6 +79,7 @@ extern Bool noPanoramiXExtension;
static int DRIScreenPrivIndex = -1;
static int DRIWindowPrivIndex = -1;
+static int DRIPixmapPrivIndex = -1;
static unsigned long DRIGeneration = 0;
static unsigned int DRIDrawableValidationStamp = 0;
@@ -616,6 +617,12 @@ DRIExtensionInit(void)
*/
if ((DRIWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
return FALSE;
+ /* Allocate a pixmap private index with a zero sized private area for
+ * each pixmap, then should a pixmap become a DRI pixmap, we'll hang
+ * a DRIPixmapPrivateRec off of this private index.
+ */
+ if ((DRIPixmapPrivIndex = AllocatePixmapPrivateIndex()) < 0)
+ return FALSE;
DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete);
DRIContextPrivResType = CreateNewResourceType(DRIContextPrivDelete);
@@ -625,6 +632,8 @@ DRIExtensionInit(void)
pScreen = screenInfo.screens[i];
if (!AllocateWindowPrivate(pScreen, DRIWindowPrivIndex, 0))
return FALSE;
+ if (!AllocatePixmapPrivate(pScreen, DRIPixmapPrivIndex, 0))
+ return FALSE;
}
RegisterBlockAndWakeupHandlers(DRIBlockHandler, DRIWakeupHandler, NULL);
@@ -1102,10 +1111,9 @@ DRICreateDrawable(ScreenPtr pScreen, Dra
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
DRIDrawablePrivPtr pDRIDrawablePriv;
- WindowPtr pWin;
if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
+ WindowPtr pWin = (WindowPtr)pDrawable;
if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
pDRIDrawablePriv->refCount++;
@@ -1154,9 +1162,47 @@ DRICreateDrawable(ScreenPtr pScreen, Dra
*hHWDrawable = pDRIDrawablePriv->hwDrawable;
}
}
- else { /* pixmap (or for GLX 1.3, a PBuffer) */
- /* NOT_DONE */
- return FALSE;
+ else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ PixmapPtr pPixmap = (PixmapPtr)pDrawable;
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPixmap))) {
+ pDRIDrawablePriv->refCount++;
+
+ if (!pDRIDrawablePriv->hwDrawable) {
+ drmCreateDrawable(pDRIPriv->drmFD, &pDRIDrawablePriv->hwDrawable);
+ }
+ }
+ else {
+ /* allocate a DRI Window Private record */
+ if (!(pDRIDrawablePriv = xalloc(sizeof(DRIDrawablePrivRec)))) {
+ return FALSE;
+ }
+
+ /* Only create a drm_drawable_t once */
+ if (drmCreateDrawable(pDRIPriv->drmFD,
+ &pDRIDrawablePriv->hwDrawable)) {
+ xfree(pDRIDrawablePriv);
+ return FALSE;
+ }
+
+ /* add it to the list of DRI drawables for this screen */
+ pDRIDrawablePriv->pScreen = pScreen;
+ pDRIDrawablePriv->refCount = 1;
+ pDRIDrawablePriv->drawableIndex = -1;
+ pDRIDrawablePriv->nrects = 1;
+
+ /* save private off of preallocated index */
+ pPixmap->devPrivates[DRIPixmapPrivIndex].ptr =
+ (pointer)pDRIDrawablePriv;
+
+ /* track this in case this window is destroyed */
+ AddResource(id, DRIDrawablePrivResType, (pointer)pPixmap);
+ }
+
+ if (pDRIDrawablePriv->hwDrawable)
+ *hHWDrawable = pDRIDrawablePriv->hwDrawable;
+ }
+ else { /* for GLX 1.3, a PBuffer */
+ return FALSE;
}
return TRUE;
@@ -1166,11 +1212,9 @@ Bool
DRIDestroyDrawable(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable)
{
DRIDrawablePrivPtr pDRIDrawablePriv;
- WindowPtr pWin;
-
if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
+ WindowPtr pWin = (WindowPtr)pDrawable;
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
pDRIDrawablePriv->refCount--;
if (pDRIDrawablePriv->refCount <= 0) {
@@ -1178,6 +1222,15 @@ DRIDestroyDrawable(ScreenPtr pScreen, Dr
FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
}
}
+ else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ PixmapPtr pPixmap = (PixmapPtr)pDrawable;
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPixmap);
+ pDRIDrawablePriv->refCount--;
+ if (pDRIDrawablePriv->refCount <= 0) {
+ /* This calls back DRIDrawablePrivDelete which frees private area */
+ FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
+ }
+ }
else { /* pixmap (or for GLX 1.3, a PBuffer) */
/* NOT_DONE */
return FALSE;
@@ -1192,10 +1245,9 @@ DRIDrawablePrivDelete(pointer pResource,
DrawablePtr pDrawable = (DrawablePtr)pResource;
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
DRIDrawablePrivPtr pDRIDrawablePriv;
- WindowPtr pWin;
if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
+ WindowPtr pWin = (WindowPtr)pDrawable;
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
if (pDRIDrawablePriv->drawableIndex != -1) {
@@ -1220,7 +1272,28 @@ DRIDrawablePrivDelete(pointer pResource,
if (REGION_NUM_RECTS(&pWin->clipList))
DRIDecreaseNumberVisible(pDrawable->pScreen);
}
- else { /* pixmap (or for GLX 1.3, a PBuffer) */
+ else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ PixmapPtr pPixmap = (PixmapPtr)pDrawable;
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPixmap);
+
+ if (pDRIDrawablePriv->drawableIndex != -1) {
+ /* bump stamp to force outstanding 3D requests to resync */
+ pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
+ = DRIDrawableValidationStamp++;
+
+ /* release drawable table entry */
+ pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
+ }
+
+ if (drmDestroyDrawable(pDRIPriv->drmFD,
+ pDRIDrawablePriv->hwDrawable)) {
+ return FALSE;
+ }
+
+ xfree(pDRIDrawablePriv);
+ pPixmap->devPrivates[DRIPixmapPrivIndex].ptr = NULL;
+ }
+ else { /* or for GLX 1.3, a PBuffer */
/* NOT_DONE */
return FALSE;
}
@@ -1246,7 +1319,6 @@ DRIGetDrawableInfo(ScreenPtr pScreen,
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
DRIDrawablePrivPtr pDRIDrawablePriv, pOldDrawPriv;
- WindowPtr pWin, pOldWin;
int i;
#if 0
@@ -1254,7 +1326,8 @@ DRIGetDrawableInfo(ScreenPtr pScreen,
#endif
if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
+ WindowPtr pOldWin;
+ WindowPtr pWin = (WindowPtr)pDrawable;
if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
/* Manage drawable table */
@@ -1387,7 +1460,92 @@ DRIGetDrawableInfo(ScreenPtr pScreen,
return FALSE;
}
}
- else { /* pixmap (or for GLX 1.3, a PBuffer) */
+ else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ PixmapPtr pOldPixmap;
+ PixmapPtr pPixmap = (PixmapPtr)pDrawable;
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPixmap))) {
+
+ /* Manage drawable table */
+ if (pDRIDrawablePriv->drawableIndex == -1) { /* load SAREA table */
+
+ /* Search table for empty entry */
+ i = 0;
+ while (i < pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
+ if (!(pDRIPriv->DRIDrawables[i])) {
+ pDRIPriv->DRIDrawables[i] = pDrawable;
+ pDRIDrawablePriv->drawableIndex = i;
+ pDRIPriv->pSAREA->drawableTable[i].stamp =
+ DRIDrawableValidationStamp++;
+ break;
+ }
+ i++;
+ }
+
+ /* Search table for oldest entry */
+ if (i == pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
+ unsigned int oldestStamp = ~0;
+ int oldestIndex = 0;
+ i = pDRIPriv->pDriverInfo->maxDrawableTableEntry;
+ while (i--) {
+ if (pDRIPriv->pSAREA->drawableTable[i].stamp <
+ oldestStamp) {
+ oldestIndex = i;
+ oldestStamp =
+ pDRIPriv->pSAREA->drawableTable[i].stamp;
+ }
+ }
+ pDRIDrawablePriv->drawableIndex = oldestIndex;
+
+ /* release oldest drawable table entry */
+ pOldPixmap = (PixmapPtr)pDRIPriv->DRIDrawables[oldestIndex];
+ pOldDrawPriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pOldPixmap);
+ pOldDrawPriv->drawableIndex = -1;
+
+ /* claim drawable table entry */
+ pDRIPriv->DRIDrawables[oldestIndex] = pDrawable;
+
+ /* validate SAREA entry */
+ pDRIPriv->pSAREA->drawableTable[oldestIndex].stamp =
+ DRIDrawableValidationStamp++;
+
+ /* check for stamp wrap around */
+ if (oldestStamp > DRIDrawableValidationStamp) {
+
+ /* walk SAREA table and invalidate all drawables */
+ for( i=0;
+ i < pDRIPriv->pDriverInfo->maxDrawableTableEntry;
+ i++) {
+ pDRIPriv->pSAREA->drawableTable[i].stamp =
+ DRIDrawableValidationStamp++;
+ }
+ }
+ }
+ }
+
+ *index = pDRIDrawablePriv->drawableIndex;
+ *stamp = pDRIPriv->pSAREA->drawableTable[*index].stamp;
+ *X = (int)(pPixmap->drawable.x);
+ *Y = (int)(pPixmap->drawable.y);
+ *W = (int)(pPixmap->drawable.width);
+ *H = (int)(pPixmap->drawable.height);
+ /* use pixmap clip rect */
+ pDRIPriv->fullscreen_rect.x1 = *X;
+ pDRIPriv->fullscreen_rect.y1 = *Y;
+ pDRIPriv->fullscreen_rect.x2 = *X + *W;
+ pDRIPriv->fullscreen_rect.y2 = *Y + *H;
+ *numClipRects = 1;
+ *pClipRects = &pDRIPriv->fullscreen_rect;
+
+ /* Use the frontbuffer cliprects for back buffers. */
+ *numBackClipRects = 0;
+ *pBackClipRects = NULL;
+ }
+ else {
+ /* Not a DRIDrawable */
+ return FALSE;
+ }
+ }
+ else { /* (or for GLX 1.3, a PBuffer) */
/* NOT_DONE */
return FALSE;
}
diff --git a/hw/xfree86/dri/dristruct.h b/hw/xfree86/dri/dristruct.h
index 9c42ff9..eba28da 100644
--- a/hw/xfree86/dri/dristruct.h
+++ b/hw/xfree86/dri/dristruct.h
@@ -45,7 +45,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
#define DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix) \
((DRIPixmapPrivIndex < 0) ? \
NULL : \
- ((DRIDrawablePrivPtr)((pPix)->devPrivates[DRIWindowPrivIndex].ptr)))
+ ((DRIDrawablePrivPtr)((pPix)->devPrivates[DRIPixmapPrivIndex].ptr)))
typedef struct _DRIDrawablePrivRec
{
More information about the xorg-commit
mailing list