summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIlija Hadzic <ilijahadzic@gmail.com>2013-05-08 22:39:45 -0400
committerMichel Dänzer <michel@daenzer.net>2013-05-29 15:27:28 +0200
commitf1584152bbeda98cc1907359f1c7954a84c8837d (patch)
tree7f3141e16c84c3e19373b87139903197a1b37184 /src
parent84bce7943b735aee19e26be4d47fdf140564f3f5 (diff)
DRI2: move rename and rework radeon_dri2_deferred_swap
radeon_dri2_deferred_swap will be used to generate real events (not just fallbacks) so now it needs to generate real timestamp and frame counter. Also this function will be used both by schedule_swap and wait_msc, so give it a more generic name: radeon_dri2_deferred_event v2: - Extrapolate the frame number from the time of actual execution of the function instead of using the MSC calculated (extrapolated) at event scheduling time. - CRTC-private now stores frame rate instead of nominal vblank period. Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'src')
-rw-r--r--src/radeon_dri2.c77
1 files changed, 65 insertions, 12 deletions
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 7d3b16ae..26201710 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -989,6 +989,67 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
return TRUE;
}
+static
+CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
+{
+ DRI2FrameEventPtr event_info = (DRI2FrameEventPtr)data;
+ DrawablePtr drawable;
+ ScreenPtr screen;
+ ScrnInfoPtr scrn;
+ RADEONInfoPtr info;
+ int status;
+ CARD64 drm_now;
+ int ret;
+ unsigned int tv_sec, tv_usec;
+ CARD64 delta_t, delta_seq, frame;
+ drmmode_crtc_private_ptr drmmode_crtc;
+ TimerFree(timer);
+
+ /*
+ * This is emulated event, so its time is current time, which we
+ * have to get in DRM-compatible form (which is a bit messy given
+ * the information that we have at this point). Can't use now argument
+ * because DRM event time may come from monotonic clock, while
+ * DIX timer facility uses real-time clock.
+ */
+ if (!event_info->crtc) {
+ ErrorF("%s no crtc\n", __func__);
+ radeon_dri2_frame_event_handler(0, 0, 0, data);
+ return 0;
+ }
+ status = dixLookupDrawable(&drawable, event_info->drawable_id, serverClient,
+ M_ANY, DixWriteAccess);
+ if (status != Success) {
+ ErrorF("%s cannot lookup drawable\n", __func__);
+ radeon_dri2_frame_event_handler(0, 0, 0, data);
+ return 0;
+ }
+ screen = drawable->pScreen;
+ scrn = xf86ScreenToScrn(screen);
+ info = RADEONPTR(scrn);
+ ret = drmmode_get_current_ust(info->dri2.drm_fd, &drm_now);
+ if (ret) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "%s cannot get current time\n", __func__);
+ radeon_dri2_frame_event_handler(0, 0, 0, data);
+ return 0;
+ }
+ tv_sec = (unsigned int)(drm_now / 1000000);
+ tv_usec = (unsigned int)(drm_now - (CARD64)tv_sec * 1000000);
+ /*
+ * calculate the frame number from current time
+ * that would come from CRTC if it were running
+ */
+ drmmode_crtc = event_info->crtc->driver_private;
+ delta_t = drm_now - (CARD64)drmmode_crtc->dpms_last_ust;
+ delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
+ delta_seq /= 1000000;
+ frame = (CARD64)drmmode_crtc->dpms_last_seq + delta_seq;
+ frame &= 0xffffffff;
+ radeon_dri2_frame_event_handler((unsigned int)frame, tv_sec, tv_usec, data);
+ return 0;
+}
+
/*
* Request a DRM event when the requested conditions will be satisfied.
*
@@ -1178,14 +1239,6 @@ void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
free(flip);
}
-static
-CARD32 radeon_dri2_deferred_swap(OsTimerPtr timer, CARD32 now, pointer data)
-{
- TimerFree(timer);
- radeon_dri2_frame_event_handler(0, 0, 0, data);
- return 0;
-}
-
/*
* ScheduleSwap is responsible for requesting a DRM vblank event for the
* appropriate frame.
@@ -1271,7 +1324,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
delay = radeon_dri2_extrapolate_msc_delay(crtc, target_msc,
divisor, remainder);
swap_info->frame = *target_msc;
- TimerSet(NULL, 0, delay, radeon_dri2_deferred_swap, swap_info);
+ TimerSet(NULL, 0, delay, radeon_dri2_deferred_event, swap_info);
return TRUE;
}
@@ -1284,7 +1337,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"first get vblank counter failed: %s\n",
strerror(errno));
- TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+ TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_event,
swap_info);
*target_msc = 0;
return TRUE;
@@ -1338,7 +1391,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"divisor 0 get vblank counter failed: %s\n",
strerror(errno));
- TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+ TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_event,
swap_info);
*target_msc = 0;
return TRUE;
@@ -1388,7 +1441,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"final get vblank counter failed: %s\n",
strerror(errno));
- TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+ TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_event,
swap_info);
*target_msc = 0;
return TRUE;