summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brehm <djp952@gmail.com>2012-09-18 00:40:03 -0400
committerJustin White <just6979@gmail.com>2012-09-18 02:23:05 -0400
commitd2075e6789979955c77b62bdc5ce8e2363e5602f (patch)
treec2fe7f8db2f295560bd3f3fd9b1a796a68b05c49
parent0085b6ef948679259a51d6818470dc1f9f772fec (diff)
downloaddevice_samsung_crespo-d2075e6789979955c77b62bdc5ce8e2363e5602f.zip
device_samsung_crespo-d2075e6789979955c77b62bdc5ce8e2363e5602f.tar.gz
device_samsung_crespo-d2075e6789979955c77b62bdc5ce8e2363e5602f.tar.bz2
Implement custom VSYNC IOCTL for crespo.
From http://review.cyanogenmod.com/#/c/23406/ Requires kernel patch http://review.cyanogenmod.com/#/c/23540/ Change-Id: I03b3e832b2973d0f7829e090639cc3d22bf45440
-rwxr-xr-xinclude/sec_lcd.h1
-rw-r--r--libhwcomposer/Android.mk4
-rw-r--r--libhwcomposer/SecHWC.cpp52
3 files changed, 57 insertions, 0 deletions
diff --git a/include/sec_lcd.h b/include/sec_lcd.h
index 6a3a34a..82ef42f 100755
--- a/include/sec_lcd.h
+++ b/include/sec_lcd.h
@@ -34,6 +34,7 @@ struct secfb_user_window {
#define FBIO_WAITFORVSYNC _IO ('F', 32)
#define SECFB_WIN_POSITION _IOW ('F', 203, struct secfb_user_window)
#define S3CFB_SET_VSYNC_INT _IOW ('F', 206, uint32_t)
+#define S3CFB_WAIT_FOR_VSYNC _IOR ('F', 311, uint64_t)
#define DEFAULT_LCD_WIDTH (480)
#define DEFAULT_LCD_HEIGHT (800)
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 72c7b59..7cc8228 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -29,6 +29,10 @@ LOCAL_C_INCLUDES := \
LOCAL_SRC_FILES := SecHWCUtils.cpp SecHWC.cpp
+ifeq ($(BOARD_CUSTOM_VSYNC_IOCTL),true)
+ LOCAL_CFLAGS += -DVSYNC_IOCTL
+endif
+
LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/SecHWC.cpp b/libhwcomposer/SecHWC.cpp
index dda1108..31d25f4 100644
--- a/libhwcomposer/SecHWC.cpp
+++ b/libhwcomposer/SecHWC.cpp
@@ -453,6 +453,17 @@ static int hwc_query(struct hwc_composer_device* dev,
return 0;
}
+#ifdef VSYNC_IOCTL
+// Linux version of a manual reset event to control when
+// and when not to ask the video card for a VSYNC. This
+// stops the worker thread from asking for a VSYNC when
+// there is nothing useful to do with it and more closely
+// mimicks the original uevent mechanism
+int vsync_enable = 0;
+pthread_mutex_t vsync_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t vsync_condition = PTHREAD_COND_INITIALIZER;
+#endif
+
static int hwc_eventControl(struct hwc_composer_device* dev,
int event, int enabled)
{
@@ -465,6 +476,18 @@ static int hwc_eventControl(struct hwc_composer_device* dev,
if (err < 0)
return -errno;
+#if VSYNC_IOCTL
+ // Enable or disable the ability for the worker thread
+ // to ask for VSYNC events from the video driver
+ pthread_mutex_lock(&vsync_mutex);
+ if(enabled) {
+ vsync_enable = 1;
+ pthread_cond_broadcast(&vsync_condition);
+ }
+ else vsync_enable = 0;
+ pthread_mutex_unlock(&vsync_mutex);
+#endif
+
return 0;
}
@@ -496,18 +519,47 @@ void handle_vsync_uevent(hwc_context_t *ctx, const char *buff, int len)
static void *hwc_vsync_thread(void *data)
{
hwc_context_t *ctx = (hwc_context_t *)(data);
+#ifdef VSYNC_IOCTL
+ uint64_t timestamp = 0;
+#else
char uevent_desc[4096];
memset(uevent_desc, 0, sizeof(uevent_desc));
+#endif
setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+#ifndef VSYNC_IOCTL
uevent_init();
+#endif
while(true) {
+#ifdef VSYNC_IOCTL
+ // Only continue if hwc_eventControl is enabled, otherwise
+ // just sit here and wait until it is. This stops the code
+ // from constantly looking for the VSYNC event with the screen
+ // turned off.
+ pthread_mutex_lock(&vsync_mutex);
+ if(!vsync_enable) pthread_cond_wait(&vsync_condition, &vsync_mutex);
+ pthread_mutex_unlock(&vsync_mutex);
+
+ timestamp = 0; // Reset the timestamp value
+
+ // S3CFB_WAIT_FOR_VSYNC is a custom IOCTL I added to wait for
+ // the VSYNC interrupt, and then return the timestamp that was
+ // originally being communicated via a uevent. The uevent was
+ // spamming the UEventObserver and events/0 process with more
+ // information than this device could really deal with every 18ms
+ int res = ioctl(ctx->global_lcd_win.fd, S3CFB_WAIT_FOR_VSYNC, &timestamp);
+ if(res > 0) {
+ if(!ctx->procs || !ctx->procs->vsync) continue;
+ ctx->procs->vsync(ctx->procs, 0, timestamp);
+ }
+#else
int len = uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2);
bool vsync = !strcmp(uevent_desc, "change@/devices/platform/s3cfb");
if(vsync)
handle_vsync_uevent(ctx, uevent_desc, len);
+#endif
}
return NULL;