diff options
Diffstat (limited to 'xorg-server/hw/xfree86/dri2')
-rw-r--r-- | xorg-server/hw/xfree86/dri2/Makefile.in | 76 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/dri2/dri2.c | 733 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/dri2/dri2.h | 125 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/dri2/dri2ext.c | 234 |
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, ®ion, &box, 0); + + DRI2CopyRegion(pDraw, ®ion, 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); |