summaryrefslogtreecommitdiff
path: root/src/armsoc_dri2.c
diff options
context:
space:
mode:
authorSunny <sunny.sun@arm.com>2014-12-09 17:21:49 +0800
committerGerrit Code Review <gerrit@mpd-gerrit.cambridge.arm.com>2015-01-16 07:14:08 +0000
commit08e6cc7773f67c3f5769c0d1687dba851ee5ad23 (patch)
treefc054189728e6ebe968a19558ae042805c3122a9 /src/armsoc_dri2.c
parentfc7ccfeedeebe278a916545ac3feb87de03df367 (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-xsrc/armsoc_dri2.c69
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);
}