summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarissa Wall <marissaw@google.com>2017-03-02 22:08:29 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-03-02 22:08:29 +0000
commitd3e6211a02fa00428d3c1e4ecabea5af9dce8f09 (patch)
tree756a753f5ab0fde5859b84fb4f5132fda77ce3e6
parente754968b56fadfa23889e4849a315e589fda67df (diff)
parentedc82b338f58ff2a5ebfbf09b4caeee9bcd0ac09 (diff)
downloadflounder-d3e6211a02fa00428d3c1e4ecabea5af9dce8f09.tar.gz
hwc2: open adf device and instantiate displays
am: edc82b338f Change-Id: I155c0fd33b48cd41ec95f0d53c23b0a7fba6e239
-rw-r--r--hwc2/Android.mk12
-rw-r--r--hwc2/hwc2.cpp16
-rw-r--r--hwc2/hwc2.h51
-rw-r--r--hwc2/hwc2_dev.cpp126
-rw-r--r--hwc2/hwc2_display.cpp36
5 files changed, 239 insertions, 2 deletions
diff --git a/hwc2/Android.mk b/hwc2/Android.mk
index c784b66..340df9f 100644
--- a/hwc2/Android.mk
+++ b/hwc2/Android.mk
@@ -31,9 +31,17 @@ LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE := hwcomposer.$(TARGET_BOOTLOADER_BOARD_NAME)
LOCAL_SHARED_LIBRARIES := \
- liblog
+ liblog \
+ libutils
-LOCAL_SRC_FILES := hwc2.cpp
+LOCAL_STATIC_LIBRARIES := \
+ libadfhwc \
+ libadf
+
+LOCAL_SRC_FILES := \
+ hwc2.cpp \
+ hwc2_dev.cpp \
+ hwc2_display.cpp
LOCAL_MODLE_TAGS := optional
diff --git a/hwc2/hwc2.cpp b/hwc2/hwc2.cpp
index e9b7e2b..8d9d24a 100644
--- a/hwc2/hwc2.cpp
+++ b/hwc2/hwc2.cpp
@@ -393,6 +393,7 @@ void get_capabilities(struct hwc2_device* /*device*/, uint32_t *out_count,
static int32_t hwc2_device_close(struct hw_device_t *device)
{
hwc2_context *ctx = reinterpret_cast<hwc2_context *>(device);
+ delete ctx->hwc2_dev;
delete ctx;
return 0;
}
@@ -416,6 +417,21 @@ static int hwc2_device_open(const struct hw_module_t *module, const char *name,
ctx->hwc2_device.getFunction = get_function;
ctx->hwc2_device.getCapabilities = get_capabilities;
+ ctx->hwc2_dev = new hwc2_dev();
+ if (!ctx->hwc2_dev) {
+ ALOGE("failed to allocate hwc2_dev");
+ delete ctx;
+ return -ENOMEM;
+ }
+
+ int ret = ctx->hwc2_dev->open_adf_device();
+ if (ret < 0) {
+ ALOGE("failed to open adf device: %s", strerror(ret));
+ delete ctx->hwc2_dev;
+ delete ctx;
+ return ret;
+ }
+
*hw_device = &ctx->hwc2_device.common;
return 0;
diff --git a/hwc2/hwc2.h b/hwc2/hwc2.h
index ea040be..f12be0f 100644
--- a/hwc2/hwc2.h
+++ b/hwc2/hwc2.h
@@ -19,8 +19,59 @@
#include <hardware/hwcomposer2.h>
+#include <unordered_map>
+
+#include <adf/adf.h>
+#include <adfhwc/adfhwc.h>
+
+class hwc2_display {
+public:
+ hwc2_display(hwc2_display_t id, int adf_intf_fd,
+ const struct adf_device &adf_dev);
+ ~hwc2_display();
+
+ hwc2_display_t get_id() const { return id; }
+
+ static hwc2_display_t get_next_id();
+
+ static void reset_ids() { display_cnt = 0; }
+
+private:
+ /* Identifies the display to the client */
+ hwc2_display_t id;
+
+ /* The adf interface file descriptor for the display */
+ int adf_intf_fd;
+
+ /* The adf device associated with the display */
+ struct adf_device adf_dev;
+
+ /* Keep track to total number of displays so new display ids can be
+ * generated */
+ static uint64_t display_cnt;
+};
+
+class hwc2_dev {
+public:
+ hwc2_dev();
+ ~hwc2_dev();
+
+ int open_adf_device();
+
+private:
+ /* The physical and virtual displays associated with this device */
+ std::unordered_map<hwc2_display_t, hwc2_display> displays;
+
+ /* The associated adf hardware composer helper */
+ struct adf_hwc_helper *adf_helper;
+
+ int open_adf_display(adf_id_t adf_id);
+};
+
struct hwc2_context {
hwc2_device_t hwc2_device; /* must be first member in struct */
+
+ hwc2_dev *hwc2_dev;
};
#endif /* ifndef _HWC2_H */
diff --git a/hwc2/hwc2_dev.cpp b/hwc2/hwc2_dev.cpp
new file mode 100644
index 0000000..82faaf6
--- /dev/null
+++ b/hwc2/hwc2_dev.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <cutils/log.h>
+#include <cstdlib>
+#include <vector>
+
+#include "hwc2.h"
+
+static void hwc2_vsync(void* /*data*/, int /*dpy_id*/, uint64_t /*timestamp*/)
+{
+ return;
+}
+
+static void hwc2_hotplug(void* /*data*/, int /*dpy_id*/, bool /*connected*/)
+{
+ return;
+}
+
+static void hwc2_custom_event(void* /*data*/, int /*dpy_id*/,
+ struct adf_event* /*event*/)
+{
+ return;
+}
+
+const struct adf_hwc_event_callbacks hwc2_adfhwc_callbacks = {
+ .vsync = hwc2_vsync,
+ .hotplug = hwc2_hotplug,
+ .custom_event = hwc2_custom_event,
+};
+
+hwc2_dev::hwc2_dev()
+ : displays(),
+ adf_helper(nullptr) { }
+
+hwc2_dev::~hwc2_dev()
+{
+ if (adf_helper)
+ adf_hwc_close(adf_helper);
+ hwc2_display::reset_ids();
+}
+
+int hwc2_dev::open_adf_device()
+{
+ adf_id_t *dev_ids = nullptr;
+ int ret;
+
+ ssize_t n_devs = adf_devices(&dev_ids);
+ if (n_devs < 0) {
+ ALOGE("failed to enumerate adf devices: %s", strerror(n_devs));
+ return n_devs;
+ }
+
+ std::vector<int> intf_fds;
+
+ for (ssize_t idx = 0; idx < n_devs; idx++) {
+ int intf_fd = open_adf_display(dev_ids[idx]);
+ if (intf_fd >= 0)
+ intf_fds.push_back(intf_fd);
+ }
+
+ if (displays.empty()) {
+ ALOGE("failed to open any physical displays");
+ ret = -EINVAL;
+ goto err_open;
+ }
+
+ ret = adf_hwc_open(intf_fds.data(), intf_fds.size(),
+ &hwc2_adfhwc_callbacks, this, &adf_helper);
+ if (ret < 0) {
+ ALOGE("failed to open adf helper: %s", strerror(ret));
+ displays.clear();
+ }
+
+err_open:
+ free(dev_ids);
+ return ret;
+}
+
+int hwc2_dev::open_adf_display(adf_id_t adf_id) {
+ struct adf_device adf_dev;
+
+ int ret = adf_device_open(adf_id, O_RDWR, &adf_dev);
+ if (ret < 0) {
+ ALOGE("failed to open adf%u device: %s", adf_id, strerror(ret));
+ return ret;
+ }
+
+ int intf_fd = adf_interface_open(&adf_dev, 0, O_RDWR);
+ if (intf_fd < 0) {
+ ALOGE("failed to open adf%u interface: %s", adf_id, strerror(intf_fd));
+ adf_device_close(&adf_dev);
+ return intf_fd;
+ }
+
+ struct adf_interface_data intf;
+ ret = adf_get_interface_data(intf_fd, &intf);
+ if (ret < 0) {
+ ALOGE("failed to get adf%u interface data: %s", adf_id, strerror(ret));
+ close(intf_fd);
+ adf_device_close(&adf_dev);
+ return ret;
+ }
+
+ 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));
+
+ adf_free_interface_data(&intf);
+
+ return intf_fd;
+}
diff --git a/hwc2/hwc2_display.cpp b/hwc2/hwc2_display.cpp
new file mode 100644
index 0000000..d066773
--- /dev/null
+++ b/hwc2/hwc2_display.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hwc2.h"
+
+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)
+ : id(id),
+ adf_intf_fd(adf_intf_fd),
+ adf_dev(adf_dev) { }
+
+hwc2_display::~hwc2_display()
+{
+ close(adf_intf_fd);
+ adf_device_close(&adf_dev);
+}
+
+hwc2_display_t hwc2_display::get_next_id()
+{
+ return display_cnt++;
+}