rpms/xorg-x11-server/devel dri2-page-flip.patch, NONE, 1.1 xorg-x11-server.spec, 1.456, 1.457

Kristian Høgsberg krh at fedoraproject.org
Fri Jul 31 17:56:40 UTC 2009


Author: krh

Update of /cvs/pkgs/rpms/xorg-x11-server/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv3864

Modified Files:
	xorg-x11-server.spec 
Added Files:
	dri2-page-flip.patch 
Log Message:
* Wed Jul 29 2009 Kristian Høgsberg <krh at redhat.com> - 1.6.99-22.20090724
- Add DRI2 page flipping feature.


dri2-page-flip.patch:
 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 |   26 +++++++++-
 7 files changed, 200 insertions(+), 28 deletions(-)

--- NEW FILE dri2-page-flip.patch ---
>From fb33e4a3cb43ff4b2ca4bdd9170d84569d3e9de0 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= <krh at redhat.com>
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 <GL/gl.h>
 #include <GL/glxproto.h>
 
-/* 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, &region, &box, 0);
+    
+    return DRI2CopyRegion(pDraw, &region,
+			  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



Index: xorg-x11-server.spec
===================================================================
RCS file: /cvs/pkgs/rpms/xorg-x11-server/devel/xorg-x11-server.spec,v
retrieving revision 1.456
retrieving revision 1.457
diff -u -p -r1.456 -r1.457
--- xorg-x11-server.spec	28 Jul 2009 18:41:28 -0000	1.456
+++ xorg-x11-server.spec	31 Jul 2009 17:56:40 -0000	1.457
@@ -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 
 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 <krh at redhat.com> - 1.6.99-22.20090724
+- Add DRI2 page flipping feature.
+
 * Tue Jul 28 2009 Adam Jackson <ajax at redhat.com> 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.




More information about the fedora-extras-commits mailing list