DRI2: add SwapBuffers support
Support the new DRI2 protocol request, DRI2SwapBuffers, in both direct and indirect rendering context. This request allows the display server to optimize back->front swaps (e.g. through page flipping) and allows us to more easily support other GLX features like swap interval and the OML sync extension in DRI2. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
parent
1baaf111c8
commit
a35f6bb207
|
@ -20,7 +20,7 @@ AC_CANONICAL_HOST
|
|||
dnl Versions for external dependencies
|
||||
LIBDRM_REQUIRED=2.4.15
|
||||
LIBDRM_RADEON_REQUIRED=2.4.17
|
||||
DRI2PROTO_REQUIRED=1.99.3
|
||||
DRI2PROTO_REQUIRED=2.2
|
||||
|
||||
dnl Check for progs
|
||||
AC_PROG_CPP
|
||||
|
|
|
@ -262,10 +262,22 @@ struct __DRItexBufferExtensionRec {
|
|||
* Used by drivers that implement DRI2
|
||||
*/
|
||||
#define __DRI2_FLUSH "DRI2_Flush"
|
||||
#define __DRI2_FLUSH_VERSION 1
|
||||
#define __DRI2_FLUSH_VERSION 2
|
||||
struct __DRI2flushExtensionRec {
|
||||
__DRIextension base;
|
||||
void (*flush)(__DRIdrawable *drawable);
|
||||
|
||||
/**
|
||||
* Flush all rendering queue in the driver to the drm and
|
||||
* invalidate all buffers. The driver will call out to
|
||||
* getBuffers/getBuffersWithFormat before it starts rendering
|
||||
* again.
|
||||
*
|
||||
* \param drawable the drawable to flush and invalidate
|
||||
*
|
||||
* \since 2
|
||||
*/
|
||||
void (*flushInvalidate)(__DRIdrawable *drawable);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -380,4 +380,20 @@ DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
|
|||
SyncHandle();
|
||||
}
|
||||
|
||||
void DRI2SwapBuffers(Display *dpy, XID drawable)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2SwapBuffersReq *req;
|
||||
|
||||
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2SwapBuffers, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2SwapBuffers;
|
||||
req->drawable = drawable;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
}
|
||||
|
||||
#endif /* GLX_DIRECT_RENDERING */
|
||||
|
|
|
@ -85,4 +85,7 @@ DRI2CopyRegion(Display * dpy, XID drawable,
|
|||
XserverRegion region,
|
||||
CARD32 dest, CARD32 src);
|
||||
|
||||
extern void
|
||||
DRI2SwapBuffers(Display *dpy, XID drawable);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#include "glapi.h"
|
||||
#include "glxclient.h"
|
||||
#include "glcontextmodes.h"
|
||||
#include "xf86dri.h"
|
||||
|
@ -64,6 +65,7 @@ struct __GLXDRIdisplayPrivateRec
|
|||
int driMajor;
|
||||
int driMinor;
|
||||
int driPatch;
|
||||
int swapAvailable;
|
||||
};
|
||||
|
||||
struct __GLXDRIcontextPrivateRec
|
||||
|
@ -240,7 +242,7 @@ dri2SwapBuffers(__GLXDRIdrawable * pdraw)
|
|||
}
|
||||
|
||||
static void
|
||||
dri2WaitX(__GLXDRIdrawable * pdraw)
|
||||
dri2WaitX(__GLXDRIdrawable *pdraw)
|
||||
{
|
||||
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
|
||||
XRectangle xrect;
|
||||
|
@ -342,6 +344,31 @@ process_buffers(__GLXDRIdrawablePrivate * pdraw, DRI2Buffer * buffers,
|
|||
|
||||
}
|
||||
|
||||
static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
|
||||
{
|
||||
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
|
||||
__GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy);
|
||||
__GLXDRIdisplayPrivate *pdp =
|
||||
(__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
|
||||
__GLXscreenConfigs *psc = pdraw->psc;
|
||||
|
||||
#ifdef __DRI2_FLUSH
|
||||
if (pdraw->psc->f)
|
||||
(*pdraw->psc->f->flush)(pdraw->driDrawable);
|
||||
#endif
|
||||
|
||||
/* Old servers can't handle swapbuffers */
|
||||
if (!pdp->swapAvailable)
|
||||
return dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
|
||||
|
||||
DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable);
|
||||
|
||||
#if __DRI2_FLUSH_VERSION >= 2
|
||||
if (pdraw->psc->f)
|
||||
(*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable);
|
||||
#endif
|
||||
}
|
||||
|
||||
static __DRIbuffer *
|
||||
dri2GetBuffers(__DRIdrawable * driDrawable,
|
||||
int *width, int *height,
|
||||
|
@ -559,6 +586,9 @@ dri2CreateDisplay(Display * dpy)
|
|||
}
|
||||
|
||||
pdp->driPatch = 0;
|
||||
pdp->swapAvailable = 0;
|
||||
if (pdp->driMinor >= 2)
|
||||
pdp->swapAvailable = 1;
|
||||
|
||||
pdp->base.destroyDisplay = dri2DestroyDisplay;
|
||||
pdp->base.createScreen = dri2CreateScreen;
|
||||
|
|
|
@ -454,6 +454,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
|
|||
|
||||
pdp->driScreenPriv = psp;
|
||||
pdp->driContextPriv = &psp->dummyContextPriv;
|
||||
pdp->validBuffers = GL_FALSE;
|
||||
|
||||
if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
|
||||
renderType == GLX_PIXMAP_BIT)) {
|
||||
|
|
|
@ -380,6 +380,8 @@ struct __DRIdrawableRec {
|
|||
* GLX_MESA_swap_control.
|
||||
*/
|
||||
unsigned int swap_interval;
|
||||
|
||||
GLboolean validBuffers;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue