summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPauli Nieminen <ext-pauli.nieminen@nokia.com>2011-02-01 17:23:16 +0200
committerPauli Nieminen <ext-pauli.nieminen@nokia.com>2011-02-04 17:32:06 +0200
commitf0f9dda84e7e9fd0fe59bdc0c2eaa75204df077e (patch)
treeb8e6fa05d5f0447622930883cfd61da0356b6ce6
parentafdbea7c8f99e822f117feefd297bda100fc4dda (diff)
dri2: Change driver interface to support DRI2Drawable
To let DRI2Drawable exists longer than Drawable driver has to use DRI2DrawablePtr to complete swaps and MSC waits. This allows DRI2 to clean up after all operations complete without accessing the freed DrawablePtr. Signed-off-by: Pauli Nieminen <ext-pauli.nieminen@nokia.com>
-rw-r--r--hw/xfree86/dri2/dri2.c72
-rw-r--r--hw/xfree86/dri2/dri2.h22
2 files changed, 58 insertions, 36 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 91ae1a0d3..f97f60ea0 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -95,7 +95,7 @@ typedef struct _DRI2Screen {
unsigned int lastSequence;
DRI2CreateBufferProcPtr CreateBuffer;
- DRI2DestroyBufferProcPtr DestroyBuffer;
+ DRI2DestroyBuffer2ProcPtr DestroyBuffer;
DRI2CopyRegionProcPtr CopyRegion;
DRI2ScheduleSwapProcPtr ScheduleSwap;
DRI2GetMSCProcPtr GetMSC;
@@ -137,6 +137,12 @@ DRI2DrawableGetDrawable(DRI2DrawablePtr pPriv)
return pPriv->drawable;
}
+ScreenPtr
+DRI2DrawableGetScreen(DRI2DrawablePtr pPriv)
+{
+ return pPriv->dri2_screen->screen;
+}
+
static unsigned long
DRI2DrawableSerial(DrawablePtr pDraw)
{
@@ -323,6 +329,7 @@ static int DRI2DrawableGone(pointer p, XID id)
return Success;
pDraw = pPriv->drawable;
+
if (pDraw->type == DRAWABLE_WINDOW) {
pWin = (WindowPtr) pDraw;
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
@@ -333,7 +340,7 @@ static int DRI2DrawableGone(pointer p, XID id)
if (pPriv->buffers != NULL) {
for (i = 0; i < pPriv->bufferCount; i++)
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+ (*ds->DestroyBuffer)(pPriv, pPriv->buffers[i]);
free(pPriv->buffers);
}
@@ -394,7 +401,7 @@ update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
if (pPriv->buffers != NULL) {
for (i = 0; i < pPriv->bufferCount; i++) {
if (pPriv->buffers[i] != NULL) {
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+ (*ds->DestroyBuffer)(pPriv, pPriv->buffers[i]);
}
}
@@ -531,7 +538,7 @@ err_out:
for (i = 0; i < count; i++) {
if (buffers[i] != NULL)
- (*ds->DestroyBuffer)(pDraw, buffers[i]);
+ (*ds->DestroyBuffer)(pPriv, buffers[i]);
}
free(buffers);
@@ -684,14 +691,10 @@ DRI2CanExchange(DrawablePtr pDraw)
}
void
-DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
+DRI2WaitMSCComplete(int client_index, DRI2DrawablePtr pPriv, int frame,
unsigned int tv_sec, unsigned int tv_usec)
{
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return;
+ ClientPtr client = clients[client_index];
ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
frame, pPriv->swap_count);
@@ -740,33 +743,30 @@ DRI2WakeClient(ClientPtr client, DRI2DrawablePtr pPriv, int frame,
}
void
-DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
+DRI2SwapComplete(int client_index, DRI2DrawablePtr pPriv, int frame,
unsigned int tv_sec, unsigned int tv_usec, int type,
DRI2SwapEventPtr swap_complete, void *swap_data)
{
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2DrawablePtr pPriv;
+ ClientPtr client = clients[client_index];
+ DrawablePtr pDraw = pPriv->drawable;
CARD64 ust = 0;
- BoxRec box;
- RegionRec region;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return;
- }
pPriv->swapsPending--;
pPriv->swap_count++;
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pDraw->width;
- box.y2 = pDraw->height;
- RegionInit(&region, &box, 0);
- DRI2CopyRegion(pPriv, &region, DRI2BufferFakeFrontLeft,
- DRI2BufferFrontLeft);
+
+ if (pDraw) {
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDraw->width;
+ box.y2 = pDraw->height;
+ RegionInit(&region, &box, 0);
+ DRI2CopyRegion(pPriv, &region, DRI2BufferFakeFrontLeft,
+ DRI2BufferFrontLeft);
+ }
ust = ((CARD64)tv_sec * 1000000) + tv_usec;
if (swap_complete)
@@ -839,7 +839,7 @@ DRI2SwapBuffers(ClientPtr client, DRI2DrawablePtr pPriv, CARD64 target_msc,
pPriv->swapsPending++;
(*ds->CopyRegion)(pDraw, &region, pDestBuffer, pSrcBuffer);
- DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
+ DRI2SwapComplete(client->index, pPriv, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
func, data);
return Success;
}
@@ -954,7 +954,7 @@ DRI2WaitMSC(ClientPtr client, DRI2DrawablePtr pPriv, CARD64 target_msc,
/* Old DDX just completes immediately */
if (!ds->ScheduleWaitMSC) {
- DRI2WaitMSCComplete(client, pDraw, target_msc, 0, 0);
+ DRI2WaitMSCComplete(client->index, pPriv, target_msc, 0, 0);
return Success;
}
@@ -1098,7 +1098,6 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
dri2_major = 1;
ds->CreateBuffer = info->CreateBuffer;
- ds->DestroyBuffer = info->DestroyBuffer;
ds->CopyRegion = info->CopyRegion;
if (info->version >= 4) {
@@ -1114,6 +1113,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
ds->AuthMagic = info->AuthMagic;
}
+ if (info->version >= 6)
+ ds->DestroyBuffer = info->DestroyBuffer2;
+
/*
* if the driver doesn't provide an AuthMagic function or the info struct
* version is too low, it relies on the old method (using libdrm) or fail
@@ -1125,6 +1127,12 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
goto err_out;
#endif
+ if (!ds->DestroyBuffer) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[DRI2] DestroyBuffer2 hook is required by this server.\n");
+ goto err_out;
+ }
+
/* Initialize minor if needed and set to minimum provied by DDX */
if (!dri2_minor || dri2_minor > cur_minor)
dri2_minor = cur_minor;
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 509d4f660..2c11e6bd6 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -113,6 +113,8 @@ typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
unsigned int format);
typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
DRI2BufferPtr buffer);
+typedef void (*DRI2DestroyBuffer2ProcPtr)(DRI2DrawablePtr pPriv,
+ DRI2BufferPtr buffer);
/**
* Get current media stamp counter values
*
@@ -166,7 +168,7 @@ typedef void (*DRI2InvalidateProcPtr)(DRI2DrawablePtr pPriv,
/**
* Version of the DRI2InfoRec structure defined in this header
*/
-#define DRI2INFOREC_VERSION 5
+#define DRI2INFOREC_VERSION 6
typedef struct {
unsigned int version; /**< Version of this struct */
@@ -175,7 +177,7 @@ typedef struct {
const char *deviceName;
DRI2CreateBufferProcPtr CreateBuffer;
- DRI2DestroyBufferProcPtr DestroyBuffer;
+ DRI2DestroyBufferProcPtr DestroyBuffer; /* Ignored in version 6 and after */
DRI2CopyRegionProcPtr CopyRegion;
DRI2WaitProcPtr Wait;
@@ -194,6 +196,10 @@ typedef struct {
/* added in version 5 */
DRI2AuthMagicProcPtr AuthMagic;
+
+ /* added in version 6 */
+
+ DRI2DestroyBuffer2ProcPtr DestroyBuffer2;
} DRI2InfoRec, *DRI2InfoPtr;
extern _X_EXPORT int DRI2EventBase;
@@ -282,12 +288,12 @@ extern _X_EXPORT Bool DRI2CanExchange(DrawablePtr pDraw);
/* Note: use *only* for MSC related waits */
extern _X_EXPORT void DRI2BlockClient(ClientPtr client, DrawablePtr pDraw);
-extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw,
+extern _X_EXPORT void DRI2SwapComplete(int client_index, DRI2DrawablePtr pPriv,
int frame, unsigned int tv_sec,
unsigned int tv_usec, int type,
DRI2SwapEventPtr swap_complete,
void *swap_data);
-extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw,
+extern _X_EXPORT void DRI2WaitMSCComplete(int client_index, DRI2DrawablePtr pPriv,
int frame, unsigned int tv_sec,
unsigned int tv_usec);
/**
@@ -301,6 +307,14 @@ extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw,
extern _X_EXPORT DrawablePtr DRI2DrawableGetDrawable(DRI2DrawablePtr pPriv);
/**
+ * Provides access to ScreenPtr trough DRI2DrawablePtr
+ *
+ * \param pPriv DRI2 private drawable
+ * \return valid pointer to Screen
+ */
+extern _X_EXPORT ScreenPtr DRI2DrawableGetScreen(DRI2DrawablePtr pPriv);
+
+/**
* Provides access to DRI2DrawablePtr trough DrawablePtr
*
* \param pDraw drawable pointer