diff options
author | Kristian Høgsberg <krh@redhat.com> | 2008-08-11 16:59:17 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2008-08-29 12:33:28 -0400 |
commit | 5af77d43fe812e127d5d335527fa940ab9d95f38 (patch) | |
tree | 88e6cf7deb768f1cccbf806c7313ce0d1ae469d2 | |
parent | 60ad8d5d05485339e89d7f1f9f1ded75de7c7ea1 (diff) |
DRI2: Drop sarea use, implement server side swap buffers.
-rw-r--r-- | configure.ac | 25 | ||||
-rw-r--r-- | glx/glxcmds.c | 1 | ||||
-rw-r--r-- | glx/glxdri2.c | 126 | ||||
-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 |
6 files changed, 310 insertions, 448 deletions
diff --git a/configure.ac b/configure.ac index 4250f80b0..aac6fbc13 100644 --- a/configure.ac +++ b/configure.ac @@ -356,7 +356,6 @@ AM_CONDITIONAL(PPC_VIDEO, [test "x$PPC_VIDEO" = xyes]) AM_CONDITIONAL(SPARC64_VIDEO, [test "x$SPARC64_VIDEO" = xyes]) DRI=no -DRI2=no KDRIVE_HW=no dnl it would be nice to autodetect these *CONS_SUPPORTs case $host_os in @@ -369,7 +368,6 @@ case $host_os in AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console]) AC_DEFINE(SYSCONS_SUPPORT, 1, [System has syscons console]) DRI=yes - PKG_CHECK_EXISTS([dri2proto >= 1.1 libdrm >= 2.3.2], DRI2=yes, DRI2=no) ;; *netbsd*) AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) @@ -377,7 +375,6 @@ case $host_os in AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console]) AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console]) DRI=yes - PKG_CHECK_EXISTS([dri2proto >= 1.1 libdrm >= 2.3.2], DRI2=yes, DRI2=no) ;; *openbsd*) AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) @@ -386,7 +383,6 @@ case $host_os in ;; *linux*) DRI=yes - PKG_CHECK_EXISTS([dri2proto >= 1.1 libdrm >= 2.3.2], DRI2=yes, DRI2=no) KDRIVE_HW=yes ;; *solaris*) @@ -528,7 +524,7 @@ AC_ARG_ENABLE(xdmcp, AS_HELP_STRING([--disable-xdmcp], [Build XDMCP ext AC_ARG_ENABLE(xdm-auth-1, AS_HELP_STRING([--disable-xdm-auth-1], [Build XDM-Auth-1 extension (default: auto)]), [XDMAUTH=$enableval], [XDMAUTH=auto]) AC_ARG_ENABLE(glx, AS_HELP_STRING([--disable-glx], [Build GLX extension (default: enabled)]), [GLX=$enableval], [GLX=yes]) AC_ARG_ENABLE(dri, AS_HELP_STRING([--enable-dri], [Build DRI extension (default: auto)]), [DRI=$enableval]) -AC_ARG_ENABLE(dri2, AS_HELP_STRING([--enable-dri2], [Build DRI2 extension (default: auto)]), [DRI2=$enableval]) +AC_ARG_ENABLE(dri2, AS_HELP_STRING([--enable-dri2], [Build DRI2 extension (default: auto)]), [DRI2=$enableval], [DRI2=auto]) AC_ARG_ENABLE(xinerama, AS_HELP_STRING([--disable-xinerama], [Build Xinerama extension (default: enabled)]), [XINERAMA=$enableval], [XINERAMA=yes]) AC_ARG_ENABLE(xf86vidmode, AS_HELP_STRING([--disable-xf86vidmode], [Build XF86VidMode extension (default: auto)]), [XF86VIDMODE=$enableval], [XF86VIDMODE=auto]) AC_ARG_ENABLE(xace, AS_HELP_STRING([--disable-xace], [Build X-ACE extension (default: enabled)]), [XACE=$enableval], [XACE=yes]) @@ -856,13 +852,18 @@ if test "x$DRI" = xyes; then AC_SUBST(GL_CFLAGS) fi -#AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes) -#if test "x$DRI2" = xyes; then -# # FIXME: Bump the versions once we have releases of these. -# AC_DEFINE(DRI2, 1, [Build DRI2 extension]) -# PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.1]) -# PKG_CHECK_MODULES([LIBDRM], [libdrm >= 2.3.2]) -#fi +PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.99.1], + [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no]) +case "$DRI2,$HAVE_DRI2PROTO" in + yes,no) + AC_MSG_ERROR([DRI2 requested, but dri2proto not found.]) + ;; + yes,yes | auto,yes) + AC_DEFINE(DRI2, 1, [Build DRI2 extension]) + DRI2=yes + ;; +esac +AM_CONDITIONAL(DRI2, test "x$DRI2" == xyes) AM_CONDITIONAL(XINERAMA, [test "x$XINERAMA" = xyes]) if test "x$XINERAMA" = xyes; then diff --git a/glx/glxcmds.c b/glx/glxcmds.c index 0421026eb..00e5b2a09 100644 --- a/glx/glxcmds.c +++ b/glx/glxcmds.c @@ -435,6 +435,7 @@ static void StopUsingContext(__GLXcontext *glxc) static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) { glxc->isCurrent = GL_TRUE; + __glXLastContext = glxc; } /** diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 7c1f00e79..495de8197 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -69,6 +69,7 @@ struct __GLXDRIscreen { xf86LeaveVTProc *leaveVT; const __DRIcoreExtension *core; + const __DRIdri2Extension *dri2; const __DRIcopySubBufferExtension *copySubBuffer; const __DRIswapControlExtension *swapControl; const __DRItexBufferExtension *texBuffer; @@ -85,6 +86,12 @@ struct __GLXDRIdrawable { __GLXdrawable base; __DRIdrawable *driDrawable; __GLXDRIscreen *screen; + + /* Dimensions as last reported by DRI2GetBuffers. */ + int width; + int height; + __DRIbuffer buffers[5]; + int count; }; static void @@ -107,9 +114,9 @@ static GLboolean __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - const __DRIcoreExtension *core = private->screen->core; - (*core->swapBuffers)(private->driDrawable); + DRI2SwapBuffers(drawable->pDraw, + 0, 0, private->width, private->height); return TRUE; } @@ -118,26 +125,15 @@ __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) static int __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval) { - __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - const __DRIswapControlExtension *swapControl = private->screen->swapControl; - - if (swapControl) - swapControl->setSwapInterval(private->driDrawable, interval); - return 0; } static void -__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, +__glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable, int x, int y, int w, int h) { - __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; - const __DRIcopySubBufferExtension *copySubBuffer = - private->screen->copySubBuffer; - - if (copySubBuffer) - (*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h); + DRI2SwapBuffers(drawable->pDraw, x, y, w, h); } static void @@ -275,7 +271,6 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; __GLXDRIcontext *context, *shareContext; __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; - const __DRIcoreExtension *core = screen->core; __DRIcontext *driShare; shareContext = (__GLXDRIcontext *) baseShareContext; @@ -297,8 +292,9 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, context->base.textureFromPixmap = &__glXDRItextureFromPixmap; context->driContext = - (*core->createNewContext)(screen->driScreen, - config->driConfig, driShare, context); + (*screen->dri2->createNewContext)(screen->driScreen, + config->driConfig, + driShare, context); return &context->base; } @@ -313,8 +309,6 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; __GLXDRIdrawable *private; - GLboolean retval; - unsigned int handle, head; private = xalloc(sizeof *private); if (private == NULL) @@ -333,42 +327,54 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, private->base.swapBuffers = __glXDRIdrawableSwapBuffers; private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; - retval = DRI2CreateDrawable(pDraw, &handle, &head); + if (DRI2CreateDrawable(pDraw)) { + xfree(private); + return NULL; + } private->driDrawable = - (*driScreen->core->createNewDrawable)(driScreen->driScreen, - config->driConfig, - handle, head, private); + (*driScreen->dri2->createNewDrawable)(driScreen->driScreen, + config->driConfig, private); return &private->base; } -static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail, - void *loaderPrivate) +static __DRIbuffer * +dri2GetBuffers(__DRIdrawable *driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) { - __GLXDRIdrawable *pdraw = loaderPrivate; + __GLXDRIdrawable *private = loaderPrivate; + DRI2BufferPtr buffers; + int i; - DRI2ReemitDrawableInfo(pdraw->base.pDraw, tail); -} + buffers = DRI2GetBuffers(private->base.pDraw, + width, height, attachments, count, out_count); + if (*out_count > 5) { + *out_count = 0; + return NULL; + } + + private->width = *width; + private->height = *height; + + /* This assumes the DRI2 buffer attachment tokens matches the + * __DRIbuffer tokens. */ + for (i = 0; i < *out_count; i++) { + private->buffers[i].attachment = buffers[i].attachment; + private->buffers[i].name = buffers[i].name; + private->buffers[i].pitch = buffers[i].pitch; + private->buffers[i].cpp = buffers[i].cpp; + private->buffers[i].flags = buffers[i].flags; + } -static void dri2PostDamage(__DRIdrawable *draw, - struct drm_clip_rect *rects, - int numRects, void *loaderPrivate) -{ - __GLXDRIdrawable *drawable = loaderPrivate; - DrawablePtr pDraw = drawable->base.pDraw; - RegionRec region; - - REGION_INIT(pDraw->pScreen, ®ion, (BoxPtr) rects, numRects); - REGION_TRANSLATE(pScreen, ®ion, pDraw->x, pDraw->y); - DamageDamageRegion(pDraw, ®ion); - REGION_UNINIT(pDraw->pScreen, ®ion); + return private->buffers; } -static const __DRIloaderExtension loaderExtension = { - { __DRI_LOADER, __DRI_LOADER_VERSION }, - dri2ReemitDrawableInfo, - dri2PostDamage +static const __DRIdri2LoaderExtension loaderExtension = { + { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, + dri2GetBuffers, }; static const __DRIextension *loader_extensions[] = { @@ -416,18 +422,11 @@ initializeExtensions(__GLXDRIscreen *screen) extensions = screen->core->getExtensions(screen->driScreen); - for (i = 0; extensions[i]; i++) { -#ifdef __DRI_COPY_SUB_BUFFER - if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { - screen->copySubBuffer = - (const __DRIcopySubBufferExtension *) extensions[i]; - __glXEnableExtension(screen->glx_enable_bits, - "GLX_MESA_copy_sub_buffer"); - - LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); - } -#endif + __glXEnableExtension(screen->glx_enable_bits, + "GLX_MESA_copy_sub_buffer"); + LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); + for (i = 0; extensions[i]; i++) { #ifdef __DRI_SWAP_CONTROL if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { screen->swapControl = @@ -461,7 +460,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) char filename[128]; size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - unsigned int sareaHandle; const __DRIextension **extensions; const __DRIconfig **driConfigs; int i; @@ -472,7 +470,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) memset(screen, 0, sizeof *screen); if (!xf86LoaderCheckSymbol("DRI2Connect") || - !DRI2Connect(pScreen, &screen->fd, &driverName, &sareaHandle)) { + !DRI2Connect(pScreen, &screen->fd, &driverName)) { LogMessage(X_INFO, "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum); return NULL; @@ -508,24 +506,28 @@ __glXDRIscreenProbe(ScreenPtr pScreen) extensions[i]->version >= __DRI_CORE_VERSION) { screen->core = (const __DRIcoreExtension *) extensions[i]; } + if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 && + extensions[i]->version >= __DRI_DRI2_VERSION) { + screen->dri2 = (const __DRIdri2Extension *) extensions[i]; + } } - if (screen->core == NULL) { + if (screen->core == NULL || screen->dri2 == NULL) { LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n", driverName); goto handle_error; } screen->driScreen = - (*screen->core->createNewScreen)(pScreen->myNum, + (*screen->dri2->createNewScreen)(pScreen->myNum, screen->fd, - sareaHandle, loader_extensions, &driConfigs, screen); if (screen->driScreen == NULL) { - LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); + LogMessage(X_ERROR, + "AIGLX error: Calling driver entry point failed\n"); goto handle_error; } 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; } |