From aa57e29080a11afd2c9feb49e9f57e1a481e1496 Mon Sep 17 00:00:00 2001 From: Alban Browaeys Date: Fri, 27 Aug 2010 02:52:44 +0200 Subject: [PATCH] radeon: event + dri2 upgrade version of the vblank fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This verison of the fix for the vblank when client gone is a partial option 3 as defined in : http://lists.x.org/archives/xorg-driver-ati/2010-August/016780.html by Oldřich Jedlička and Christopher James Halse Rogers. It relies on another patches for xserver dri2 implementation. --- src/radeon_dri2.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 45 insertions(+), 1 deletions(-) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index a0ed085..d64a477 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -345,9 +345,22 @@ typedef struct _DRI2FrameEvent { DRI2SwapEventPtr event_complete; void *event_data; DRI2BufferPtr front; - DRI2BufferPtr back; + + Bool valid; + + DRI2FrameEventBasePtr event_base; } DRI2FrameEventRec, *DRI2FrameEventPtr; + +static void +radeon_dri2_invalidate_event(DRI2FrameEventBasePtr event_base) +{ + DRI2FrameEventPtr ref; + ref = (DRI2FrameEventPtr) event_base->driverEvent; + ref->valid = FALSE; +} + + void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void *event_data) { @@ -394,6 +407,7 @@ void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, break; } + ListDelDRI2ClientEntry(event->client, &event->event_base->link); free(event); } @@ -468,6 +482,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, ScrnInfoPtr scrn = xf86Screens[screen->myNum]; RADEONInfoPtr info = RADEONPTR(scrn); DRI2FrameEventPtr wait_info; + DRI2FrameEventBasePtr event_base; drmVBlank vbl; int ret, crtc = radeon_dri2_drawable_crtc(draw); CARD64 current_msc; @@ -486,9 +501,23 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, if (!wait_info) goto out_complete; + event_base = calloc(1, sizeof(DRI2FrameEventBaseRec)); + if (!event_base) + goto out_complete; + wait_info->drawable_id = draw->id; wait_info->client = client; wait_info->type = DRI2_WAITMSC; + wait_info->valid = TRUE; + + event_base->driverEvent = wait_info; + wait_info->event_base = event_base; + + if (!ListAddDRI2ClientEntry(client, &event_base->link)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "add events to client private failed.\n"); + goto out_complete; + } /* Get current count */ vbl.request.type = DRM_VBLANK_RELATIVE; @@ -605,6 +634,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, drmVBlank vbl; int ret, crtc= radeon_dri2_drawable_crtc(draw), flip = 0; DRI2FrameEventPtr swap_info; + DRI2FrameEventBasePtr event_base; enum DRI2FrameEventType swap_type = DRI2_SWAP; CARD64 current_msc; BoxRec box; @@ -618,6 +648,8 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, swap_info = calloc(1, sizeof(DRI2FrameEventRec)); + event_base = calloc(1, sizeof(DRI2FrameEventBaseRec)); + /* Drawable not displayed... just complete the swap */ if (crtc == -1 || !swap_info) goto blit_fallback; @@ -628,6 +660,16 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, swap_info->event_data = data; swap_info->front = front; swap_info->back = back; + swap_info->valid = TRUE; + + event_base->driverEvent = swap_info; + swap_info->event_base = event_base; + + if (!ListAddDRI2ClientEntry(client, &event_base->link)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "add events to client private failed.\n"); + goto blit_fallback; + } /* Get current count */ vbl.request.type = DRM_VBLANK_RELATIVE; @@ -810,6 +852,8 @@ radeon_dri2_screen_init(ScreenPtr pScreen) } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for sync extension\n"); } + + InvalidateDRI2ClientEntry = radeon_dri2_invalidate_event; #endif info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info); -- 1.7.1