diff options
Diffstat (limited to 'hw/xfree86/dri2/dri2.c')
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 452 |
1 files changed, 130 insertions, 322 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; } |