summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2008-08-11 16:59:17 -0400
committerKristian Høgsberg <krh@redhat.com>2008-08-29 12:33:28 -0400
commit5af77d43fe812e127d5d335527fa940ab9d95f38 (patch)
tree88e6cf7deb768f1cccbf806c7313ce0d1ae469d2
parent60ad8d5d05485339e89d7f1f9f1ded75de7c7ea1 (diff)
DRI2: Drop sarea use, implement server side swap buffers.
-rw-r--r--configure.ac25
-rw-r--r--glx/glxcmds.c1
-rw-r--r--glx/glxdri2.c126
-rw-r--r--hw/xfree86/dri2/dri2.c452
-rw-r--r--hw/xfree86/dri2/dri2.h68
-rw-r--r--hw/xfree86/dri2/dri2ext.c86
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, &region, (BoxPtr) rects, numRects);
- REGION_TRANSLATE(pScreen, &region, pDraw->x, pDraw->y);
- DamageDamageRegion(pDraw, &region);
- REGION_UNINIT(pDraw->pScreen, &region);
+ 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;
}