hwc: poll for vsync event
poll on the vsync file descriptor. This prepares the ground for
multiple vsync updates without adding additional threads.
Change-Id: I30ef0fb34816d438501475cd3e4967775fcb1d19
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index c0a33c1..2f4475e 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -25,6 +25,7 @@
#include <linux/msm_mdp.h>
#include <sys/resource.h>
#include <sys/prctl.h>
+#include <poll.h>
#include "hwc_utils.h"
#include "string.h"
#include "external.h"
@@ -61,10 +62,11 @@
const int MAX_DATA = 64;
static char vdata[MAX_DATA];
+ struct pollfd pfd;
uint64_t cur_timestamp=0;
ssize_t len = -1;
- int fd_timestamp = -1;
+ int fb0_fd = -1;
int ret = 0;
bool fb1_vsync = false;
bool logvsync = false;
@@ -83,8 +85,11 @@
/* Currently read vsync timestamp from drivers
e.g. VSYNC=41800875994
*/
- fd_timestamp = open(vsync_timestamp_fb0, O_RDONLY);
- if (fd_timestamp < 0) {
+ fb0_fd = open(vsync_timestamp_fb0, O_RDONLY);
+ pfd.fd = fb0_fd;
+ pfd.events = POLLPRI | POLLERR;
+
+ if (fb0_fd < 0) {
// Make sure fb device is opened before starting this thread so this
// never happens.
ALOGE ("FATAL:%s:not able to open file:%s, %s", __FUNCTION__,
@@ -95,24 +100,30 @@
do {
if (LIKELY(!ctx->vstate.fakevsync)) {
- len = pread(fd_timestamp, vdata, MAX_DATA, 0);
- if (len < 0) {
- // If the read was just interrupted - it is not a fatal error
- // In either case, just continue.
- if (errno != EAGAIN &&
- errno != EINTR &&
- errno != EBUSY) {
- ALOGE ("FATAL:%s:not able to read file:%s, %s",
- __FUNCTION__,
- vsync_timestamp_fb0, strerror(errno));
+ int err = poll(&pfd, 1, -1);
+ if(err > 0) {
+ if (pfd.revents & POLLPRI) {
+ len = pread(fb0_fd, vdata, MAX_DATA, 0);
+ if (UNLIKELY(len < 0)) {
+ // If the read was just interrupted - it is not a fatal
+ // error. Just continue in this case
+ ALOGE ("FATAL:%s:not able to read file:%s, %s",
+ __FUNCTION__,
+ vsync_timestamp_fb0, strerror(errno));
+ continue;
+ }
+ // extract timestamp
+ const char *str = vdata;
+ if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) {
+ cur_timestamp = strtoull(str + strlen("VSYNC="),
+ NULL, 0);
+ }
}
+ } else {
+ ALOGE("%s: vsync poll failed errno: %s", __FUNCTION__,
+ strerror(errno));
continue;
}
- // extract timestamp
- const char *str = vdata;
- if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) {
- cur_timestamp = strtoull(str + strlen("VSYNC="), NULL, 0);
- }
} else {
usleep(16666);
cur_timestamp = systemTime();
@@ -125,8 +136,8 @@
}
} while (true);
- if(fd_timestamp >= 0)
- close (fd_timestamp);
+ if(fb0_fd >= 0)
+ close (fb0_fd);
return NULL;
}