diff options
author | Marissa Wall <marissaw@google.com> | 2016-09-01 14:42:02 -0700 |
---|---|---|
committer | Marissa Wall <marissaw@google.com> | 2017-03-02 12:35:06 -0800 |
commit | d0db535d69470750c321f789eb4857b19edefa83 (patch) | |
tree | 688416e388acce87afa4179d8dc50578ec05c02e | |
parent | 25789155cba5e0ec17c51276d3b02e7783eb6b05 (diff) | |
download | flounder-d0db535d69470750c321f789eb4857b19edefa83.tar.gz |
hwc2: enable vsync
Allow client to enable and disable vsync callbacks
Test: Add "TARGET_USES_HWC2 := true" to BoardConfig.mk.
Recompile.
Run testcases: https://android-review.googlesource.com/#/q/project:
platform/frameworks/native+branch:master+topic:test-hwc2
Change-Id: Ie694a7eec29b2b1aa7a4b0fc6316f5e6130b7f55
-rw-r--r-- | hwc2/hwc2.cpp | 7 | ||||
-rw-r--r-- | hwc2/hwc2.h | 9 | ||||
-rw-r--r-- | hwc2/hwc2_callback.cpp | 7 | ||||
-rw-r--r-- | hwc2/hwc2_dev.cpp | 56 | ||||
-rw-r--r-- | hwc2/hwc2_display.cpp | 12 |
5 files changed, 86 insertions, 5 deletions
diff --git a/hwc2/hwc2.cpp b/hwc2/hwc2.cpp index a70833a..285603b 100644 --- a/hwc2/hwc2.cpp +++ b/hwc2/hwc2.cpp @@ -229,10 +229,11 @@ hwc2_error_t set_power_mode(hwc2_device_t *device, hwc2_display_t display, return dev->set_power_mode(display, mode); } -hwc2_error_t set_vsync_enabled(hwc2_device_t* /*device*/, - hwc2_display_t /*display*/, hwc2_vsync_t /*enabled*/) +hwc2_error_t set_vsync_enabled(hwc2_device_t *device, hwc2_display_t display, + hwc2_vsync_t enabled) { - return HWC2_ERROR_NONE; + hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev; + return dev->set_vsync_enabled(display, static_cast<hwc2_vsync_t>(enabled)); } hwc2_error_t validate_display(hwc2_device_t* /*device*/, diff --git a/hwc2/hwc2.h b/hwc2/hwc2.h index 44e8a82..4acda2a 100644 --- a/hwc2/hwc2.h +++ b/hwc2/hwc2.h @@ -55,6 +55,7 @@ public: hwc2_function_pointer_t pointer); void call_hotplug(hwc2_display_t dpy_id, hwc2_connection_t connection); + void call_vsync(hwc2_display_t dpy_id, int64_t timestamp); private: std::mutex state_mutex; @@ -101,8 +102,10 @@ public: hwc2_display_t get_id() const { return id; } hwc2_display_type_t get_type() const { return type; } hwc2_connection_t get_connection() const { return connection; } + hwc2_vsync_t get_vsync_enabled() const { return vsync_enabled; } hwc2_error_t set_connection(hwc2_connection_t connection); + hwc2_error_t set_vsync_enabled(hwc2_vsync_t enabled); /* Power modes */ hwc2_error_t set_power_mode(hwc2_power_mode_t mode); @@ -139,6 +142,9 @@ private: /* The layers currently in use */ std::unordered_map<hwc2_layer_t, hwc2_layer> layers; + /* Is vsync enabled */ + hwc2_vsync_t vsync_enabled; + /* All the valid configurations for the display */ std::unordered_map<hwc2_config_t, hwc2_config> configs; @@ -188,6 +194,9 @@ public: /* Callback functions */ void hotplug(hwc2_display_t dpy_id, hwc2_connection_t connection); + void vsync(hwc2_display_t dpy_id, uint64_t timestamp); + + hwc2_error_t set_vsync_enabled(hwc2_display_t dpy_id, hwc2_vsync_t enabled); hwc2_error_t register_callback(hwc2_callback_descriptor_t descriptor, hwc2_callback_data_t callback_data, diff --git a/hwc2/hwc2_callback.cpp b/hwc2/hwc2_callback.cpp index 041bc86..84ad2a8 100644 --- a/hwc2/hwc2_callback.cpp +++ b/hwc2/hwc2_callback.cpp @@ -73,3 +73,10 @@ void hwc2_callback::call_hotplug(hwc2_display_t dpy_id, else hotplug_pending.push(std::make_pair(dpy_id, connection)); } + +void hwc2_callback::call_vsync(hwc2_display_t dpy_id, int64_t timestamp) +{ + std::lock_guard<std::mutex> lock(state_mutex); + if (vsync) + vsync(vsync_data, dpy_id, timestamp); +} diff --git a/hwc2/hwc2_dev.cpp b/hwc2/hwc2_dev.cpp index 28b365e..09ae5a4 100644 --- a/hwc2/hwc2_dev.cpp +++ b/hwc2/hwc2_dev.cpp @@ -22,9 +22,10 @@ #include "hwc2.h" -static void hwc2_vsync(void* /*data*/, int /*dpy_id*/, uint64_t /*timestamp*/) +static void hwc2_vsync(void *data, int dpy_id, uint64_t timestamp) { - return; + hwc2_dev *dev = static_cast<hwc2_dev *>(data); + dev->vsync(static_cast<hwc2_display_t>(dpy_id), timestamp); } static void hwc2_hotplug(void *data, int dpy_id, bool connected) @@ -183,6 +184,57 @@ void hwc2_dev::hotplug(hwc2_display_t dpy_id, hwc2_connection_t connection) callback_handler.call_hotplug(dpy_id, connection); } +void hwc2_dev::vsync(hwc2_display_t dpy_id, uint64_t timestamp) +{ + auto it = displays.find(dpy_id); + if (it == displays.end()) { + ALOGW("dpy %" PRIu64 ": invalid display handle preventing vsync" + " callback", dpy_id); + return; + } + + callback_handler.call_vsync(dpy_id, timestamp); +} + +hwc2_error_t hwc2_dev::set_vsync_enabled(hwc2_display_t dpy_id, + hwc2_vsync_t enabled) +{ + auto it = displays.find(dpy_id); + if (it == displays.end()) { + ALOGE("dpy %" PRIu64 ": invalid display handle", dpy_id); + return HWC2_ERROR_BAD_DISPLAY; + } + + if (it->second.get_type() != HWC2_DISPLAY_TYPE_PHYSICAL) + return HWC2_ERROR_NONE; + + if (it->second.get_vsync_enabled() == enabled) + return HWC2_ERROR_NONE; + + bool adf_enabled; + switch (enabled) { + case HWC2_VSYNC_ENABLE: + adf_enabled = true; + break; + case HWC2_VSYNC_DISABLE: + adf_enabled = false; + break; + default: + ALOGW("dpy %" PRIu64 ": invalid vsync enable parameter %u", dpy_id, + enabled); + return HWC2_ERROR_BAD_PARAMETER; + } + + int ret = adf_eventControl(adf_helper, dpy_id, HWC_EVENT_VSYNC, adf_enabled); + if (ret < 0) { + ALOGW("dpy %" PRIu64 ": failed to set vsync enabled: %s", dpy_id, + strerror(ret)); + return HWC2_ERROR_BAD_PARAMETER; + } + + return it->second.set_vsync_enabled(enabled); +} + hwc2_error_t hwc2_dev::register_callback(hwc2_callback_descriptor_t descriptor, hwc2_callback_data_t callback_data, hwc2_function_pointer_t pointer) { diff --git a/hwc2/hwc2_display.cpp b/hwc2/hwc2_display.cpp index 90d8048..35dacbd 100644 --- a/hwc2/hwc2_display.cpp +++ b/hwc2/hwc2_display.cpp @@ -31,6 +31,7 @@ hwc2_display::hwc2_display(hwc2_display_t id, int adf_intf_fd, connection(connection), type(type), layers(), + vsync_enabled(HWC2_VSYNC_DISABLE), configs(), active_config(0), power_mode(power_mode), @@ -86,6 +87,17 @@ hwc2_error_t hwc2_display::get_doze_support(int32_t *out_support) const return HWC2_ERROR_NONE; } +hwc2_error_t hwc2_display::set_vsync_enabled(hwc2_vsync_t enabled) +{ + if (enabled == HWC2_VSYNC_INVALID) { + ALOGE("dpy %" PRIu64 ": invalid vsync enabled", id); + return HWC2_ERROR_BAD_PARAMETER; + } + + this->vsync_enabled = enabled; + return HWC2_ERROR_NONE; +} + int hwc2_display::retrieve_display_configs(struct adf_hwc_helper *adf_helper) { size_t num_configs = 0; |