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.am13
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.c330
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.h29
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2ext.c153
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2int.h26
5 files changed, 403 insertions, 148 deletions
diff --git a/xorg-server/hw/xfree86/dri2/Makefile.am b/xorg-server/hw/xfree86/dri2/Makefile.am
index 390ed12c8..502a2ee29 100644
--- a/xorg-server/hw/xfree86/dri2/Makefile.am
+++ b/xorg-server/hw/xfree86/dri2/Makefile.am
@@ -1,17 +1,14 @@
-libdri2_la_LTLIBRARIES = libdri2.la
-libdri2_la_CFLAGS = \
+noinst_LTLIBRARIES = libdri2.la
+AM_CFLAGS = \
-DHAVE_XORG_CONFIG_H \
- @DRI_CFLAGS@ \
- @DIX_CFLAGS@ @XORG_CFLAGS@ @DRI2PROTO_CFLAGS@ @LIBDRM_CFLAGS@ \
+ @DIX_CFLAGS@ @XORG_CFLAGS@ \
-I$(top_srcdir)/hw/xfree86/common \
-I$(top_srcdir)/hw/xfree86/os-support/bus
-libdri2_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG)
-libdri2_la_LIBADD = @LIBDRM_LIBS@ $(PIXMAN_LIBS)
-libdri2_ladir = $(moduledir)/extensions
libdri2_la_SOURCES = \
dri2.c \
dri2.h \
- dri2ext.c
+ dri2ext.c \
+ dri2int.h
sdk_HEADERS = dri2.h
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index d3b3c73f8..2ea0c331e 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -44,13 +44,16 @@
#include "windowstr.h"
#include "dixstruct.h"
#include "dri2.h"
+#include "dri2int.h"
#include "xf86VGAarbiter.h"
-
+#include "damage.h"
#include "xf86.h"
CARD8 dri2_major; /* version of DRI2 supported by DDX */
CARD8 dri2_minor;
+uint32_t prime_id_allocate_bitmask;
+
static DevPrivateKeyRec dri2ScreenPrivateKeyRec;
#define dri2ScreenPrivateKey (&dri2ScreenPrivateKeyRec)
@@ -63,6 +66,17 @@ static DevPrivateKeyRec dri2PixmapPrivateKeyRec;
#define dri2PixmapPrivateKey (&dri2PixmapPrivateKeyRec)
+static DevPrivateKeyRec dri2ClientPrivateKeyRec;
+
+#define dri2ClientPrivateKey (&dri2ClientPrivateKeyRec)
+
+#define dri2ClientPrivate(_pClient) (dixLookupPrivate(&(_pClient)->devPrivates, \
+ dri2ClientPrivateKey))
+
+typedef struct _DRI2Client {
+ int prime_id;
+} DRI2ClientRec, *DRI2ClientPtr;
+
static RESTYPE dri2DrawableRes;
typedef struct _DRI2Screen *DRI2ScreenPtr;
@@ -87,6 +101,9 @@ typedef struct _DRI2Drawable {
int swap_limit; /* for N-buffering */
unsigned long serialNumber;
Bool needInvalidate;
+ int prime_id;
+ PixmapPtr prime_slave_pixmap;
+ PixmapPtr redirectpixmap;
} DRI2DrawableRec, *DRI2DrawablePtr;
typedef struct _DRI2Screen {
@@ -97,6 +114,7 @@ typedef struct _DRI2Screen {
const char *deviceName;
int fd;
unsigned int lastSequence;
+ int prime_id;
DRI2CreateBufferProcPtr CreateBuffer;
DRI2DestroyBufferProcPtr DestroyBuffer;
@@ -113,14 +131,46 @@ typedef struct _DRI2Screen {
HandleExposuresProcPtr HandleExposures;
ConfigNotifyProcPtr ConfigNotify;
+ DRI2CreateBuffer2ProcPtr CreateBuffer2;
+ DRI2DestroyBuffer2ProcPtr DestroyBuffer2;
+ DRI2CopyRegion2ProcPtr CopyRegion2;
} DRI2ScreenRec;
+static void
+destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, int prime_id);
+
static DRI2ScreenPtr
DRI2GetScreen(ScreenPtr pScreen)
{
return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey);
}
+static ScreenPtr
+GetScreenPrime(ScreenPtr master, int prime_id)
+{
+ ScreenPtr slave;
+ if (prime_id == 0 || xorg_list_is_empty(&master->offload_slave_list)) {
+ return master;
+ }
+ xorg_list_for_each_entry(slave, &master->offload_slave_list, offload_head) {
+ DRI2ScreenPtr ds;
+
+ ds = DRI2GetScreen(slave);
+ if (ds->prime_id == prime_id)
+ break;
+ }
+ if (!slave)
+ return master;
+ return slave;
+}
+
+static DRI2ScreenPtr
+DRI2GetScreenPrime(ScreenPtr master, int prime_id)
+{
+ ScreenPtr slave = GetScreenPrime(master, prime_id);
+ return DRI2GetScreen(slave);
+}
+
static DRI2DrawablePtr
DRI2GetDrawable(DrawablePtr pDraw)
{
@@ -187,7 +237,8 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
xorg_list_init(&pPriv->reference_list);
pPriv->serialNumber = DRI2DrawableSerial(pDraw);
pPriv->needInvalidate = FALSE;
-
+ pPriv->redirectpixmap = NULL;
+ pPriv->prime_slave_pixmap = NULL;
if (pDraw->type == DRAWABLE_WINDOW) {
pWin = (WindowPtr) pDraw;
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
@@ -286,6 +337,7 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
DRI2InvalidateProcPtr invalidate, void *priv)
{
DRI2DrawablePtr pPriv;
+ DRI2ClientPtr dri2_client = dri2ClientPrivate(client);
XID dri2_id;
int rc;
@@ -295,6 +347,8 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
if (pPriv == NULL)
return BadAlloc;
+ pPriv->prime_id = dri2_client->prime_id;
+
dri2_id = FakeClientID(client->index);
rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv);
if (rc != Success)
@@ -307,7 +361,6 @@ static int
DRI2DrawableGone(pointer p, XID id)
{
DRI2DrawablePtr pPriv = p;
- DRI2ScreenPtr ds = pPriv->dri2_screen;
DRI2DrawableRefPtr ref, next;
WindowPtr pWin;
PixmapPtr pPixmap;
@@ -347,16 +400,52 @@ DRI2DrawableGone(pointer p, XID id)
if (pPriv->buffers != NULL) {
for (i = 0; i < pPriv->bufferCount; i++)
- (*ds->DestroyBuffer) (pDraw, pPriv->buffers[i]);
+ destroy_buffer(pDraw, pPriv->buffers[i], pPriv->prime_id);
free(pPriv->buffers);
}
+ if (pPriv->redirectpixmap) {
+ (*pDraw->pScreen->ReplaceScanoutPixmap)(pDraw, pPriv->redirectpixmap, FALSE);
+ (*pDraw->pScreen->DestroyPixmap)(pPriv->redirectpixmap);
+ }
+
free(pPriv);
return Success;
}
+static DRI2BufferPtr
+create_buffer(DrawablePtr pDraw,
+ unsigned int attachment, unsigned int format)
+{
+ ScreenPtr primeScreen;
+ DRI2DrawablePtr pPriv;
+ DRI2ScreenPtr ds;
+ DRI2BufferPtr buffer;
+ pPriv = DRI2GetDrawable(pDraw);
+ primeScreen = GetScreenPrime(pDraw->pScreen, pPriv->prime_id);
+ ds = DRI2GetScreenPrime(pDraw->pScreen, pPriv->prime_id);
+ if (ds->CreateBuffer2)
+ buffer = (*ds->CreateBuffer2)(primeScreen, pDraw, attachment, format);
+ else
+ buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
+ return buffer;
+}
+
+static void
+destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, int prime_id)
+{
+ ScreenPtr primeScreen;
+ DRI2ScreenPtr ds;
+ primeScreen = GetScreenPrime(pDraw->pScreen, prime_id);
+ ds = DRI2GetScreen(primeScreen);
+ if (ds->DestroyBuffer2)
+ (*ds->DestroyBuffer2)(primeScreen, pDraw, buffer);
+ else
+ (*ds->DestroyBuffer)(pDraw, buffer);
+}
+
static int
find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
{
@@ -387,7 +476,7 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
if ((old_buf < 0)
|| attachment == DRI2BufferFrontLeft
|| !dimensions_match || (pPriv->buffers[old_buf]->format != format)) {
- *buffer = (*ds->CreateBuffer) (pDraw, attachment, format);
+ *buffer = create_buffer (pDraw, attachment, format);
pPriv->serialNumber = DRI2DrawableSerial(pDraw);
return TRUE;
@@ -408,13 +497,12 @@ update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
DRI2BufferPtr * buffers, int out_count, int *width,
int *height)
{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
int i;
if (pPriv->buffers != NULL) {
for (i = 0; i < pPriv->bufferCount; i++) {
if (pPriv->buffers[i] != NULL) {
- (*ds->DestroyBuffer) (pDraw, pPriv->buffers[i]);
+ destroy_buffer(pDraw, pPriv->buffers[i], pPriv->prime_id);
}
}
@@ -434,8 +522,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
unsigned int *attachments, int count, int *out_count,
int has_format)
{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ DRI2ScreenPtr ds;
DRI2BufferPtr *buffers;
int need_real_front = 0;
int need_fake_front = 0;
@@ -452,6 +540,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
return NULL;
}
+ ds = DRI2GetScreen(pDraw->pScreen);
+
dimensions_match = (pDraw->width == pPriv->width)
&& (pDraw->height == pPriv->height)
&& (pPriv->serialNumber == DRI2DrawableSerial(pDraw));
@@ -556,7 +646,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
if (buffers) {
for (i = 0; i < count; i++) {
if (buffers[i] != NULL)
- (*ds->DestroyBuffer) (pDraw, buffers[i]);
+ destroy_buffer(pDraw, buffers[i], 0);
}
free(buffers);
@@ -650,11 +740,118 @@ DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
pPriv->blockedOnMsc = TRUE;
}
+static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable)
+{
+ if (drawable->type == DRAWABLE_PIXMAP)
+ return (PixmapPtr)drawable;
+ else {
+ struct _Window *pWin = (struct _Window *)drawable;
+ return drawable->pScreen->GetWindowPixmap(pWin);
+ }
+}
+
+DrawablePtr DRI2UpdatePrime(DrawablePtr pDraw, DRI2BufferPtr pDest)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ PixmapPtr spix;
+ PixmapPtr mpix = GetDrawablePixmap(pDraw);
+ ScreenPtr master, slave;
+ Bool ret;
+
+ master = mpix->drawable.pScreen;
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr)pDraw;
+ PixmapPtr pPixmap = pDraw->pScreen->GetWindowPixmap(pWin);
+
+ if (pDraw->pScreen->GetScreenPixmap(pDraw->pScreen) == pPixmap) {
+ if (pPriv->redirectpixmap &&
+ pPriv->redirectpixmap->drawable.width == pDraw->width &&
+ pPriv->redirectpixmap->drawable.height == pDraw->height &&
+ pPriv->redirectpixmap->drawable.depth == pDraw->depth) {
+ mpix = pPriv->redirectpixmap;
+ } else {
+ if (master->ReplaceScanoutPixmap) {
+ mpix = (*master->CreatePixmap)(master, pDraw->width, pDraw->height,
+ pDraw->depth, CREATE_PIXMAP_USAGE_SHARED);
+ if (!mpix)
+ return NULL;
+
+ ret = (*master->ReplaceScanoutPixmap)(pDraw, mpix, TRUE);
+ if (ret == FALSE) {
+ (*master->DestroyPixmap)(mpix);
+ return NULL;
+ }
+ pPriv->redirectpixmap = mpix;
+ } else
+ return NULL;
+ }
+ } else if (pPriv->redirectpixmap) {
+ (*master->ReplaceScanoutPixmap)(pDraw, pPriv->redirectpixmap, FALSE);
+ (*master->DestroyPixmap)(pPriv->redirectpixmap);
+ pPriv->redirectpixmap = NULL;
+ }
+ }
+
+ slave = GetScreenPrime(pDraw->pScreen, pPriv->prime_id);
+
+ /* check if the pixmap is still fine */
+ if (pPriv->prime_slave_pixmap) {
+ if (pPriv->prime_slave_pixmap->master_pixmap == mpix)
+ return &pPriv->prime_slave_pixmap->drawable;
+ else {
+ (*master->DestroyPixmap)(pPriv->prime_slave_pixmap->master_pixmap);
+ (*slave->DestroyPixmap)(pPriv->prime_slave_pixmap);
+ }
+ }
+
+ spix = PixmapShareToSlave(mpix, slave);
+ if (!spix)
+ return NULL;
+
+ pPriv->prime_slave_pixmap = spix;
+#ifdef COMPOSITE
+ spix->screen_x = mpix->screen_x;
+ spix->screen_y = mpix->screen_y;
+#endif
+ return &spix->drawable;
+}
+
+static void dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
+ DRI2BufferPtr pDest, DRI2BufferPtr pSrc)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ DRI2ScreenPtr ds;
+ ScreenPtr primeScreen;
+
+ primeScreen = GetScreenPrime(pDraw->pScreen, pPriv->prime_id);
+ ds = DRI2GetScreen(primeScreen);
+
+ if (ds->CopyRegion2)
+ (*ds->CopyRegion2)(primeScreen, pDraw, pRegion, pDest, pSrc);
+ else
+ (*ds->CopyRegion) (pDraw, pRegion, pDest, pSrc);
+
+ /* cause damage to the box */
+ if (pPriv->prime_id) {
+ BoxRec box;
+ RegionRec region;
+ box.x1 = 0;
+ box.x2 = box.x1 + pDraw->width;
+ box.y1 = 0;
+ box.y2 = box.y1 + pDraw->height;
+ RegionInit(&region, &box, 1);
+ RegionTranslate(&region, pDraw->x, pDraw->y);
+ DamageRegionAppend(pDraw, &region);
+ DamageRegionProcessPending(pDraw);
+ RegionUninit(&region);
+ }
+}
+
int
DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
unsigned int dest, unsigned int src)
{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
DRI2DrawablePtr pPriv;
DRI2BufferPtr pDestBuffer, pSrcBuffer;
int i;
@@ -674,7 +871,7 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
if (pSrcBuffer == NULL || pDestBuffer == NULL)
return BadValue;
- (*ds->CopyRegion) (pDraw, pRegion, pDestBuffer, pSrcBuffer);
+ dri2_copy_region(pDraw, pRegion, pDestBuffer, pSrcBuffer);
return Success;
}
@@ -879,7 +1076,7 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
}
/* Old DDX or no swap interval, just blit */
- if (!ds->ScheduleSwap || !pPriv->swap_interval) {
+ if (!ds->ScheduleSwap || !pPriv->swap_interval || pPriv->prime_id) {
BoxRec box;
RegionRec region;
@@ -891,7 +1088,7 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
pPriv->swapsPending++;
- (*ds->CopyRegion) (pDraw, &region, pDestBuffer, pSrcBuffer);
+ dri2_copy_region(pDraw, &region, pDestBuffer, pSrcBuffer);
DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
func, data);
return Success;
@@ -1091,22 +1288,34 @@ DRI2HasSwapControl(ScreenPtr pScreen)
}
Bool
-DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
+DRI2Connect(ClientPtr client, ScreenPtr pScreen,
+ unsigned int driverType, int *fd,
const char **driverName, const char **deviceName)
{
DRI2ScreenPtr ds;
+ uint32_t prime_id = DRI2DriverPrimeId(driverType);
+ uint32_t driver_id = driverType & 0xffff;
if (!dixPrivateKeyRegistered(dri2ScreenPrivateKey))
return FALSE;
- ds = DRI2GetScreen(pScreen);
- if (ds == NULL || driverType >= ds->numDrivers ||
- !ds->driverNames[driverType])
+ ds = DRI2GetScreenPrime(pScreen, prime_id);
+ if (ds == NULL)
return FALSE;
- *fd = ds->fd;
- *driverName = ds->driverNames[driverType];
+ if (driver_id >= ds->numDrivers ||
+ !ds->driverNames[driver_id])
+ return FALSE;
+
+ *driverName = ds->driverNames[driver_id];
*deviceName = ds->deviceName;
+ *fd = ds->fd;
+
+ if (client) {
+ DRI2ClientPtr dri2_client;
+ dri2_client = dri2ClientPrivate(client);
+ dri2_client->prime_id = prime_id;
+ }
return TRUE;
}
@@ -1122,13 +1331,19 @@ DRI2AuthMagic (ScreenPtr pScreen, uint32_t magic)
}
Bool
-DRI2Authenticate(ScreenPtr pScreen, uint32_t magic)
+DRI2Authenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic)
{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+ DRI2ScreenPtr ds;
+ DRI2ClientPtr dri2_client = dri2ClientPrivate(client);
+ ScreenPtr primescreen;
- if (ds == NULL || (*ds->AuthMagic) (pScreen, magic))
+ ds = DRI2GetScreenPrime(pScreen, dri2_client->prime_id);
+ if (ds == NULL)
return FALSE;
+ primescreen = GetScreenPrime(pScreen, dri2_client->prime_id);
+ if ((*ds->AuthMagic)(primescreen, magic))
+ return FALSE;
return TRUE;
}
@@ -1160,6 +1375,22 @@ DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
return Success;
}
+#define MAX_PRIME DRI2DriverPrimeMask
+static int
+get_prime_id(void)
+{
+ int i;
+ /* start at 1, prime id 0 is just normal driver */
+ for (i = 1; i < MAX_PRIME; i++) {
+ if (prime_id_allocate_bitmask & (1 << i))
+ continue;
+
+ prime_id_allocate_bitmask |= (1 << i);
+ return i;
+ }
+ return -1;
+}
+
Bool
DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
{
@@ -1190,6 +1421,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
if (!dixRegisterPrivateKey(&dri2PixmapPrivateKeyRec, PRIVATE_PIXMAP, 0))
return FALSE;
+ if (!dixRegisterPrivateKey(&dri2ClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(DRI2ClientRec)))
+ return FALSE;
+
ds = calloc(1, sizeof *ds);
if (!ds)
return FALSE;
@@ -1230,6 +1464,19 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
cur_minor = 4;
}
+ if (info->version >= 9) {
+ ds->CreateBuffer2 = info->CreateBuffer2;
+ if (info->CreateBuffer2 && pScreen->isGPU) {
+ ds->prime_id = get_prime_id();
+ if (ds->prime_id == -1) {
+ free(ds);
+ return FALSE;
+ }
+ }
+ ds->DestroyBuffer2 = info->DestroyBuffer2;
+ ds->CopyRegion2 = info->CopyRegion2;
+ }
+
/*
* if the driver doesn't provide an AuthMagic function or the info struct
* version is too low, call through LegacyAuthMagic
@@ -1299,12 +1546,13 @@ DRI2CloseScreen(ScreenPtr pScreen)
pScreen->ConfigNotify = ds->ConfigNotify;
+ if (ds->prime_id)
+ prime_id_allocate_bitmask &= ~(1 << ds->prime_id);
free(ds->driverNames);
free(ds);
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
}
-extern ExtensionModule dri2ExtensionModule;
extern Bool DRI2ModuleSetup(void);
/* Called by InitExtensions() */
@@ -1318,46 +1566,14 @@ DRI2ModuleSetup(void)
return TRUE;
}
-static pointer
-DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
- static Bool setupDone = FALSE;
-
- if (!setupDone) {
- setupDone = TRUE;
- LoadExtension(&dri2ExtensionModule, FALSE);
- }
- else {
- if (errmaj)
- *errmaj = LDR_ONCEONLY;
- }
-
- return (pointer) 1;
-}
-
-static XF86ModuleVersionInfo DRI2VersRec = {
- "dri2",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- 1, 2, 0,
- ABI_CLASS_EXTENSION,
- ABI_EXTENSION_VERSION,
- MOD_CLASS_NONE,
- {0, 0, 0, 0}
-};
-
-_X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL };
-
void
DRI2Version(int *major, int *minor)
{
if (major != NULL)
- *major = DRI2VersRec.majorversion;
+ *major = 1;
if (minor != NULL)
- *minor = DRI2VersRec.minorversion;
+ *minor = 2;
}
int
diff --git a/xorg-server/hw/xfree86/dri2/dri2.h b/xorg-server/hw/xfree86/dri2/dri2.h
index 4fd0fbc52..da7825e09 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.h
+++ b/xorg-server/hw/xfree86/dri2/dri2.h
@@ -176,6 +176,18 @@ typedef void (*DRI2InvalidateProcPtr) (DrawablePtr pDraw, void *data, XID id);
typedef Bool (*DRI2SwapLimitValidateProcPtr) (DrawablePtr pDraw,
int swap_limit);
+typedef DRI2BufferPtr(*DRI2CreateBuffer2ProcPtr) (ScreenPtr pScreen,
+ DrawablePtr pDraw,
+ unsigned int attachment,
+ unsigned int format);
+typedef void (*DRI2DestroyBuffer2ProcPtr) (ScreenPtr pScreen, DrawablePtr pDraw,
+ DRI2BufferPtr buffer);
+
+typedef void (*DRI2CopyRegion2ProcPtr) (ScreenPtr pScreen, DrawablePtr pDraw,
+ RegionPtr pRegion,
+ DRI2BufferPtr pDestBuffer,
+ DRI2BufferPtr pSrcBuffer);
+
/**
* \brief Get the value of a parameter.
*
@@ -193,7 +205,7 @@ typedef int (*DRI2GetParamProcPtr) (ClientPtr client,
/**
* Version of the DRI2InfoRec structure defined in this header
*/
-#define DRI2INFOREC_VERSION 8
+#define DRI2INFOREC_VERSION 9
typedef struct {
unsigned int version; /**< Version of this struct */
@@ -228,7 +240,6 @@ typedef struct {
DRI2SwapLimitValidateProcPtr SwapLimitValidate;
/* added in version 7 */
-
DRI2GetParamProcPtr GetParam;
/* added in version 8 */
@@ -236,9 +247,12 @@ typedef struct {
/* If this is NULL the AuthMagic callback is used */
/* If this is non-NULL the AuthMagic callback is ignored */
DRI2AuthMagic2ProcPtr AuthMagic2;
-} DRI2InfoRec, *DRI2InfoPtr;
-extern _X_EXPORT int DRI2EventBase;
+ /* added in version 9 */
+ DRI2CreateBuffer2ProcPtr CreateBuffer2;
+ DRI2DestroyBuffer2ProcPtr DestroyBuffer2;
+ DRI2CopyRegion2ProcPtr CopyRegion2;
+} DRI2InfoRec, *DRI2InfoPtr;
extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info);
@@ -246,13 +260,13 @@ extern _X_EXPORT void DRI2CloseScreen(ScreenPtr pScreen);
extern _X_EXPORT Bool DRI2HasSwapControl(ScreenPtr pScreen);
-extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen,
+extern _X_EXPORT Bool DRI2Connect(ClientPtr client, ScreenPtr pScreen,
unsigned int driverType,
int *fd,
const char **driverName,
const char **deviceName);
-extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, uint32_t magic);
+extern _X_EXPORT Bool DRI2Authenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic);
extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
DrawablePtr pDraw,
@@ -260,8 +274,6 @@ extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
DRI2InvalidateProcPtr invalidate,
void *priv);
-extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
-
extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw,
int *width,
int *height,
@@ -339,4 +351,5 @@ extern _X_EXPORT int DRI2GetParam(ClientPtr client,
BOOL *is_param_recognized,
CARD64 *value);
+extern _X_EXPORT DrawablePtr DRI2UpdatePrime(DrawablePtr pDraw, DRI2BufferPtr pDest);
#endif
diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c
index c6f5b4e11..eb6fd44fc 100644
--- a/xorg-server/hw/xfree86/dri2/dri2ext.c
+++ b/xorg-server/hw/xfree86/dri2/dri2ext.c
@@ -44,13 +44,15 @@
#include "extnsionst.h"
#include "xfixes.h"
#include "dri2.h"
+#include "dri2int.h"
#include "protocol-versions.h"
-/* The only xf86 include */
+/* The only xf86 includes */
#include "xf86Module.h"
+#include "xf86Extensions.h"
+
+static int DRI2EventBase;
-static ExtensionEntry *dri2Extension;
-extern Bool DRI2ModuleSetup(void);
static Bool
validDrawable(ClientPtr client, XID drawable, Mask access_mode,
@@ -71,17 +73,18 @@ static int
ProcDRI2QueryVersion(ClientPtr client)
{
REQUEST(xDRI2QueryVersionReq);
- xDRI2QueryVersionReply rep;
+ xDRI2QueryVersionReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .majorVersion = dri2_major,
+ .minorVersion = dri2_minor
+ };
if (client->swapped)
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDRI2QueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = dri2_major;
- rep.minorVersion = dri2_minor;
if (client->swapped) {
swaps(&rep.sequenceNumber);
@@ -99,7 +102,13 @@ static int
ProcDRI2Connect(ClientPtr client)
{
REQUEST(xDRI2ConnectReq);
- xDRI2ConnectReply rep;
+ xDRI2ConnectReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .driverNameLength = 0,
+ .deviceNameLength = 0
+ };
DrawablePtr pDraw;
int fd, status;
const char *driverName;
@@ -110,13 +119,7 @@ ProcDRI2Connect(ClientPtr client)
&pDraw, &status))
return status;
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.driverNameLength = 0;
- rep.deviceNameLength = 0;
-
- if (!DRI2Connect(pDraw->pScreen,
+ if (!DRI2Connect(client, pDraw->pScreen,
stuff->driverType, &fd, &driverName, &deviceName))
goto fail;
@@ -146,10 +149,12 @@ ProcDRI2Authenticate(ClientPtr client)
&pDraw, &status))
return status;
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic);
+ rep = (xDRI2AuthenticateReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .authenticated = DRI2Authenticate(client, pDraw->pScreen, stuff->magic)
+ };
WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
return Success;
@@ -158,11 +163,11 @@ ProcDRI2Authenticate(ClientPtr client)
static void
DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv, XID id)
{
- xDRI2InvalidateBuffers event;
ClientPtr client = priv;
-
- event.type = DRI2EventBase + DRI2_InvalidateBuffers;
- event.drawable = id;
+ xDRI2InvalidateBuffers event = {
+ .type = DRI2EventBase + DRI2_InvalidateBuffers,
+ .drawable = id
+ };
WriteEventsToClient(client, 1, (xEvent *) &event);
}
@@ -225,12 +230,14 @@ send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
}
}
- 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;
+ rep = (xDRI2GetBuffersReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = (count - skip) * sizeof(xDRI2Buffer) / 4,
+ .width = width,
+ .height = height,
+ .count = count - skip
+ };
WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);
for (i = 0; i < count; i++) {
@@ -330,9 +337,11 @@ ProcDRI2CopyRegion(ClientPtr client)
* that yet.
*/
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
+ rep = (xDRI2CopyRegionReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0
+ };
WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep);
@@ -356,17 +365,17 @@ static void
DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc,
CARD32 sbc)
{
- xDRI2BufferSwapComplete2 event;
DrawablePtr pDrawable = data;
-
- event.type = DRI2EventBase + DRI2_BufferSwapComplete;
- event.event_type = type;
- event.drawable = pDrawable->id;
- event.ust_hi = (CARD64) ust >> 32;
- event.ust_lo = ust & 0xffffffff;
- event.msc_hi = (CARD64) msc >> 32;
- event.msc_lo = msc & 0xffffffff;
- event.sbc = sbc;
+ xDRI2BufferSwapComplete2 event = {
+ .type = DRI2EventBase + DRI2_BufferSwapComplete,
+ .event_type = type,
+ .drawable = pDrawable->id,
+ .ust_hi = (CARD64) ust >> 32,
+ .ust_lo = ust & 0xffffffff,
+ .msc_hi = (CARD64) msc >> 32,
+ .msc_lo = msc & 0xffffffff,
+ .sbc = sbc
+ };
WriteEventsToClient(client, 1, (xEvent *) &event);
}
@@ -375,7 +384,11 @@ static int
ProcDRI2SwapBuffers(ClientPtr client)
{
REQUEST(xDRI2SwapBuffersReq);
- xDRI2SwapBuffersReply rep;
+ xDRI2SwapBuffersReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0
+ };
DrawablePtr pDrawable;
CARD64 target_msc, divisor, remainder, swap_target;
int status;
@@ -402,9 +415,6 @@ ProcDRI2SwapBuffers(ClientPtr client)
if (status != Success)
return BadDrawable;
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
load_swap_reply(&rep, swap_target);
WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep);
@@ -427,7 +437,11 @@ static int
ProcDRI2GetMSC(ClientPtr client)
{
REQUEST(xDRI2GetMSCReq);
- xDRI2MSCReply rep;
+ xDRI2MSCReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0
+ };
DrawablePtr pDrawable;
CARD64 ust, msc, sbc;
int status;
@@ -442,9 +456,6 @@ ProcDRI2GetMSC(ClientPtr client)
if (status != Success)
return status;
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
load_msc_reply(&rep, ust, msc, sbc);
WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
@@ -482,11 +493,12 @@ ProcDRI2WaitMSC(ClientPtr client)
int
ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, CARD64 msc, CARD64 sbc)
{
- xDRI2MSCReply rep;
+ xDRI2MSCReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0
+ };
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
load_msc_reply(&rep, ust, msc, sbc);
WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
@@ -614,7 +626,13 @@ static int
SProcDRI2Connect(ClientPtr client)
{
REQUEST(xDRI2ConnectReq);
- xDRI2ConnectReply rep;
+ xDRI2ConnectReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .driverNameLength = 0,
+ .deviceNameLength = 0
+ };
/* If the client is swapped, it's not local. Talk to the hand. */
@@ -622,12 +640,7 @@ SProcDRI2Connect(ClientPtr client)
if (sizeof(*stuff) / 4 != client->req_len)
return BadLength;
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
swaps(&rep.sequenceNumber);
- rep.length = 0;
- rep.driverNameLength = 0;
- rep.deviceNameLength = 0;
WriteToClient(client, sizeof(xDRI2ConnectReply), &rep);
@@ -653,11 +666,11 @@ SProcDRI2Dispatch(ClientPtr client)
}
}
-int DRI2EventBase;
-
-static void
+void
DRI2ExtensionInit(void)
{
+ ExtensionEntry *dri2Extension;
+
dri2Extension = AddExtension(DRI2_NAME,
DRI2NumberEvents,
DRI2NumberErrors,
@@ -668,13 +681,3 @@ DRI2ExtensionInit(void)
DRI2ModuleSetup();
}
-
-extern Bool noDRI2Extension;
-
-_X_HIDDEN ExtensionModule dri2ExtensionModule = {
- DRI2ExtensionInit,
- DRI2_NAME,
- &noDRI2Extension,
- NULL,
- NULL
-};
diff --git a/xorg-server/hw/xfree86/dri2/dri2int.h b/xorg-server/hw/xfree86/dri2/dri2int.h
new file mode 100644
index 000000000..7f53eba45
--- /dev/null
+++ b/xorg-server/hw/xfree86/dri2/dri2int.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright © 2011 Daniel Stone
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+extern Bool DRI2ModuleSetup(void);