diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 452 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.h | 68 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2ext.c | 86 |
3 files changed, 232 insertions, 374 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index a5aef9135..7bb6ac185 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -1,5 +1,5 @@ /* - * Copyright © 2007 Red Hat, Inc. + * Copyright © 2007, 2008 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Soft- @@ -38,8 +38,6 @@ #include "xf86Module.h" #include "scrnintstr.h" #include "windowstr.h" -#include "region.h" -#include "damage.h" #include "dri2.h" #include <GL/internal/dri_sarea.h> @@ -52,29 +50,20 @@ static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex; static int dri2PixmapPrivateKeyIndex; static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex; -typedef struct _DRI2DrawablePriv { - unsigned int refCount; - unsigned int boHandle; - unsigned int dri2Handle; -} DRI2DrawablePrivRec, *DRI2DrawablePrivPtr; +typedef struct _DRI2Drawable { + unsigned int refCount; + int width; + int height; + DRI2BufferPtr buffers; + int bufferCount; +} DRI2DrawableRec, *DRI2DrawablePtr; typedef struct _DRI2Screen { - int fd; - drmBO sareaBO; - void *sarea; - unsigned int sareaSize; const char *driverName; - unsigned int nextHandle; - - __DRIEventBuffer *buffer; - int locked; - - DRI2GetPixmapHandleProcPtr getPixmapHandle; - DRI2BeginClipNotifyProcPtr beginClipNotify; - DRI2EndClipNotifyProcPtr endClipNotify; - - ClipNotifyProcPtr ClipNotify; - HandleExposuresProcPtr HandleExposures; + int fd; + DRI2CreateBuffersProcPtr CreateBuffers; + DRI2DestroyBuffersProcPtr DestroyBuffers; + DRI2SwapBuffersProcPtr SwapBuffers; } DRI2ScreenRec, *DRI2ScreenPtr; static DRI2ScreenPtr @@ -83,277 +72,145 @@ DRI2GetScreen(ScreenPtr pScreen) return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey); } -static void * -DRI2ScreenAllocEvent(DRI2ScreenPtr ds, size_t size) -{ - unsigned int *pad, mask = ds->buffer->size - 1; - size_t pad_size; - void *p; - - if ((ds->buffer->head & mask) + size > ds->buffer->size) { - /* The requested event size would wrap the buffer, so pad to - * the end and allocate the event from the start. */ - pad_size = ds->buffer->size - (ds->buffer->head & mask); - pad = (unsigned int *) - (ds->buffer->data + (ds->buffer->prealloc & mask)); - *pad = DRI2_EVENT_HEADER(DRI2_EVENT_PAD, pad_size); - ds->buffer->prealloc += pad_size; - } - - p = ds->buffer->data + (ds->buffer->prealloc & mask); - ds->buffer->prealloc += size; - - return p; -} - -static void -DRI2ScreenCommitEvents(DRI2ScreenPtr ds) +static DRI2DrawablePtr +DRI2GetDrawable(DrawablePtr pDraw) { - ds->buffer->head = ds->buffer->prealloc; -} + WindowPtr pWin; + PixmapPtr pPixmap; -static void -DRI2PostDrawableConfig(DrawablePtr pDraw) -{ - ScreenPtr pScreen = pDraw->pScreen; - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); - DRI2DrawablePrivPtr pPriv; - WindowPtr pWin; - PixmapPtr pPixmap; - BoxPtr pBox; - BoxRec pixmapBox; - int nBox; - int i; - __DRIDrawableConfigEvent *e; - size_t size; - - if (pDraw->type == DRAWABLE_WINDOW) { + if (pDraw->type == DRAWABLE_WINDOW) + { pWin = (WindowPtr) pDraw; - pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey); - - nBox = REGION_NUM_RECTS(&pWin->clipList); - pBox = REGION_RECTS(&pWin->clipList); - - pPixmap = pScreen->GetWindowPixmap(pWin); - } else { - pPixmap = (PixmapPtr) pDraw; - pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey); - - pixmapBox.x1 = 0; - pixmapBox.y1 = 0; - pixmapBox.x2 = pDraw->width; - pixmapBox.y2 = pDraw->height; - nBox = 1; - pBox = &pixmapBox; + return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey); } - - if (!pPriv) - return; - - size = sizeof *e + nBox * sizeof e->rects[0]; - - e = DRI2ScreenAllocEvent(ds, size); - e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_DRAWABLE_CONFIG, size); - e->drawable = pPriv->dri2Handle; - e->x = pDraw->x - pPixmap->screen_x; - e->y = pDraw->y - pPixmap->screen_y; - e->width = pDraw->width; - e->height = pDraw->height; - - e->num_rects = nBox; - for (i = 0; i < nBox; i++) { - e->rects[i].x1 = pBox->x1 - pPixmap->screen_x; - e->rects[i].y1 = pBox->y1 - pPixmap->screen_y; - e->rects[i].x2 = pBox->x2 - pPixmap->screen_x; - e->rects[i].y2 = pBox->y2 - pPixmap->screen_y; - pBox++; + else + { + pPixmap = (PixmapPtr) pDraw; + return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey); } } -static void -DRI2PostBufferAttach(DrawablePtr pDraw, Bool force) +int +DRI2CreateDrawable(DrawablePtr pDraw) { - ScreenPtr pScreen = pDraw->pScreen; - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); - DRI2DrawablePrivPtr pPriv; - WindowPtr pWin; - PixmapPtr pPixmap; - __DRIBufferAttachEvent *e; - size_t size; - unsigned int flags; - unsigned int boHandle; - - if (pDraw->type == DRAWABLE_WINDOW) { - pWin = (WindowPtr) pDraw; - pPixmap = pScreen->GetWindowPixmap(pWin); - pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey); - } else { - pPixmap = (PixmapPtr) pDraw; - pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey); - } - - if (!pPriv) - return; + WindowPtr pWin; + PixmapPtr pPixmap; + DRI2DrawablePtr pPriv; - boHandle = ds->getPixmapHandle(pPixmap, &flags); - if (boHandle == pPriv->boHandle && !force) - return; + pPriv = DRI2GetDrawable(pDraw); + if (pPriv != NULL) + { + pPriv->refCount++; + return Success; + } - pPriv->boHandle = boHandle; - size = sizeof *e; - e = DRI2ScreenAllocEvent(ds, size); - e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_BUFFER_ATTACH, size); - e->drawable = pPriv->dri2Handle; - e->buffer.attachment = DRI_DRAWABLE_BUFFER_FRONT_LEFT; - e->buffer.handle = pPriv->boHandle; - e->buffer.pitch = pPixmap->devKind; - e->buffer.cpp = pPixmap->drawable.bitsPerPixel / 8; - e->buffer.flags = flags; -} + pPriv = xalloc(sizeof *pPriv); + if (pPriv == NULL) + return BadAlloc; -static void -DRI2ClipNotify(WindowPtr pWin, int dx, int dy) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); + pPriv->refCount = 1; + pPriv->width = pDraw->width; + pPriv->height = pDraw->height; + pPriv->buffers = NULL; + pPriv->bufferCount = 0; - if (!ds->locked) { - ds->beginClipNotify(pScreen); - ds->locked = 1; + if (pDraw->type == DRAWABLE_WINDOW) + { + pWin = (WindowPtr) pDraw; + dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv); } - - if (ds->ClipNotify) { - pScreen->ClipNotify = ds->ClipNotify; - pScreen->ClipNotify(pWin, dx, dy); - pScreen->ClipNotify = DRI2ClipNotify; + else + { + pPixmap = (PixmapPtr) pDraw; + dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv); } - DRI2PostDrawableConfig(&pWin->drawable); - DRI2PostBufferAttach(&pWin->drawable, FALSE); + return Success; } -static void -DRI2HandleExposures(WindowPtr pWin) +DRI2BufferPtr +DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height, + unsigned int *attachments, int count, int *out_count) { - ScreenPtr pScreen = pWin->drawable.pScreen; - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); - - if (ds->HandleExposures) { - pScreen->HandleExposures = ds->HandleExposures; - pScreen->HandleExposures(pWin); - pScreen->HandleExposures = DRI2HandleExposures; + DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); + DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); + DRI2BufferPtr buffers; + + if (pPriv->buffers == NULL || + pDraw->width != pPriv->width || pDraw->height != pPriv->height) + { + buffers = (*ds->CreateBuffers)(pDraw, attachments, count); + (*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount); + pPriv->buffers = buffers; + pPriv->bufferCount = count; + pPriv->width = pDraw->width; + pPriv->height = pDraw->height; } - DRI2ScreenCommitEvents(ds); + *width = pPriv->width; + *height = pPriv->height; + *out_count = pPriv->bufferCount; - if (ds->locked) { - ds->endClipNotify(pScreen); - ds->locked = 0; - } + return pPriv->buffers; } void -DRI2CloseScreen(ScreenPtr pScreen) +DRI2SwapBuffers(DrawablePtr pDraw, int x, int y, int width, int height) { - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); - - pScreen->ClipNotify = ds->ClipNotify; - pScreen->HandleExposures = ds->HandleExposures; + DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); + DRI2DrawablePtr pPriv; + DRI2BufferPtr pSrcBuffer; + int i; - drmBOUnmap(ds->fd, &ds->sareaBO); - drmBOUnreference(ds->fd, &ds->sareaBO); - - xfree(ds); - dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL); -} - -Bool -DRI2CreateDrawable(DrawablePtr pDraw, - unsigned int *handle, unsigned int *head) -{ - DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); - WindowPtr pWin; - PixmapPtr pPixmap; - DRI2DrawablePrivPtr pPriv; - DevPrivateKey key; - PrivateRec **devPrivates; - - if (pDraw->type == DRAWABLE_WINDOW) { - pWin = (WindowPtr) pDraw; - devPrivates = &pWin->devPrivates; - key = dri2WindowPrivateKey; - } else { - pPixmap = (PixmapPtr) pDraw; - devPrivates = &pPixmap->devPrivates; - key = dri2PixmapPrivateKey; - } + pPriv = DRI2GetDrawable(pDraw); + if (pPriv == NULL) + return; - pPriv = dixLookupPrivate(devPrivates, key); - if (pPriv != NULL) { - pPriv->refCount++; - } else { - pPriv = xalloc(sizeof *pPriv); - pPriv->refCount = 1; - pPriv->boHandle = 0; - pPriv->dri2Handle = ds->nextHandle++; - dixSetPrivate(devPrivates, key, pPriv); + pSrcBuffer = NULL; + for (i = 0; i < pPriv->bufferCount; i++) + { + if (pPriv->buffers[i].attachment == DRI2_BUFFER_BACK_LEFT) + pSrcBuffer = &pPriv->buffers[i]; } - - *handle = pPriv->dri2Handle; - *head = ds->buffer->head; - - DRI2PostDrawableConfig(pDraw); - DRI2PostBufferAttach(pDraw, TRUE); - DRI2ScreenCommitEvents(ds); - - return TRUE; + if (pSrcBuffer == NULL) + return; + + (*ds->SwapBuffers)(pDraw, pSrcBuffer, x, y, width, height); } void DRI2DestroyDrawable(DrawablePtr pDraw) { - PixmapPtr pPixmap; - WindowPtr pWin; - DRI2DrawablePrivPtr pPriv; - DevPrivateKey key; - PrivateRec **devPrivates; + DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); + DRI2DrawablePtr pPriv; + WindowPtr pWin; + PixmapPtr pPixmap; - if (pDraw->type == DRAWABLE_WINDOW) { - pWin = (WindowPtr) pDraw; - devPrivates = &pWin->devPrivates; - key = dri2WindowPrivateKey; - } else { - pPixmap = (PixmapPtr) pDraw; - devPrivates = &pPixmap->devPrivates; - key = dri2PixmapPrivateKey; - } - - pPriv = dixLookupPrivate(devPrivates, key); + pPriv = DRI2GetDrawable(pDraw); if (pPriv == NULL) return; pPriv->refCount--; - if (pPriv->refCount == 0) { - dixSetPrivate(devPrivates, key, NULL); - xfree(pPriv); - } -} - -void -DRI2ReemitDrawableInfo(DrawablePtr pDraw, unsigned int *head) -{ - DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); + if (pPriv->refCount > 0) + return; - *head = ds->buffer->head; + (*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount); + xfree(pPriv); - DRI2PostDrawableConfig(pDraw); - DRI2PostBufferAttach(pDraw, TRUE); - DRI2ScreenCommitEvents(ds); + if (pDraw->type == DRAWABLE_WINDOW) + { + pWin = (WindowPtr) pDraw; + dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL); + } + else + { + pPixmap = (PixmapPtr) pDraw; + dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL); + } } Bool -DRI2Connect(ScreenPtr pScreen, int *fd, const char **driverName, - unsigned int *sareaHandle) +DRI2Connect(ScreenPtr pScreen, int *fd, const char **driverName) { DRI2ScreenPtr ds = DRI2GetScreen(pScreen); @@ -362,7 +219,6 @@ DRI2Connect(ScreenPtr pScreen, int *fd, const char **driverName, *fd = ds->fd; *driverName = ds->driverName; - *sareaHandle = ds->sareaBO.handle; return TRUE; } @@ -378,86 +234,35 @@ DRI2AuthConnection(ScreenPtr pScreen, drm_magic_t magic) return TRUE; } -unsigned int -DRI2GetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags) -{ - DRI2ScreenPtr ds = DRI2GetScreen(pPixmap->drawable.pScreen); - - return ds->getPixmapHandle(pPixmap, flags); -} - -static void * -DRI2SetupSAREA(ScreenPtr pScreen, size_t driverSareaSize) -{ - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); - unsigned long mask; - const size_t event_buffer_size = 32 * 1024; - - ds->sareaSize = - sizeof(*ds->buffer) + event_buffer_size + - driverSareaSize + - sizeof (unsigned int); - - mask = DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE | - DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_SHAREABLE; - - if (drmBOCreate(ds->fd, ds->sareaSize, 1, NULL, mask, 0, &ds->sareaBO)) - return NULL; - - if (drmBOMap(ds->fd, &ds->sareaBO, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &ds->sarea)) { - drmBOUnreference(ds->fd, &ds->sareaBO); - return NULL; - } - - xf86DrvMsg(pScreen->myNum, X_INFO, - "[DRI2] Allocated %d byte SAREA, BO handle 0x%08x\n", - ds->sareaSize, ds->sareaBO.handle); - memset(ds->sarea, 0, ds->sareaSize); - - ds->buffer = ds->sarea; - ds->buffer->block_header = - DRI2_SAREA_BLOCK_HEADER(DRI2_SAREA_BLOCK_EVENT_BUFFER, - sizeof *ds->buffer + event_buffer_size); - ds->buffer->size = event_buffer_size; - - return DRI2_SAREA_BLOCK_NEXT(ds->buffer); -} - -void * +Bool DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) { DRI2ScreenPtr ds; - void *p; ds = xalloc(sizeof *ds); if (!ds) - return NULL; - - ds->fd = info->fd; - ds->driverName = info->driverName; - ds->nextHandle = 1; - - ds->getPixmapHandle = info->getPixmapHandle; - ds->beginClipNotify = info->beginClipNotify; - ds->endClipNotify = info->endClipNotify; + return FALSE; - ds->ClipNotify = pScreen->ClipNotify; - pScreen->ClipNotify = DRI2ClipNotify; - ds->HandleExposures = pScreen->HandleExposures; - pScreen->HandleExposures = DRI2HandleExposures; + ds->fd = info->fd; + ds->driverName = info->driverName; + ds->CreateBuffers = info->CreateBuffers; + ds->DestroyBuffers = info->DestroyBuffers; + ds->SwapBuffers = info->SwapBuffers; dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds); - p = DRI2SetupSAREA(pScreen, info->driverSareaSize); - if (p == NULL) { - xfree(ds); - return NULL; - } - xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n"); - return p; + return TRUE; +} + +void +DRI2CloseScreen(ScreenPtr pScreen) +{ + DRI2ScreenPtr ds = DRI2GetScreen(pScreen); + + xfree(ds); + dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL); } extern ExtensionModule dri2ExtensionModule; @@ -467,10 +272,13 @@ DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin) { static Bool setupDone = FALSE; - if (!setupDone) { + if (!setupDone) + { setupDone = TRUE; LoadExtension(&dri2ExtensionModule, FALSE); - } else { + } + else + { if (errmaj) *errmaj = LDR_ONCEONLY; } diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index 85b3da41c..2f4e4fe05 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -33,49 +33,67 @@ #ifndef _DRI2_H_ #define _DRI2_H_ -typedef unsigned int (*DRI2GetPixmapHandleProcPtr)(PixmapPtr p, - unsigned int *flags); -typedef void (*DRI2BeginClipNotifyProcPtr)(ScreenPtr pScreen); -typedef void (*DRI2EndClipNotifyProcPtr)(ScreenPtr pScreen); +#include <X11/extensions/dri2tokens.h> + +typedef struct { + unsigned int attachment; + unsigned int name; + unsigned int pitch; + unsigned int cpp; + unsigned int flags; + void *driverPrivate; +} DRI2BufferRec, *DRI2BufferPtr; + +typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw, + unsigned int *attachments, + int count); +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 struct { unsigned int version; /* Version of this struct */ int fd; - size_t driverSareaSize; const char *driverName; - DRI2GetPixmapHandleProcPtr getPixmapHandle; - DRI2BeginClipNotifyProcPtr beginClipNotify; - DRI2EndClipNotifyProcPtr endClipNotify; + + DRI2CreateBuffersProcPtr CreateBuffers; + DRI2DestroyBuffersProcPtr DestroyBuffers; + DRI2SwapBuffersProcPtr SwapBuffers; + } DRI2InfoRec, *DRI2InfoPtr; -void *DRI2ScreenInit(ScreenPtr pScreen, - DRI2InfoPtr info); +Bool DRI2ScreenInit(ScreenPtr pScreen, + DRI2InfoPtr info); void DRI2CloseScreen(ScreenPtr pScreen); Bool DRI2Connect(ScreenPtr pScreen, int *fd, - const char **driverName, - unsigned int *sareaHandle); + const char **driverName); Bool DRI2AuthConnection(ScreenPtr pScreen, drm_magic_t magic); -unsigned int DRI2GetPixmapHandle(PixmapPtr pPixmap, - unsigned int *flags); - -void DRI2Lock(ScreenPtr pScreen); -void DRI2Unlock(ScreenPtr pScreen); - -Bool DRI2CreateDrawable(DrawablePtr pDraw, - unsigned int *handle, - unsigned int *head); +int DRI2CreateDrawable(DrawablePtr pDraw); void DRI2DestroyDrawable(DrawablePtr pDraw); -void DRI2ReemitDrawableInfo(DrawablePtr pDraw, - unsigned int *head); +DRI2BufferPtr DRI2GetBuffers(DrawablePtr pDraw, + int *width, + int *height, + unsigned int *attachments, + int count, + int *out_count); -Bool DRI2PostDamage(DrawablePtr pDrawable, - struct drm_clip_rect *rects, int numRects); +void DRI2SwapBuffers(DrawablePtr pDraw, + int x, + int y, + int width, + int height); #endif diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index 8b939143b..ce2290b11 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -115,7 +115,6 @@ ProcDRI2Connect(ClientPtr client) int fd; const char *driverName; char *busId = NULL; - unsigned int sareaHandle; REQUEST_SIZE_MATCH(xDRI2ConnectReq); if (!validScreen(client, stuff->screen, &pScreen)) @@ -126,9 +125,8 @@ ProcDRI2Connect(ClientPtr client) rep.sequenceNumber = client->sequence; rep.driverNameLength = 0; rep.busIdLength = 0; - rep.sareaHandle = 0; - if (!DRI2Connect(pScreen, &fd, &driverName, &sareaHandle)) + if (!DRI2Connect(pScreen, &fd, &driverName)) goto fail; busId = drmGetBusid(fd); @@ -137,7 +135,6 @@ ProcDRI2Connect(ClientPtr client) rep.driverNameLength = strlen(driverName); rep.busIdLength = strlen(busId); - rep.sareaHandle = sareaHandle; rep.length = (rep.driverNameLength + 3) / 4 + (rep.busIdLength + 3) / 4; fail: @@ -180,9 +177,7 @@ static int ProcDRI2CreateDrawable(ClientPtr client) { REQUEST(xDRI2CreateDrawableReq); - xDRI2CreateDrawableReply rep; DrawablePtr pDrawable; - unsigned int handle, head; int status; REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); @@ -190,22 +185,15 @@ ProcDRI2CreateDrawable(ClientPtr client) if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) return status; - if (!DRI2CreateDrawable(pDrawable, &handle, &head)) - return BadMatch; + status = DRI2CreateDrawable(pDrawable); + if (status != Success) + return status; if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) { DRI2DestroyDrawable(pDrawable); return BadAlloc; } - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.handle = handle; - rep.head = head; - - WriteToClient(client, sizeof(xDRI2CreateDrawableReply), &rep); - return client->noClientException; } @@ -226,26 +214,69 @@ ProcDRI2DestroyDrawable(ClientPtr client) } static int -ProcDRI2ReemitDrawableInfo(ClientPtr client) +ProcDRI2GetBuffers(ClientPtr client) { - REQUEST(xDRI2ReemitDrawableInfoReq); - xDRI2ReemitDrawableInfoReply rep; + REQUEST(xDRI2GetBuffersReq); + xDRI2GetBuffersReply rep; + DrawablePtr pDrawable; + DRI2BufferPtr buffers; + int i, status, width, height, count; + unsigned int *attachments; + xDRI2Buffer buffer; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + attachments = (CARD32 *) &stuff[1]; + buffers = DRI2GetBuffers(pDrawable, &width, &height, + attachments, stuff->count, &count); + + rep.type = X_Reply; + rep.length = count * sizeof(xDRI2Buffer) / 4; + rep.sequenceNumber = client->sequence; + rep.width = width; + rep.height = height; + rep.count = count; + WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep); + + for (i = 0; i < count; i++) { + buffer.attachment = buffers[i].attachment; + buffer.name = buffers[i].name; + buffer.pitch = buffers[i].pitch; + buffer.cpp = buffers[i].cpp; + buffer.flags = buffers[i].flags; + WriteToClient(client, sizeof(xDRI2Buffer), &buffer); + } + + return client->noClientException; +} + +static int +ProcDRI2SwapBuffers(ClientPtr client) +{ + REQUEST(xDRI2SwapBuffersReq); + xDRI2SwapBuffersReply rep; DrawablePtr pDrawable; - unsigned int head; int status; - REQUEST_SIZE_MATCH(xDRI2ReemitDrawableInfoReq); + REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq); if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) return status; - DRI2ReemitDrawableInfo(pDrawable, &head); + /* 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. + */ + + DRI2SwapBuffers(pDrawable, stuff->x, stuff->y, + stuff->width, stuff->height); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; - rep.head = head; - WriteToClient(client, sizeof(xDRI2ReemitDrawableInfoReply), &rep); + WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep); return client->noClientException; } @@ -272,8 +303,10 @@ ProcDRI2Dispatch (ClientPtr client) return ProcDRI2CreateDrawable(client); case X_DRI2DestroyDrawable: return ProcDRI2DestroyDrawable(client); - case X_DRI2ReemitDrawableInfo: - return ProcDRI2ReemitDrawableInfo(client); + case X_DRI2GetBuffers: + return ProcDRI2GetBuffers(client); + case X_DRI2SwapBuffers: + return ProcDRI2SwapBuffers(client); default: return BadRequest; } @@ -297,7 +330,6 @@ SProcDRI2Connect(ClientPtr client) rep.length = 0; rep.driverNameLength = 0; rep.busIdLength = 0; - rep.sareaHandle = 0; return client->noClientException; } |