From 3457ada32ed09bc3f4ff16ca741c1eef13a61f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 31 Jul 2009 17:56:40 +0000 Subject: [PATCH] =?UTF-8?q?*=20Wed=20Jul=2029=202009=20Kristian=20H=C3=B8g?= =?UTF-8?q?sberg=20=20-=201.6.99-22.20090724=20-=20Add=20D?= =?UTF-8?q?RI2=20page=20flipping=20feature.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dri2-page-flip.patch | 460 +++++++++++++++++++++++++++++++++++++++++++ xorg-x11-server.spec | 13 +- 2 files changed, 469 insertions(+), 4 deletions(-) create mode 100644 dri2-page-flip.patch diff --git a/dri2-page-flip.patch b/dri2-page-flip.patch new file mode 100644 index 0000000..fa8327f --- /dev/null +++ b/dri2-page-flip.patch @@ -0,0 +1,460 @@ +From fb33e4a3cb43ff4b2ca4bdd9170d84569d3e9de0 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= +Date: Wed, 29 Jul 2009 08:26:14 -0400 +Subject: [PATCH] DRI2 Page Flipping + +--- + glx/glxcontext.h | 4 ++ + glx/glxdri2.c | 47 ++++++++++++++---- + glx/glxext.c | 3 + + glx/glxserver.h | 18 +++---- + hw/xfree86/dri2/dri2.c | 118 +++++++++++++++++++++++++++++++++++++++++++- + hw/xfree86/dri2/dri2.h | 12 ++++- + hw/xfree86/dri2/dri2ext.c | 25 +++++++++- + 7 files changed, 200 insertions(+), 27 deletions(-) + +diff --git a/glx/glxcontext.h b/glx/glxcontext.h +index 70a1411..79bc083 100644 +--- a/glx/glxcontext.h ++++ b/glx/glxcontext.h +@@ -55,6 +55,10 @@ struct __GLXcontext { + unsigned long mask); + int (*forceCurrent) (__GLXcontext *context); + ++ Bool (*wait) (__GLXcontext *context, ++ __GLXclientState *cl, ++ int *error); ++ + __GLXtextureFromPixmap *textureFromPixmap; + + /* +diff --git a/glx/glxdri2.c b/glx/glxdri2.c +index ed7fb4c..4b89c31 100644 +--- a/glx/glxdri2.c ++++ b/glx/glxdri2.c +@@ -70,6 +70,7 @@ struct __GLXDRIscreen { + + const __DRIcoreExtension *core; + const __DRIdri2Extension *dri2; ++ const __DRI2flushExtension *flush; + const __DRIcopySubBufferExtension *copySubBuffer; + const __DRIswapControlExtension *swapControl; + const __DRItexBufferExtension *texBuffer; +@@ -132,17 +133,6 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable, + DRI2BufferFrontLeft, DRI2BufferBackLeft); + } + +-static GLboolean +-__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) +-{ +- __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; +- +- __glXDRIdrawableCopySubBuffer(drawable, 0, 0, +- private->width, private->height); +- +- return TRUE; +-} +- + static void + __glXDRIdrawableWaitX(__GLXdrawable *drawable) + { +@@ -177,6 +167,20 @@ __glXDRIdrawableWaitGL(__GLXdrawable *drawable) + DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); + } + ++static GLboolean ++__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) ++{ ++ __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable; ++ __GLXDRIscreen *screen = priv->screen; ++ ++ (*screen->flush->flushInvalidate)(priv->driDrawable); ++ ++ if (DRI2SwapBuffers(drawable->pDraw) != Success) ++ return FALSE; ++ ++ return TRUE; ++} ++ + static int + __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval) + { +@@ -241,6 +245,18 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext) + read->driDrawable); + } + ++static Bool ++__glXDRIcontextWait(__GLXcontext *baseContext, ++ __GLXclientState *cl, int *error) ++{ ++ if (DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw)) { ++ *error = cl->client->noClientException; ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ + #ifdef __DRI_TEX_BUFFER + + static int +@@ -346,6 +362,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, + context->base.copy = __glXDRIcontextCopy; + context->base.forceCurrent = __glXDRIcontextForceCurrent; + context->base.textureFromPixmap = &__glXDRItextureFromPixmap; ++ context->base.wait = __glXDRIcontextWait; + + context->driContext = + (*screen->dri2->createNewContext)(screen->driScreen, +@@ -581,6 +598,14 @@ initializeExtensions(__GLXDRIscreen *screen) + LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); + } + #endif ++ ++#ifdef __DRI2_FLUSH ++ if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 && ++ extensions[i]->version >= __DRI2_FLUSH_VERSION) { ++ screen->flush = (__DRI2flushExtension *) extensions[i]; ++ } ++#endif ++ + /* Ignore unknown extensions */ + } + } +diff --git a/glx/glxext.c b/glx/glxext.c +index 19d70d4..f57ccf5 100644 +--- a/glx/glxext.c ++++ b/glx/glxext.c +@@ -439,6 +439,9 @@ __GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag, + } + } + ++ if (cx->wait && (*cx->wait)(cx, cl, error)) ++ return NULL; ++ + if (cx == __glXLastContext) { + /* No need to re-bind */ + return cx; +diff --git a/glx/glxserver.h b/glx/glxserver.h +index 46c9382..3e62782 100644 +--- a/glx/glxserver.h ++++ b/glx/glxserver.h +@@ -56,7 +56,14 @@ + #include + #include + +-/* For glxscreens.h */ ++/* ++** GLX resources. ++*/ ++typedef XID GLXContextID; ++typedef XID GLXPixmap; ++typedef XID GLXDrawable; ++ ++typedef struct __GLXclientStateRec __GLXclientState; + typedef struct __GLXdrawable __GLXdrawable; + typedef struct __GLXcontext __GLXcontext; + +@@ -75,15 +82,6 @@ typedef struct __GLXcontext __GLXcontext; + #define False 0 + #endif + +-/* +-** GLX resources. +-*/ +-typedef XID GLXContextID; +-typedef XID GLXPixmap; +-typedef XID GLXDrawable; +- +-typedef struct __GLXclientStateRec __GLXclientState; +- + extern __GLXscreen *glxGetScreen(ScreenPtr pScreen); + extern __GLXclientState *glxGetClient(ClientPtr pClient); + +diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c +index 8795cd1..8f5e0c3 100644 +--- a/hw/xfree86/dri2/dri2.c ++++ b/hw/xfree86/dri2/dri2.c +@@ -38,6 +38,7 @@ + #include "xf86Module.h" + #include "scrnintstr.h" + #include "windowstr.h" ++#include "dixstruct.h" + #include "dri2.h" + + #include "xf86.h" +@@ -55,7 +56,8 @@ typedef struct _DRI2Drawable { + int height; + DRI2BufferPtr *buffers; + int bufferCount; +- unsigned int pendingSequence; ++ unsigned int swapPending; ++ ClientPtr blockedClient; + } DRI2DrawableRec, *DRI2DrawablePtr; + + typedef struct _DRI2Screen { +@@ -67,6 +69,7 @@ typedef struct _DRI2Screen { + DRI2CreateBufferProcPtr CreateBuffer; + DRI2DestroyBufferProcPtr DestroyBuffer; + DRI2CopyRegionProcPtr CopyRegion; ++ DRI2SwapBuffersProcPtr SwapBuffers; + + HandleExposuresProcPtr HandleExposures; + } DRI2ScreenRec, *DRI2ScreenPtr; +@@ -118,6 +121,8 @@ DRI2CreateDrawable(DrawablePtr pDraw) + pPriv->height = pDraw->height; + pPriv->buffers = NULL; + pPriv->bufferCount = 0; ++ pPriv->swapPending = FALSE; ++ pPriv->blockedClient = NULL; + + if (pDraw->type == DRAWABLE_WINDOW) + { +@@ -337,6 +342,106 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, + return Success; + } + ++static Bool ++DRI2FlipCheck(DrawablePtr pDraw) ++{ ++ ScreenPtr pScreen = pDraw->pScreen; ++ WindowPtr pWin, pRoot; ++ PixmapPtr pWinPixmap, pRootPixmap; ++ ++ if (pDraw->type == DRAWABLE_PIXMAP) ++ return TRUE; ++ ++ pRoot = WindowTable[pScreen->myNum]; ++ pRootPixmap = pScreen->GetWindowPixmap(pRoot); ++ ++ pWin = (WindowPtr) pDraw; ++ pWinPixmap = pScreen->GetWindowPixmap(pWin); ++ if (pRootPixmap != pWinPixmap) ++ return FALSE; ++ if (!REGION_EQUAL(pScreen, &pWin->clipList, &pRoot->winSize)) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++int ++DRI2SwapBuffers(DrawablePtr pDraw) ++{ ++ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); ++ DRI2DrawablePtr pPriv; ++ DRI2BufferPtr pDestBuffer, pSrcBuffer; ++ int i; ++ BoxRec box; ++ RegionRec region; ++ ++ pPriv = DRI2GetDrawable(pDraw); ++ if (pPriv == NULL) ++ return BadDrawable; ++ ++ pDestBuffer = NULL; ++ pSrcBuffer = NULL; ++ for (i = 0; i < pPriv->bufferCount; i++) ++ { ++ if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft) ++ pDestBuffer = pPriv->buffers[i]; ++ if (pPriv->buffers[i]->attachment == DRI2BufferBackLeft) ++ pSrcBuffer = pPriv->buffers[i]; ++ } ++ if (pSrcBuffer == NULL || pDestBuffer == NULL) ++ return BadValue; ++ ++ if (DRI2FlipCheck(pDraw) && ++ (*ds->SwapBuffers)(pDraw, pDestBuffer, pSrcBuffer, pPriv)) ++ { ++ pPriv->swapPending = TRUE; ++ return Success; ++ } ++ ++ box.x1 = 0; ++ box.y1 = 0; ++ box.x2 = pDraw->width; ++ box.y2 = pDraw->height; ++ REGION_INIT(drawable->pDraw->pScreen, ®ion, &box, 0); ++ ++ return DRI2CopyRegion(pDraw, ®ion, ++ DRI2BufferFrontLeft, DRI2BufferBackLeft); ++} ++ ++Bool ++DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable) ++{ ++ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable); ++ ++ /* If we're currently waiting for a swap on this drawable, reset ++ * the request and suspend the client. We only support one ++ * blocked client per drawable. */ ++ if (pPriv->swapPending && pPriv->blockedClient == NULL) { ++ ResetCurrentRequest(client); ++ client->sequence--; ++ IgnoreClient(client); ++ pPriv->blockedClient = client; ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++void ++DRI2SwapComplete(void *data) ++{ ++ DRI2DrawablePtr pPriv = data; ++ ++ if (pPriv->blockedClient) ++ AttendClient(pPriv->blockedClient); ++ ++ pPriv->swapPending = FALSE; ++ pPriv->blockedClient = NULL; ++ ++ if (pPriv->refCount == 0) ++ xfree(pPriv); ++} ++ + void + DRI2DestroyDrawable(DrawablePtr pDraw) + { +@@ -362,7 +467,11 @@ DRI2DestroyDrawable(DrawablePtr pDraw) + xfree(pPriv->buffers); + } + +- xfree(pPriv); ++ /* If the window is destroyed while we have a swap pending, don't ++ * actually free the priv yet. We'll need it in the DRI2SwapComplete() ++ * callback and we'll free it there once we're done. */ ++ if (!pPriv->swapPending) ++ xfree(pPriv); + + if (pDraw->type == DRAWABLE_WINDOW) + { +@@ -414,7 +523,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) + if (info->version < 3) + return FALSE; + +- ds = xalloc(sizeof *ds); ++ ds = xcalloc(1, sizeof *ds); + if (!ds) + return FALSE; + +@@ -426,6 +535,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) + ds->DestroyBuffer = info->DestroyBuffer; + ds->CopyRegion = info->CopyRegion; + ++ if (info->version >= 4) ++ ds->SwapBuffers = info->SwapBuffers; ++ + dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds); + + xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n"); +diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h +index 175471a..42bdb09 100644 +--- a/hw/xfree86/dri2/dri2.h ++++ b/hw/xfree86/dri2/dri2.h +@@ -58,6 +58,10 @@ typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw, + RegionPtr pRegion, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer); ++typedef Bool (*DRI2SwapBuffersProcPtr)(DrawablePtr pDraw, ++ DRI2BufferPtr pFrontBuffer, ++ DRI2BufferPtr pBackBuffer, ++ void *data); + + typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, + unsigned int sequence); +@@ -71,7 +75,7 @@ typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw, + /** + * Version of the DRI2InfoRec structure defined in this header + */ +-#define DRI2INFOREC_VERSION 3 ++#define DRI2INFOREC_VERSION 4 + + typedef struct { + unsigned int version; /**< Version of this struct */ +@@ -82,7 +86,7 @@ typedef struct { + DRI2CreateBufferProcPtr CreateBuffer; + DRI2DestroyBufferProcPtr DestroyBuffer; + DRI2CopyRegionProcPtr CopyRegion; +- DRI2WaitProcPtr Wait; ++ DRI2SwapBuffersProcPtr SwapBuffers; + + } DRI2InfoRec, *DRI2InfoPtr; + +@@ -137,4 +141,8 @@ extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw, + int *width, int *height, unsigned int *attachments, int count, + int *out_count); + ++extern _X_EXPORT int DRI2SwapBuffers(DrawablePtr pDrawable); ++extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable); ++extern _X_EXPORT void DRI2SwapComplete(void *data); ++ + #endif +diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c +index 029dce8..9f5f389 100644 +--- a/hw/xfree86/dri2/dri2ext.c ++++ b/hw/xfree86/dri2/dri2ext.c +@@ -80,7 +80,7 @@ ProcDRI2QueryVersion(ClientPtr client) + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = 1; +- rep.minorVersion = 1; ++ rep.minorVersion = 2; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); +@@ -253,6 +253,9 @@ ProcDRI2GetBuffers(ClientPtr client) + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + ++ if (DRI2WaitSwap(client, pDrawable)) ++ return client->noClientException; ++ + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffers(pDrawable, &width, &height, + attachments, stuff->count, &count); +@@ -276,6 +279,9 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client) + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + ++ if (DRI2WaitSwap(client, pDrawable)) ++ return client->noClientException; ++ + attachments = (unsigned int *) &stuff[1]; + buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height, + attachments, stuff->count, &count); +@@ -322,6 +328,21 @@ ProcDRI2CopyRegion(ClientPtr client) + } + + static int ++ProcDRI2SwapBuffers(ClientPtr client) ++{ ++ REQUEST(xDRI2SwapBuffersReq); ++ DrawablePtr pDrawable; ++ int status; ++ ++ REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq); ++ ++ if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) ++ return status; ++ ++ return DRI2SwapBuffers(pDrawable); ++} ++ ++static int + ProcDRI2Dispatch (ClientPtr client) + { + REQUEST(xReq); +@@ -349,6 +370,8 @@ ProcDRI2Dispatch (ClientPtr client) + return ProcDRI2CopyRegion(client); + case X_DRI2GetBuffersWithFormat: + return ProcDRI2GetBuffersWithFormat(client); ++ case X_DRI2SwapBuffers: ++ return ProcDRI2SwapBuffers(client); + default: + return BadRequest; + } +-- +1.6.3.3 + diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 2fe416f..b85ea1f 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -19,7 +19,7 @@ Summary: X.Org X11 X server Name: xorg-x11-server Version: 1.6.99 -Release: 21.%{gitdate}%{?dist} +Release: 22.%{gitdate}%{?dist} URL: http://www.x.org License: MIT Group: User Interface/X @@ -50,6 +50,7 @@ Patch10: xserver-1.6.99-linkmap.patch # OpenGL compositing manager feature/optimization patches. Patch103: xserver-1.5.0-bg-none-root.patch +Patch104: dri2-page-flip.patch Patch2013: xserver-1.4.99-document-fontpath-correctly.patch Patch2014: xserver-1.5.0-projector-fb-size.patch @@ -103,7 +104,7 @@ BuildRequires: git-core BuildRequires: automake autoconf libtool pkgconfig BuildRequires: xorg-x11-util-macros >= 1.1.5 -BuildRequires: xorg-x11-proto-devel >= 7.4-23 +BuildRequires: xorg-x11-proto-devel >= 7.4-27 BuildRequires: xorg-x11-xtrans-devel >= 1.2.2-1 BuildRequires: libXfont-devel libXau-devel libxkbfile-devel libXres-devel @@ -119,8 +120,9 @@ BuildRequires: libXi-devel libXpm-devel libXaw-devel libXfixes-devel BuildRequires: libXv-devel # openssl? really? -BuildRequires: pixman-devel libpciaccess-devel >= 0.10.6-1 openssl-devel byacc flex -BuildRequires: mesa-libGL-devel >= 7.1-0.37 +BuildRequires: pixman-devel >= 0.15.14 +BuildRequires: libpciaccess-devel >= 0.10.6-1 openssl-devel byacc flex +BuildRequires: mesa-libGL-devel >= 7.6-0.6 # XXX silly... BuildRequires: libdrm-devel >= 2.4.0 kernel-headers @@ -525,6 +527,9 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Wed Jul 29 2009 Kristian Høgsberg - 1.6.99-22.20090724 +- Add DRI2 page flipping feature. + * Tue Jul 28 2009 Adam Jackson 1.6.99-21.20090724 - xserver-1.6.99-right-of.patch: Default to right-of initial placement for RANDR 1.2 drivers with enough virtual space.