diff options
author | Sunny <sunny.sun@arm.com> | 2014-12-09 17:21:49 +0800 |
---|---|---|
committer | Gerrit Code Review <gerrit@mpd-gerrit.cambridge.arm.com> | 2015-01-16 07:14:08 +0000 |
commit | 08e6cc7773f67c3f5769c0d1687dba851ee5ad23 (patch) | |
tree | fc054189728e6ebe968a19558ae042805c3122a9 /src/armsoc_dri2.c | |
parent | fc7ccfeedeebe278a916545ac3feb87de03df367 (diff) |
add DRI2WaitMSC support
set "vblank_query_supported" dynamically.
add vblank handler function to handle vblank interrupt, and then
calls DRI2WaitMSCComplete to wake up client process
Change-Id: Iecb262287cdae33e29a518d1fcd3ce7089aa60d1
Diffstat (limited to 'src/armsoc_dri2.c')
-rwxr-xr-x | src/armsoc_dri2.c | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/src/armsoc_dri2.c b/src/armsoc_dri2.c index 437cdf0..a5658cd 100755 --- a/src/armsoc_dri2.c +++ b/src/armsoc_dri2.c @@ -498,6 +498,12 @@ static const char * const swap_names[] = { [DRI2_FLIP_COMPLETE] = "flip," }; +struct ARMSOCDRIVBlankCmd { + int type; + ClientPtr client; + DrawablePtr pDraw; +}; + static Bool allocNextBuffer(DrawablePtr pDraw, PixmapPtr *ppPixmap, uint32_t *name) { ScreenPtr pScreen = pDraw->pScreen; @@ -945,6 +951,13 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw, return TRUE; } +void ARMSOCDRI2VBlankHandler(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + struct ARMSOCDRIVBlankCmd *cmd = (struct ARMSOCDRIVBlankCmd *)user_data; + DRI2WaitMSCComplete(cmd->client, cmd->pDraw, sequence, tv_sec, tv_usec); + free(cmd); +} + /** * Request a DRM event when the requested conditions will be satisfied. * @@ -957,9 +970,49 @@ ARMSOCDRI2ScheduleWaitMSC(ClientPtr client, DrawablePtr pDraw, { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); + struct ARMSOCDRIVBlankCmd *cmd = NULL; + drmVBlank vbl = { .request = { + .type = DRM_VBLANK_RELATIVE, + .sequence = 0, + } }; + int ret; + CARD64 current_msc; - ERROR_MSG("not implemented"); - return FALSE; + if (!pARMSOC->drmmode_interface->vblank_query_supported) + return FALSE; + + ret = drmWaitVBlank(pARMSOC->drmFD, &vbl); + if (ret) { + ERROR_MSG("get vblank counter failed: %s", strerror(errno)); + return FALSE; + } + current_msc = vbl.reply.sequence; + + if (current_msc >= target_msc) { + DRI2WaitMSCComplete(client, pDraw, current_msc, 0, 0); + return TRUE; + } + + cmd = calloc(1, sizeof(*cmd)); + if (!cmd) + return FALSE; + + cmd->type = 0; + cmd->client = client; + cmd->pDraw = pDraw; + + vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; + vbl.request.sequence = target_msc; + vbl.request.signal = (unsigned long)cmd; + ret = drmWaitVBlank(pARMSOC->drmFD, &vbl); + if (ret) { + ERROR_MSG("get vblank counter failed: %s", strerror(errno)); + return FALSE; + } + DRI2BlockClient(client, pDraw); + + return TRUE; } #if DRI2INFOREC_VERSION >= 6 /** @@ -1018,6 +1071,12 @@ ARMSOCDRI2ScreenInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); + drmVBlank vbl = { .request = { + .type = DRM_VBLANK_RELATIVE, + .sequence = 0, + } }; + int ret; + DRI2InfoRec info = { #if DRI2INFOREC_VERSION >= 6 .version = 6, @@ -1080,6 +1139,12 @@ ARMSOCDRI2ScreenInit(ScreenPtr pScreen) INFO_MSG("Setting swap chain size: %d ", pARMSOC->swap_chain_size); + ret = drmWaitVBlank(pARMSOC->drmFD, &vbl); + if (ret) + pARMSOC->drmmode_interface->vblank_query_supported = 0; + else + pARMSOC->drmmode_interface->vblank_query_supported = 1; + return DRI2ScreenInit(pScreen, &info); } |