minui/drm: wait for page flip completion

If two consecutive call are made to drmModePageFlip, the second call
may fail with -EBUSY because the first flip is not completed yet.

This patch adds a wait for completion mechanism based on
drmHandleEvent.

Change-Id: Ied13ebefc7523003431b1b307bae70d1a70cb24b
Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
Signed-off-by: Benoit Fradin <benoit.fradin@intel.com>
This commit is contained in:
Jeremy Compostella 2018-06-07 10:51:33 -07:00 committed by Tao Bao
parent 95b8d2b064
commit 955da1e26d

View file

@ -17,6 +17,7 @@
#include "graphics_drm.h"
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
@ -378,13 +379,49 @@ GRSurface* MinuiBackendDrm::Init() {
return GRSurfaceDrms[0];
}
static void page_flip_complete(__unused int fd,
__unused unsigned int sequence,
__unused unsigned int tv_sec,
__unused unsigned int tv_usec,
void *user_data) {
*static_cast<bool*>(user_data) = false;
}
GRSurface* MinuiBackendDrm::Flip() {
bool ongoing_flip = true;
int ret = drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id,
GRSurfaceDrms[current_buffer]->fb_id, 0, nullptr);
GRSurfaceDrms[current_buffer]->fb_id,
DRM_MODE_PAGE_FLIP_EVENT, &ongoing_flip);
if (ret < 0) {
printf("drmModePageFlip failed ret=%d\n", ret);
return nullptr;
}
while (ongoing_flip) {
struct pollfd fds = {
.fd = drm_fd,
.events = POLLIN
};
ret = poll(&fds, 1, -1);
if (ret == -1 || !(fds.revents & POLLIN)) {
printf("poll() failed on drm fd\n");
break;
}
drmEventContext evctx = {
.version = DRM_EVENT_CONTEXT_VERSION,
.page_flip_handler = page_flip_complete
};
ret = drmHandleEvent(drm_fd, &evctx);
if (ret != 0) {
printf("drmHandleEvent failed ret=%d\n", ret);
break;
}
}
current_buffer = 1 - current_buffer;
return GRSurfaceDrms[current_buffer];
}