summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarissa Wall <marissaw@google.com>2016-09-01 14:42:02 -0700
committerMarissa Wall <marissaw@google.com>2017-03-02 12:35:06 -0800
commitd0db535d69470750c321f789eb4857b19edefa83 (patch)
tree688416e388acce87afa4179d8dc50578ec05c02e
parent25789155cba5e0ec17c51276d3b02e7783eb6b05 (diff)
downloadflounder-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.cpp7
-rw-r--r--hwc2/hwc2.h9
-rw-r--r--hwc2/hwc2_callback.cpp7
-rw-r--r--hwc2/hwc2_dev.cpp56
-rw-r--r--hwc2/hwc2_display.cpp12
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;