summaryrefslogtreecommitdiff
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
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
-rwxr-xr-xsrc/armsoc_dri2.c69
-rw-r--r--src/armsoc_driver.h1
-rw-r--r--src/drmmode_display.c8
3 files changed, 76 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);
}
diff --git a/src/armsoc_driver.h b/src/armsoc_driver.h
index 947b2e4..09af18d 100644
--- a/src/armsoc_driver.h
+++ b/src/armsoc_driver.h
@@ -224,6 +224,7 @@ Bool ARMSOCDRI2ScreenInit(ScreenPtr pScreen);
void ARMSOCDRI2CloseScreen(ScreenPtr pScreen);
void ARMSOCDRI2SwapComplete(struct ARMSOCDRISwapCmd *cmd);
void ARMSOCDRI2ResizeSwapChain(ScrnInfoPtr pScrn, struct armsoc_bo *old_bo, struct armsoc_bo *resized_bo);
+void ARMSOCDRI2VBlankHandler(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data);
/**
* DRI2 util functions..
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 771af0f..80cf562 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1735,9 +1735,17 @@ page_flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
ARMSOCDRI2SwapComplete(user_data);
}
+static void
+vblank_handler(int fd, unsigned int sequence, unsigned int tv_sec,
+ unsigned int tv_usec, void *user_data)
+{
+ ARMSOCDRI2VBlankHandler(sequence, tv_sec, tv_usec, user_data);
+}
+
static drmEventContext event_context = {
.version = DRM_EVENT_CONTEXT_VERSION,
.page_flip_handler = page_flip_handler,
+ .vblank_handler = vblank_handler,
};
int