diff options
author | Marissa Wall <marissaw@google.com> | 2017-03-02 22:08:29 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-03-02 22:08:29 +0000 |
commit | d3e6211a02fa00428d3c1e4ecabea5af9dce8f09 (patch) | |
tree | 756a753f5ab0fde5859b84fb4f5132fda77ce3e6 | |
parent | e754968b56fadfa23889e4849a315e589fda67df (diff) | |
parent | edc82b338f58ff2a5ebfbf09b4caeee9bcd0ac09 (diff) | |
download | flounder-d3e6211a02fa00428d3c1e4ecabea5af9dce8f09.tar.gz |
hwc2: open adf device and instantiate displays
am: edc82b338f
Change-Id: I155c0fd33b48cd41ec95f0d53c23b0a7fba6e239
-rw-r--r-- | hwc2/Android.mk | 12 | ||||
-rw-r--r-- | hwc2/hwc2.cpp | 16 | ||||
-rw-r--r-- | hwc2/hwc2.h | 51 | ||||
-rw-r--r-- | hwc2/hwc2_dev.cpp | 126 | ||||
-rw-r--r-- | hwc2/hwc2_display.cpp | 36 |
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++; +} |