Merge changes I66d4fc71,I686dce91,I31325c76 am: 497cb085c7 am: 2993cc1e07
am: 3f4c0aa72a
Change-Id: Ic6e047e9a3958db3021566dd9d6d859789d81a1a
diff --git a/adf/libadfhwc/adfhwc.cpp b/adf/libadfhwc/adfhwc.cpp
index a97862a..63c0f75 100644
--- a/adf/libadfhwc/adfhwc.cpp
+++ b/adf/libadfhwc/adfhwc.cpp
@@ -166,6 +166,71 @@
return 0;
}
+static int32_t adf_display_attribute_hwc2(const adf_interface_data &data,
+ const drm_mode_modeinfo &mode, const uint32_t attribute)
+{
+ switch (attribute) {
+ case HWC2_ATTRIBUTE_VSYNC_PERIOD:
+ if (mode.vrefresh)
+ return 1000000000 / mode.vrefresh;
+ return 0;
+
+ case HWC2_ATTRIBUTE_WIDTH:
+ return mode.hdisplay;
+
+ case HWC2_ATTRIBUTE_HEIGHT:
+ return mode.vdisplay;
+
+ case HWC2_ATTRIBUTE_DPI_X:
+ return dpi(mode.hdisplay, data.width_mm);
+
+ case HWC2_ATTRIBUTE_DPI_Y:
+ return dpi(mode.vdisplay, data.height_mm);
+
+ default:
+ ALOGE("unknown display attribute %u", attribute);
+ return -EINVAL;
+ }
+}
+
+int adf_getDisplayAttributes_hwc2(struct adf_hwc_helper *dev, int disp,
+ uint32_t config, const uint32_t *attributes, int32_t *values)
+{
+ if ((size_t)disp >= dev->intf_fds.size())
+ return -EINVAL;
+
+ if (config >= dev->display_configs.size())
+ return -EINVAL;
+
+ adf_interface_data data;
+ int err = adf_get_interface_data(dev->intf_fds[disp], &data);
+ if (err < 0) {
+ ALOGE("failed to get ADF interface data: %s", strerror(err));
+ return err;
+ }
+
+ for (int i = 0; attributes[i] != HWC2_ATTRIBUTE_INVALID; i++)
+ values[i] = adf_display_attribute_hwc2(data,
+ dev->display_configs[config], attributes[i]);
+
+ adf_free_interface_data(&data);
+ return 0;
+}
+
+int adf_set_active_config_hwc2(struct adf_hwc_helper *dev, int disp,
+ uint32_t config)
+{
+ if ((size_t)disp >= dev->intf_fds.size())
+ return -EINVAL;
+
+ if (config >= dev->display_configs.size())
+ return -EINVAL;
+
+ struct drm_mode_modeinfo mode = dev->display_configs[config];
+
+ return adf_interface_set_mode(dev->intf_fds[disp], &mode);
+}
+
static void handle_adf_event(struct adf_hwc_helper *dev, int disp)
{
adf_event *event;
@@ -208,28 +273,39 @@
setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
- pollfd *fds = new pollfd[dev->intf_fds.size()];
+ struct sigaction action = { };
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ action.sa_handler = [](int) { pthread_exit(0); };
+
+ if (sigaction(SIGUSR2, &action, NULL) < 0) {
+ ALOGE("failed to set thread exit action %s", strerror(errno));
+ return NULL;
+ }
+
+ sigset_t signal_set;
+ sigemptyset(&signal_set);
+ sigaddset(&signal_set, SIGUSR2);
+
+ pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL);
+
+ pollfd fds[dev->intf_fds.size()];
for (size_t i = 0; i < dev->intf_fds.size(); i++) {
fds[i].fd = dev->intf_fds[i];
fds[i].events = POLLIN | POLLPRI;
}
while (true) {
- int err = poll(fds, dev->intf_fds.size(), -1);
-
- if (err > 0) {
- for (size_t i = 0; i < dev->intf_fds.size(); i++)
- if (fds[i].revents & (POLLIN | POLLPRI))
- handle_adf_event(dev, i);
- }
- else if (err == -1) {
- if (errno == EINTR)
- break;
+ if (TEMP_FAILURE_RETRY(poll(fds, dev->intf_fds.size(), -1)) < 0) {
ALOGE("error in event thread: %s", strerror(errno));
+ break;
}
+
+ for (size_t i = 0; i < dev->intf_fds.size(); i++)
+ if (fds[i].revents & (POLLIN | POLLPRI))
+ handle_adf_event(dev, i);
}
- delete [] fds;
return NULL;
}
@@ -264,6 +340,12 @@
}
}
+ sigset_t signal_set;
+ sigemptyset(&signal_set);
+ sigaddset(&signal_set, SIGUSR2);
+
+ pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
+
ret = pthread_create(&dev_ret->event_thread, NULL, adf_event_thread,
dev_ret);
if (ret) {
@@ -284,7 +366,7 @@
void adf_hwc_close(struct adf_hwc_helper *dev)
{
- pthread_kill(dev->event_thread, SIGTERM);
+ pthread_kill(dev->event_thread, SIGUSR2);
pthread_join(dev->event_thread, NULL);
for (size_t i = 0; i < dev->intf_fds.size(); i++)
diff --git a/adf/libadfhwc/include/adfhwc/adfhwc.h b/adf/libadfhwc/include/adfhwc/adfhwc.h
index 71e7624..4f70925 100644
--- a/adf/libadfhwc/include/adfhwc/adfhwc.h
+++ b/adf/libadfhwc/include/adfhwc/adfhwc.h
@@ -23,6 +23,7 @@
#include <video/adf.h>
#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer2.h>
struct adf_hwc_helper;
@@ -123,6 +124,16 @@
uint32_t *configs, size_t *numConfigs);
int adf_getDisplayAttributes(struct adf_hwc_helper *dev, int disp,
uint32_t config, const uint32_t *attributes, int32_t *values);
+/**
+ * Generic implementation of common HWC2 functions.
+ *
+ * The HWC2 should not return these functions directly through getFunction.
+ * Instead, the HWC2 should return stub functions which call these helpers.
+ */
+int adf_getDisplayAttributes_hwc2(struct adf_hwc_helper *dev, int disp,
+ uint32_t config, const uint32_t *attributes, int32_t *values);
+int adf_set_active_config_hwc2(struct adf_hwc_helper *dev, int disp,
+ uint32_t config);
__END_DECLS