mirror of
https://github.com/team-infusion-developers/android_hardware_samsung.git
synced 2024-11-01 07:47:55 +00:00
exynos3: Implement custom VSYNC IOCTL
* Replace crespo-based VSYNC uevent mechanism in hwcomposer with a custom IOCTL mechanism instead (required kernel modifications. * The VSYNC uevents were spamming the Android UEventObserver and causing about 7% of constant CPU load c86856efabfa0b2981ceb47898dc5873a4998707 Improve custom VSYNC handler in hwcomposer * only poll when necessary * solves suspend/resume instability? 45bf1dae7fa9057a3415151f7559e7bd2a162ead Change-Id: Icdb5c60059e71688479d390b7b3a1f09a0315a5f
This commit is contained in:
parent
317dcfa0f0
commit
3c938a7e18
3 changed files with 57 additions and 0 deletions
|
@ -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)
|
||||
|
|
|
@ -27,6 +27,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)
|
||||
|
|
|
@ -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, ×tamp);
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue