aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/dri2
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86/dri2')
-rw-r--r--xorg-server/hw/xfree86/dri2/Makefile.in76
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.c733
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.h125
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2ext.c234
4 files changed, 693 insertions, 475 deletions
diff --git a/xorg-server/hw/xfree86/dri2/Makefile.in b/xorg-server/hw/xfree86/dri2/Makefile.in
index c37499cf3..74cc5d42f 100644
--- a/xorg-server/hw/xfree86/dri2/Makefile.in
+++ b/xorg-server/hw/xfree86/dri2/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -45,7 +45,6 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \
$(top_builddir)/include/xorg-server.h \
$(top_builddir)/include/dix-config.h \
- $(top_builddir)/include/xgl-config.h \
$(top_builddir)/include/xorg-config.h \
$(top_builddir)/include/xkb-config.h \
$(top_builddir)/include/xwin-config.h \
@@ -71,9 +70,6 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
@@ -90,8 +86,9 @@ ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
-APPDEFAULTDIR = @APPDEFAULTDIR@
APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@
+APPLE_APPLICATION_ID = @APPLE_APPLICATION_ID@
+APPLE_APPLICATION_NAME = @APPLE_APPLICATION_NAME@
APP_MAN_DIR = @APP_MAN_DIR@
APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
AR = @AR@
@@ -112,10 +109,6 @@ CFLAGS = @CFLAGS@
COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DARWIN_LIBS = @DARWIN_LIBS@
DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -137,6 +130,7 @@ DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@
DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@
DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@
DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@
+DOLT_BASH = @DOLT_BASH@
DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@
@@ -146,18 +140,15 @@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
DRI_DRIVER_PATH = @DRI_DRIVER_PATH@
DSYMUTIL = @DSYMUTIL@
DTRACE = @DTRACE@
-ECHO = @ECHO@
+DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
-F77 = @F77@
-FFLAGS = @FFLAGS@
+FGREP = @FGREP@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
-FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
-FREETYPE_LIBS = @FREETYPE_LIBS@
GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@
GLX_DEFINES = @GLX_DEFINES@
GL_CFLAGS = @GL_CFLAGS@
@@ -176,7 +167,7 @@ KDRIVE_LIBS = @KDRIVE_LIBS@
KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@
KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@
KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@
-LAUNCHD = @LAUNCHD@
+LD = @LD@
LDFLAGS = @LDFLAGS@
LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@
LEX = @LEX@
@@ -190,7 +181,10 @@ LIBTOOL = @LIBTOOL@
LIB_MAN_DIR = @LIB_MAN_DIR@
LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
LINUXDOC = @LINUXDOC@
+LIPO = @LIPO@
LN_S = @LN_S@
+LTCOMPILE = @LTCOMPILE@
+LTCXXCOMPILE = @LTCXXCOMPILE@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -202,8 +196,7 @@ MESA_SOURCE = @MESA_SOURCE@
MISC_MAN_DIR = @MISC_MAN_DIR@
MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
MKDIR_P = @MKDIR_P@
-MKFONTDIR = @MKFONTDIR@
-MKFONTSCALE = @MKFONTSCALE@
+NM = @NM@
NMEDIT = @NMEDIT@
OBJC = @OBJC@
OBJCCLD = @OBJCCLD@
@@ -212,8 +205,8 @@ OBJCFLAGS = @OBJCFLAGS@
OBJCLINK = @OBJCLINK@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
-OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
@@ -246,7 +239,6 @@ VENDOR_NAME = @VENDOR_NAME@
VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@
VENDOR_RELEASE = @VENDOR_RELEASE@
VERSION = @VERSION@
-X11APP_ARCHS = @X11APP_ARCHS@
X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@
X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@
XDMCP_CFLAGS = @XDMCP_CFLAGS@
@@ -256,27 +248,12 @@ XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@
XDMX_CFLAGS = @XDMX_CFLAGS@
XDMX_LIBS = @XDMX_LIBS@
XDMX_SYS_LIBS = @XDMX_SYS_LIBS@
-XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@
-XEGL_LIBS = @XEGL_LIBS@
-XEGL_SYS_LIBS = @XEGL_SYS_LIBS@
XEPHYR_CFLAGS = @XEPHYR_CFLAGS@
-XEPHYR_DRI_LIBS = @XEPHYR_DRI_LIBS@
XEPHYR_INCS = @XEPHYR_INCS@
XEPHYR_LIBS = @XEPHYR_LIBS@
XF86CONFIGFILE = @XF86CONFIGFILE@
-XF86MISC_CFLAGS = @XF86MISC_CFLAGS@
-XF86MISC_LIBS = @XF86MISC_LIBS@
XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
-XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@
-XGLMODULES_LIBS = @XGLMODULES_LIBS@
-XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@
-XGLXMODULES_LIBS = @XGLXMODULES_LIBS@
-XGLX_LIBS = @XGLX_LIBS@
-XGLX_SYS_LIBS = @XGLX_SYS_LIBS@
-XGL_LIBS = @XGL_LIBS@
-XGL_MODULE_PATH = @XGL_MODULE_PATH@
-XGL_SYS_LIBS = @XGL_SYS_LIBS@
XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@
XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@
XKB_COMPILED_DIR = @XKB_COMPILED_DIR@
@@ -287,10 +264,6 @@ XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@
XNESTMODULES_LIBS = @XNESTMODULES_LIBS@
XNEST_LIBS = @XNEST_LIBS@
XNEST_SYS_LIBS = @XNEST_SYS_LIBS@
-XORGCFG_DEP_CFLAGS = @XORGCFG_DEP_CFLAGS@
-XORGCFG_DEP_LIBS = @XORGCFG_DEP_LIBS@
-XORGCONFIG_DEP_CFLAGS = @XORGCONFIG_DEP_CFLAGS@
-XORGCONFIG_DEP_LIBS = @XORGCONFIG_DEP_LIBS@
XORG_CFLAGS = @XORG_CFLAGS@
XORG_INCS = @XORG_INCS@
XORG_LIBS = @XORG_LIBS@
@@ -299,13 +272,8 @@ XORG_MODULES_LIBS = @XORG_MODULES_LIBS@
XORG_OS = @XORG_OS@
XORG_OS_SUBDIR = @XORG_OS_SUBDIR@
XORG_SYS_LIBS = @XORG_SYS_LIBS@
-XPRINTMODULES_CFLAGS = @XPRINTMODULES_CFLAGS@
-XPRINTMODULES_LIBS = @XPRINTMODULES_LIBS@
-XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@
-XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@
-XPRINT_CFLAGS = @XPRINT_CFLAGS@
-XPRINT_LIBS = @XPRINT_LIBS@
-XPRINT_SYS_LIBS = @XPRINT_SYS_LIBS@
+XPBPROXY_CFLAGS = @XPBPROXY_CFLAGS@
+XPBPROXY_LIBS = @XPBPROXY_LIBS@
XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@
XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@
XSDL_INCS = @XSDL_INCS@
@@ -338,8 +306,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -359,7 +326,6 @@ driverdir = @driverdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
extdir = @extdir@
-ft_config = @ft_config@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -369,12 +335,12 @@ htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
-launchagentsdir = @launchagentsdir@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
logdir = @logdir@
+lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
moduledir = @moduledir@
@@ -392,8 +358,6 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-xglmoduledir = @xglmoduledir@
-xpconfigdir = @xpconfigdir@
libdri2_la_LTLIBRARIES = libdri2.la
libdri2_la_CFLAGS = \
-DHAVE_XORG_CONFIG_H \
@@ -418,8 +382,8 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -545,7 +509,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index 74aef7196..580383dbc 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/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,40 +38,40 @@
#include "xf86Module.h"
#include "scrnintstr.h"
#include "windowstr.h"
-#include "region.h"
-#include "damage.h"
#include "dri2.h"
-#include <GL/internal/dri_sarea.h>
#include "xf86.h"
-static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKey;
-static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKey;
-static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKey;
-
-typedef struct _DRI2DrawablePriv {
- unsigned int refCount;
- unsigned int boHandle;
- unsigned int dri2Handle;
-} DRI2DrawablePrivRec, *DRI2DrawablePrivPtr;
+static int dri2ScreenPrivateKeyIndex;
+static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
+static int dri2WindowPrivateKeyIndex;
+static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
+static int dri2PixmapPrivateKeyIndex;
+static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
+
+typedef struct _DRI2Drawable {
+ unsigned int refCount;
+ int width;
+ int height;
+ DRI2Buffer2Ptr *buffers;
+ int bufferCount;
+ unsigned int pendingSequence;
+} DRI2DrawableRec, *DRI2DrawablePtr;
typedef struct _DRI2Screen {
- int fd;
- drmBO sareaBO;
- void *sarea;
- unsigned int sareaSize;
const char *driverName;
- unsigned int nextHandle;
+ const char *deviceName;
+ int fd;
+ unsigned int lastSequence;
- __DRIEventBuffer *buffer;
- int locked;
+ DRI2CreateBuffersProcPtr CreateBuffers;
+ DRI2DestroyBuffersProcPtr DestroyBuffers;
- DRI2GetPixmapHandleProcPtr getPixmapHandle;
- DRI2BeginClipNotifyProcPtr beginClipNotify;
- DRI2EndClipNotifyProcPtr endClipNotify;
+ DRI2CreateBufferProcPtr CreateBuffer;
+ DRI2DestroyBufferProcPtr DestroyBuffer;
+ DRI2CopyRegionProcPtr CopyRegion;
- ClipNotifyProcPtr ClipNotify;
- HandleExposuresProcPtr HandleExposures;
+ HandleExposuresProcPtr HandleExposures;
} DRI2ScreenRec, *DRI2ScreenPtr;
static DRI2ScreenPtr
@@ -80,292 +80,414 @@ DRI2GetScreen(ScreenPtr pScreen)
return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey);
}
-static void *
-DRI2ScreenAllocEvent(DRI2ScreenPtr ds, size_t size)
+static DRI2DrawablePtr
+DRI2GetDrawable(DrawablePtr pDraw)
{
- 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;
-}
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
-static void
-DRI2ScreenCommitEvents(DRI2ScreenPtr ds)
-{
- ds->buffer->head = ds->buffer->prealloc;
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ pWin = (WindowPtr) pDraw;
+ return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
+ }
+ else
+ {
+ pPixmap = (PixmapPtr) pDraw;
+ return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
+ }
}
-static void
-DRI2PostDrawableConfig(DrawablePtr pDraw)
+int
+DRI2CreateDrawable(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) {
- pWin = (WindowPtr) pDraw;
- pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
-
- nBox = REGION_NUM_RECTS(&pWin->clipList);
- pBox = REGION_RECTS(&pWin->clipList);
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
+ DRI2DrawablePtr pPriv;
- 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;
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv != NULL)
+ {
+ pPriv->refCount++;
+ return Success;
}
- if (!pPriv)
- return;
+ pPriv = xalloc(sizeof *pPriv);
+ if (pPriv == NULL)
+ return BadAlloc;
- 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++;
- }
-}
+ pPriv->refCount = 1;
+ pPriv->width = pDraw->width;
+ pPriv->height = pDraw->height;
+ pPriv->buffers = NULL;
+ pPriv->bufferCount = 0;
-static void
-DRI2PostBufferAttach(DrawablePtr pDraw, Bool force)
-{
- 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) {
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
pWin = (WindowPtr) pDraw;
- pPixmap = pScreen->GetWindowPixmap(pWin);
- pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
- } else {
+ dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
+ }
+ else
+ {
pPixmap = (PixmapPtr) pDraw;
- pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
+ dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
}
- if (!pPriv)
- return;
-
- boHandle = ds->getPixmapHandle(pPixmap, &flags);
- if (boHandle == pPriv->boHandle && !force)
- return;
-
- 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;
+ return Success;
}
-static void
-DRI2ClipNotify(WindowPtr pWin, int dx, int dy)
+static int
+find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+ int i;
- if (!ds->locked) {
- ds->beginClipNotify(pScreen);
- ds->locked = 1;
+ if (pPriv->buffers == NULL) {
+ return -1;
}
- if (ds->ClipNotify) {
- pScreen->ClipNotify = ds->ClipNotify;
- pScreen->ClipNotify(pWin, dx, dy);
- pScreen->ClipNotify = DRI2ClipNotify;
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if ((pPriv->buffers[i] != NULL)
+ && (pPriv->buffers[i]->attachment == attachment)) {
+ return i;
+ }
}
- DRI2PostDrawableConfig(&pWin->drawable);
- DRI2PostBufferAttach(&pWin->drawable, FALSE);
+ return -1;
}
-static void
-DRI2HandleExposures(WindowPtr pWin)
+static DRI2Buffer2Ptr
+allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
+ DRI2DrawablePtr pPriv,
+ unsigned int attachment, unsigned int format,
+ int dimensions_match)
{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+ DRI2Buffer2Ptr buffer;
+ int old_buf;
- if (ds->HandleExposures) {
- pScreen->HandleExposures = ds->HandleExposures;
- pScreen->HandleExposures(pWin);
- pScreen->HandleExposures = DRI2HandleExposures;
- }
+ old_buf = find_attachment(pPriv, attachment);
- DRI2ScreenCommitEvents(ds);
-
- if (ds->locked) {
- ds->endClipNotify(pScreen);
- ds->locked = 0;
+ if ((old_buf < 0)
+ || !dimensions_match
+ || (pPriv->buffers[old_buf]->format != format)) {
+ buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
+ } else {
+ buffer = pPriv->buffers[old_buf];
+ pPriv->buffers[old_buf] = NULL;
}
+
+ return buffer;
}
-void
-DRI2CloseScreen(ScreenPtr pScreen)
+static DRI2Buffer2Ptr *
+do_get_buffers(DrawablePtr pDraw, int *width, int *height,
+ unsigned int *attachments, int count, int *out_count,
+ int has_format)
{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ DRI2Buffer2Ptr *buffers;
+ int need_real_front = 0;
+ int need_fake_front = 0;
+ int have_fake_front = 0;
+ int front_format = 0;
+ const int dimensions_match = (pDraw->width == pPriv->width)
+ && (pDraw->height == pPriv->height);
+ int i;
+
+
+ buffers = xalloc((count + 1) * sizeof(buffers[0]));
+
+ if (ds->CreateBuffer) {
+ /* Version 2 API with CreateBuffer */
+ for (i = 0; i < count; i++) {
+ const unsigned attachment = *(attachments++);
+ const unsigned format = (has_format) ? *(attachments++) : 0;
+
+ buffers[i] = allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
+ format, dimensions_match);
+
+ /* If the drawable is a window and the front-buffer is requested,
+ * silently add the fake front-buffer to the list of requested
+ * attachments. The counting logic in the loop accounts for the case
+ * where the client requests both the fake and real front-buffer.
+ */
+ if (attachment == DRI2BufferBackLeft) {
+ need_real_front++;
+ front_format = format;
+ }
+
+ if (attachment == DRI2BufferFrontLeft) {
+ need_real_front--;
+ front_format = format;
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ need_fake_front++;
+ }
+ }
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ if (attachment == DRI2BufferFakeFrontLeft) {
+ need_fake_front--;
+ have_fake_front = 1;
+ }
+ }
+ }
+
+ if (need_real_front > 0) {
+ buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
+ DRI2BufferFrontLeft,
+ front_format, dimensions_match);
+ }
+
+ if (need_fake_front > 0) {
+ buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
+ DRI2BufferFakeFrontLeft,
+ front_format, dimensions_match);
+ have_fake_front = 1;
+ }
+
+ *out_count = i;
+
+
+ if (pPriv->buffers != NULL) {
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if (pPriv->buffers[i] != NULL) {
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+ }
+ }
+
+ xfree(pPriv->buffers);
+ }
+ } else {
+ DRI2BufferPtr buffers1;
+ unsigned int temp_buf[32];
+ unsigned int *temp = temp_buf;
+ int i;
+ int buffers_match = 1;
+
+ /* Version 1 API with CreateBuffers */
+
+ if ((count + 1) > 32) {
+ temp = xalloc((count + 1) * sizeof(temp[0]));
+ }
+
+ for (i = 0; i < count; i++) {
+ const unsigned attachment = *(attachments++);
+
+ /* Version 1 doesn't deal with the format at all */
+ if (has_format)
+ attachments++;
+
+ /*
+ * Make sure the client also gets the front buffer when
+ * it asks for a back buffer
+ */
+ if (attachment == DRI2BufferBackLeft)
+ need_real_front++;
+
+ /*
+ * If the drawable is a window and the front-buffer is requested,
+ * silently add the fake front-buffer to the list of requested
+ * attachments. The counting logic in the loop accounts for the
+ * case where the client requests both the fake and real
+ * front-buffer.
+ */
+ if (attachment == DRI2BufferFrontLeft) {
+ need_real_front--;
+ if (pDraw->type == DRAWABLE_WINDOW)
+ need_fake_front++;
+ }
+ if (pDraw->type == DRAWABLE_WINDOW &&
+ attachment == DRI2BufferFakeFrontLeft)
+ {
+ need_fake_front--;
+ have_fake_front = 1;
+ }
+
+ temp[i] = attachment;
+ }
+
+ if (need_real_front > 0)
+ temp[count++] = DRI2BufferFrontLeft;
+
+ if (need_fake_front > 0) {
+ temp[count++] = DRI2BufferFakeFrontLeft;
+ have_fake_front = 1;
+ }
+
+ if (count != pPriv->bufferCount)
+ buffers_match = 0;
+ else {
+ for (i = 0; i < count; i++)
+ if (pPriv->buffers[i]->attachment != temp[i]) {
+ buffers_match = 0;
+ break;
+ }
+ }
+ if (pPriv->buffers == NULL || !dimensions_match || !buffers_match)
+ {
+ buffers1 = (*ds->CreateBuffers)(pDraw, temp, count);
+ if (pPriv->buffers != NULL)
+ (*ds->DestroyBuffers)(pDraw, (DRI2BufferPtr) pPriv->buffers[0],
+ pPriv->bufferCount);
+ }
+ else
+ buffers1 = (DRI2BufferPtr) pPriv->buffers[0];
+
+ for (i = 0; i < count; i++)
+ buffers[i] = (DRI2Buffer2Ptr) &buffers1[i];
+
+ *out_count = count;
+
+ if (pPriv->buffers)
+ xfree (pPriv->buffers);
+
+ if (temp != temp_buf) {
+ xfree(temp);
+ }
+ }
- pScreen->ClipNotify = ds->ClipNotify;
- pScreen->HandleExposures = ds->HandleExposures;
+ pPriv->buffers = buffers;
+ pPriv->bufferCount = *out_count;
+ pPriv->width = pDraw->width;
+ pPriv->height = pDraw->height;
+ *width = pPriv->width;
+ *height = pPriv->height;
+
+
+ /* If the client is getting a fake front-buffer, pre-fill it with the
+ * contents of the real front-buffer. This ensures correct operation of
+ * applications that call glXWaitX before calling glDrawBuffer.
+ */
+ if (have_fake_front) {
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pPriv->width;
+ box.y2 = pPriv->height;
+ REGION_INIT(pDraw->pScreen, &region, &box, 0);
+
+ DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
+ DRI2BufferFrontLeft);
+ }
- drmBOUnmap(ds->fd, &ds->sareaBO);
- drmBOUnreference(ds->fd, &ds->sareaBO);
+ return pPriv->buffers;
+}
- xfree(ds);
- dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
+DRI2Buffer2Ptr *
+DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
+ unsigned int *attachments, int count, int *out_count)
+{
+ return do_get_buffers(pDraw, width, height, attachments, count,
+ out_count, FALSE);
}
-Bool
-DRI2CreateDrawable(DrawablePtr pDraw,
- unsigned int *handle, unsigned int *head)
+DRI2Buffer2Ptr *
+DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
+ unsigned int *attachments, int count, int *out_count)
{
- 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;
- }
+ return do_get_buffers(pDraw, width, height, attachments, count,
+ out_count, TRUE);
+}
- 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);
- }
+int
+DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
+ unsigned int dest, unsigned int src)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ DRI2BufferPtr pDestBuffer, pSrcBuffer;
+ int i;
- *handle = pPriv->dri2Handle;
- *head = ds->buffer->head;
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadDrawable;
+
+ pDestBuffer = NULL;
+ pSrcBuffer = NULL;
+ for (i = 0; i < pPriv->bufferCount; i++)
+ {
+ if (pPriv->buffers[i]->attachment == dest)
+ pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ if (pPriv->buffers[i]->attachment == src)
+ pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ }
+ if (pSrcBuffer == NULL || pDestBuffer == NULL)
+ return BadValue;
- DRI2PostDrawableConfig(pDraw);
- DRI2PostBufferAttach(pDraw, TRUE);
- DRI2ScreenCommitEvents(ds);
+ (*ds->CopyRegion)(pDraw, pRegion, pDestBuffer, pSrcBuffer);
- return TRUE;
+ return Success;
}
void
DRI2DestroyDrawable(DrawablePtr pDraw)
{
- PixmapPtr pPixmap;
- WindowPtr pWin;
- 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;
- }
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
- pPriv = dixLookupPrivate(devPrivates, key);
+ pPriv = DRI2GetDrawable(pDraw);
if (pPriv == NULL)
return;
-
+
pPriv->refCount--;
- if (pPriv->refCount == 0) {
- dixSetPrivate(devPrivates, key, NULL);
- xfree(pPriv);
- }
-}
+ if (pPriv->refCount > 0)
+ return;
-void
-DRI2ReemitDrawableInfo(DrawablePtr pDraw, unsigned int *head)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ if (pPriv->buffers != NULL) {
+ int i;
- *head = ds->buffer->head;
+ if (ds->DestroyBuffer) {
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+ }
+ } else {
+ (*ds->DestroyBuffers)(pDraw, (DRI2BufferPtr) pPriv->buffers[0],
+ pPriv->bufferCount);
+ }
- DRI2PostDrawableConfig(pDraw);
- DRI2PostBufferAttach(pDraw, TRUE);
- DRI2ScreenCommitEvents(ds);
+ xfree(pPriv->buffers);
+ }
+
+ xfree(pPriv);
+
+ 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, unsigned int driverType, int *fd,
+ const char **driverName, const char **deviceName)
{
DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
if (ds == NULL)
return FALSE;
+ if (driverType != DRI2DriverDRI)
+ return BadValue;
+
*fd = ds->fd;
*driverName = ds->driverName;
- *sareaHandle = ds->sareaBO.handle;
+ *deviceName = ds->deviceName;
return TRUE;
}
Bool
-DRI2AuthConnection(ScreenPtr pScreen, drm_magic_t magic)
+DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic)
{
DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
@@ -375,86 +497,61 @@ 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;
-
- ds->ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = DRI2ClipNotify;
- ds->HandleExposures = pScreen->HandleExposures;
- pScreen->HandleExposures = DRI2HandleExposures;
+ return FALSE;
- dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
+ ds->fd = info->fd;
+ ds->driverName = info->driverName;
+ ds->deviceName = info->deviceName;
+
+ /* Prefer the new one-at-a-time buffer API */
+ if (info->version >= 2 && info->CreateBuffer && info->DestroyBuffer) {
+ ds->CreateBuffer = info->CreateBuffer;
+ ds->DestroyBuffer = info->DestroyBuffer;
+ ds->CreateBuffers = NULL;
+ ds->DestroyBuffers = NULL;
+ } else if (info->CreateBuffers && info->DestroyBuffers) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[DRI2] Version 1 API (broken front buffer rendering)\n");
+ ds->CreateBuffer = NULL;
+ ds->DestroyBuffer = NULL;
+ ds->CreateBuffers = info->CreateBuffers;
+ ds->DestroyBuffers = info->DestroyBuffers;
+ } else {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] Missing buffer management functions\n");
+ xfree(ds);
+ return FALSE;
+ }
- p = DRI2SetupSAREA(pScreen, info->driverSareaSize);
- if (p == NULL) {
+ if (!info->CopyRegion) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] Missing copy region function\n");
xfree(ds);
- return NULL;
+ return FALSE;
}
+ ds->CopyRegion = info->CopyRegion;
+
+ dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
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;
@@ -464,10 +561,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;
}
@@ -482,7 +582,7 @@ static XF86ModuleVersionInfo DRI2VersRec =
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
- 1, 0, 0,
+ 1, 1, 0,
ABI_CLASS_EXTENSION,
ABI_EXTENSION_VERSION,
MOD_CLASS_NONE,
@@ -491,3 +591,12 @@ static XF86ModuleVersionInfo DRI2VersRec =
_X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL };
+void
+DRI2Version(int *major, int *minor)
+{
+ if (major != NULL)
+ *major = DRI2VersRec.majorversion;
+
+ if (minor != NULL)
+ *minor = DRI2VersRec.minorversion;
+}
diff --git a/xorg-server/hw/xfree86/dri2/dri2.h b/xorg-server/hw/xfree86/dri2/dri2.h
index 85b3da41c..f3692673a 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.h
+++ b/xorg-server/hw/xfree86/dri2/dri2.h
@@ -33,49 +33,124 @@
#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>
+/* Version 1 structure (for ABI compatibility) */
typedef struct {
- unsigned int version; /* Version of this struct */
+ unsigned int attachment;
+ unsigned int name;
+ unsigned int pitch;
+ unsigned int cpp;
+ unsigned int flags;
+ void *driverPrivate;
+} DRI2BufferRec, *DRI2BufferPtr;
+
+/* Version 2 structure (with format at the end) */
+typedef struct {
+ unsigned int attachment;
+ unsigned int name;
+ unsigned int pitch;
+ unsigned int cpp;
+ unsigned int flags;
+ void *driverPrivate;
+ unsigned int format;
+} DRI2Buffer2Rec, *DRI2Buffer2Ptr;
+
+typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw,
+ unsigned int *attachments,
+ int count);
+typedef void (*DRI2DestroyBuffersProcPtr)(DrawablePtr pDraw,
+ DRI2BufferPtr buffers,
+ int count);
+typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
+ RegionPtr pRegion,
+ DRI2BufferPtr pDestBuffer,
+ DRI2BufferPtr pSrcBuffer);
+
+typedef void (*DRI2WaitProcPtr)(WindowPtr pWin,
+ unsigned int sequence);
+
+typedef DRI2Buffer2Ptr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
+ unsigned int attachment,
+ unsigned int format);
+typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
+ DRI2Buffer2Ptr buffer);
+
+/**
+ * Version of the DRI2InfoRec structure defined in this header
+ */
+#define DRI2INFOREC_VERSION 2
+
+typedef struct {
+ unsigned int version; /**< Version of this struct */
int fd;
- size_t driverSareaSize;
const char *driverName;
- DRI2GetPixmapHandleProcPtr getPixmapHandle;
- DRI2BeginClipNotifyProcPtr beginClipNotify;
- DRI2EndClipNotifyProcPtr endClipNotify;
+ const char *deviceName;
+
+ DRI2CreateBuffersProcPtr CreateBuffers;
+ DRI2DestroyBuffersProcPtr DestroyBuffers;
+ DRI2CopyRegionProcPtr CopyRegion;
+ DRI2WaitProcPtr Wait;
+
+ /**
+ * \name Fields added in version 2 of the structure.
+ */
+ /*@{*/
+ DRI2CreateBufferProcPtr CreateBuffer;
+ DRI2DestroyBufferProcPtr DestroyBuffer;
+ /*@}*/
+
} DRI2InfoRec, *DRI2InfoPtr;
-void *DRI2ScreenInit(ScreenPtr pScreen,
- DRI2InfoPtr info);
+Bool DRI2ScreenInit(ScreenPtr pScreen,
+ DRI2InfoPtr info);
void DRI2CloseScreen(ScreenPtr pScreen);
Bool DRI2Connect(ScreenPtr pScreen,
+ unsigned int driverType,
int *fd,
const char **driverName,
- unsigned int *sareaHandle);
+ const char **deviceName);
-Bool DRI2AuthConnection(ScreenPtr pScreen, drm_magic_t magic);
+Bool DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic);
-unsigned int DRI2GetPixmapHandle(PixmapPtr pPixmap,
- unsigned int *flags);
+int DRI2CreateDrawable(DrawablePtr pDraw);
-void DRI2Lock(ScreenPtr pScreen);
-void DRI2Unlock(ScreenPtr pScreen);
+void DRI2DestroyDrawable(DrawablePtr pDraw);
-Bool DRI2CreateDrawable(DrawablePtr pDraw,
- unsigned int *handle,
- unsigned int *head);
+DRI2Buffer2Ptr *DRI2GetBuffers(DrawablePtr pDraw,
+ int *width,
+ int *height,
+ unsigned int *attachments,
+ int count,
+ int *out_count);
-void DRI2DestroyDrawable(DrawablePtr pDraw);
+int DRI2CopyRegion(DrawablePtr pDraw,
+ RegionPtr pRegion,
+ unsigned int dest,
+ unsigned int src);
-void DRI2ReemitDrawableInfo(DrawablePtr pDraw,
- unsigned int *head);
+/**
+ * Determine the major and minor version of the DRI2 extension.
+ *
+ * Provides a mechanism to other modules (e.g., 2D drivers) to determine the
+ * version of the DRI2 extension. While it is possible to peek directly at
+ * the \c XF86ModuleData from a layered module, such a module will fail to
+ * load (due to an unresolved symbol) if the DRI2 extension is not loaded.
+ *
+ * \param major Location to store the major verion of the DRI2 extension
+ * \param minor Location to store the minor verion of the DRI2 extension
+ *
+ * \note
+ * This interface was added some time after the initial release of the DRI2
+ * module. Layered modules that wish to use this interface must first test
+ * its existance by calling \c xf86LoaderCheckSymbol.
+ */
+extern _X_EXPORT void DRI2Version(int *major, int *minor);
-Bool DRI2PostDamage(DrawablePtr pDrawable,
- struct drm_clip_rect *rects, int numRects);
+extern _X_EXPORT DRI2Buffer2Ptr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
+ int *width, int *height, unsigned int *attachments, int count,
+ int *out_count);
#endif
diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c
index 4ae0fda3a..3c06174cb 100644
--- a/xorg-server/hw/xfree86/dri2/dri2ext.c
+++ b/xorg-server/hw/xfree86/dri2/dri2ext.c
@@ -38,11 +38,13 @@
#include <X11/X.h>
#include <X11/Xproto.h>
#include <X11/extensions/dri2proto.h>
+#include <X11/extensions/xfixeswire.h>
#include "dixstruct.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "xf86drm.h"
+#include "xfixes.h"
#include "dri2.h"
/* The only xf86 include */
@@ -52,19 +54,6 @@ static ExtensionEntry *dri2Extension;
static RESTYPE dri2DrawableRes;
static Bool
-validScreen(ClientPtr client, int screen, ScreenPtr *pScreen)
-{
- if (screen >= screenInfo.numScreens) {
- client->errorValue = screen;
- return FALSE;
- }
-
- *pScreen = screenInfo.screens[screen];
-
- return TRUE;
-}
-
-static Bool
validDrawable(ClientPtr client, XID drawable,
DrawablePtr *pDrawable, int *status)
{
@@ -91,8 +80,8 @@ ProcDRI2QueryVersion(ClientPtr client)
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
- rep.majorVersion = DRI2_MAJOR;
- rep.minorVersion = DRI2_MINOR;
+ rep.majorVersion = 1;
+ rep.minorVersion = 1;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
@@ -111,67 +100,55 @@ ProcDRI2Connect(ClientPtr client)
{
REQUEST(xDRI2ConnectReq);
xDRI2ConnectReply rep;
- ScreenPtr pScreen;
- int fd;
+ DrawablePtr pDraw;
+ int fd, status;
const char *driverName;
- char *busId = NULL;
- unsigned int sareaHandle;
+ const char *deviceName;
REQUEST_SIZE_MATCH(xDRI2ConnectReq);
- if (!validScreen(client, stuff->screen, &pScreen))
- return BadValue;
+ if (!validDrawable(client, stuff->window, &pDraw, &status))
+ return status;
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.driverNameLength = 0;
- rep.busIdLength = 0;
- rep.sareaHandle = 0;
-
- if (!DRI2Connect(pScreen, &fd, &driverName, &sareaHandle))
- goto fail;
+ rep.deviceNameLength = 0;
- busId = drmGetBusid(fd);
- if (busId == NULL)
+ if (!DRI2Connect(pDraw->pScreen,
+ stuff->driverType, &fd, &driverName, &deviceName))
goto fail;
rep.driverNameLength = strlen(driverName);
- rep.busIdLength = strlen(busId);
- rep.sareaHandle = sareaHandle;
- rep.length = (rep.driverNameLength + 3) / 4 + (rep.busIdLength + 3) / 4;
+ rep.deviceNameLength = strlen(deviceName);
+ rep.length = (rep.driverNameLength + 3) / 4 +
+ (rep.deviceNameLength + 3) / 4;
fail:
WriteToClient(client, sizeof(xDRI2ConnectReply), &rep);
WriteToClient(client, rep.driverNameLength, driverName);
- WriteToClient(client, rep.busIdLength, busId);
- drmFreeBusid(busId);
+ WriteToClient(client, rep.deviceNameLength, deviceName);
return client->noClientException;
}
static int
-ProcDRI2AuthConnection(ClientPtr client)
+ProcDRI2Authenticate(ClientPtr client)
{
- REQUEST(xDRI2AuthConnectionReq);
- xDRI2AuthConnectionReply rep;
- ScreenPtr pScreen;
+ REQUEST(xDRI2AuthenticateReq);
+ xDRI2AuthenticateReply rep;
+ DrawablePtr pDraw;
+ int status;
- REQUEST_SIZE_MATCH(xDRI2AuthConnectionReq);
- if (!validScreen(client, stuff->screen, &pScreen))
- return BadValue;
+ REQUEST_SIZE_MATCH(xDRI2AuthenticateReq);
+ if (!validDrawable(client, stuff->window, &pDraw, &status))
+ return status;
rep.type = X_Reply;
- rep.length = 0;
rep.sequenceNumber = client->sequence;
- rep.authenticated = 1;
-
- if (!DRI2AuthConnection(pScreen, stuff->magic)) {
- ErrorF("DRI2: Failed to authenticate %lu\n",
- (unsigned long) stuff->magic);
- rep.authenticated = 0;
- }
-
- WriteToClient(client, sizeof(xDRI2AuthConnectionReply), &rep);
+ rep.length = 0;
+ rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic);
+ WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
return client->noClientException;
}
@@ -180,9 +157,7 @@ static int
ProcDRI2CreateDrawable(ClientPtr client)
{
REQUEST(xDRI2CreateDrawableReq);
- xDRI2CreateDrawableReply rep;
DrawablePtr pDrawable;
- unsigned int handle, head;
int status;
REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq);
@@ -190,22 +165,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;
}
@@ -225,27 +193,131 @@ ProcDRI2DestroyDrawable(ClientPtr client)
return client->noClientException;
}
+
+static void
+send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
+ DRI2Buffer2Ptr *buffers, int count, int width, int height)
+{
+ xDRI2GetBuffersReply rep;
+ int skip = 0;
+ int i;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ for (i = 0; i < count; i++) {
+ /* Do not send the real front buffer of a window to the client.
+ */
+ if (buffers[i]->attachment == DRI2BufferFrontLeft) {
+ skip++;
+ continue;
+ }
+ }
+ }
+
+ rep.type = X_Reply;
+ rep.length = (count - skip) * sizeof(xDRI2Buffer) / 4;
+ rep.sequenceNumber = client->sequence;
+ rep.width = width;
+ rep.height = height;
+ rep.count = count - skip;
+ WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);
+
+ for (i = 0; i < count; i++) {
+ xDRI2Buffer buffer;
+
+ /* Do not send the real front buffer of a window to the client.
+ */
+ if ((pDrawable->type == DRAWABLE_WINDOW)
+ && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
+ continue;
+ }
+
+ 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);
+ }
+}
+
+
+static int
+ProcDRI2GetBuffers(ClientPtr client)
+{
+ REQUEST(xDRI2GetBuffersReq);
+ DrawablePtr pDrawable;
+ DRI2Buffer2Ptr *buffers;
+ int status, width, height, count;
+ unsigned int *attachments;
+
+ REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
+ if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
+ return status;
+
+ attachments = (unsigned int *) &stuff[1];
+ buffers = DRI2GetBuffers(pDrawable, &width, &height,
+ attachments, stuff->count, &count);
+
+
+ send_buffers_reply(client, pDrawable, buffers, count, width, height);
+
+ return client->noClientException;
+}
+
static int
-ProcDRI2ReemitDrawableInfo(ClientPtr client)
+ProcDRI2GetBuffersWithFormat(ClientPtr client)
{
- REQUEST(xDRI2ReemitDrawableInfoReq);
- xDRI2ReemitDrawableInfoReply rep;
+ REQUEST(xDRI2GetBuffersReq);
+ DrawablePtr pDrawable;
+ DRI2Buffer2Ptr *buffers;
+ int status, width, height, count;
+ unsigned int *attachments;
+
+ REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4));
+ if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
+ return status;
+
+ attachments = (unsigned int *) &stuff[1];
+ buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
+ attachments, stuff->count, &count);
+
+ send_buffers_reply(client, pDrawable, buffers, count, width, height);
+
+ return client->noClientException;
+}
+
+static int
+ProcDRI2CopyRegion(ClientPtr client)
+{
+ REQUEST(xDRI2CopyRegionReq);
+ xDRI2CopyRegionReply rep;
DrawablePtr pDrawable;
- unsigned int head;
int status;
+ RegionPtr pRegion;
+
+ REQUEST_SIZE_MATCH(xDRI2CopyRegionReq);
- REQUEST_SIZE_MATCH(xDRI2ReemitDrawableInfoReq);
if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
return status;
- DRI2ReemitDrawableInfo(pDrawable, &head);
+ VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess);
+
+ status = DRI2CopyRegion(pDrawable, pRegion, stuff->dest, stuff->src);
+ if (status != Success)
+ return status;
+
+ /* CopyRegion needs to be a round trip to make sure the X server
+ * queues the swap buffer rendering commands before the DRI client
+ * continues rendering. The reply has a bitmask to signal the
+ * presense of optional return values as well, but we're not using
+ * that yet.
+ */
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
- rep.head = head;
- WriteToClient(client, sizeof(xDRI2ReemitDrawableInfoReply), &rep);
+ WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep);
return client->noClientException;
}
@@ -266,14 +338,18 @@ ProcDRI2Dispatch (ClientPtr client)
switch (stuff->data) {
case X_DRI2Connect:
return ProcDRI2Connect(client);
- case X_DRI2AuthConnection:
- return ProcDRI2AuthConnection(client);
+ case X_DRI2Authenticate:
+ return ProcDRI2Authenticate(client);
case X_DRI2CreateDrawable:
return ProcDRI2CreateDrawable(client);
case X_DRI2DestroyDrawable:
return ProcDRI2DestroyDrawable(client);
- case X_DRI2ReemitDrawableInfo:
- return ProcDRI2ReemitDrawableInfo(client);
+ case X_DRI2GetBuffers:
+ return ProcDRI2GetBuffers(client);
+ case X_DRI2CopyRegion:
+ return ProcDRI2CopyRegion(client);
+ case X_DRI2GetBuffersWithFormat:
+ return ProcDRI2GetBuffersWithFormat(client);
default:
return BadRequest;
}
@@ -296,8 +372,7 @@ SProcDRI2Connect(ClientPtr client)
swaps(&rep.sequenceNumber, n);
rep.length = 0;
rep.driverNameLength = 0;
- rep.busIdLength = 0;
- rep.sareaHandle = 0;
+ rep.deviceNameLength = 0;
return client->noClientException;
}
@@ -322,11 +397,6 @@ SProcDRI2Dispatch (ClientPtr client)
}
}
-static void
-DRI2ResetProc (ExtensionEntry *extEntry)
-{
-}
-
static int DRI2DrawableGone(pointer p, XID id)
{
DrawablePtr pDrawable = p;
@@ -344,7 +414,7 @@ DRI2ExtensionInit(void)
DRI2NumberErrors,
ProcDRI2Dispatch,
SProcDRI2Dispatch,
- DRI2ResetProc,
+ NULL,
StandardMinorOpcode);
dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone);