summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarissa Wall <marissaw@google.com>2016-09-01 14:38:04 -0700
committerMarissa Wall <marissaw@google.com>2017-03-02 12:35:01 -0800
commit954c3776e61ebe04e6b98cd12045cec9700e8452 (patch)
tree8fb0528d21c915addb81b58b67651c972a3d7073
parent7384507cad45dc3c1deb4b4f9d41a69362f664dc (diff)
downloadflounder-954c3776e61ebe04e6b98cd12045cec9700e8452.tar.gz
hwc2: call hotplug on physical displays
Call the hotplug callback on all physical displays. If the hotplug callback has not been registered, store the information for when the callback has been registered. Keep track of connection status and update it with each hotplug event. 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: I56af90482e0323e64fc86909d70f66a92c600c1d
-rw-r--r--hwc2/hwc2.h20
-rw-r--r--hwc2/hwc2_callback.cpp25
-rw-r--r--hwc2/hwc2_dev.cpp31
-rw-r--r--hwc2/hwc2_display.cpp14
4 files changed, 84 insertions, 6 deletions
diff --git a/hwc2/hwc2.h b/hwc2/hwc2.h
index 6bb500c..9bf84b6 100644
--- a/hwc2/hwc2.h
+++ b/hwc2/hwc2.h
@@ -20,6 +20,8 @@
#include <hardware/hwcomposer2.h>
#include <unordered_map>
+#include <queue>
+#include <mutex>
#include <adf/adf.h>
#include <adfhwc/adfhwc.h>
@@ -51,7 +53,15 @@ public:
hwc2_callback_data_t callback_data,
hwc2_function_pointer_t pointer);
+ void call_hotplug(hwc2_display_t dpy_id, hwc2_connection_t connection);
+
private:
+ std::mutex state_mutex;
+
+ /* A queue of all the hotplug notifications that were called before the
+ * callback was registered */
+ std::queue<std::pair<hwc2_display_t, hwc2_connection_t>> hotplug_pending;
+
/* All of the client callback functions and their data */
hwc2_callback_data_t hotplug_data;
HWC2_PFN_HOTPLUG hotplug;
@@ -66,10 +76,13 @@ private:
class hwc2_display {
public:
hwc2_display(hwc2_display_t id, int adf_intf_fd,
- const struct adf_device &adf_dev);
+ const struct adf_device &adf_dev, hwc2_connection_t connection);
~hwc2_display();
hwc2_display_t get_id() const { return id; }
+ hwc2_connection_t get_connection() const { return connection; }
+
+ hwc2_error_t set_connection(hwc2_connection_t connection);
int retrieve_display_configs(struct adf_hwc_helper *adf_helper);
@@ -81,6 +94,9 @@ private:
/* Identifies the display to the client */
hwc2_display_t id;
+ /* The display is connected to an output */
+ hwc2_connection_t connection;
+
/* All the valid configurations for the display */
std::unordered_map<hwc2_config_t, hwc2_config> configs;
@@ -103,6 +119,8 @@ public:
hwc2_dev();
~hwc2_dev();
+ void hotplug(hwc2_display_t dpy_id, hwc2_connection_t connection);
+
hwc2_error_t register_callback(hwc2_callback_descriptor_t descriptor,
hwc2_callback_data_t callback_data,
hwc2_function_pointer_t pointer);
diff --git a/hwc2/hwc2_callback.cpp b/hwc2/hwc2_callback.cpp
index 1900b1e..041bc86 100644
--- a/hwc2/hwc2_callback.cpp
+++ b/hwc2/hwc2_callback.cpp
@@ -19,7 +19,9 @@
#include "hwc2.h"
hwc2_callback::hwc2_callback()
- : hotplug_data(nullptr),
+ : state_mutex(),
+ hotplug_pending(),
+ hotplug_data(nullptr),
hotplug(nullptr),
refresh_data(nullptr),
refresh(nullptr),
@@ -30,6 +32,8 @@ hwc2_error_t hwc2_callback::register_callback(
hwc2_callback_descriptor_t descriptor,
hwc2_callback_data_t callback_data, hwc2_function_pointer_t pointer)
{
+ std::lock_guard<std::mutex> lock(state_mutex);
+
switch (descriptor) {
case HWC2_CALLBACK_HOTPLUG:
hotplug = (HWC2_PFN_HOTPLUG) pointer;
@@ -48,5 +52,24 @@ hwc2_error_t hwc2_callback::register_callback(
return HWC2_ERROR_BAD_PARAMETER;
}
+ if (descriptor == HWC2_CALLBACK_HOTPLUG && hotplug) {
+ while (!hotplug_pending.empty()) {
+ hotplug(hotplug_data, std::get<0>(hotplug_pending.front()),
+ std::get<1>(hotplug_pending.front()));
+ hotplug_pending.pop();
+ }
+ }
+
return HWC2_ERROR_NONE;
}
+
+void hwc2_callback::call_hotplug(hwc2_display_t dpy_id,
+ hwc2_connection_t connection)
+{
+ std::lock_guard<std::mutex> lock(state_mutex);
+
+ if (hotplug)
+ hotplug(hotplug_data, dpy_id, connection);
+ else
+ hotplug_pending.push(std::make_pair(dpy_id, connection));
+}
diff --git a/hwc2/hwc2_dev.cpp b/hwc2/hwc2_dev.cpp
index 6754087..3123679 100644
--- a/hwc2/hwc2_dev.cpp
+++ b/hwc2/hwc2_dev.cpp
@@ -27,9 +27,12 @@ static void hwc2_vsync(void* /*data*/, int /*dpy_id*/, uint64_t /*timestamp*/)
return;
}
-static void hwc2_hotplug(void* /*data*/, int /*dpy_id*/, bool /*connected*/)
+static void hwc2_hotplug(void *data, int dpy_id, bool connected)
{
- return;
+ hwc2_dev *dev = static_cast<hwc2_dev *>(data);
+ dev->hotplug(static_cast<hwc2_display_t>(dpy_id),
+ (connected)? HWC2_CONNECTION_CONNECTED:
+ HWC2_CONNECTION_DISCONNECTED);
}
static void hwc2_custom_event(void* /*data*/, int /*dpy_id*/,
@@ -56,6 +59,22 @@ hwc2_dev::~hwc2_dev()
hwc2_display::reset_ids();
}
+void hwc2_dev::hotplug(hwc2_display_t dpy_id, hwc2_connection_t connection)
+{
+ auto it = displays.find(dpy_id);
+ if (it == displays.end()) {
+ ALOGW("dpy %" PRIu64 ": invalid display handle preventing hotplug"
+ " callback", dpy_id);
+ return;
+ }
+
+ hwc2_error_t ret = it->second.set_connection(connection);
+ if (ret != HWC2_ERROR_NONE)
+ return;
+
+ callback_handler.call_hotplug(dpy_id, connection);
+}
+
hwc2_error_t hwc2_dev::register_callback(hwc2_callback_descriptor_t descriptor,
hwc2_callback_data_t callback_data, hwc2_function_pointer_t pointer)
{
@@ -109,6 +128,10 @@ int hwc2_dev::open_adf_device()
}
}
+ for (auto &dpy: displays)
+ callback_handler.call_hotplug(dpy.second.get_id(),
+ dpy.second.get_connection());
+
free(dev_ids);
return 0;
@@ -148,7 +171,9 @@ int hwc2_dev::open_adf_display(adf_id_t adf_id) {
hwc2_display_t dpy_id = hwc2_display::get_next_id();
displays.emplace(std::piecewise_construct, std::forward_as_tuple(dpy_id),
- std::forward_as_tuple(dpy_id, intf_fd, adf_dev));
+ std::forward_as_tuple(dpy_id, intf_fd, adf_dev,
+ (intf.hotplug_detect)? HWC2_CONNECTION_CONNECTED:
+ HWC2_CONNECTION_DISCONNECTED));
adf_free_interface_data(&intf);
diff --git a/hwc2/hwc2_display.cpp b/hwc2/hwc2_display.cpp
index e25eded..b68d251 100644
--- a/hwc2/hwc2_display.cpp
+++ b/hwc2/hwc2_display.cpp
@@ -25,8 +25,9 @@
uint64_t hwc2_display::display_cnt = 0;
hwc2_display::hwc2_display(hwc2_display_t id, int adf_intf_fd,
- const struct adf_device &adf_dev)
+ const struct adf_device &adf_dev, hwc2_connection_t connection)
: id(id),
+ connection(connection),
configs(),
active_config(0),
adf_intf_fd(adf_intf_fd),
@@ -38,6 +39,17 @@ hwc2_display::~hwc2_display()
adf_device_close(&adf_dev);
}
+hwc2_error_t hwc2_display::set_connection(hwc2_connection_t connection)
+{
+ if (connection == HWC2_CONNECTION_INVALID) {
+ ALOGE("dpy %" PRIu64 ": invalid connection", id);
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ this->connection = connection;
+ return HWC2_ERROR_NONE;
+}
+
int hwc2_display::retrieve_display_configs(struct adf_hwc_helper *adf_helper)
{
size_t num_configs = 0;