dri2: Update to latest protocol draft.

Mainly rename SwapBuffers to CopyRegion, which adds the xfixes region
argument and the bitmask argument to let us extend it in the future.
This commit is contained in:
Kristian Høgsberg 2008-10-07 13:49:28 -04:00
parent 87a016ae00
commit ced6690284
4 changed files with 147 additions and 100 deletions

View File

@ -110,13 +110,30 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
xfree(private); xfree(private);
} }
static void
__glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
int x, int y, int w, int h)
{
BoxRec box;
RegionRec region;
box.x1 = x;
box.y1 = y;
box.x2 = x + w;
box.y2 = y + h;
REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
DRI2CopyRegion(drawable->pDraw, &region,
DRI2BufferFrontLeft, DRI2BufferBackLeft);
}
static GLboolean static GLboolean
__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
{ {
__GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
DRI2SwapBuffers(drawable->pDraw, __glXDRIdrawableCopySubBuffer(drawable, 0, 0,
0, 0, private->width, private->height); private->width, private->height);
return TRUE; return TRUE;
} }
@ -128,14 +145,6 @@ __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
return 0; return 0;
} }
static void
__glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
int x, int y, int w, int h)
{
DRI2SwapBuffers(drawable->pDraw, x, y, w, h);
}
static void static void
__glXDRIcontextDestroy(__GLXcontext *baseContext) __glXDRIcontextDestroy(__GLXcontext *baseContext)
{ {
@ -452,7 +461,7 @@ initializeExtensions(__GLXDRIscreen *screen)
static __GLXscreen * static __GLXscreen *
__glXDRIscreenProbe(ScreenPtr pScreen) __glXDRIscreenProbe(ScreenPtr pScreen)
{ {
const char *driverName; const char *driverName, *deviceName;
__GLXDRIscreen *screen; __GLXDRIscreen *screen;
char filename[128]; char filename[128];
size_t buffer_size; size_t buffer_size;
@ -466,7 +475,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
return NULL; return NULL;
if (!xf86LoaderCheckSymbol("DRI2Connect") || if (!xf86LoaderCheckSymbol("DRI2Connect") ||
!DRI2Connect(pScreen, &screen->fd, &driverName)) { !DRI2Connect(pScreen, DRI2DriverDRI,
&screen->fd, &driverName, &deviceName)) {
LogMessage(X_INFO, LogMessage(X_INFO,
"AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum); "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum);
return NULL; return NULL;

View File

@ -55,14 +55,21 @@ typedef struct _DRI2Drawable {
int height; int height;
DRI2BufferPtr buffers; DRI2BufferPtr buffers;
int bufferCount; int bufferCount;
unsigned int pendingSequence;
} DRI2DrawableRec, *DRI2DrawablePtr; } DRI2DrawableRec, *DRI2DrawablePtr;
typedef struct _DRI2Screen { typedef struct _DRI2Screen {
const char *driverName; const char *driverName;
const char *deviceName;
int fd; int fd;
unsigned int lastSequence;
DRI2CreateBuffersProcPtr CreateBuffers; DRI2CreateBuffersProcPtr CreateBuffers;
DRI2DestroyBuffersProcPtr DestroyBuffers; DRI2DestroyBuffersProcPtr DestroyBuffers;
DRI2SwapBuffersProcPtr SwapBuffers; DRI2CopyRegionProcPtr CopyRegion;
DRI2WaitProcPtr Wait;
ClipNotifyProcPtr ClipNotify;
HandleExposuresProcPtr HandleExposures;
} DRI2ScreenRec, *DRI2ScreenPtr; } DRI2ScreenRec, *DRI2ScreenPtr;
static DRI2ScreenPtr static DRI2ScreenPtr
@ -153,28 +160,34 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
return pPriv->buffers; return pPriv->buffers;
} }
void int
DRI2SwapBuffers(DrawablePtr pDraw, int x, int y, int width, int height) DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
unsigned int dest, unsigned int src)
{ {
DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
DRI2DrawablePtr pPriv; DRI2DrawablePtr pPriv;
DRI2BufferPtr pSrcBuffer; DRI2BufferPtr pDestBuffer, pSrcBuffer;
int i; int i;
pPriv = DRI2GetDrawable(pDraw); pPriv = DRI2GetDrawable(pDraw);
if (pPriv == NULL) if (pPriv == NULL)
return; return BadDrawable;
pDestBuffer = NULL;
pSrcBuffer = NULL; pSrcBuffer = NULL;
for (i = 0; i < pPriv->bufferCount; i++) for (i = 0; i < pPriv->bufferCount; i++)
{ {
if (pPriv->buffers[i].attachment == DRI2_BUFFER_BACK_LEFT) if (pPriv->buffers[i].attachment == dest)
pDestBuffer = &pPriv->buffers[i];
if (pPriv->buffers[i].attachment == src)
pSrcBuffer = &pPriv->buffers[i]; pSrcBuffer = &pPriv->buffers[i];
} }
if (pSrcBuffer == NULL) if (pSrcBuffer == NULL || pDestBuffer == NULL)
return; return BadValue;
(*ds->SwapBuffers)(pDraw, pSrcBuffer, x, y, width, height); (*ds->CopyRegion)(pDraw, pRegion, pDestBuffer, pSrcBuffer);
return Success;
} }
void void
@ -209,21 +222,26 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
} }
Bool Bool
DRI2Connect(ScreenPtr pScreen, int *fd, const char **driverName) DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
const char **driverName, const char **deviceName)
{ {
DRI2ScreenPtr ds = DRI2GetScreen(pScreen); DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
if (ds == NULL) if (ds == NULL)
return FALSE; return FALSE;
if (driverType != DRI2DriverDRI)
return BadValue;
*fd = ds->fd; *fd = ds->fd;
*driverName = ds->driverName; *driverName = ds->driverName;
*deviceName = ds->deviceName;
return TRUE; return TRUE;
} }
Bool Bool
DRI2AuthConnection(ScreenPtr pScreen, drm_magic_t magic) DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic)
{ {
DRI2ScreenPtr ds = DRI2GetScreen(pScreen); DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
@ -233,6 +251,23 @@ DRI2AuthConnection(ScreenPtr pScreen, drm_magic_t magic)
return TRUE; return TRUE;
} }
static void
DRI2ClipNotify(WindowPtr pWin, int dx, int dy)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
DRI2DrawablePtr dd = DRI2GetDrawable(&pWin->drawable);
if (ds->lastSequence < dd->pendingSequence && ds->Wait)
ds->Wait(pWin, dd->pendingSequence);
if (ds->ClipNotify) {
pScreen->ClipNotify = ds->ClipNotify;
pScreen->ClipNotify(pWin, dx, dy);
pScreen->ClipNotify = DRI2ClipNotify;
}
}
Bool Bool
DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
{ {
@ -244,9 +279,14 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
ds->fd = info->fd; ds->fd = info->fd;
ds->driverName = info->driverName; ds->driverName = info->driverName;
ds->deviceName = info->deviceName;
ds->CreateBuffers = info->CreateBuffers; ds->CreateBuffers = info->CreateBuffers;
ds->DestroyBuffers = info->DestroyBuffers; ds->DestroyBuffers = info->DestroyBuffers;
ds->SwapBuffers = info->SwapBuffers; ds->CopyRegion = info->CopyRegion;
ds->Wait = info->Wait;
ds->ClipNotify = pScreen->ClipNotify;
pScreen->ClipNotify = DRI2ClipNotify;
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds); dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
@ -260,6 +300,7 @@ DRI2CloseScreen(ScreenPtr pScreen)
{ {
DRI2ScreenPtr ds = DRI2GetScreen(pScreen); DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
pScreen->ClipNotify = ds->ClipNotify;
xfree(ds); xfree(ds);
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL); dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
} }

View File

@ -50,21 +50,24 @@ typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw,
typedef void (*DRI2DestroyBuffersProcPtr)(DrawablePtr pDraw, typedef void (*DRI2DestroyBuffersProcPtr)(DrawablePtr pDraw,
DRI2BufferPtr buffers, DRI2BufferPtr buffers,
int count); int count);
typedef void (*DRI2SwapBuffersProcPtr)(DrawablePtr pDraw, typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
DRI2BufferPtr pSrcBuffer, RegionPtr pRegion,
int x, DRI2BufferPtr pDestBuffer,
int y, DRI2BufferPtr pSrcBuffer);
int width,
int height); typedef void (*DRI2WaitProcPtr)(WindowPtr pWin,
unsigned int sequence);
typedef struct { typedef struct {
unsigned int version; /* Version of this struct */ unsigned int version; /* Version of this struct */
int fd; int fd;
const char *driverName; const char *driverName;
const char *deviceName;
DRI2CreateBuffersProcPtr CreateBuffers; DRI2CreateBuffersProcPtr CreateBuffers;
DRI2DestroyBuffersProcPtr DestroyBuffers; DRI2DestroyBuffersProcPtr DestroyBuffers;
DRI2SwapBuffersProcPtr SwapBuffers; DRI2CopyRegionProcPtr CopyRegion;
DRI2WaitProcPtr Wait;
} DRI2InfoRec, *DRI2InfoPtr; } DRI2InfoRec, *DRI2InfoPtr;
@ -74,10 +77,12 @@ Bool DRI2ScreenInit(ScreenPtr pScreen,
void DRI2CloseScreen(ScreenPtr pScreen); void DRI2CloseScreen(ScreenPtr pScreen);
Bool DRI2Connect(ScreenPtr pScreen, Bool DRI2Connect(ScreenPtr pScreen,
unsigned int driverType,
int *fd, int *fd,
const char **driverName); const char **driverName,
const char **deviceName);
Bool DRI2AuthConnection(ScreenPtr pScreen, drm_magic_t magic); Bool DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic);
int DRI2CreateDrawable(DrawablePtr pDraw); int DRI2CreateDrawable(DrawablePtr pDraw);
@ -90,10 +95,9 @@ DRI2BufferPtr DRI2GetBuffers(DrawablePtr pDraw,
int count, int count,
int *out_count); int *out_count);
void DRI2SwapBuffers(DrawablePtr pDraw, int DRI2CopyRegion(DrawablePtr pDraw,
int x, RegionPtr pRegion,
int y, unsigned int dest,
int width, unsigned int src);
int height);
#endif #endif

View File

@ -38,11 +38,13 @@
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xproto.h> #include <X11/Xproto.h>
#include <X11/extensions/dri2proto.h> #include <X11/extensions/dri2proto.h>
#include <X11/extensions/xfixeswire.h>
#include "dixstruct.h" #include "dixstruct.h"
#include "scrnintstr.h" #include "scrnintstr.h"
#include "pixmapstr.h" #include "pixmapstr.h"
#include "extnsionst.h" #include "extnsionst.h"
#include "xf86drm.h" #include "xf86drm.h"
#include "xfixes.h"
#include "dri2.h" #include "dri2.h"
/* The only xf86 include */ /* The only xf86 include */
@ -51,19 +53,6 @@
static ExtensionEntry *dri2Extension; static ExtensionEntry *dri2Extension;
static RESTYPE dri2DrawableRes; static RESTYPE dri2DrawableRes;
static Bool
validScreen(ClientPtr client, int screen, ScreenPtr *pScreen)
{
if (screen >= screenInfo.numScreens) {
client->errorValue = screen;
return FALSE;
}
*pScreen = screenInfo.screens[screen];
return TRUE;
}
static Bool static Bool
validDrawable(ClientPtr client, XID drawable, validDrawable(ClientPtr client, XID drawable,
DrawablePtr *pDrawable, int *status) DrawablePtr *pDrawable, int *status)
@ -111,64 +100,55 @@ ProcDRI2Connect(ClientPtr client)
{ {
REQUEST(xDRI2ConnectReq); REQUEST(xDRI2ConnectReq);
xDRI2ConnectReply rep; xDRI2ConnectReply rep;
ScreenPtr pScreen; DrawablePtr pDraw;
int fd; int fd, status;
const char *driverName; const char *driverName;
char *busId = NULL; const char *deviceName;
REQUEST_SIZE_MATCH(xDRI2ConnectReq); REQUEST_SIZE_MATCH(xDRI2ConnectReq);
if (!validScreen(client, stuff->screen, &pScreen)) if (!validDrawable(client, stuff->window, &pDraw, &status))
return BadValue; return status;
rep.type = X_Reply; rep.type = X_Reply;
rep.length = 0; rep.length = 0;
rep.sequenceNumber = client->sequence; rep.sequenceNumber = client->sequence;
rep.driverNameLength = 0; rep.driverNameLength = 0;
rep.busIdLength = 0; rep.deviceNameLength = 0;
if (!DRI2Connect(pScreen, &fd, &driverName)) if (!DRI2Connect(pDraw->pScreen,
goto fail; stuff->driverType, &fd, &driverName, &deviceName))
busId = drmGetBusid(fd);
if (busId == NULL)
goto fail; goto fail;
rep.driverNameLength = strlen(driverName); rep.driverNameLength = strlen(driverName);
rep.busIdLength = strlen(busId); rep.deviceNameLength = strlen(deviceName);
rep.length = (rep.driverNameLength + 3) / 4 + (rep.busIdLength + 3) / 4; rep.length = (rep.driverNameLength + 3) / 4 +
(rep.deviceNameLength + 3) / 4;
fail: fail:
WriteToClient(client, sizeof(xDRI2ConnectReply), &rep); WriteToClient(client, sizeof(xDRI2ConnectReply), &rep);
WriteToClient(client, rep.driverNameLength, driverName); WriteToClient(client, rep.driverNameLength, driverName);
WriteToClient(client, rep.busIdLength, busId); WriteToClient(client, rep.deviceNameLength, deviceName);
drmFreeBusid(busId);
return client->noClientException; return client->noClientException;
} }
static int static int
ProcDRI2AuthConnection(ClientPtr client) ProcDRI2Authenticate(ClientPtr client)
{ {
REQUEST(xDRI2AuthConnectionReq); REQUEST(xDRI2AuthenticateReq);
xDRI2AuthConnectionReply rep; xDRI2AuthenticateReply rep;
ScreenPtr pScreen; DrawablePtr pDraw;
int status;
REQUEST_SIZE_MATCH(xDRI2AuthConnectionReq); REQUEST_SIZE_MATCH(xDRI2AuthenticateReq);
if (!validScreen(client, stuff->screen, &pScreen)) if (!validDrawable(client, stuff->window, &pDraw, &status))
return BadValue; return status;
rep.type = X_Reply; rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence; rep.sequenceNumber = client->sequence;
rep.authenticated = 1; rep.length = 0;
rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic);
if (!DRI2AuthConnection(pScreen, stuff->magic)) { WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
ErrorF("DRI2: Failed to authenticate %lu\n",
(unsigned long) stuff->magic);
rep.authenticated = 0;
}
WriteToClient(client, sizeof(xDRI2AuthConnectionReply), &rep);
return client->noClientException; return client->noClientException;
} }
@ -228,7 +208,7 @@ ProcDRI2GetBuffers(ClientPtr client)
if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
return status; return status;
attachments = (CARD32 *) &stuff[1]; attachments = (unsigned int *) &stuff[1];
buffers = DRI2GetBuffers(pDrawable, &width, &height, buffers = DRI2GetBuffers(pDrawable, &width, &height,
attachments, stuff->count, &count); attachments, stuff->count, &count);
@ -253,30 +233,42 @@ ProcDRI2GetBuffers(ClientPtr client)
} }
static int static int
ProcDRI2SwapBuffers(ClientPtr client) ProcDRI2CopyRegion(ClientPtr client)
{ {
REQUEST(xDRI2SwapBuffersReq); REQUEST(xDRI2CopyRegionReq);
xDRI2SwapBuffersReply rep; xDRI2CopyRegionReply rep;
DrawablePtr pDrawable; DrawablePtr pDrawable;
int status; int status;
RegionPtr pRegion;
REQUEST_SIZE_MATCH(xDRI2CopyRegionReq);
/* No optional values supported for DRI2 2.0 protocol. */
if (stuff->bitmask != 0)
return BadValue;
REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq);
if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
return status; return status;
/* Swap buffers need to do a round trip to make sure the X server VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess);
* queues the swap buffer rendering commands before the DRI client
* continues rendering.
*/
DRI2SwapBuffers(pDrawable, stuff->x, stuff->y, status = DRI2CopyRegion(pDrawable, pRegion, stuff->dest, stuff->src);
stuff->width, stuff->height); if (status != Success)
return status;
/* CopyRegion needs to be a round trip to make sure the X server
* queues the swap buffer rendering commands before the DRI client
* continues rendering. The reply has a bitmask to signal the
* presense of optional return values as well, but we're not using
* that yet.
*/
rep.type = X_Reply; rep.type = X_Reply;
rep.length = 0; rep.length = 0;
rep.sequenceNumber = client->sequence; rep.sequenceNumber = client->sequence;
rep.bitmask = 0;
WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep); WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep);
return client->noClientException; return client->noClientException;
} }
@ -297,16 +289,16 @@ ProcDRI2Dispatch (ClientPtr client)
switch (stuff->data) { switch (stuff->data) {
case X_DRI2Connect: case X_DRI2Connect:
return ProcDRI2Connect(client); return ProcDRI2Connect(client);
case X_DRI2AuthConnection: case X_DRI2Authenticate:
return ProcDRI2AuthConnection(client); return ProcDRI2Authenticate(client);
case X_DRI2CreateDrawable: case X_DRI2CreateDrawable:
return ProcDRI2CreateDrawable(client); return ProcDRI2CreateDrawable(client);
case X_DRI2DestroyDrawable: case X_DRI2DestroyDrawable:
return ProcDRI2DestroyDrawable(client); return ProcDRI2DestroyDrawable(client);
case X_DRI2GetBuffers: case X_DRI2GetBuffers:
return ProcDRI2GetBuffers(client); return ProcDRI2GetBuffers(client);
case X_DRI2SwapBuffers: case X_DRI2CopyRegion:
return ProcDRI2SwapBuffers(client); return ProcDRI2CopyRegion(client);
default: default:
return BadRequest; return BadRequest;
} }
@ -329,7 +321,7 @@ SProcDRI2Connect(ClientPtr client)
swaps(&rep.sequenceNumber, n); swaps(&rep.sequenceNumber, n);
rep.length = 0; rep.length = 0;
rep.driverNameLength = 0; rep.driverNameLength = 0;
rep.busIdLength = 0; rep.deviceNameLength = 0;
return client->noClientException; return client->noClientException;
} }