diff options
author | Ilija Hadzic <ilijahadzic@gmail.com> | 2013-05-08 22:39:41 -0400 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2013-05-29 15:15:39 +0200 |
commit | 80ae2291d082b57c70d27a80182f00d760fb3d3a (patch) | |
tree | 21a7457e7a8d34773a176db9ffb8520cf71da1ae | |
parent | 5fd2eb5d12cea32927a9e6c6ce4afd18aa7d046a (diff) |
DRI2: adjust MSC by the number of interpolated vblanks
Normally, MSC value equals the vblank count of the CRTC
on which the drawable resides. However, we are now interpolating
vblanks through DPMS-off state, so if the CRTC is turned
off at some point, the vlbank count does not change, but
MSC does change by the amount that equals the cumulative
number of interpolated vblanks.
So each time we interact with the CRTC's vblank facility,
we have to adjust the vblank counter: in the request, we
have to subtract the number of interpolated vblanks from
MSC and in the reply we have to add the number of interpolated
vblanks to the MSC.
This patch only makes the MSC correct when CRTC is on.
The subsequent patch will construct the MSC when CRTC is not
running.
Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | src/radeon_dri2.c | 17 | ||||
-rw-r--r-- | src/radeon_video.c | 6 | ||||
-rw-r--r-- | src/radeon_video.h | 1 |
3 files changed, 21 insertions, 3 deletions
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 10ea0f7e..cd2be2bd 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -905,7 +905,8 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) } *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec; - *msc = vbl.reply.sequence; + *msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc); + *msc &= 0xffffffff; return TRUE; } @@ -967,7 +968,8 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, goto out_complete; } - current_msc = vbl.reply.sequence; + current_msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc); + current_msc &= 0xffffffff; /* * If divisor is zero, or current_msc is smaller than target_msc, @@ -986,6 +988,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; vbl.request.type |= radeon_populate_vbl_request_type(crtc); vbl.request.sequence = target_msc; + vbl.request.sequence -= radeon_get_interpolated_vblanks(crtc); vbl.request.signal = (unsigned long)wait_info; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { @@ -995,6 +998,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, } wait_info->frame = vbl.reply.sequence; + wait_info->frame += radeon_get_interpolated_vblanks(crtc); DRI2BlockClient(client, draw); return TRUE; } @@ -1017,6 +1021,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, */ if ((current_msc % divisor) >= remainder) vbl.request.sequence += divisor; + vbl.request.sequence -= radeon_get_interpolated_vblanks(crtc); vbl.request.signal = (unsigned long)wait_info; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); @@ -1027,6 +1032,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, } wait_info->frame = vbl.reply.sequence; + wait_info->frame += radeon_get_interpolated_vblanks(crtc); DRI2BlockClient(client, draw); return TRUE; @@ -1202,7 +1208,8 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, return TRUE; } - current_msc = vbl.reply.sequence; + current_msc = vbl.reply.sequence + radeon_get_interpolated_vblanks(crtc); + current_msc &= 0xffffffff; /* Flips need to be submitted one frame before */ if (can_flip(scrn, draw, front, back)) { @@ -1242,6 +1249,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, *target_msc = current_msc; vbl.request.sequence = *target_msc; + vbl.request.sequence -= radeon_get_interpolated_vblanks(crtc); vbl.request.signal = (unsigned long)swap_info; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { @@ -1255,6 +1263,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, } *target_msc = vbl.reply.sequence + flip; + *target_msc += radeon_get_interpolated_vblanks(crtc); swap_info->frame = *target_msc; return TRUE; @@ -1286,6 +1295,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, */ if (vbl.request.sequence <= current_msc) vbl.request.sequence += divisor; + vbl.request.sequence -= radeon_get_interpolated_vblanks(crtc); /* Account for 1 frame extra pageflip delay if flip > 0 */ vbl.request.sequence -= flip; @@ -1304,6 +1314,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, /* Adjust returned value for 1 fame pageflip offset of flip > 0 */ *target_msc = vbl.reply.sequence + flip; + *target_msc += radeon_get_interpolated_vblanks(crtc); swap_info->frame = *target_msc; return TRUE; diff --git a/src/radeon_video.c b/src/radeon_video.c index c0505282..56cd9abd 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -73,6 +73,12 @@ Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc) return drmmode_crtc->dpms_mode == DPMSModeOn; } +uint32_t radeon_get_interpolated_vblanks(xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + return drmmode_crtc->interpolated_vblanks; +} + xf86CrtcPtr radeon_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled, int x1, int x2, int y1, int y2) diff --git a/src/radeon_video.h b/src/radeon_video.h index e6068e86..2a092954 100644 --- a/src/radeon_video.h +++ b/src/radeon_video.h @@ -101,5 +101,6 @@ RADEONCopyMungedData(ScrnInfoPtr pScrn, unsigned int dstPitch, unsigned int h, unsigned int w); Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc); +uint32_t radeon_get_interpolated_vblanks(xf86CrtcPtr crtc); #endif |