From c38dead3ea7e177728d90cd815cf4eead0c9f534 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 15 May 2010 16:28:11 +0000 Subject: xserver git update 15/5/2010 --- xorg-server/hw/xfree86/dri2/dri2.c | 165 +++++++++++++++++++++++++++++-------- 1 file changed, 129 insertions(+), 36 deletions(-) (limited to 'xorg-server/hw/xfree86/dri2/dri2.c') 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, ®ion, &box, 0); + DRI2CopyRegion(pDraw, ®ion, 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); } -- cgit v1.2.3