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);
}
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
__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
DRI2SwapBuffers(drawable->pDraw,
0, 0, private->width, private->height);
__glXDRIdrawableCopySubBuffer(drawable, 0, 0,
private->width, private->height);
return TRUE;
}
@ -128,14 +145,6 @@ __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
return 0;
}
static void
__glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
int x, int y, int w, int h)
{
DRI2SwapBuffers(drawable->pDraw, x, y, w, h);
}
static void
__glXDRIcontextDestroy(__GLXcontext *baseContext)
{
@ -452,7 +461,7 @@ initializeExtensions(__GLXDRIscreen *screen)
static __GLXscreen *
__glXDRIscreenProbe(ScreenPtr pScreen)
{
const char *driverName;
const char *driverName, *deviceName;
__GLXDRIscreen *screen;
char filename[128];
size_t buffer_size;
@ -466,7 +475,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
return NULL;
if (!xf86LoaderCheckSymbol("DRI2Connect") ||
!DRI2Connect(pScreen, &screen->fd, &driverName)) {
!DRI2Connect(pScreen, DRI2DriverDRI,
&screen->fd, &driverName, &deviceName)) {
LogMessage(X_INFO,
"AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum);
return NULL;

View File

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

View File

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

View File

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