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/dri2.c165
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.h9
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2ext.c64
3 files changed, 178 insertions, 60 deletions
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index abcb96668..64be079ca 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -96,6 +96,8 @@ typedef struct _DRI2Screen {
DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
HandleExposuresProcPtr HandleExposures;
+
+ ConfigNotifyProcPtr ConfigNotify;
} DRI2ScreenRec;
static DRI2ScreenPtr
@@ -128,7 +130,7 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
WindowPtr pWin;
PixmapPtr pPixmap;
- pPriv = xalloc(sizeof *pPriv);
+ pPriv = malloc(sizeof *pPriv);
if (pPriv == NULL)
return NULL;
@@ -165,9 +167,11 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
}
typedef struct DRI2DrawableRefRec {
- XID id;
- XID dri2_id;
- struct list link;
+ XID id;
+ XID dri2_id;
+ DRI2InvalidateProcPtr invalidate;
+ void *priv;
+ struct list link;
} DRI2DrawableRefRec, *DRI2DrawableRefPtr;
static DRI2DrawableRefPtr
@@ -184,7 +188,8 @@ DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id)
}
static int
-DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id)
+DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id,
+ DRI2InvalidateProcPtr invalidate, void *priv)
{
DRI2DrawableRefPtr ref;
@@ -200,13 +205,16 @@ DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id)
ref->id = id;
ref->dri2_id = dri2_id;
+ ref->invalidate = invalidate;
+ ref->priv = priv;
list_add(&ref->link, &pPriv->reference_list);
return Success;
}
int
-DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id)
+DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
+ DRI2InvalidateProcPtr invalidate, void *priv)
{
DRI2DrawablePtr pPriv;
XID dri2_id;
@@ -219,7 +227,7 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id)
return BadAlloc;
dri2_id = FakeClientID(client->index);
- rc = DRI2AddDrawableRef(pPriv, id, dri2_id);
+ rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv);
if (rc != Success)
return rc;
@@ -270,10 +278,10 @@ static int DRI2DrawableGone(pointer p, XID id)
for (i = 0; i < pPriv->bufferCount; i++)
(*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
- xfree(pPriv->buffers);
+ free(pPriv->buffers);
}
- xfree(pPriv);
+ free(pPriv);
return Success;
}
@@ -318,6 +326,31 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
}
}
+static void
+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]);
+ }
+ }
+
+ free(pPriv->buffers);
+ }
+
+ pPriv->buffers = buffers;
+ pPriv->bufferCount = *out_count;
+ pPriv->width = pDraw->width;
+ pPriv->height = pDraw->height;
+ *width = pPriv->width;
+ *height = pPriv->height;
+}
+
static DRI2BufferPtr *
do_get_buffers(DrawablePtr pDraw, int *width, int *height,
unsigned int *attachments, int count, int *out_count,
@@ -344,7 +377,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
dimensions_match = (pDraw->width == pPriv->width)
&& (pDraw->height == pPriv->height);
- buffers = xalloc((count + 1) * sizeof(buffers[0]));
+ buffers = malloc((count + 1) * sizeof(buffers[0]));
for (i = 0; i < count; i++) {
const unsigned attachment = *(attachments++);
@@ -355,6 +388,9 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
&buffers[i]))
buffers_changed = 1;
+ if (buffers[i] == NULL)
+ goto err_out;
+
/* 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
@@ -387,6 +423,9 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
front_format, dimensions_match,
&buffers[i++]))
buffers_changed = 1;
+
+ if (buffers[i] == NULL)
+ goto err_out;
}
if (need_fake_front > 0) {
@@ -395,29 +434,15 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
&buffers[i++]))
buffers_changed = 1;
+ if (buffers[i] == NULL)
+ goto err_out;
+
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);
- }
-
- pPriv->buffers = buffers;
- pPriv->bufferCount = *out_count;
- pPriv->width = pDraw->width;
- pPriv->height = pDraw->height;
- *width = pPriv->width;
- *height = pPriv->height;
-
+ update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, 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
@@ -438,6 +463,22 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
}
return pPriv->buffers;
+
+err_out:
+
+ *out_count = 0;
+
+ for (i = 0; i < count; i++) {
+ if (buffers[i] != NULL)
+ (*ds->DestroyBuffer)(pDraw, buffers[i]);
+ }
+
+ free(buffers);
+ buffers = NULL;
+
+ update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
+
+ return buffers;
}
DRI2BufferPtr *
@@ -456,6 +497,19 @@ DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
out_count, TRUE);
}
+static void
+DRI2InvalidateDrawable(DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ DRI2DrawableRefPtr ref;
+
+ if (!pPriv)
+ return;
+
+ list_for_each_entry(ref, &pPriv->reference_list, link)
+ ref->invalidate(pDraw, ref->priv);
+}
+
/*
* In the direct rendered case, we throttle the clients that have more
* than their share of outstanding swaps (and thus busy buffers) when a
@@ -634,6 +688,8 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
ScreenPtr pScreen = pDraw->pScreen;
DRI2DrawablePtr pPriv;
CARD64 ust = 0;
+ BoxRec box;
+ RegionRec region;
pPriv = DRI2GetDrawable(pDraw);
if (pPriv == NULL) {
@@ -645,6 +701,14 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
pPriv->swapsPending--;
pPriv->swap_count++;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDraw->width;
+ box.y2 = pDraw->height;
+ REGION_INIT(pScreen, &region, &box, 0);
+ DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
+ DRI2BufferFrontLeft);
+
ust = ((CARD64)tv_sec * 1000000) + tv_usec;
if (swap_complete)
swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
@@ -756,6 +820,8 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
*/
*swap_target = pPriv->swap_count + pPriv->swapsPending;
+ DRI2InvalidateDrawable(pDraw);
+
return Success;
}
@@ -906,6 +972,30 @@ DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic)
return TRUE;
}
+static void
+DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
+ WindowPtr pSib)
+{
+ DrawablePtr pDraw = (DrawablePtr)pWin;
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+ DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
+
+ if (ds->ConfigNotify) {
+ pScreen->ConfigNotify = ds->ConfigNotify;
+
+ (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
+
+ ds->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = DRI2ConfigNotify;
+ }
+
+ if (!dd || (dd->width == w && dd->height == h))
+ return;
+
+ DRI2InvalidateDrawable(pDraw);
+}
+
Bool
DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
{
@@ -926,7 +1016,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
return FALSE;
}
- ds = xcalloc(1, sizeof *ds);
+ ds = calloc(1, sizeof *ds);
if (!ds)
return FALSE;
@@ -943,7 +1033,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
ds->ScheduleSwap = info->ScheduleSwap;
ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
ds->GetMSC = info->GetMSC;
- cur_minor = 2;
+ cur_minor = 3;
} else {
cur_minor = 1;
}
@@ -955,17 +1045,17 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
if (info->version == 3 || info->numDrivers == 0) {
/* Driver too old: use the old-style driverName field */
ds->numDrivers = 1;
- ds->driverNames = xalloc(sizeof(*ds->driverNames));
+ ds->driverNames = malloc(sizeof(*ds->driverNames));
if (!ds->driverNames) {
- xfree(ds);
+ free(ds);
return FALSE;
}
ds->driverNames[0] = info->driverName;
} else {
ds->numDrivers = info->numDrivers;
- ds->driverNames = xalloc(info->numDrivers * sizeof(*ds->driverNames));
+ ds->driverNames = malloc(info->numDrivers * sizeof(*ds->driverNames));
if (!ds->driverNames) {
- xfree(ds);
+ free(ds);
return FALSE;
}
memcpy(ds->driverNames, info->driverNames,
@@ -974,6 +1064,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
+ ds->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = DRI2ConfigNotify;
+
xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
for (i = 0; i < sizeof(driverTypeNames) / sizeof(driverTypeNames[0]); i++) {
if (i < ds->numDrivers && ds->driverNames[i]) {
@@ -990,8 +1083,8 @@ DRI2CloseScreen(ScreenPtr pScreen)
{
DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
- xfree(ds->driverNames);
- xfree(ds);
+ free(ds->driverNames);
+ free(ds);
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
}
diff --git a/xorg-server/hw/xfree86/dri2/dri2.h b/xorg-server/hw/xfree86/dri2/dri2.h
index cc15f120d..c43aa6a04 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.h
+++ b/xorg-server/hw/xfree86/dri2/dri2.h
@@ -152,6 +152,10 @@ typedef int (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client,
CARD64 target_msc,
CARD64 divisor,
CARD64 remainder);
+
+typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw,
+ void *data);
+
/**
* Version of the DRI2InfoRec structure defined in this header
*/
@@ -199,7 +203,10 @@ extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen,
extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic);
extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
- DrawablePtr pDraw, XID id);
+ DrawablePtr pDraw,
+ XID id,
+ DRI2InvalidateProcPtr invalidate,
+ void *priv);
extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c
index 8bed02055..38efc86e0 100644
--- a/xorg-server/hw/xfree86/dri2/dri2ext.c
+++ b/xorg-server/hw/xfree86/dri2/dri2ext.c
@@ -91,7 +91,7 @@ ProcDRI2QueryVersion(ClientPtr client)
WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep);
- return client->noClientException;
+ return Success;
}
static int
@@ -129,7 +129,7 @@ ProcDRI2Connect(ClientPtr client)
WriteToClient(client, rep.driverNameLength, driverName);
WriteToClient(client, rep.deviceNameLength, deviceName);
- return client->noClientException;
+ return Success;
}
static int
@@ -151,7 +151,23 @@ ProcDRI2Authenticate(ClientPtr client)
rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic);
WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
- return client->noClientException;
+ return Success;
+}
+
+static void
+DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv)
+{
+ xDRI2InvalidateBuffers event;
+ ClientPtr client = priv;
+
+ if (client->clientGone)
+ return;
+
+ event.type = DRI2EventBase + DRI2_InvalidateBuffers;
+ event.sequenceNumber = client->sequence;
+ event.drawable = pDraw->id;
+
+ WriteEventsToClient(client, 1, (xEvent *)&event);
}
static int
@@ -167,11 +183,12 @@ ProcDRI2CreateDrawable(ClientPtr client)
&pDrawable, &status))
return status;
- status = DRI2CreateDrawable(client, pDrawable, stuff->drawable);
+ status = DRI2CreateDrawable(client, pDrawable, stuff->drawable,
+ DRI2InvalidateBuffersEvent, client);
if (status != Success)
return status;
- return client->noClientException;
+ return Success;
}
static int
@@ -186,11 +203,11 @@ ProcDRI2DestroyDrawable(ClientPtr client)
&pDrawable, &status))
return status;
- return client->noClientException;
+ return Success;
}
-static void
+static int
send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
DRI2BufferPtr *buffers, int count, int width, int height)
{
@@ -198,6 +215,9 @@ send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
int skip = 0;
int i;
+ if (buffers == NULL)
+ return BadAlloc;
+
if (pDrawable->type == DRAWABLE_WINDOW) {
for (i = 0; i < count; i++) {
/* Do not send the real front buffer of a window to the client.
@@ -234,6 +254,7 @@ send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
buffer.flags = buffers[i]->flags;
WriteToClient(client, sizeof(xDRI2Buffer), &buffer);
}
+ return Success;
}
@@ -252,16 +273,15 @@ ProcDRI2GetBuffers(ClientPtr client)
return status;
if (DRI2ThrottleClient(client, pDrawable))
- return client->noClientException;
+ return Success;
attachments = (unsigned int *) &stuff[1];
buffers = DRI2GetBuffers(pDrawable, &width, &height,
attachments, stuff->count, &count);
- send_buffers_reply(client, pDrawable, buffers, count, width, height);
+ return send_buffers_reply(client, pDrawable, buffers, count, width, height);
- return client->noClientException;
}
static int
@@ -279,15 +299,13 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client)
return status;
if (DRI2ThrottleClient(client, pDrawable))
- return client->noClientException;
+ return Success;
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;
+ return send_buffers_reply(client, pDrawable, buffers, count, width, height);
}
static int
@@ -324,7 +342,7 @@ ProcDRI2CopyRegion(ClientPtr client)
WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep);
- return client->noClientException;
+ return Success;
}
static void
@@ -381,7 +399,7 @@ ProcDRI2SwapBuffers(ClientPtr client)
* also orders swaps.
*/
if (DRI2ThrottleClient(client, pDrawable))
- return client->noClientException;
+ return Success;
target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
@@ -399,7 +417,7 @@ ProcDRI2SwapBuffers(ClientPtr client)
WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep);
- return client->noClientException;
+ return Success;
}
static void
@@ -439,7 +457,7 @@ ProcDRI2GetMSC(ClientPtr client)
WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
- return client->noClientException;
+ return Success;
}
static int
@@ -466,7 +484,7 @@ ProcDRI2WaitMSC(ClientPtr client)
if (status != Success)
return status;
- return client->noClientException;
+ return Success;
}
int
@@ -481,7 +499,7 @@ ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, CARD64 msc, CARD64 sbc)
WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
- return client->noClientException;
+ return Success;
}
static int
@@ -501,7 +519,7 @@ ProcDRI2SwapInterval(ClientPtr client)
DRI2SwapInterval(pDrawable, stuff->interval);
- return client->noClientException;
+ return Success;
}
static int
@@ -531,7 +549,7 @@ ProcDRI2WaitSBC(ClientPtr client)
WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
- return client->noClientException;
+ return Success;
}
static int
@@ -596,7 +614,7 @@ SProcDRI2Connect(ClientPtr client)
rep.driverNameLength = 0;
rep.deviceNameLength = 0;
- return client->noClientException;
+ return Success;
}
static int