sdm: Implement composer hidl directly.
- Implement the hidl .hal interfaces directly instead of
using the default shims.
- This is required since new additions to .hal will no
longer be added to the legacy hwcomposer C header.
- Create new composer process in INIT_RC
- Implement CommandQueue Reader and Writer
-Reader is used to parse the commands from
i/p CMQ of client
-Writer is used to write the outputs if any,
for parsed commands then o/p CMQ passed to client.
- Add IMapper support to clone buffer handles for HWComposer
-In IComposer, any buffer_handle_t is owned by the caller
and we need to make a clone for HWComposer.
- Implement composer 2.1 and 2.2 API's as well.
CRs-Fixed: 2466333
Change-Id: Ife311443efdc067399d928221478d84677c17191
diff --git a/common.mk b/common.mk
index eca4769..5db3d16 100644
--- a/common.mk
+++ b/common.mk
@@ -48,7 +48,7 @@
#Common C flags
common_flags := -Wno-missing-field-initializers
-common_flags += -Wconversion -Wall -Werror -std=c++14
+common_flags += -Wall -Werror -std=c++14
common_flags += -DUSE_GRALLOC1
ifeq ($(TARGET_IS_HEADLESS), true)
common_flags += -DTARGET_HEADLESS
diff --git a/composer/Android.mk b/composer/Android.mk
index 8050cfc..a13889a 100644
--- a/composer/Android.mk
+++ b/composer/Android.mk
@@ -1,12 +1,11 @@
LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
include $(LOCAL_PATH)/../common.mk
+include $(CLEAR_VARS)
ifeq ($(use_hwc2),true)
LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes)
LOCAL_C_INCLUDES += $(kernel_includes)
@@ -113,4 +112,101 @@
hwc_buffer_allocator.cpp
include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vendor.qti.hardware.display.composer@1.0-service
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_HEADER_LIBRARIES := display_headers
+
+LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \
+ -std=c++11 -fcolor-diagnostics \
+ -DLOG_TAG=\"SDM\" $(common_flags)
+LOCAL_CLANG := true
+
+LOCAL_SHARED_LIBRARIES := libbinder libhardware libutils libcutils libsync \
+ libc++ liblog libhidlbase libhidltransport \
+ hwcomposer.$(TARGET_BOARD_PLATFORM) \
+ vendor.display.config@1.0 liblog libfmq \
+ vendor.qti.hardware.display.composer@1.0 \
+ android.hardware.graphics.composer@2.1 \
+ android.hardware.graphics.composer@2.2 \
+ android.hardware.graphics.composer@2.3 \
+ android.hardware.graphics.mapper@2.0 \
+ android.hardware.graphics.mapper@2.1 \
+ android.hardware.graphics.mapper@3.0 \
+ android.hardware.graphics.allocator@2.0 \
+ android.hardware.graphics.allocator@3.0
+
+$(info IDisplayConfig version: $(display_config_version))
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_1)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_2)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2 vendor.display.config@1.1
+endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_3)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
+endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_4)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.4
+endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_5)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.4
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.5
+endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_6)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.4
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.5
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.6
+endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_7)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.4
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.5
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.6
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.7
+endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_8)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.4
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.5
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.6
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.7
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.8
+endif
+ifeq ($(display_config_version), DISPLAY_CONFIG_1_9)
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.2
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.3
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.4
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.5
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.6
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.7
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.8
+LOCAL_SHARED_LIBRARIES += vendor.display.config@1.9
+endif
+
+LOCAL_SRC_FILES := QtiComposer.cpp QtiComposerClient.cpp service.cpp \
+ QtiComposerHandleImporter.cpp
+LOCAL_INIT_RC := vendor.qti.hardware.display.composer@1.0-service.rc
+include $(BUILD_EXECUTABLE)
endif
diff --git a/composer/QtiComposer.cpp b/composer/QtiComposer.cpp
new file mode 100644
index 0000000..b4760bd
--- /dev/null
+++ b/composer/QtiComposer.cpp
@@ -0,0 +1,147 @@
+/*
+* Copyright (c) 2019, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <vector>
+#include "QtiComposer.h"
+
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace composer {
+namespace V1_0 {
+namespace implementation {
+
+QtiComposer::QtiComposer() {
+ hwc_session_ = HWCSession::GetInstance();
+}
+
+QtiComposer::~QtiComposer() {
+ hwc_session_->Deinit();
+}
+
+// Methods from ::android::hardware::graphics::composer::V2_1::IComposer follow.
+Return<void> QtiComposer::getCapabilities(getCapabilities_cb _hidl_cb) {
+ const std::array<IComposer::Capability, 3> all_caps = {{
+ IComposer::Capability::SIDEBAND_STREAM,
+ IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM,
+ IComposer::Capability::PRESENT_FENCE_IS_NOT_RELIABLE,
+ }};
+
+ uint32_t count = 0;
+ hwc_session_->GetCapabilities(&count, nullptr);
+
+ std::vector<int32_t> composer_caps(count);
+ hwc_session_->GetCapabilities(&count, composer_caps.data());
+ composer_caps.resize(count);
+
+ std::unordered_set<hwc2_capability_t> Capabilities;
+ Capabilities.reserve(count);
+ for (auto cap : composer_caps) {
+ Capabilities.insert(static_cast<hwc2_capability_t>(cap));
+ }
+
+ std::vector<IComposer::Capability> caps;
+ for (auto cap : all_caps) {
+ if (Capabilities.count(static_cast<hwc2_capability_t>(cap)) > 0) {
+ caps.push_back(cap);
+ }
+ }
+
+ hidl_vec<IComposer::Capability> caps_reply;
+ caps_reply.setToExternal(caps.data(), caps.size());
+
+ _hidl_cb(caps_reply);
+ return Void();
+}
+
+Return<void> QtiComposer::dumpDebugInfo(dumpDebugInfo_cb _hidl_cb) {
+ uint32_t len;
+ hwc_session_->Dump(&len, nullptr);
+
+ std::vector<char> buf(len + 1);
+ hwc_session_->Dump(&len, buf.data());
+
+ buf.resize(len + 1);
+ buf[len] = '\0';
+ hidl_string buf_reply;
+ buf_reply.setToExternal(buf.data(), len);
+
+ _hidl_cb(buf_reply);
+ return Void();
+}
+
+Return<void> QtiComposer::createClient(createClient_cb _hidl_cb) {
+ // TODO(user): Implement combinedly w.r.t createClient_2_3
+ sp<IQtiComposerClient> composer_client = new QtiComposerClient();
+ if (!composer_client) {
+ _hidl_cb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ _hidl_cb(Error::NONE, composer_client);
+ return Void();
+}
+
+
+// Methods from ::android::hardware::graphics::composer::V2_3::IComposer follow.
+Return<void> QtiComposer::createClient_2_3(createClient_2_3_cb _hidl_cb) {
+ sp<IQtiComposerClient> composer_client = new QtiComposerClient();
+ if (!composer_client) {
+ _hidl_cb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ _hidl_cb(Error::NONE, composer_client);
+ return Void();
+}
+
+QtiComposer *QtiComposer::initialize() {
+ auto error = HWCSession::GetInstance()->Init();
+ if (error) {
+ ALOGE("failed to get hwcomposer instance");
+ return nullptr;
+ }
+
+ return new QtiComposer();
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+IQtiComposer* HIDL_FETCH_IQtiComposer(const char* /* name */) {
+ return new QtiComposer();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace composer
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
diff --git a/composer/QtiComposer.h b/composer/QtiComposer.h
new file mode 100644
index 0000000..1452a06
--- /dev/null
+++ b/composer/QtiComposer.h
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2019, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __QTICOMPOSER_H__
+#define __QTICOMPOSER_H__
+
+#include <vendor/qti/hardware/display/composer/1.0/IQtiComposer.h>
+#include <log/log.h>
+#include <unordered_set>
+#include <QtiComposerClient.h>
+
+// TODO(user): recheck on this header inclusion
+#include <hardware/hwcomposer2.h>
+
+
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace composer {
+namespace V1_0 {
+namespace implementation {
+
+using ::vendor::qti::hardware::display::composer::V1_0::IQtiComposer;
+
+class QtiComposer : public IQtiComposer {
+ public:
+ QtiComposer();
+ virtual ~QtiComposer();
+ // Methods from ::android::hardware::graphics::composer::V2_1::IComposer follow.
+ Return<void> getCapabilities(getCapabilities_cb _hidl_cb) override;
+ Return<void> dumpDebugInfo(dumpDebugInfo_cb _hidl_cb) override;
+ Return<void> createClient(createClient_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::graphics::composer::V2_3::IComposer follow.
+ Return<void> createClient_2_3(createClient_2_3_cb _hidl_cb) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+
+ static QtiComposer *initialize();
+
+ private:
+ HWCSession *hwc_session_ = nullptr;
+};
+
+extern "C" IQtiComposer* HIDL_FETCH_IQtiComposer(const char* name);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace composer
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
+
+#endif // __QTICOMPOSER_H__
diff --git a/composer/QtiComposerClient.cpp b/composer/QtiComposerClient.cpp
new file mode 100644
index 0000000..2a858b4
--- /dev/null
+++ b/composer/QtiComposerClient.cpp
@@ -0,0 +1,1841 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2017 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 <vector>
+
+#include "QtiComposerClient.h"
+
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace composer {
+namespace V1_0 {
+namespace implementation {
+
+ComposerHandleImporter mHandleImporter;
+
+BufferCacheEntry::BufferCacheEntry() : mHandle(nullptr) {}
+
+BufferCacheEntry::BufferCacheEntry(BufferCacheEntry&& other) {
+ mHandle = other.mHandle;
+ other.mHandle = nullptr;
+}
+
+BufferCacheEntry& BufferCacheEntry::operator=(buffer_handle_t handle) {
+ clear();
+ mHandle = handle;
+ return *this;
+}
+
+BufferCacheEntry::~BufferCacheEntry() {
+ clear();
+}
+
+void BufferCacheEntry::clear() {
+ if (mHandle) {
+ mHandleImporter.freeBuffer(mHandle);
+ }
+}
+
+QtiComposerClient::QtiComposerClient() : mWriter(kWriterInitialSize), mReader(*this) {
+ hwc_session_ = HWCSession::GetInstance();
+ mHandleImporter.initialize();
+}
+
+QtiComposerClient::~QtiComposerClient() {
+ // We want to call hwc2_close here (and move hwc2_open to the
+ // constructor), with the assumption that hwc2_close would
+ //
+ // - clean up all resources owned by the client
+ // - make sure all displays are blank (since there is no layer)
+ //
+ // But since SF used to crash at this point, different hwcomposer2
+ // implementations behave differently on hwc2_close. Our only portable
+ // choice really is to abort(). But that is not an option anymore
+ // because we might also have VTS or VR as clients that can come and go.
+ //
+ // Below we manually clean all resources (layers and virtual
+ // displays), and perform a presentDisplay afterwards.
+ ALOGW("destroying composer client");
+
+ enableCallback(false);
+
+ // no need to grab the mutex as any in-flight hwbinder call would have
+ // kept the client alive
+ for (const auto& dpy : mDisplayData) {
+ ALOGW("destroying client resources for display %" PRIu64, dpy.first);
+
+ for (const auto& ly : dpy.second.Layers) {
+ hwc_session_->DestroyLayer(dpy.first, ly.first);
+ }
+
+ if (dpy.second.IsVirtual) {
+ destroyVirtualDisplay(dpy.first);
+ } else {
+ ALOGW("performing a final presentDisplay");
+
+ std::vector<Layer> changedLayers;
+ std::vector<IComposerClient::Composition> compositionTypes;
+ uint32_t displayRequestMask = 0;
+ std::vector<Layer> requestedLayers;
+ std::vector<uint32_t> requestMasks;
+ mReader.validateDisplay(dpy.first, changedLayers, compositionTypes, displayRequestMask,
+ requestedLayers, requestMasks);
+
+ hwc_session_->AcceptDisplayChanges(dpy.first);
+
+ int32_t presentFence = -1;
+ std::vector<Layer> releasedLayers;
+ std::vector<int32_t> releaseFences;
+ mReader.presentDisplay(dpy.first, presentFence, releasedLayers, releaseFences);
+
+ if (presentFence >= 0) {
+ close(presentFence);
+ }
+ for (auto fence : releaseFences) {
+ if (fence >= 0) {
+ close(fence);
+ }
+ }
+ }
+ }
+
+ mDisplayData.clear();
+
+ mHandleImporter.cleanup();
+
+ ALOGW("removed composer client");
+}
+
+void QtiComposerClient::onHotplug(hwc2_callback_data_t callbackData, hwc2_display_t display,
+ int32_t connected) {
+ auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
+ auto connect = static_cast<composer_V2_1::IComposerCallback::Connection>(connected);
+ {
+ std::lock_guard<std::mutex> lock(client->mDisplayDataMutex);
+ if (connect == composer_V2_1::IComposerCallback::Connection::CONNECTED) {
+ client->mDisplayData.emplace(display, DisplayData(false));
+ } else if (connect == composer_V2_1::IComposerCallback::Connection::DISCONNECTED) {
+ client->mDisplayData.erase(display);
+ }
+ }
+
+ auto ret = client->mCallback->onHotplug(display, connect);
+ ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s", ret.description().c_str());
+}
+
+void QtiComposerClient::onRefresh(hwc2_callback_data_t callbackData, hwc2_display_t display) {
+ auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
+ auto ret = client->mCallback->onRefresh(display);
+ ALOGE_IF(!ret.isOk(), "failed to send onRefresh: %s", ret.description().c_str());
+}
+
+void QtiComposerClient::onVsync(hwc2_callback_data_t callbackData, hwc2_display_t display,
+ int64_t timestamp) {
+ auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
+ auto ret = client->mCallback->onVsync(display, timestamp);
+ ALOGE_IF(!ret.isOk(), "failed to send onVsync: %s", ret.description().c_str());
+}
+
+// convert fenceFd to or from hidl_handle
+Error QtiComposerClient::getFenceFd(const hidl_handle& fenceHandle,
+ android::base::unique_fd* outFenceFd) {
+ auto handle = fenceHandle.getNativeHandle();
+ if (handle && handle->numFds > 1) {
+ ALOGE("invalid fence handle with %d fds", handle->numFds);
+ return Error::BAD_PARAMETER;
+ }
+
+ int fenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
+ if (fenceFd >= 0) {
+ fenceFd = dup(fenceFd);
+ if (fenceFd < 0) {
+ return Error::NO_RESOURCES;
+ }
+ }
+
+ outFenceFd->reset(fenceFd);
+
+ return Error::NONE;
+}
+
+hidl_handle QtiComposerClient::getFenceHandle(const android::base::unique_fd& fenceFd,
+ char* handleStorage) {
+ native_handle_t* handle = nullptr;
+ if (fenceFd >= 0) {
+ handle = native_handle_init(handleStorage, 1, 0);
+ handle->data[0] = fenceFd;
+ }
+
+ return hidl_handle(handle);
+}
+
+Error QtiComposerClient::getDisplayReadbackBuffer(Display display,
+ const native_handle_t* rawHandle,
+ const native_handle_t** outHandle) {
+ // TODO(user): revisit for caching and freeBuffer in success case.
+ if (!mHandleImporter.importBuffer(rawHandle)) {
+ ALOGE("%s: importBuffer failed: ", __FUNCTION__);
+ return Error::NO_RESOURCES;
+ }
+
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+ auto iter = mDisplayData.find(display);
+ if (iter == mDisplayData.end()) {
+ mHandleImporter.freeBuffer(rawHandle);
+ return Error::BAD_DISPLAY;
+ }
+
+ *outHandle = rawHandle;
+ return Error::NONE;
+}
+
+void QtiComposerClient::getCapabilities() {
+ uint32_t count = 0;
+ hwc_session_->GetCapabilities(&count, nullptr);
+
+ std::vector<int32_t> composer_caps(count);
+ hwc_session_->GetCapabilities(&count, composer_caps.data());
+ composer_caps.resize(count);
+
+ mCapabilities.reserve(count);
+ for (auto cap : composer_caps) {
+ mCapabilities.insert(static_cast<hwc2_capability_t>(cap));
+ }
+}
+
+void QtiComposerClient::enableCallback(bool enable) {
+ if (enable) {
+ hwc_session_->RegisterCallback(HWC2_CALLBACK_HOTPLUG, this,
+ reinterpret_cast<hwc2_function_pointer_t>(onHotplug));
+ hwc_session_->RegisterCallback(HWC2_CALLBACK_REFRESH, this,
+ reinterpret_cast<hwc2_function_pointer_t>(onRefresh));
+ hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC, this,
+ reinterpret_cast<hwc2_function_pointer_t>(onVsync));
+ } else {
+ hwc_session_->RegisterCallback(HWC2_CALLBACK_HOTPLUG, this, nullptr);
+ hwc_session_->RegisterCallback(HWC2_CALLBACK_REFRESH, this, nullptr);
+ hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC, this, nullptr);
+ }
+}
+
+// Methods from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
+Return<void> QtiComposerClient::registerCallback(
+ const sp<composer_V2_1::IComposerCallback>& callback) {
+ mCallback = callback;
+ enableCallback(callback != nullptr);
+ return Void();
+}
+
+Return<uint32_t> QtiComposerClient::getMaxVirtualDisplayCount() {
+ return hwc_session_->GetMaxVirtualDisplayCount();
+}
+
+Return<void> QtiComposerClient::createVirtualDisplay(uint32_t width, uint32_t height,
+ common_V1_0::PixelFormat formatHint,
+ uint32_t outputBufferSlotCount,
+ createVirtualDisplay_cb _hidl_cb) {
+ // TODO(user): Implement combinedly w.r.t createVirtualDisplay_2_2
+ int32_t format = static_cast<int32_t>(formatHint);
+ uint64_t display;
+ auto error = hwc_session_->CreateVirtualDisplay(width, height, &format, &display);
+
+ if (static_cast<Error>(error) == Error::NONE) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ auto dpy = mDisplayData.emplace(static_cast<Display>(display), DisplayData(true)).first;
+ dpy->second.OutputBuffers.resize(outputBufferSlotCount);
+ }
+
+ _hidl_cb(static_cast<Error>(error), display, static_cast<common_V1_0::PixelFormat>(format));
+ return Void();
+}
+
+Return<composer_V2_1::Error> QtiComposerClient::destroyVirtualDisplay(uint64_t display) {
+ auto error = hwc_session_->DestroyVirtualDisplay(display);
+ if (static_cast<Error>(error) == Error::NONE) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ mDisplayData.erase(display);
+ }
+
+ return static_cast<Error>(error);
+}
+
+Return<void> QtiComposerClient::createLayer(uint64_t display, uint32_t bufferSlotCount,
+ createLayer_cb _hidl_cb) {
+ composer_V2_1::Layer layer = 0;
+ auto error = hwc_session_->CreateLayer(display, &layer);
+ Error err = static_cast<Error>(error);
+ if (err == Error::NONE) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+ auto dpy = mDisplayData.find(display);
+ // The display entry may have already been removed by onHotplug.
+ if (dpy != mDisplayData.end()) {
+ auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
+ ly->second.Buffers.resize(bufferSlotCount);
+ } else {
+ err = Error::BAD_DISPLAY;
+ // Note: We do not destroy the layer on this error as the hotplug
+ // disconnect invalidates the display id. The implementation should
+ // ensure all layers for the display are destroyed.
+ }
+ }
+
+ _hidl_cb(err, layer);
+ return Void();
+}
+
+Return<Error> QtiComposerClient::destroyLayer(uint64_t display, uint64_t layer) {
+ auto error = hwc_session_->DestroyLayer(display, layer);
+ Error err = static_cast<Error>(error);
+ if (err == Error::NONE) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ auto dpy = mDisplayData.find(display);
+ // The display entry may have already been removed by onHotplug.
+ if (dpy != mDisplayData.end()) {
+ dpy->second.Layers.erase(layer);
+ }
+ }
+
+ return static_cast<Error>(error);
+}
+
+Return<void> QtiComposerClient::getActiveConfig(uint64_t display, getActiveConfig_cb _hidl_cb) {
+ uint32_t config = 0;
+ auto error = hwc_session_->GetActiveConfig(display, &config);
+
+ _hidl_cb(static_cast<Error>(error), config);
+
+ return Void();
+}
+
+Return<Error> QtiComposerClient::getClientTargetSupport(uint64_t display, uint32_t width,
+ uint32_t height,
+ common_V1_0::PixelFormat format,
+ common_V1_0::Dataspace dataspace) {
+ auto error = hwc_session_->GetClientTargetSupport(display, width, height,
+ static_cast<int32_t>(format),
+ static_cast<int32_t>(dataspace));
+
+ return static_cast<Error>(error);
+}
+
+Return<void> QtiComposerClient::getColorModes(uint64_t display, getColorModes_cb _hidl_cb) {
+ // TODO(user): Implement combinedly w.r.t getColorModes_2_3
+ hidl_vec<common_V1_0::ColorMode> modes;
+ uint32_t count = 0;
+
+ auto error = hwc_session_->GetColorModes(display, &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), modes);
+ return Void();
+ }
+
+ modes.resize(count);
+ error = hwc_session_->GetColorModes(display, &count,
+ reinterpret_cast<std::underlying_type<common_V1_0::ColorMode>::type*>(modes.data()));
+
+ _hidl_cb(static_cast<Error>(error), modes);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getDisplayAttribute(uint64_t display, uint32_t config,
+ composer_V2_1::IComposerClient::Attribute attribute,
+ getDisplayAttribute_cb _hidl_cb) {
+ int32_t value = 0;
+ auto error = hwc_session_->GetDisplayAttribute(display, config, static_cast<int32_t>(attribute),
+ &value);
+
+ _hidl_cb(static_cast<Error>(error), value);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getDisplayConfigs(uint64_t display,
+ getDisplayConfigs_cb _hidl_cb) {
+ hidl_vec<uint32_t> configs;
+ uint32_t count = 0;
+
+ auto error = hwc_session_->GetDisplayConfigs(display, &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), configs);
+ return Void();
+ }
+
+ configs.resize(count);
+ error = hwc_session_->GetDisplayConfigs(display, &count, configs.data());
+
+ _hidl_cb(static_cast<Error>(error), configs);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getDisplayName(uint64_t display, getDisplayName_cb _hidl_cb) {
+ uint32_t count = 0;
+ hidl_string name_reply;
+ std::vector<char> name;
+
+ auto error = hwc_session_->GetDisplayName(display, &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), name_reply);
+ return Void();
+ }
+
+ name.resize(count + 1);
+ error = hwc_session_->GetDisplayName(display, &count, name.data());
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), name_reply);
+ return Void();
+ }
+
+ name.resize(count + 1);
+ name[count] = '\0';
+ name_reply.setToExternal(name.data(), count);
+
+ _hidl_cb(static_cast<Error>(error), name_reply);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getDisplayType(uint64_t display, getDisplayType_cb _hidl_cb) {
+ int32_t hwc_type;
+ auto error = hwc_session_->GetDisplayType(display, &hwc_type);
+
+ _hidl_cb(static_cast<Error>(error), static_cast<IComposerClient::DisplayType>(hwc_type));
+ return Void();
+}
+
+Return<void> QtiComposerClient::getDozeSupport(uint64_t display, getDozeSupport_cb _hidl_cb) {
+ int32_t hwc_support = 0;
+ auto error = hwc_session_->GetDozeSupport(display, &hwc_support);
+
+ _hidl_cb(static_cast<Error>(error), hwc_support);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getHdrCapabilities(uint64_t display,
+ getHdrCapabilities_cb _hidl_cb) {
+ // TODO(user): Implement combinedly w.r.t getHdrCapabilities_2_3
+ uint32_t count = 0;
+ hidl_vec<common_V1_0::Hdr> types;
+ float max_lumi = 0.0f;
+ float max_avg_lumi = 0.0f;
+ float min_lumi = 0.0f;
+
+ auto error = hwc_session_->GetHdrCapabilities(display, &count, nullptr, &max_lumi,
+ &max_avg_lumi, &min_lumi);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
+ return Void();
+ }
+
+ types.resize(count);
+ error = hwc_session_->GetHdrCapabilities(display, &count,
+ reinterpret_cast<std::underlying_type<common_V1_2::Hdr>::type*>(types.data()),
+ &max_lumi, &max_avg_lumi, &min_lumi);
+
+ _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
+ return Void();
+}
+
+Return<Error> QtiComposerClient::setClientTargetSlotCount(uint64_t display,
+ uint32_t clientTargetSlotCount) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ auto dpy = mDisplayData.find(display);
+ if (dpy == mDisplayData.end()) {
+ return Error::BAD_DISPLAY;
+ }
+ dpy->second.ClientTargets.resize(clientTargetSlotCount);
+
+ return Error::NONE;
+}
+
+Return<Error> QtiComposerClient::setActiveConfig(uint64_t display, uint32_t config) {
+ auto error = hwc_session_->SetActiveConfig(display, config);
+
+ return static_cast<Error>(error);
+}
+
+Return<Error> QtiComposerClient::setColorMode(uint64_t display, common_V1_0::ColorMode mode) {
+ auto error = hwc_session_->SetColorMode(display, static_cast<int32_t>(mode));
+
+ return static_cast<Error>(error);
+}
+
+Return<Error> QtiComposerClient::setPowerMode(uint64_t display,
+ composer_V2_1::IComposerClient::PowerMode mode) {
+ // TODO(user): Implement combinedly w.r.t setPowerMode_2_2
+ auto error = hwc_session_->SetPowerMode(display, static_cast<int32_t>(mode));
+
+ return static_cast<Error>(error);
+}
+
+Return<Error> QtiComposerClient::setVsyncEnabled(uint64_t display,
+ composer_V2_1::IComposerClient::Vsync enabled) {
+ auto error = hwc_session_->SetVsyncEnabled(display, static_cast<int32_t>(enabled));
+
+ return static_cast<Error>(error);
+}
+
+Return<Error> QtiComposerClient::setInputCommandQueue(
+ const MQDescriptorSync<uint32_t>& descriptor) {
+ std::lock_guard<std::mutex> lock(mCommandMutex);
+ return mReader.setMQDescriptor(descriptor) ? Error::NONE : Error::NO_RESOURCES;
+}
+
+Return<void> QtiComposerClient::getOutputCommandQueue(getOutputCommandQueue_cb _hidl_cb) {
+ // no locking as we require this function to be called inside
+ // executeCommands_cb
+
+ auto outDescriptor = mWriter.getMQDescriptor();
+ if (outDescriptor) {
+ _hidl_cb(Error::NONE, *outDescriptor);
+ } else {
+ _hidl_cb(Error::NO_RESOURCES, MQDescriptorSync<uint32_t>());
+ }
+
+ return Void();
+}
+
+Return<void> QtiComposerClient::executeCommands(uint32_t inLength,
+ const hidl_vec<hidl_handle>& inHandles,
+ executeCommands_cb _hidl_cb) {
+ std::lock_guard<std::mutex> lock(mCommandMutex);
+
+ bool outChanged = false;
+ uint32_t outLength = 0;
+ hidl_vec<hidl_handle> outHandles;
+
+ if (!mReader.readQueue(inLength, inHandles)) {
+ _hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
+ return Void();
+ }
+
+ Error err = mReader.parse();
+ if (err == Error::NONE &&
+ !mWriter.writeQueue(outChanged, outLength, outHandles)) {
+ err = Error::NO_RESOURCES;
+ }
+
+ _hidl_cb(Error::NONE, outChanged, outLength, outHandles);
+
+ mReader.reset();
+ mWriter.reset();
+
+ return Void();
+}
+
+
+// Methods from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
+Return<void> QtiComposerClient::getPerFrameMetadataKeys(uint64_t display,
+ getPerFrameMetadataKeys_cb _hidl_cb) {
+ // TODO(user): Implement combinedly w.r.t getPerFrameMetadataKeys_2_3
+ std::vector<PerFrameMetadataKey_V2> keys;
+ uint32_t count = 0;
+
+ auto error = hwc_session_->GetPerFrameMetadataKeys(display, &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), keys);
+ return Void();
+ }
+
+ keys.resize(count);
+ error = hwc_session_->GetPerFrameMetadataKeys(display, &count,
+ reinterpret_cast<std::underlying_type<PerFrameMetadataKey_V2>::type*>(keys.data()));
+
+ _hidl_cb(static_cast<Error>(error), keys);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getReadbackBufferAttributes(uint64_t display,
+ getReadbackBufferAttributes_cb _hidl_cb) {
+ // TODO(user): Implement combinedly w.r.t getReadbackBufferAttributes_2_3
+ int32_t format = 0;
+ int32_t dataspace = 0;
+
+ auto error = hwc_session_->GetReadbackBufferAttributes(display, &format, &dataspace);
+
+ if (error != HWC2_ERROR_NONE) {
+ format = 0;
+ dataspace = 0;
+ }
+
+ _hidl_cb(static_cast<Error>(error), static_cast<common_V1_1::PixelFormat>(format),
+ static_cast<common_V1_1::Dataspace>(dataspace));
+ return Void();
+}
+
+Return<void> QtiComposerClient::getReadbackBufferFence(uint64_t display,
+ getReadbackBufferFence_cb _hidl_cb) {
+ int32_t Fd = -1;
+ auto error = hwc_session_->GetReadbackBufferFence(display, &Fd);
+ if (static_cast<Error>(error) != Error::NONE) {
+ _hidl_cb(static_cast<Error>(error), nullptr);
+ return Void();
+ }
+
+ android::base::unique_fd fenceFd;
+ fenceFd.reset(Fd);
+ NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
+
+ _hidl_cb(static_cast<Error>(error), getFenceHandle(fenceFd, fenceStorage));
+ return Void();
+}
+
+Return<Error> QtiComposerClient::setReadbackBuffer(uint64_t display, const hidl_handle& buffer,
+ const hidl_handle& releaseFence) {
+ android::base::unique_fd fenceFd;
+ Error error = getFenceFd(releaseFence, &fenceFd);
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ const native_handle_t* readbackBuffer;
+ getDisplayReadbackBuffer(display, buffer.getNativeHandle(), &readbackBuffer);
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ auto err = hwc_session_->SetReadbackBuffer(display, readbackBuffer, std::move(fenceFd));
+ return static_cast<Error>(err);
+}
+
+Return<void> QtiComposerClient::createVirtualDisplay_2_2(uint32_t width, uint32_t height,
+ common_V1_1::PixelFormat formatHint,
+ uint32_t outputBufferSlotCount,
+ createVirtualDisplay_2_2_cb _hidl_cb) {
+ int32_t format = static_cast<int32_t>(formatHint);
+ uint64_t display;
+ auto error = hwc_session_->CreateVirtualDisplay(width, height, &format, &display);
+
+ if (static_cast<Error>(error) == Error::NONE) {
+ std::lock_guard<std::mutex> lock(mDisplayDataMutex);
+
+ auto dpy = mDisplayData.emplace(static_cast<Display>(display), DisplayData(true)).first;
+ dpy->second.OutputBuffers.resize(outputBufferSlotCount);
+ }
+
+ _hidl_cb(static_cast<Error>(error), display, static_cast<common_V1_1::PixelFormat>(format));
+ return Void();
+}
+
+Return<Error> QtiComposerClient::getClientTargetSupport_2_2(uint64_t display, uint32_t width,
+ uint32_t height,
+ common_V1_1::PixelFormat format,
+ common_V1_1::Dataspace dataspace) {
+ auto error = hwc_session_->GetClientTargetSupport(display, width, height,
+ static_cast<int32_t>(format),
+ static_cast<int32_t>(dataspace));
+
+ return static_cast<Error>(error);
+}
+
+Return<Error> QtiComposerClient::setPowerMode_2_2(uint64_t display,
+ composer_V2_2::IComposerClient::PowerMode mode) {
+ if (mode == IComposerClient::PowerMode::ON_SUSPEND) {
+ return Error::UNSUPPORTED;
+ }
+ auto error = hwc_session_->SetPowerMode(display, static_cast<int32_t>(mode));
+
+ return static_cast<Error>(error);
+}
+
+Return<void> QtiComposerClient::getColorModes_2_2(uint64_t display,
+ getColorModes_2_2_cb _hidl_cb) {
+ // TODO(user): Implement combinedly w.r.t getColorModes_2_3
+ hidl_vec<common_V1_1::ColorMode> modes;
+ uint32_t count = 0;
+
+ auto error = hwc_session_->GetColorModes(display, &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), modes);
+ return Void();
+ }
+
+ modes.resize(count);
+ error = hwc_session_->GetColorModes(display, &count,
+ reinterpret_cast<std::underlying_type<common_V1_1::ColorMode>::type*>(modes.data()));
+
+ _hidl_cb(static_cast<Error>(error), modes);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getRenderIntents(uint64_t display, common_V1_1::ColorMode mode,
+ getRenderIntents_cb _hidl_cb) {
+ // TODO(user): Implement combinedly w.r.t getRenderIntents_2_3
+ uint32_t count = 0;
+ std::vector<RenderIntent> intents;
+
+ auto error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), intents);
+ return Void();
+ }
+
+ intents.resize(count);
+ error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count,
+ reinterpret_cast<std::underlying_type<RenderIntent>::type*>(intents.data()));
+
+ _hidl_cb(static_cast<Error>(error), intents);
+ return Void();
+}
+
+Return<Error> QtiComposerClient::setColorMode_2_2(uint64_t display, common_V1_1::ColorMode mode,
+ common_V1_1::RenderIntent intent) {
+ auto error = hwc_session_->SetColorModeWithRenderIntent(display, static_cast<int32_t>(mode),
+ static_cast<int32_t>(intent));
+
+ return static_cast<Error>(error);
+}
+
+Return<void> QtiComposerClient::getDataspaceSaturationMatrix(common_V1_1::Dataspace dataspace,
+ getDataspaceSaturationMatrix_cb _hidl_cb) {
+ if (dataspace != common_V1_1::Dataspace::SRGB_LINEAR) {
+ _hidl_cb(Error::BAD_PARAMETER, std::array<float, 16>{0.0f}.data());
+ return Void();
+ }
+
+ std::array<float, 16> matrix;
+ int32_t error = HWC2_ERROR_UNSUPPORTED;
+ error = hwc_session_->GetDataspaceSaturationMatrix(static_cast<int32_t>(dataspace),
+ matrix.data());
+ if (error != HWC2_ERROR_NONE) {
+ matrix = {
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+ };
+ }
+ _hidl_cb(Error::NONE, matrix.data());
+ return Void();
+}
+
+Return<void> QtiComposerClient::executeCommands_2_2(uint32_t inLength,
+ const hidl_vec<hidl_handle>& inHandles,
+ executeCommands_2_2_cb _hidl_cb) {
+ std::lock_guard<std::mutex> lock(mCommandMutex);
+
+ bool outChanged = false;
+ uint32_t outLength = 0;
+ hidl_vec<hidl_handle> outHandles;
+
+ if (!mReader.readQueue(inLength, inHandles)) {
+ _hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
+ return Void();
+ }
+
+ Error err = mReader.parse();
+ if (err == Error::NONE &&
+ !mWriter.writeQueue(outChanged, outLength, outHandles)) {
+ err = Error::NO_RESOURCES;
+ }
+
+ _hidl_cb(Error::NONE, outChanged, outLength, outHandles);
+
+ mReader.reset();
+ mWriter.reset();
+
+ return Void();
+}
+
+
+// Methods from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
+Return<void> QtiComposerClient::getDisplayIdentificationData(uint64_t display,
+ getDisplayIdentificationData_cb _hidl_cb) {
+ uint8_t port = 0;
+ uint32_t size = 0;
+ std::vector<uint8_t> data(size);
+
+ auto error = hwc_session_->GetDisplayIdentificationData(display, &port, &size, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), port, data);
+ return Void();
+ }
+
+ data.resize(size);
+ error = hwc_session_->GetDisplayIdentificationData(display, &port, &size, data.data());
+
+ _hidl_cb(static_cast<Error>(error), port, data);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getReadbackBufferAttributes_2_3(uint64_t display,
+ getReadbackBufferAttributes_2_3_cb _hidl_cb) {
+ int32_t format = 0;
+ int32_t dataspace = 0;
+
+ auto error = hwc_session_->GetReadbackBufferAttributes(display, &format, &dataspace);
+
+ if (error != HWC2_ERROR_NONE) {
+ format = 0;
+ dataspace = 0;
+ }
+
+ _hidl_cb(static_cast<Error>(error), static_cast<common_V1_2::PixelFormat>(format),
+ static_cast<common_V1_2::Dataspace>(dataspace));
+ return Void();
+}
+
+Return<Error> QtiComposerClient::getClientTargetSupport_2_3(uint64_t display, uint32_t width,
+ uint32_t height,
+ common_V1_2::PixelFormat format,
+ common_V1_2::Dataspace dataspace) {
+ auto error = hwc_session_->GetClientTargetSupport(display, width, height,
+ static_cast<int32_t>(format),
+ static_cast<int32_t>(dataspace));
+
+ return static_cast<Error>(error);
+}
+
+Return<void> QtiComposerClient::getDisplayedContentSamplingAttributes(uint64_t display,
+ getDisplayedContentSamplingAttributes_cb _hidl_cb) {
+ // getDisplayedContentSamplingAttributes is not supported
+ int constexpr invalid = -1;
+ auto error = Error::UNSUPPORTED;
+ common_V1_2::PixelFormat format = static_cast<common_V1_2::PixelFormat>(invalid);
+ common_V1_2::Dataspace dataspace = static_cast<common_V1_2::Dataspace>(invalid);
+ hidl_bitfield<IComposerClient::FormatColorComponent> componentMask =
+ static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(invalid);
+
+ _hidl_cb(error, format, dataspace, componentMask);
+ return Void();
+}
+
+Return<Error> QtiComposerClient::setDisplayedContentSamplingEnabled(uint64_t display,
+ composer_V2_3::IComposerClient::DisplayedContentSampling enable,
+ hidl_bitfield<FormatColorComponent> componentMask,
+ uint64_t maxFrames) {
+ // setDisplayedContentSamplingEnabled is not supported
+ return Error::UNSUPPORTED;
+}
+
+Return<void> QtiComposerClient::getDisplayedContentSample(uint64_t display, uint64_t maxFrames,
+ uint64_t timestamp,
+ getDisplayedContentSample_cb _hidl_cb) {
+ // getDisplayedContentSample is not supported
+ auto error = Error::UNSUPPORTED;
+ uint64_t frameCount = 0;
+ hidl_vec<uint64_t> sampleComponent0 = 0;
+ hidl_vec<uint64_t> sampleComponent1 = 0;
+ hidl_vec<uint64_t> sampleComponent2 = 0;
+ hidl_vec<uint64_t> sampleComponent3 = 0;
+
+ _hidl_cb(error, frameCount, sampleComponent0, sampleComponent1, sampleComponent2,
+ sampleComponent3);
+ return Void();
+}
+
+Return<void> QtiComposerClient::executeCommands_2_3(uint32_t inLength,
+ const hidl_vec<hidl_handle>& inHandles,
+ executeCommands_2_3_cb _hidl_cb) {
+ // TODO(user): Implement combinedly w.r.t executeCommands_2_2
+ std::lock_guard<std::mutex> lock(mCommandMutex);
+
+ bool outChanged = false;
+ uint32_t outLength = 0;
+ hidl_vec<hidl_handle> outHandles;
+
+ if (!mReader.readQueue(inLength, inHandles)) {
+ _hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
+ return Void();
+ }
+
+ Error err = mReader.parse();
+ if (err == Error::NONE &&
+ !mWriter.writeQueue(outChanged, outLength, outHandles)) {
+ err = Error::NO_RESOURCES;
+ }
+
+ _hidl_cb(Error::NONE, outChanged, outLength, outHandles);
+
+ mReader.reset();
+ mWriter.reset();
+
+ return Void();
+}
+
+Return<void> QtiComposerClient::getRenderIntents_2_3(uint64_t display, common_V1_2::ColorMode mode,
+ getRenderIntents_2_3_cb _hidl_cb) {
+ uint32_t count = 0;
+ std::vector<RenderIntent> intents;
+
+ auto error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), intents);
+ return Void();
+ }
+
+ intents.resize(count);
+ error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count,
+ reinterpret_cast<std::underlying_type<RenderIntent>::type*>(intents.data()));
+
+ _hidl_cb(static_cast<Error>(error), intents);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getColorModes_2_3(uint64_t display,
+ getColorModes_2_3_cb _hidl_cb) {
+ hidl_vec<common_V1_2::ColorMode> modes;
+ uint32_t count = 0;
+
+ auto error = hwc_session_->GetColorModes(display, &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), modes);
+ return Void();
+ }
+
+ modes.resize(count);
+ error = hwc_session_->GetColorModes(display, &count,
+ reinterpret_cast<std::underlying_type<common_V1_2::ColorMode>::type*>(modes.data()));
+
+ _hidl_cb(static_cast<Error>(error), modes);
+ return Void();
+}
+
+Return<Error> QtiComposerClient::setColorMode_2_3(uint64_t display, common_V1_2::ColorMode mode,
+ common_V1_1::RenderIntent intent) {
+ auto error = hwc_session_->SetColorModeWithRenderIntent(display, static_cast<int32_t>(mode),
+ static_cast<int32_t>(intent));
+
+ return static_cast<Error>(error);
+}
+
+Return<void> QtiComposerClient::getDisplayCapabilities(uint64_t display,
+ getDisplayCapabilities_cb _hidl_cb) {
+ hidl_vec<IComposerClient::DisplayCapability> capabilities;
+ uint32_t count = 0;
+ auto error = hwc_session_->GetDisplayCapabilities(display, &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), capabilities);
+ return Void();
+ }
+
+ capabilities.resize(count);
+ error = hwc_session_->GetDisplayCapabilities(display, &count,
+ reinterpret_cast<std::underlying_type<IComposerClient::DisplayCapability>::type*>(
+ capabilities.data()));
+ if (error != HWC2_ERROR_NONE) {
+ capabilities = hidl_vec<IComposerClient::DisplayCapability>();
+ _hidl_cb(static_cast<Error>(error), capabilities);
+ return Void();
+ }
+
+ _hidl_cb(static_cast<Error>(error), capabilities);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getPerFrameMetadataKeys_2_3(uint64_t display,
+ getPerFrameMetadataKeys_2_3_cb _hidl_cb) {
+ std::vector<PerFrameMetadataKey> keys;
+ uint32_t count = 0;
+
+ auto error = hwc_session_->GetPerFrameMetadataKeys(display, &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), keys);
+ return Void();
+ }
+
+ keys.resize(count);
+ error = hwc_session_->GetPerFrameMetadataKeys(display, &count,
+ reinterpret_cast<std::underlying_type<PerFrameMetadataKey>::type*>(keys.data()));
+
+ _hidl_cb(static_cast<Error>(error), keys);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getHdrCapabilities_2_3(uint64_t display,
+ getHdrCapabilities_2_3_cb _hidl_cb) {
+ uint32_t count = 0;
+ hidl_vec<common_V1_2::Hdr> types;
+ float max_lumi = 0.0f;
+ float max_avg_lumi = 0.0f;
+ float min_lumi = 0.0f;
+
+ auto error = hwc_session_->GetHdrCapabilities(display, &count, nullptr, &max_lumi,
+ &max_avg_lumi, &min_lumi);
+ if (error != HWC2_ERROR_NONE) {
+ _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
+ return Void();
+ }
+
+ types.resize(count);
+ error = hwc_session_->GetHdrCapabilities(display, &count,
+ reinterpret_cast<std::underlying_type<common_V1_2::Hdr>::type*>(types.data()),
+ &max_lumi, &max_avg_lumi, &min_lumi);
+
+ _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
+ return Void();
+}
+
+Return<void> QtiComposerClient::getDisplayBrightnessSupport(uint64_t display,
+ getDisplayBrightnessSupport_cb _hidl_cb) {
+ bool support = false;
+ auto error = hwc_session_->GetDisplayBrightnessSupport(display, &support);
+
+ _hidl_cb(static_cast<Error>(error), support);
+ return Void();
+}
+
+Return<Error> QtiComposerClient::setDisplayBrightness(uint64_t display, float brightness) {
+ if (std::isnan(brightness) || brightness > 1.0f || (brightness < 0.0f && brightness != -1.0f)) {
+ return Error::BAD_PARAMETER;
+ }
+
+ auto error = hwc_session_->SetDisplayBrightness(display, brightness);
+ return static_cast<Error>(error);
+}
+
+QtiComposerClient::CommandReader::CommandReader(QtiComposerClient& client)
+ : mClient(client), mWriter(client.mWriter) {
+}
+
+Error QtiComposerClient::CommandReader::parse() {
+ IComposerClient::Command command;
+ uint16_t length;
+
+ while (!isEmpty()) {
+ if (!beginCommand(command, length)) {
+ break;
+ }
+
+ bool parsed = false;
+ switch (command) {
+ // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
+ case IComposerClient::Command::SELECT_DISPLAY:
+ parsed = parseSelectDisplay(length);
+ break;
+ case IComposerClient::Command::SELECT_LAYER:
+ parsed = parseSelectLayer(length);
+ break;
+ case IComposerClient::Command::SET_COLOR_TRANSFORM:
+ parsed = parseSetColorTransform(length);
+ break;
+ case IComposerClient::Command::SET_CLIENT_TARGET:
+ parsed = parseSetClientTarget(length);
+ break;
+ case IComposerClient::Command::SET_OUTPUT_BUFFER:
+ parsed = parseSetOutputBuffer(length);
+ break;
+ case IComposerClient::Command::VALIDATE_DISPLAY:
+ parsed = parseValidateDisplay(length);
+ break;
+ case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
+ parsed = parseAcceptDisplayChanges(length);
+ break;
+ case IComposerClient::Command::PRESENT_DISPLAY:
+ parsed = parsePresentDisplay(length);
+ break;
+ case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
+ parsed = parsePresentOrValidateDisplay(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
+ parsed = parseSetLayerCursorPosition(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_BUFFER:
+ parsed = parseSetLayerBuffer(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
+ parsed = parseSetLayerSurfaceDamage(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_BLEND_MODE:
+ parsed = parseSetLayerBlendMode(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_COLOR:
+ parsed = parseSetLayerColor(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
+ parsed = parseSetLayerCompositionType(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_DATASPACE:
+ parsed = parseSetLayerDataspace(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
+ parsed = parseSetLayerDisplayFrame(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
+ parsed = parseSetLayerPlaneAlpha(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
+ parsed = parseSetLayerSidebandStream(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
+ parsed = parseSetLayerSourceCrop(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_TRANSFORM:
+ parsed = parseSetLayerTransform(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
+ parsed = parseSetLayerVisibleRegion(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_Z_ORDER:
+ parsed = parseSetLayerZOrder(length);
+ break;
+ // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
+ case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA:
+ parsed = parseSetLayerPerFrameMetadata(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_FLOAT_COLOR:
+ parsed = parseSetLayerFloatColor(length);
+ break;
+ // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
+ case IComposerClient::Command::SET_LAYER_COLOR_TRANSFORM:
+ parsed = parseSetLayerColorTransform(length);
+ break;
+ case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS:
+ parsed = parseSetLayerPerFrameMetadataBlobs(length);
+ break;
+ default:
+ parsed = false;
+ break;
+ }
+
+ endCommand();
+
+ if (!parsed) {
+ ALOGE("failed to parse command 0x%x, length %" PRIu16,
+ command, length);
+ break;
+ }
+ }
+
+ return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
+}
+
+bool QtiComposerClient::CommandReader::parseSelectDisplay(uint16_t length) {
+ if (length != CommandWriter::kSelectDisplayLength) {
+ return false;
+ }
+
+ mDisplay = read64();
+ mWriter.selectDisplay(mDisplay);
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSelectLayer(uint16_t length) {
+ if (length != CommandWriter::kSelectLayerLength) {
+ return false;
+ }
+
+ mLayer = read64();
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetColorTransform(uint16_t length) {
+ if (length != CommandWriter::kSetColorTransformLength) {
+ return false;
+ }
+
+ float matrix[16];
+ for (int i = 0; i < 16; i++) {
+ matrix[i] = readFloat();
+ }
+ auto transform = readSigned();
+
+ auto err = mClient.hwc_session_->SetColorTransform(mDisplay, matrix, transform);
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetClientTarget(uint16_t length) {
+ // 4 parameters followed by N rectangles
+ if ((length - 4) % 4 != 0) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto clientTarget = readHandle(useCache);
+ auto fence = readFence();
+ auto dataspace = readSigned();
+ auto damage = readRegion((length - 4) / 4);
+ bool closeFence = true;
+ hwc_region region = {damage.size(), damage.data()};
+ auto err = lookupBuffer(BufferCache::CLIENT_TARGETS, slot, useCache, clientTarget, &clientTarget);
+ if (err == Error::NONE) {
+ auto error = mClient.hwc_session_->SetClientTarget(mDisplay, clientTarget, fence,
+ dataspace, region);
+ err = static_cast<Error>(error);
+ auto updateBufErr = updateBuffer(BufferCache::CLIENT_TARGETS, slot,
+ useCache, clientTarget);
+ if (err == Error::NONE) {
+ closeFence = false;
+ err = updateBufErr;
+ }
+ }
+ if (closeFence) {
+ close(fence);
+ }
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length) {
+ if (length != CommandWriter::kSetOutputBufferLength) {
+ return false;
+ }
+
+ bool useCache;
+ auto slot = read();
+ auto outputBuffer = readHandle(useCache);
+ auto fence = readFence();
+ bool closeFence = true;
+
+ auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS, slot, useCache, outputBuffer, &outputBuffer);
+ if (err == Error::NONE) {
+ auto error = mClient.hwc_session_->SetOutputBuffer(mDisplay, outputBuffer, fence);
+ err = static_cast<Error>(error);
+ auto updateBufErr = updateBuffer(BufferCache::OUTPUT_BUFFERS, slot, useCache, outputBuffer);
+ if (err == Error::NONE) {
+ closeFence = false;
+ err = updateBufErr;
+ }
+ }
+ if (closeFence) {
+ close(fence);
+ }
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+Error QtiComposerClient::CommandReader::validateDisplay(Display display,
+ std::vector<Layer>& changedLayers,
+ std::vector<IComposerClient::Composition>& compositionTypes,
+ uint32_t& displayRequestMask,
+ std::vector<Layer>& requestedLayers,
+ std::vector<uint32_t>& requestMasks) {
+ uint32_t types_count = 0;
+ uint32_t reqs_count = 0;
+
+ auto err = mClient.hwc_session_->ValidateDisplay(mDisplay, &types_count, &reqs_count);
+ if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) {
+ return static_cast<Error>(err);
+ }
+
+ err = mClient.hwc_session_->GetChangedCompositionTypes(mDisplay, &types_count, nullptr, nullptr);
+ if (err != HWC2_ERROR_NONE) {
+ return static_cast<Error>(err);
+ }
+
+ changedLayers.resize(types_count);
+ compositionTypes.resize(types_count);
+ err = mClient.hwc_session_->GetChangedCompositionTypes(mDisplay, &types_count,
+ changedLayers.data(),
+ reinterpret_cast<std::underlying_type<IComposerClient::Composition>::type*>(
+ compositionTypes.data()));
+
+ if (err != HWC2_ERROR_NONE) {
+ changedLayers.clear();
+ compositionTypes.clear();
+ return static_cast<Error>(err);
+ }
+
+ int32_t display_reqs = 0;
+ err = mClient.hwc_session_->GetDisplayRequests(mDisplay, &display_reqs, &reqs_count, nullptr,
+ nullptr);
+ if (err != HWC2_ERROR_NONE) {
+ changedLayers.clear();
+ compositionTypes.clear();
+ return static_cast<Error>(err);
+ }
+
+ requestedLayers.resize(reqs_count);
+ requestMasks.resize(reqs_count);
+ err = mClient.hwc_session_->GetDisplayRequests(mDisplay, &display_reqs, &reqs_count,
+ requestedLayers.data(),
+ reinterpret_cast<int32_t*>(requestMasks.data()));
+ if (err != HWC2_ERROR_NONE) {
+ changedLayers.clear();
+ compositionTypes.clear();
+
+ requestedLayers.clear();
+ requestMasks.clear();
+ return static_cast<Error>(err);
+ }
+
+ displayRequestMask = display_reqs;
+
+ return static_cast<Error>(err);
+}
+
+bool QtiComposerClient::CommandReader::parseValidateDisplay(uint16_t length) {
+ if (length != CommandWriter::kValidateDisplayLength) {
+ return false;
+ }
+
+ std::vector<Layer> changedLayers;
+ std::vector<IComposerClient::Composition> compositionTypes;
+ uint32_t displayRequestMask;
+ std::vector<Layer> requestedLayers;
+ std::vector<uint32_t> requestMasks;
+
+ auto err = validateDisplay(mDisplay, changedLayers, compositionTypes, displayRequestMask,
+ requestedLayers, requestMasks);
+
+ if (static_cast<Error>(err) == Error::NONE) {
+ mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
+ mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
+ } else {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length) {
+ if (length != CommandWriter::kAcceptDisplayChangesLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->AcceptDisplayChanges(mDisplay);
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+Error QtiComposerClient::CommandReader::presentDisplay(Display display, int32_t& presentFence,
+ std::vector<Layer>& layers,
+ std::vector<int32_t>& releaseFences) {
+ int32_t err = mClient.hwc_session_->PresentDisplay(display, &presentFence);
+ if (err != HWC2_ERROR_NONE) {
+ return static_cast<Error>(err);
+ }
+
+ uint32_t count = 0;
+ err = mClient.hwc_session_->GetReleaseFences(display, &count, nullptr, nullptr);
+ if (err != HWC2_ERROR_NONE) {
+ ALOGW("failed to get release fences");
+ return Error::NONE;
+ }
+
+ layers.resize(count);
+ releaseFences.resize(count);
+ err = mClient.hwc_session_->GetReleaseFences(display, &count, layers.data(),
+ releaseFences.data());
+ if (err != HWC2_ERROR_NONE) {
+ ALOGW("failed to get release fences");
+ layers.clear();
+ releaseFences.clear();
+ return Error::NONE;
+ }
+
+ return static_cast<Error>(err);
+}
+
+bool QtiComposerClient::CommandReader::parsePresentDisplay(uint16_t length) {
+ if (length != CommandWriter::kPresentDisplayLength) {
+ return false;
+ }
+
+ int presentFence;
+ std::vector<Layer> layers;
+ std::vector<int> fences;
+
+ auto err = presentDisplay(mDisplay, presentFence, layers, fences);
+ if (err == Error::NONE) {
+ mWriter.setPresentFence(presentFence);
+ mWriter.setReleaseFences(layers, fences);
+ } else {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length) {
+ if (length != CommandWriter::kPresentOrValidateDisplayLength) {
+ return false;
+ }
+
+ // First try to Present as is.
+ mClient.getCapabilities();
+ if (mClient.hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
+ int presentFence = -1;
+ std::vector<Layer> layers;
+ std::vector<int> fences;
+ auto err = presentDisplay(mDisplay, presentFence, layers, fences);
+ if (err == Error::NONE) {
+ mWriter.setPresentOrValidateResult(1);
+ mWriter.setPresentFence(presentFence);
+ mWriter.setReleaseFences(layers, fences);
+ return true;
+ }
+ }
+
+ // Present has failed. We need to fallback to validate
+ std::vector<Layer> changedLayers;
+ std::vector<IComposerClient::Composition> compositionTypes;
+ uint32_t displayRequestMask = 0x0;
+ std::vector<Layer> requestedLayers;
+ std::vector<uint32_t> requestMasks;
+
+ auto err = validateDisplay(mDisplay, changedLayers, compositionTypes, displayRequestMask,
+ requestedLayers, requestMasks);
+ // mResources->setDisplayMustValidateState(mDisplay, false);
+ if (err == Error::NONE) {
+ mWriter.setPresentOrValidateResult(0);
+ mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
+ mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
+ } else {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length) {
+ if (length != CommandWriter::kSetLayerCursorPositionLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->SetCursorPosition(mDisplay, mLayer, readSigned(), readSigned());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length) {
+ if (length != CommandWriter::kSetLayerBufferLength) {
+ return false;
+ }
+
+ bool useCache;
+ auto slot = read();
+ auto buffer = readHandle(useCache);
+ auto fence = readFence();
+ bool closeFence = true;
+
+ auto error = lookupBuffer(BufferCache::LAYER_BUFFERS, slot, useCache, buffer, &buffer);
+ if (error == Error::NONE) {
+ auto err = mClient.hwc_session_->SetLayerBuffer(mDisplay, mLayer, buffer, fence);
+ error = static_cast<Error>(err);
+ auto updateBufErr = updateBuffer(BufferCache::LAYER_BUFFERS, slot, useCache, buffer);
+ if (static_cast<Error>(error) == Error::NONE) {
+ closeFence = false;
+ error = updateBufErr;
+ }
+ }
+ if (closeFence) {
+ close(fence);
+ }
+ if (static_cast<Error>(error) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(error));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length) {
+ // N rectangles
+ if (length % 4 != 0) {
+ return false;
+ }
+
+ auto damage = readRegion(length / 4);
+ hwc_region region = {damage.size(), damage.data()};
+ auto err = mClient.hwc_session_->SetLayerSurfaceDamage(mDisplay, mLayer, region);
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length) {
+ if (length != CommandWriter::kSetLayerBlendModeLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->SetLayerBlendMode(mDisplay, mLayer, readSigned());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerColor(uint16_t length) {
+ if (length != CommandWriter::kSetLayerColorLength) {
+ return false;
+ }
+ auto color = readColor();
+ hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
+ auto err = mClient.hwc_session_->SetLayerColor(mDisplay, mLayer, hwc_color);
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerCompositionType(uint16_t length) {
+ if (length != CommandWriter::kSetLayerCompositionTypeLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->SetLayerCompositionType(mDisplay, mLayer, readSigned());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length) {
+ if (length != CommandWriter::kSetLayerDataspaceLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->SetLayerDataspace(mDisplay, mLayer, readSigned());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length) {
+ if (length != CommandWriter::kSetLayerDisplayFrameLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->SetLayerDisplayFrame(mDisplay, mLayer, readRect());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length) {
+ if (length != CommandWriter::kSetLayerPlaneAlphaLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->SetLayerPlaneAlpha(mDisplay, mLayer, readFloat());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length) {
+ if (length != CommandWriter::kSetLayerSidebandStreamLength) {
+ return false;
+ }
+
+ // Sideband stream is not supported
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length) {
+ if (length != CommandWriter::kSetLayerSourceCropLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->SetLayerSourceCrop(mDisplay, mLayer, readFRect());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerTransform(uint16_t length) {
+ if (length != CommandWriter::kSetLayerTransformLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->SetLayerTransform(mDisplay, mLayer, readSigned());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length) {
+ // N rectangles
+ if (length % 4 != 0) {
+ return false;
+ }
+
+ auto region = readRegion(length / 4);
+ hwc_region visibleRegion = {region.size(), region.data()};
+ auto err = mClient.hwc_session_->SetLayerVisibleRegion(mDisplay, mLayer, visibleRegion);
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length) {
+ if (length != CommandWriter::kSetLayerZOrderLength) {
+ return false;
+ }
+
+ auto err = mClient.hwc_session_->SetLayerZOrder(mDisplay, mLayer, read());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerPerFrameMetadata(uint16_t length) {
+ // (key, value) pairs
+ if (length % 2 != 0) {
+ return false;
+ }
+
+ std::vector<IComposerClient::PerFrameMetadata> metadata;
+ metadata.reserve(length / 2);
+ while (length > 0) {
+ metadata.emplace_back(IComposerClient::PerFrameMetadata{
+ static_cast<IComposerClient::PerFrameMetadataKey>(readSigned()),
+ readFloat()});
+ length -= 2;
+ }
+
+ std::vector<int32_t> keys;
+ std::vector<float> values;
+ keys.reserve(metadata.size());
+ values.reserve(metadata.size());
+ for (const auto& m : metadata) {
+ keys.push_back(static_cast<int32_t>(m.key));
+ values.push_back(m.value);
+ }
+
+ auto err = mClient.hwc_session_->SetLayerPerFrameMetadata(mDisplay, mLayer, metadata.size(),
+ keys.data(), values.data());
+ if (static_cast<Error>(err) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerFloatColor(uint16_t length) {
+ if (length != CommandWriter::kSetLayerFloatColorLength) {
+ return false;
+ }
+
+ // setLayerFloatColor is not supported
+ auto err = Error::UNSUPPORTED;
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerColorTransform(uint16_t length) {
+ if (length != CommandWriter::kSetLayerColorTransformLength) {
+ return false;
+ }
+
+ float matrix[16];
+ for (int i = 0; i < 16; i++) {
+ matrix[i] = readFloat();
+ }
+
+ auto error = mClient.hwc_session_->SetLayerColorTransform(mDisplay, mLayer, matrix);
+ if (static_cast<Error>(error) != Error::NONE) {
+ mWriter.setError(getCommandLoc(), static_cast<Error>(error));
+ }
+
+ return true;
+}
+
+bool QtiComposerClient::CommandReader::parseSetLayerPerFrameMetadataBlobs(uint16_t length) {
+ // must have at least one metadata blob
+ // of at least size 1 in queue (i.e {/*numBlobs=*/1, key, size, blob})
+ if (length < 4) {
+ return false;
+ }
+
+ // SetLayerPerFrameMetadataBlobs is not supported
+ auto err = Error::UNSUPPORTED;
+ mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+
+ return true;
+}
+
+hwc_rect_t QtiComposerClient::CommandReader::readRect() {
+ return hwc_rect_t{
+ readSigned(),
+ readSigned(),
+ readSigned(),
+ readSigned(),
+ };
+}
+
+std::vector<hwc_rect_t> QtiComposerClient::CommandReader::readRegion(size_t count) {
+ std::vector<hwc_rect_t> region;
+ region.reserve(count);
+ while (count > 0) {
+ region.emplace_back(readRect());
+ count--;
+ }
+
+ return region;
+}
+
+hwc_frect_t QtiComposerClient::CommandReader::readFRect() {
+ return hwc_frect_t{
+ readFloat(),
+ readFloat(),
+ readFloat(),
+ readFloat(),
+ };
+}
+
+Error QtiComposerClient::CommandReader::lookupBufferCacheEntryLocked(BufferCache cache,
+ uint32_t slot,
+ BufferCacheEntry** outEntry) {
+ auto dpy = mClient.mDisplayData.find(mDisplay);
+ if (dpy == mClient.mDisplayData.end()) {
+ return Error::BAD_DISPLAY;
+ }
+
+ BufferCacheEntry* entry = nullptr;
+ switch (cache) {
+ case BufferCache::CLIENT_TARGETS:
+ if (slot < dpy->second.ClientTargets.size()) {
+ entry = &dpy->second.ClientTargets[slot];
+ }
+ break;
+ case BufferCache::OUTPUT_BUFFERS:
+ if (slot < dpy->second.OutputBuffers.size()) {
+ entry = &dpy->second.OutputBuffers[slot];
+ }
+ break;
+ case BufferCache::LAYER_BUFFERS:
+ {
+ auto ly = dpy->second.Layers.find(mLayer);
+ if (ly == dpy->second.Layers.end()) {
+ return Error::BAD_LAYER;
+ }
+ if (slot < ly->second.Buffers.size()) {
+ entry = &ly->second.Buffers[slot];
+ }
+ }
+ break;
+ case BufferCache::LAYER_SIDEBAND_STREAMS:
+ {
+ auto ly = dpy->second.Layers.find(mLayer);
+ if (ly == dpy->second.Layers.end()) {
+ return Error::BAD_LAYER;
+ }
+ if (slot == 0) {
+ entry = &ly->second.SidebandStream;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!entry) {
+ ALOGW("invalid buffer slot %" PRIu32, slot);
+ return Error::BAD_PARAMETER;
+ }
+
+ *outEntry = entry;
+
+ return Error::NONE;
+}
+
+Error QtiComposerClient::CommandReader::lookupBuffer(BufferCache cache, uint32_t slot,
+ bool useCache, buffer_handle_t handle,
+ buffer_handle_t* outHandle) {
+ if (useCache) {
+ std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
+
+ BufferCacheEntry* entry;
+ Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ // input handle is ignored
+ *outHandle = entry->getHandle();
+ } else if (cache == BufferCache::LAYER_SIDEBAND_STREAMS) {
+ if (handle) {
+ *outHandle = native_handle_clone(handle);
+ if (*outHandle == nullptr) {
+ return Error::NO_RESOURCES;
+ }
+ }
+ } else {
+ if (!mHandleImporter.importBuffer(handle)) {
+ return Error::NO_RESOURCES;
+ }
+
+ *outHandle = handle;
+ }
+
+ return Error::NONE;
+}
+
+Error QtiComposerClient::CommandReader::updateBuffer(BufferCache cache, uint32_t slot,
+ bool useCache, buffer_handle_t handle) {
+ // handle was looked up from cache
+ if (useCache) {
+ return Error::NONE;
+ }
+
+ std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
+
+ BufferCacheEntry* entry = nullptr;
+ Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ *entry = handle;
+ return Error::NONE;
+}
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+IQtiComposerClient* HIDL_FETCH_IQtiComposerClient(const char* /* name */) {
+ return new QtiComposerClient();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace composer
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
diff --git a/composer/QtiComposerClient.h b/composer/QtiComposerClient.h
new file mode 100644
index 0000000..8db39db
--- /dev/null
+++ b/composer/QtiComposerClient.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef __QTICOMPOSERCLIENT_H__
+#define __QTICOMPOSERCLIENT_H__
+
+#include <vendor/qti/hardware/display/composer/1.0/IQtiComposerClient.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <log/log.h>
+#include <unordered_set>
+#include <vector>
+
+#include "hwc_session.h"
+#include "QtiComposerCommandBuffer.h"
+#include "QtiComposerHandleImporter.h"
+
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace composer {
+namespace V1_0 {
+namespace implementation {
+
+namespace common_V1_0 = ::android::hardware::graphics::common::V1_0;
+namespace common_V1_1 = ::android::hardware::graphics::common::V1_1;
+namespace common_V1_2 = ::android::hardware::graphics::common::V1_2;
+
+namespace composer_V2_1 = ::android::hardware::graphics::composer::V2_1;
+namespace composer_V2_2 = ::android::hardware::graphics::composer::V2_2;
+namespace composer_V2_3 = ::android::hardware::graphics::composer::V2_3;
+
+using PerFrameMetadataKey_V2 = composer_V2_2::IComposerClient::PerFrameMetadataKey;
+using PerFrameMetadataKey = composer_V2_3::IComposerClient::PerFrameMetadataKey;
+
+using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_bitfield;
+using ::android::hardware::graphics::composer::V2_1::Error;
+
+using sdm::HWCSession;
+
+class BufferCacheEntry {
+ public:
+ BufferCacheEntry();
+ BufferCacheEntry(BufferCacheEntry&& other);
+
+ BufferCacheEntry(const BufferCacheEntry& other) = delete;
+ BufferCacheEntry& operator=(const BufferCacheEntry& other) = delete;
+
+ BufferCacheEntry& operator=(buffer_handle_t handle);
+ ~BufferCacheEntry();
+
+ buffer_handle_t getHandle() const { return mHandle; }
+
+ private:
+ void clear();
+
+ buffer_handle_t mHandle;
+};
+
+class QtiComposerClient : public IQtiComposerClient {
+ public:
+ QtiComposerClient();
+ virtual ~QtiComposerClient();
+
+ // Methods from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
+ Return<void> registerCallback(const sp<composer_V2_1::IComposerCallback>& callback) override;
+ Return<uint32_t> getMaxVirtualDisplayCount() override;
+ Return<void> createVirtualDisplay(uint32_t width, uint32_t height,
+ common_V1_0::PixelFormat formatHint,
+ uint32_t outputBufferSlotCount,
+ createVirtualDisplay_cb _hidl_cb) override;
+ Return<Error> destroyVirtualDisplay(uint64_t display) override;
+ Return<void> createLayer(uint64_t display, uint32_t bufferSlotCount,
+ createLayer_cb _hidl_cb) override;
+ Return<Error> destroyLayer(uint64_t display, uint64_t layer) override;
+ Return<void> getActiveConfig(uint64_t display, getActiveConfig_cb _hidl_cb) override;
+ Return<Error> getClientTargetSupport(uint64_t display, uint32_t width, uint32_t height,
+ common_V1_0::PixelFormat format,
+ common_V1_0::Dataspace dataspace) override;
+ Return<void> getColorModes(uint64_t display, getColorModes_cb _hidl_cb) override;
+ Return<void> getDisplayAttribute(uint64_t display, uint32_t config,
+ composer_V2_1::IComposerClient::Attribute attribute,
+ getDisplayAttribute_cb _hidl_cb) override;
+ Return<void> getDisplayConfigs(uint64_t display, getDisplayConfigs_cb _hidl_cb) override;
+ Return<void> getDisplayName(uint64_t display, getDisplayName_cb _hidl_cb) override;
+ Return<void> getDisplayType(uint64_t display, getDisplayType_cb _hidl_cb) override;
+ Return<void> getDozeSupport(uint64_t display, getDozeSupport_cb _hidl_cb) override;
+ Return<void> getHdrCapabilities(uint64_t display, getHdrCapabilities_cb _hidl_cb) override;
+ Return<Error> setClientTargetSlotCount(uint64_t display,
+ uint32_t clientTargetSlotCount) override;
+ Return<Error> setActiveConfig(uint64_t display, uint32_t config) override;
+ Return<Error> setColorMode(uint64_t display, common_V1_0::ColorMode mode) override;
+ Return<Error> setPowerMode(uint64_t display,
+ composer_V2_1::IComposerClient::PowerMode mode) override;
+ Return<Error> setVsyncEnabled(uint64_t display,
+ composer_V2_1::IComposerClient::Vsync enabled) override;
+ Return<Error> setInputCommandQueue(const MQDescriptorSync<uint32_t>& descriptor) override;
+ Return<void> getOutputCommandQueue(getOutputCommandQueue_cb _hidl_cb) override;
+ Return<void> executeCommands(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles,
+ executeCommands_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
+ Return<void> getPerFrameMetadataKeys(uint64_t display,
+ getPerFrameMetadataKeys_cb _hidl_cb) override;
+ Return<void> getReadbackBufferAttributes(uint64_t display,
+ getReadbackBufferAttributes_cb _hidl_cb) override;
+ Return<void> getReadbackBufferFence(uint64_t display,
+ getReadbackBufferFence_cb _hidl_cb) override;
+ Return<Error> setReadbackBuffer(uint64_t display, const hidl_handle& buffer,
+ const hidl_handle& releaseFence) override;
+ Return<void> createVirtualDisplay_2_2(uint32_t width, uint32_t height,
+ common_V1_1::PixelFormat formatHint,
+ uint32_t outputBufferSlotCount,
+ createVirtualDisplay_2_2_cb _hidl_cb) override;
+ Return<Error> getClientTargetSupport_2_2(uint64_t display, uint32_t width, uint32_t height,
+ common_V1_1::PixelFormat format,
+ common_V1_1::Dataspace dataspace) override;
+ Return<Error> setPowerMode_2_2(uint64_t display,
+ composer_V2_2::IComposerClient::PowerMode mode) override;
+ Return<void> getColorModes_2_2(uint64_t display, getColorModes_2_2_cb _hidl_cb) override;
+ Return<void> getRenderIntents(uint64_t display, common_V1_1::ColorMode mode,
+ getRenderIntents_cb _hidl_cb) override;
+ Return<Error> setColorMode_2_2(uint64_t display, common_V1_1::ColorMode mode,
+ common_V1_1::RenderIntent intent) override;
+ Return<void> getDataspaceSaturationMatrix(common_V1_1::Dataspace dataspace,
+ getDataspaceSaturationMatrix_cb _hidl_cb) override;
+ Return<void> executeCommands_2_2(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles,
+ executeCommands_2_2_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
+ Return<void> getDisplayIdentificationData(uint64_t display,
+ getDisplayIdentificationData_cb _hidl_cb) override;
+ Return<void> getReadbackBufferAttributes_2_3(uint64_t display,
+ getReadbackBufferAttributes_2_3_cb _hidl_cb) override;
+ Return<Error> getClientTargetSupport_2_3(uint64_t display, uint32_t width, uint32_t height,
+ common_V1_2::PixelFormat format,
+ common_V1_2::Dataspace dataspace) override;
+ Return<void> getDisplayedContentSamplingAttributes(uint64_t display,
+ getDisplayedContentSamplingAttributes_cb _hidl_cb) override;
+ Return<Error> setDisplayedContentSamplingEnabled(uint64_t display,
+ composer_V2_3::IComposerClient::DisplayedContentSampling enable,
+ hidl_bitfield<FormatColorComponent> componentMask,
+ uint64_t maxFrames) override;
+ Return<void> getDisplayedContentSample(uint64_t display, uint64_t maxFrames,
+ uint64_t timestamp,
+ getDisplayedContentSample_cb _hidl_cb) override;
+ Return<void> executeCommands_2_3(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles,
+ executeCommands_2_3_cb _hidl_cb) override;
+ Return<void> getRenderIntents_2_3(uint64_t display, common_V1_2::ColorMode mode,
+ getRenderIntents_2_3_cb _hidl_cb) override;
+ Return<void> getColorModes_2_3(uint64_t display, getColorModes_2_3_cb _hidl_cb) override;
+ Return<Error> setColorMode_2_3(uint64_t display, common_V1_2::ColorMode mode,
+ common_V1_1::RenderIntent intent) override;
+ Return<void> getDisplayCapabilities(uint64_t display,
+ getDisplayCapabilities_cb _hidl_cb) override;
+ Return<void> getPerFrameMetadataKeys_2_3(uint64_t display,
+ getPerFrameMetadataKeys_2_3_cb _hidl_cb) override;
+ Return<void> getHdrCapabilities_2_3(uint64_t display,
+ getHdrCapabilities_2_3_cb _hidl_cb) override;
+ Return<void> getDisplayBrightnessSupport(uint64_t display,
+ getDisplayBrightnessSupport_cb _hidl_cb) override;
+ Return<Error> setDisplayBrightness(uint64_t display, float brightness) override;
+
+ // Methods for RegisterCallback
+ void enableCallback(bool enable);
+ static void onHotplug(hwc2_callback_data_t callbackData, hwc2_display_t display,
+ int32_t connected);
+ static void onRefresh(hwc2_callback_data_t callbackData, hwc2_display_t display);
+ static void onVsync(hwc2_callback_data_t callbackData, hwc2_display_t display,
+ int64_t timestamp);
+
+ // Methods for ConcurrentWriteBack
+ hidl_handle getFenceHandle(const android::base::unique_fd& fenceFd, char* handleStorage);
+ Error getFenceFd(const hidl_handle& fenceHandle, android::base::unique_fd* outFenceFd);
+ Error getDisplayReadbackBuffer(Display display, const native_handle_t* rawHandle,
+ const native_handle_t** outHandle);
+
+ // Methods to check support of specific features like skip_validate
+ std::unordered_set<hwc2_capability_t> mCapabilities;
+ void getCapabilities();
+ bool hasCapability(hwc2_capability_t capability) {
+ return (mCapabilities.count(capability) > 0);
+ }
+
+ private:
+ struct LayerBuffers {
+ std::vector<BufferCacheEntry> Buffers;
+ // the handle is a sideband stream handle, not a buffer handle
+ BufferCacheEntry SidebandStream;
+ };
+
+ struct DisplayData {
+ bool IsVirtual;
+
+ std::vector<BufferCacheEntry> ClientTargets;
+ std::vector<BufferCacheEntry> OutputBuffers;
+
+ std::unordered_map<Layer, LayerBuffers> Layers;
+
+ DisplayData(bool isVirtual) : IsVirtual(isVirtual) {}
+ };
+
+ class CommandReader : public CommandReaderBase {
+ public:
+ CommandReader(QtiComposerClient& client);
+ Error parse();
+ Error validateDisplay(Display display, std::vector<Layer>& changedLayers,
+ std::vector<IComposerClient::Composition>& compositionTypes,
+ uint32_t& displayRequestMask, std::vector<Layer>& requestedLayers,
+ std::vector<uint32_t>& requestMasks);
+ Error presentDisplay(Display display, int32_t& presentFence, std::vector<Layer>& layers,
+ std::vector<int32_t>& releaseFences);
+
+ private:
+ // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
+ bool parseSelectDisplay(uint16_t length);
+ bool parseSelectLayer(uint16_t length);
+ bool parseSetColorTransform(uint16_t length);
+ bool parseSetClientTarget(uint16_t length);
+ bool parseSetOutputBuffer(uint16_t length);
+ bool parseValidateDisplay(uint16_t length);
+ bool parseAcceptDisplayChanges(uint16_t length);
+ bool parsePresentDisplay(uint16_t length);
+ bool parsePresentOrValidateDisplay(uint16_t length);
+ bool parseSetLayerCursorPosition(uint16_t length);
+ bool parseSetLayerBuffer(uint16_t length);
+ bool parseSetLayerSurfaceDamage(uint16_t length);
+ bool parseSetLayerBlendMode(uint16_t length);
+ bool parseSetLayerColor(uint16_t length);
+ bool parseSetLayerCompositionType(uint16_t length);
+ bool parseSetLayerDataspace(uint16_t length);
+ bool parseSetLayerDisplayFrame(uint16_t length);
+ bool parseSetLayerPlaneAlpha(uint16_t length);
+ bool parseSetLayerSidebandStream(uint16_t length);
+ bool parseSetLayerSourceCrop(uint16_t length);
+ bool parseSetLayerTransform(uint16_t length);
+ bool parseSetLayerVisibleRegion(uint16_t length);
+ bool parseSetLayerZOrder(uint16_t length);
+
+ // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
+ bool parseSetLayerPerFrameMetadata(uint16_t length);
+ bool parseSetLayerFloatColor(uint16_t length);
+
+ // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
+ bool parseSetLayerColorTransform(uint16_t length);
+ bool parseSetLayerPerFrameMetadataBlobs(uint16_t length);
+
+ hwc_rect_t readRect();
+ std::vector<hwc_rect_t> readRegion(size_t count);
+ hwc_frect_t readFRect();
+ QtiComposerClient& mClient;
+ CommandWriter& mWriter;
+ Display mDisplay;
+ Layer mLayer;
+
+ // Buffer cache impl
+ enum class BufferCache {
+ CLIENT_TARGETS,
+ OUTPUT_BUFFERS,
+ LAYER_BUFFERS,
+ LAYER_SIDEBAND_STREAMS,
+ };
+
+ Error lookupBufferCacheEntryLocked(BufferCache cache, uint32_t slot,
+ BufferCacheEntry** outEntry);
+ Error lookupBuffer(BufferCache cache, uint32_t slot, bool useCache, buffer_handle_t handle,
+ buffer_handle_t* outHandle);
+ Error updateBuffer(BufferCache cache, uint32_t slot, bool useCache, buffer_handle_t handle);
+
+ Error lookupLayerSidebandStream(buffer_handle_t handle, buffer_handle_t* outHandle) {
+ return lookupBuffer(BufferCache::LAYER_SIDEBAND_STREAMS, 0, false, handle, outHandle);
+ }
+ Error updateLayerSidebandStream(buffer_handle_t handle) {
+ return updateBuffer(BufferCache::LAYER_SIDEBAND_STREAMS, 0, false, handle);
+ }
+ };
+
+ HWCSession *hwc_session_ = nullptr;
+ sp<composer_V2_1::IComposerCallback> mCallback;
+ std::mutex mCommandMutex;
+ // 64KiB minus a small space for metadata such as read/write pointers */
+ static constexpr size_t kWriterInitialSize = 64 * 1024 / sizeof(uint32_t) - 16;
+ CommandWriter mWriter;
+ CommandReader mReader;
+ std::mutex mDisplayDataMutex;
+ std::unordered_map<Display, DisplayData> mDisplayData;
+};
+
+extern "C" IQtiComposerClient* HIDL_FETCH_IQtiComposerClient(const char* name);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace composer
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
+
+#endif // __QTICOMPOSERCLIENT_H__
diff --git a/composer/QtiComposerCommandBuffer.h b/composer/QtiComposerCommandBuffer.h
new file mode 100644
index 0000000..9139906
--- /dev/null
+++ b/composer/QtiComposerCommandBuffer.h
@@ -0,0 +1,843 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef __QTICOMPOSERCOMMANDBUFFER_H__
+#define __QTICOMPOSERCOMMANDBUFFER_H__
+
+#include <limits>
+#include <algorithm>
+#include <vector>
+
+#include <log/log.h>
+#include <sync/sync.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace composer {
+namespace V1_0 {
+
+using ::android::hardware::graphics::common::V1_0::ColorTransform;
+using ::android::hardware::graphics::common::V1_0::Dataspace;
+using ::android::hardware::graphics::common::V1_0::Transform;
+using ::android::hardware::graphics::composer::V2_1::Error;
+using ::android::hardware::graphics::composer::V2_1::Display;
+using ::android::hardware::graphics::composer::V2_1::Layer;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_handle;
+
+using CommandQueueType = MessageQueue<uint32_t, ::android::hardware::kSynchronizedReadWrite>;
+
+// This class helps build a command queue. Note that all sizes/lengths are in units of uint32_t's.
+class CommandWriter {
+ public:
+ CommandWriter(uint32_t initialMaxSize) : mDataMaxSize(initialMaxSize) {
+ mData = std::make_unique<uint32_t[]>(mDataMaxSize);
+ reset();
+ }
+
+ ~CommandWriter() { reset(); }
+
+ void reset() {
+ mDataWritten = 0;
+ mCommandEnd = 0;
+
+ // handles in mDataHandles are owned by the caller
+ mDataHandles.clear();
+
+ // handles in mTemporaryHandles are owned by the writer
+ for (auto handle : mTemporaryHandles) {
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ }
+ mTemporaryHandles.clear();
+ }
+
+ IQtiComposerClient::Command getCommand(uint32_t offset) {
+ uint32_t val = (offset < mDataWritten) ? mData[offset] : 0;
+ return static_cast<IQtiComposerClient::Command>(val &
+ static_cast<uint32_t>(IQtiComposerClient::Command::OPCODE_MASK));
+ }
+
+ bool writeQueue(bool& queueChanged, uint32_t& commandLength,
+ hidl_vec<hidl_handle>& commandHandles) {
+ if (mDataWritten == 0) {
+ queueChanged = false;
+ commandLength = 0;
+ commandHandles.setToExternal(nullptr, 0);
+ return true;
+ }
+
+ // After data are written to the queue, it may not be read by the
+ // remote reader when
+ //
+ // - the writer does not send them (because of other errors)
+ // - the hwbinder transaction fails
+ // - the reader does not read them (because of other errors)
+ //
+ // Discard the stale data here.
+ size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0;
+ if (staleDataSize > 0) {
+ ALOGW("discarding stale data from message queue");
+ CommandQueueType::MemTransaction tx;
+ if (mQueue->beginRead(staleDataSize, &tx)) {
+ mQueue->commitRead(staleDataSize);
+ }
+ }
+ // write data to queue, optionally resizing it
+ if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
+ if (!mQueue->write(mData.get(), mDataWritten)) {
+ ALOGE("failed to write commands to message queue");
+ return false;
+ }
+
+ queueChanged = false;
+ } else {
+ auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
+ if (!newQueue->isValid() || !newQueue->write(mData.get(), mDataWritten)) {
+ ALOGE("failed to prepare a new message queue ");
+ return false;
+ }
+
+ mQueue = std::move(newQueue);
+ queueChanged = true;
+ }
+
+ commandLength = mDataWritten;
+ commandHandles.setToExternal(const_cast<hidl_handle*>(mDataHandles.data()),
+ mDataHandles.size());
+
+ return true;
+ }
+
+ const MQDescriptorSync<uint32_t>* getMQDescriptor() const {
+ return (mQueue) ? mQueue->getDesc() : nullptr;
+ }
+
+ // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
+ static constexpr uint16_t kSelectDisplayLength = 2;
+ void selectDisplay(Display display) {
+ beginCommand(IQtiComposerClient::Command::SELECT_DISPLAY, kSelectDisplayLength);
+ write64(display);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSelectLayerLength = 2;
+ void selectLayer(Layer layer) {
+ beginCommand(IQtiComposerClient::Command::SELECT_LAYER, kSelectLayerLength);
+ write64(layer);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetErrorLength = 2;
+ void setError(uint32_t location, Error error) {
+ beginCommand(IQtiComposerClient::Command::SET_ERROR, kSetErrorLength);
+ write(location);
+ writeSigned(static_cast<int32_t>(error));
+ endCommand();
+ }
+
+ static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
+ void setPresentOrValidateResult(uint32_t state) {
+ beginCommand(IQtiComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT,
+ kPresentOrValidateDisplayResultLength);
+ write(state);
+ endCommand();
+ }
+
+ void setChangedCompositionTypes(const std::vector<Layer>& layers,
+ const std::vector<IQtiComposerClient::Composition>& types) {
+ size_t totalLayers = std::min(layers.size(), types.size());
+ size_t currentLayer = 0;
+
+ while (currentLayer < totalLayers) {
+ size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
+
+ beginCommand(IQtiComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES, count * 3);
+ for (size_t i = 0; i < count; i++) {
+ write64(layers[currentLayer + i]);
+ writeSigned(static_cast<int32_t>(types[currentLayer + i]));
+ }
+ endCommand();
+
+ currentLayer += count;
+ }
+ }
+
+ void setDisplayRequests(uint32_t displayRequestMask, const std::vector<Layer>& layers,
+ const std::vector<uint32_t>& layerRequestMasks) {
+ size_t totalLayers = std::min(layers.size(), layerRequestMasks.size());
+ size_t currentLayer = 0;
+
+ while (currentLayer < totalLayers) {
+ size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength - 1) / 3);
+
+ beginCommand(IQtiComposerClient::Command::SET_DISPLAY_REQUESTS, 1 + count * 3);
+ write(displayRequestMask);
+ for (size_t i = 0; i < count; i++) {
+ write64(layers[currentLayer + i]);
+ write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
+ }
+ endCommand();
+
+ currentLayer += count;
+ }
+ }
+
+ static constexpr uint16_t kSetPresentFenceLength = 1;
+ void setPresentFence(int presentFence) {
+ beginCommand(IQtiComposerClient::Command::SET_PRESENT_FENCE, kSetPresentFenceLength);
+ writeFence(presentFence);
+ endCommand();
+ }
+
+ void setReleaseFences(const std::vector<Layer>& layers, const std::vector<int>& releaseFences) {
+ size_t totalLayers = std::min(layers.size(), releaseFences.size());
+ size_t currentLayer = 0;
+
+ while (currentLayer < totalLayers) {
+ size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
+
+ beginCommand(IQtiComposerClient::Command::SET_RELEASE_FENCES, count * 3);
+ for (size_t i = 0; i < count; i++) {
+ write64(layers[currentLayer + i]);
+ writeFence(releaseFences[currentLayer + i]);
+ }
+ endCommand();
+
+ currentLayer += count;
+ }
+ }
+
+ static constexpr uint16_t kSetColorTransformLength = 17;
+ void setColorTransform(const float* matrix, ColorTransform hint) {
+ beginCommand(IQtiComposerClient::Command::SET_COLOR_TRANSFORM, kSetColorTransformLength);
+ for (int i = 0; i < 16; i++) {
+ writeFloat(matrix[i]);
+ }
+ writeSigned(static_cast<int32_t>(hint));
+ endCommand();
+ }
+
+ void setClientTarget(uint32_t slot, const native_handle_t* target, int acquireFence,
+ Dataspace dataspace, const std::vector<IQtiComposerClient::Rect>& damage) {
+ bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
+ size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
+
+ beginCommand(IQtiComposerClient::Command::SET_CLIENT_TARGET, length);
+ write(slot);
+ writeHandle(target, true);
+ writeFence(acquireFence);
+ writeSigned(static_cast<int32_t>(dataspace));
+ // When there are too many rectangles in the damage region and doWrite
+ // is false, we write no rectangle at all which means the entire
+ // client target is damaged.
+ if (doWrite) {
+ writeRegion(damage);
+ }
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetOutputBufferLength = 3;
+ void setOutputBuffer(uint32_t slot, const native_handle_t* buffer, int releaseFence) {
+ beginCommand(IQtiComposerClient::Command::SET_OUTPUT_BUFFER, kSetOutputBufferLength);
+ write(slot);
+ writeHandle(buffer, true);
+ writeFence(releaseFence);
+ endCommand();
+ }
+
+ static constexpr uint16_t kValidateDisplayLength = 0;
+ void validateDisplay() {
+ beginCommand(IQtiComposerClient::Command::VALIDATE_DISPLAY, kValidateDisplayLength);
+ endCommand();
+ }
+
+ static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
+ void presentOrvalidateDisplay() {
+ beginCommand(IQtiComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY,
+ kPresentOrValidateDisplayLength);
+ endCommand();
+ }
+
+ static constexpr uint16_t kAcceptDisplayChangesLength = 0;
+ void acceptDisplayChanges() {
+ beginCommand(IQtiComposerClient::Command::ACCEPT_DISPLAY_CHANGES, kAcceptDisplayChangesLength);
+ endCommand();
+ }
+
+ static constexpr uint16_t kPresentDisplayLength = 0;
+ void presentDisplay() {
+ beginCommand(IQtiComposerClient::Command::PRESENT_DISPLAY, kPresentDisplayLength);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerCursorPositionLength = 2;
+ void setLayerCursorPosition(int32_t x, int32_t y) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_CURSOR_POSITION,
+ kSetLayerCursorPositionLength);
+ writeSigned(x);
+ writeSigned(y);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerBufferLength = 3;
+ void setLayerBuffer(uint32_t slot, const native_handle_t* buffer, int acquireFence) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_BUFFER, kSetLayerBufferLength);
+ write(slot);
+ writeHandle(buffer, true);
+ writeFence(acquireFence);
+ endCommand();
+ }
+
+ void setLayerSurfaceDamage(const std::vector<IQtiComposerClient::Rect>& damage) {
+ bool doWrite = (damage.size() <= kMaxLength / 4);
+ size_t length = (doWrite) ? damage.size() * 4 : 0;
+
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_SURFACE_DAMAGE, length);
+ // When there are too many rectangles in the damage region and doWrite
+ // is false, we write no rectangle at all which means the entire
+ // layer is damaged.
+ if (doWrite) {
+ writeRegion(damage);
+ }
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerBlendModeLength = 1;
+ void setLayerBlendMode(IQtiComposerClient::BlendMode mode) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_BLEND_MODE, kSetLayerBlendModeLength);
+ writeSigned(static_cast<int32_t>(mode));
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerColorLength = 1;
+ void setLayerColor(IQtiComposerClient::Color color) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_COLOR, kSetLayerColorLength);
+ writeColor(color);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
+ void setLayerCompositionType(IQtiComposerClient::Composition type) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_COMPOSITION_TYPE,
+ kSetLayerCompositionTypeLength);
+ writeSigned(static_cast<int32_t>(type));
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerDataspaceLength = 1;
+ void setLayerDataspace(Dataspace dataspace) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
+ writeSigned(static_cast<int32_t>(dataspace));
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
+ void setLayerDisplayFrame(const IQtiComposerClient::Rect& frame) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_DISPLAY_FRAME, kSetLayerDisplayFrameLength);
+ writeRect(frame);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
+ void setLayerPlaneAlpha(float alpha) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_PLANE_ALPHA, kSetLayerPlaneAlphaLength);
+ writeFloat(alpha);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
+ void setLayerSidebandStream(const native_handle_t* stream) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_SIDEBAND_STREAM,
+ kSetLayerSidebandStreamLength);
+ writeHandle(stream);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerSourceCropLength = 4;
+ void setLayerSourceCrop(const IQtiComposerClient::FRect& crop) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_SOURCE_CROP, kSetLayerSourceCropLength);
+ writeFRect(crop);
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerTransformLength = 1;
+ void setLayerTransform(Transform transform) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_TRANSFORM, kSetLayerTransformLength);
+ writeSigned(static_cast<int32_t>(transform));
+ endCommand();
+ }
+
+ void setLayerVisibleRegion(const std::vector<IQtiComposerClient::Rect>& visible) {
+ bool doWrite = (visible.size() <= kMaxLength / 4);
+ size_t length = (doWrite) ? visible.size() * 4 : 0;
+
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_VISIBLE_REGION, length);
+ // When there are too many rectangles in the visible region and
+ // doWrite is false, we write no rectangle at all which means the
+ // entire layer is visible.
+ if (doWrite) {
+ writeRegion(visible);
+ }
+ endCommand();
+ }
+
+ static constexpr uint16_t kSetLayerZOrderLength = 1;
+ void setLayerZOrder(uint32_t z) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_Z_ORDER, kSetLayerZOrderLength);
+ write(z);
+ endCommand();
+ }
+
+ // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
+ static constexpr uint16_t kSetLayerFloatColorLength = 4;
+ void setLayerFloatColor(IQtiComposerClient::FloatColor color) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_FLOAT_COLOR, kSetLayerFloatColorLength);
+ writeFloatColor(color);
+ endCommand();
+ }
+
+ void setLayerPerFrameMetadata(const hidl_vec<IQtiComposerClient::PerFrameMetadata>& metadataVec) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
+ metadataVec.size() * 2);
+ for (const auto& metadata : metadataVec) {
+ writeSigned(static_cast<int32_t>(metadata.key));
+ writeFloat(metadata.value);
+ }
+ endCommand();
+ }
+
+ // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
+ static constexpr uint16_t kSetLayerColorTransformLength = 16;
+ void setLayerColorTransform(const float* matrix) {
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_COLOR_TRANSFORM,
+ kSetLayerColorTransformLength);
+ for (int i = 0; i < 16; i++) {
+ writeFloat(matrix[i]);
+ }
+ endCommand();
+ }
+
+ void setLayerPerFrameMetadataBlobs(
+ const hidl_vec<IQtiComposerClient::PerFrameMetadataBlob>& metadata) {
+ size_t commandLength = 0;
+
+ if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
+ LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
+ return;
+ }
+
+ // number of blobs
+ commandLength += metadata.size();
+
+ for (auto metadataBlob : metadata) {
+ commandLength += sizeof(int32_t); // key of metadata blob
+ commandLength += 1; // size information of metadata blob
+
+ // metadata content size
+ size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
+ commandLength += metadataSize;
+ commandLength += (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
+ }
+
+ if (commandLength > std::numeric_limits<uint16_t>::max()) {
+ LOG_FATAL("dynamic metadata size is too large");
+ return;
+ }
+
+ // Blobs are written as:
+ // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
+ uint16_t length = static_cast<uint16_t>(commandLength);
+ beginCommand(IQtiComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
+ write(static_cast<uint32_t>(metadata.size()));
+ for (auto metadataBlob : metadata) {
+ writeSigned(static_cast<int32_t>(metadataBlob.key));
+ write(static_cast<uint32_t>(metadataBlob.blob.size()));
+ writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
+ }
+ endCommand();
+ }
+
+ protected:
+ // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
+ void beginCommand(IQtiComposerClient::Command command, uint16_t length) {
+ if (mCommandEnd) {
+ LOG_FATAL("endCommand was not called before command 0x%x", command);
+ }
+
+ growData(1 + length);
+ write(static_cast<uint32_t>(command) | length);
+
+ mCommandEnd = mDataWritten + length;
+ }
+
+ void endCommand() {
+ if (!mCommandEnd) {
+ LOG_FATAL("beginCommand was not called");
+ } else if (mDataWritten > mCommandEnd) {
+ LOG_FATAL("too much data written");
+ mDataWritten = mCommandEnd;
+ } else if (mDataWritten < mCommandEnd) {
+ LOG_FATAL("too little data written");
+ while (mDataWritten < mCommandEnd) {
+ write(0);
+ }
+ }
+
+ mCommandEnd = 0;
+ }
+
+ void write(uint32_t val) { mData[mDataWritten++] = val; }
+
+ void writeSigned(int32_t val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
+
+ void writeFloat(float val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
+
+ void write64(uint64_t val) {
+ uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
+ uint32_t hi = static_cast<uint32_t>(val >> 32);
+ write(lo);
+ write(hi);
+ }
+
+ void writeRect(const IQtiComposerClient::Rect& rect) {
+ writeSigned(rect.left);
+ writeSigned(rect.top);
+ writeSigned(rect.right);
+ writeSigned(rect.bottom);
+ }
+
+ void writeRegion(const std::vector<IQtiComposerClient::Rect>& region) {
+ for (const auto& rect : region) {
+ writeRect(rect);
+ }
+ }
+
+ void writeFRect(const IQtiComposerClient::FRect& rect) {
+ writeFloat(rect.left);
+ writeFloat(rect.top);
+ writeFloat(rect.right);
+ writeFloat(rect.bottom);
+ }
+
+ void writeColor(const IQtiComposerClient::Color& color) {
+ write((color.r << 0) | (color.g << 8) | (color.b << 16) | (color.a << 24));
+ }
+
+ // ownership of handle is not transferred
+ void writeHandle(const native_handle_t* handle, bool useCache) {
+ if (!handle) {
+ writeSigned(static_cast<int32_t>((useCache) ?
+ IQtiComposerClient::HandleIndex::CACHED : IQtiComposerClient::HandleIndex::EMPTY));
+ return;
+ }
+
+ mDataHandles.push_back(handle);
+ writeSigned(mDataHandles.size() - 1);
+ }
+
+ void writeHandle(const native_handle_t* handle) {
+ writeHandle(handle, false);
+ }
+
+ // ownership of fence is transferred
+ void writeFence(int fence) {
+ native_handle_t* handle = nullptr;
+ if (fence >= 0) {
+ handle = getTemporaryHandle(1, 0);
+ if (handle) {
+ handle->data[0] = fence;
+ } else {
+ ALOGW("failed to get temporary handle for fence %d", fence);
+ sync_wait(fence, -1);
+ close(fence);
+ }
+ }
+
+ writeHandle(handle);
+ }
+
+ native_handle_t* getTemporaryHandle(int numFds, int numInts) {
+ native_handle_t* handle = native_handle_create(numFds, numInts);
+ if (handle) {
+ mTemporaryHandles.push_back(handle);
+ }
+ return handle;
+ }
+
+ static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();
+
+ // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
+ void writeFloatColor(const IQtiComposerClient::FloatColor& color) {
+ writeFloat(color.r);
+ writeFloat(color.g);
+ writeFloat(color.b);
+ writeFloat(color.a);
+ }
+
+ // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
+ void writeBlob(uint32_t length, const unsigned char* blob) {
+ memcpy(&mData[mDataWritten], blob, length);
+ uint32_t numElements = length / 4;
+ mDataWritten += numElements;
+ mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
+ }
+
+ private:
+ void growData(uint32_t grow) {
+ uint32_t newWritten = mDataWritten + grow;
+ if (newWritten < mDataWritten) {
+ LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32
+ ", growing by %" PRIu32, mDataWritten, grow);
+ }
+
+ if (newWritten <= mDataMaxSize) {
+ return;
+ }
+
+ uint32_t newMaxSize = mDataMaxSize << 1;
+ if (newMaxSize < newWritten) {
+ newMaxSize = newWritten;
+ }
+
+ auto newData = std::make_unique<uint32_t[]>(newMaxSize);
+ std::copy_n(mData.get(), mDataWritten, newData.get());
+ mDataMaxSize = newMaxSize;
+ mData = std::move(newData);
+ }
+
+ uint32_t mDataMaxSize;
+ std::unique_ptr<uint32_t[]> mData;
+
+ uint32_t mDataWritten;
+ // end offset of the current command
+ uint32_t mCommandEnd;
+
+ std::vector<hidl_handle> mDataHandles;
+ std::vector<native_handle_t *> mTemporaryHandles;
+
+ std::unique_ptr<CommandQueueType> mQueue;
+};
+
+// This class helps parse a command queue. Note that all sizes/lengths are in units of uint32_t's.
+class CommandReaderBase {
+ public:
+ CommandReaderBase() : mDataMaxSize(0) { reset(); }
+
+ bool setMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor) {
+ mQueue = std::make_unique<CommandQueueType>(descriptor, false);
+ if (mQueue->isValid()) {
+ return true;
+ } else {
+ mQueue = nullptr;
+ return false;
+ }
+ }
+
+ bool readQueue(uint32_t commandLength, const hidl_vec<hidl_handle>& commandHandles) {
+ if (!mQueue) {
+ return false;
+ }
+
+ auto quantumCount = mQueue->getQuantumCount();
+ if (mDataMaxSize < quantumCount) {
+ mDataMaxSize = quantumCount;
+ mData = std::make_unique<uint32_t[]>(mDataMaxSize);
+ }
+
+ if (commandLength > mDataMaxSize || !mQueue->read(mData.get(), commandLength)) {
+ ALOGE("failed to read commands from message queue");
+ return false;
+ }
+
+ mDataSize = commandLength;
+ mDataRead = 0;
+ mCommandBegin = 0;
+ mCommandEnd = 0;
+ mDataHandles.setToExternal(const_cast<hidl_handle*>(commandHandles.data()),
+ commandHandles.size());
+
+ return true;
+ }
+
+ void reset() {
+ mDataSize = 0;
+ mDataRead = 0;
+ mCommandBegin = 0;
+ mCommandEnd = 0;
+ mDataHandles.setToExternal(nullptr, 0);
+ }
+
+ protected:
+ bool isEmpty() const { return (mDataRead >= mDataSize); }
+
+ bool beginCommand(IQtiComposerClient::Command& command, uint16_t& length) {
+ if (mCommandEnd) {
+ LOG_FATAL("endCommand was not called before command 0x%x", command);
+ }
+
+ constexpr uint32_t opcode_mask =
+ static_cast<uint32_t>(IQtiComposerClient::Command::OPCODE_MASK);
+ constexpr uint32_t length_mask =
+ static_cast<uint32_t>(IQtiComposerClient::Command::LENGTH_MASK);
+
+ uint32_t val = read();
+ command = static_cast<IQtiComposerClient::Command>(val & opcode_mask);
+ length = static_cast<uint16_t>(val & length_mask);
+
+ if (mDataRead + length > mDataSize) {
+ ALOGE("command 0x%x has invalid command length %" PRIu16, command, length);
+ // undo the read() above
+ mDataRead--;
+ return false;
+ }
+
+ mCommandEnd = mDataRead + length;
+
+ return true;
+ }
+
+ void endCommand() {
+ if (!mCommandEnd) {
+ LOG_FATAL("beginCommand was not called");
+ } else if (mDataRead > mCommandEnd) {
+ LOG_FATAL("too much data read");
+ mDataRead = mCommandEnd;
+ } else if (mDataRead < mCommandEnd) {
+ LOG_FATAL("too little data read");
+ mDataRead = mCommandEnd;
+ }
+
+ mCommandBegin = mCommandEnd;
+ mCommandEnd = 0;
+ }
+
+ uint32_t getCommandLoc() const { return mCommandBegin; }
+
+ uint32_t read() { return mData[mDataRead++]; }
+
+ int32_t readSigned() {
+ int32_t val;
+ memcpy(&val, &mData[mDataRead++], sizeof(val));
+ return val;
+ }
+
+ float readFloat() {
+ float val;
+ memcpy(&val, &mData[mDataRead++], sizeof(val));
+ return val;
+ }
+
+ uint64_t read64() {
+ uint32_t lo = read();
+ uint32_t hi = read();
+ return (static_cast<uint64_t>(hi) << 32) | lo;
+ }
+
+ IQtiComposerClient::Color readColor() {
+ uint32_t val = read();
+ return IQtiComposerClient::Color{
+ static_cast<uint8_t>((val >> 0) & 0xff),
+ static_cast<uint8_t>((val >> 8) & 0xff),
+ static_cast<uint8_t>((val >> 16) & 0xff),
+ static_cast<uint8_t>((val >> 24) & 0xff),
+ };
+ }
+
+ // ownership of handle is not transferred
+ const native_handle_t* readHandle(bool& useCache) {
+ const native_handle_t* handle = nullptr;
+
+ int32_t index = readSigned();
+ switch (index) {
+ case static_cast<int32_t>(IQtiComposerClient::HandleIndex::EMPTY):
+ useCache = false;
+ break;
+ case static_cast<int32_t>(IQtiComposerClient::HandleIndex::CACHED):
+ useCache = true;
+ break;
+ default:
+ if (static_cast<size_t>(index) < mDataHandles.size()) {
+ handle = mDataHandles[index].getNativeHandle();
+ } else {
+ ALOGE("invalid handle index %zu", static_cast<size_t>(index));
+ }
+ useCache = false;
+ break;
+ }
+
+ return handle;
+ }
+
+ const native_handle_t* readHandle() {
+ bool useCache;
+ return readHandle(useCache);
+ }
+
+ // ownership of fence is transferred
+ int readFence() {
+ auto handle = readHandle();
+ if (!handle || handle->numFds == 0) {
+ return -1;
+ }
+
+ if (handle->numFds != 1) {
+ ALOGE("invalid fence handle with %d fds", handle->numFds);
+ return -1;
+ }
+
+ int fd = dup(handle->data[0]);
+ if (fd < 0) {
+ ALOGW("failed to dup fence %d", handle->data[0]);
+ sync_wait(handle->data[0], -1);
+ fd = -1;
+ }
+
+ return fd;
+ }
+
+ private:
+ std::unique_ptr<CommandQueueType> mQueue;
+ uint32_t mDataMaxSize;
+ std::unique_ptr<uint32_t[]> mData;
+
+ uint32_t mDataSize;
+ uint32_t mDataRead;
+
+ // begin/end offsets of the current command
+ uint32_t mCommandBegin;
+ uint32_t mCommandEnd;
+
+ hidl_vec<hidl_handle> mDataHandles;
+};
+
+} // namespace V1_0
+} // namespace composer
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
+
+#endif // __QTICOMPOSERCOMMANDBUFFER_H__
diff --git a/composer/QtiComposerHandleImporter.cpp b/composer/QtiComposerHandleImporter.cpp
new file mode 100644
index 0000000..1518cbf
--- /dev/null
+++ b/composer/QtiComposerHandleImporter.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2017 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 <log/log.h>
+
+#include "QtiComposerHandleImporter.h"
+
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace composer {
+namespace V1_0 {
+
+using MapperError = android::hardware::graphics::mapper::V2_0::Error;
+
+ComposerHandleImporter::ComposerHandleImporter() : mInitialized(false) {}
+
+void ComposerHandleImporter::initialize() {
+ // allow only one client
+ if (mInitialized) {
+ return;
+ }
+
+ mMapper = IMapper::getService();
+ if (mMapper == nullptr) {
+ ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
+ return;
+ }
+
+ mInitialized = true;
+ return;
+}
+
+void ComposerHandleImporter::cleanup() {
+ mMapper.clear();
+ mInitialized = false;
+}
+
+// In IComposer, any buffer_handle_t is owned by the caller and we need to
+// make a clone for hwcomposer2. We also need to translate empty handle
+// to nullptr. This function does that, in-place.
+bool ComposerHandleImporter::importBuffer(buffer_handle_t& handle) {
+ if (!handle) {
+ return true;
+ }
+
+ if (!handle->numFds && !handle->numInts) {
+ handle = nullptr;
+ return true;
+ }
+
+ Mutex::Autolock lock(mLock);
+ if (!mInitialized) {
+ initialize();
+ }
+
+ if (mMapper == nullptr) {
+ ALOGE("%s: mMapper is null!", __FUNCTION__);
+ return false;
+ }
+
+ MapperError error;
+ buffer_handle_t importedHandle;
+ auto ret = mMapper->importBuffer(
+ hidl_handle(handle),
+ [&](const auto& tmpError, const auto& tmpBufferHandle) {
+ error = tmpError;
+ importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
+ });
+
+ if (!ret.isOk()) {
+ ALOGE("%s: mapper importBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+ return false;
+ }
+
+ if (error != MapperError::NONE) {
+ return false;
+ }
+
+ handle = importedHandle;
+
+ return true;
+}
+
+void ComposerHandleImporter::freeBuffer(buffer_handle_t handle) {
+ if (!handle) {
+ return;
+ }
+
+ Mutex::Autolock lock(mLock);
+ if (mMapper == nullptr) {
+ ALOGE("%s: mMapper is null!", __FUNCTION__);
+ return;
+ }
+
+ auto ret = mMapper->freeBuffer(const_cast<native_handle_t*>(handle));
+ if (!ret.isOk()) {
+ ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+ }
+}
+
+} // namespace V1_0
+} // namespace composer
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
diff --git a/composer/QtiComposerHandleImporter.h b/composer/QtiComposerHandleImporter.h
new file mode 100644
index 0000000..f110e68
--- /dev/null
+++ b/composer/QtiComposerHandleImporter.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef __QTICOMPOSERHANDLEIMPORTER_H__
+#define __QTICOMPOSERHANDLEIMPORTER_H__
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <utils/Mutex.h>
+
+namespace vendor {
+namespace qti {
+namespace hardware {
+namespace display {
+namespace composer {
+namespace V1_0 {
+
+using ::android::hardware::graphics::mapper::V2_0::IMapper;
+using ::android::sp;
+using ::android::Mutex;
+using ::android::hardware::hidl_handle;
+
+class ComposerHandleImporter {
+ public:
+ ComposerHandleImporter();
+
+ // In IComposer, any buffer_handle_t is owned by the caller and we need to
+ // make a clone for hwcomposer2. We also need to translate empty handle
+ // to nullptr. This function does that, in-place.
+ bool importBuffer(buffer_handle_t& handle);
+ void freeBuffer(buffer_handle_t handle);
+ void initialize();
+ void cleanup();
+
+ private:
+ Mutex mLock;
+ bool mInitialized = false;
+ sp<IMapper> mMapper;
+};
+
+} // namespace V1_0
+} // namespace composer
+} // namespace display
+} // namespace hardware
+} // namespace qti
+} // namespace vendor
+
+#endif // __QTICOMPOSERHANDLEIMPORTER_H__
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index 2c840ff..3a3cbfd 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -51,22 +51,6 @@
#define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
#define HWC_UEVENT_DRM_EXT_HOTPLUG "mdss_mdp/drm/card"
-static sdm::HWCSession::HWCModuleMethods g_hwc_module_methods;
-
-hwc_module_t HAL_MODULE_INFO_SYM = {
- .common = {
- .tag = HARDWARE_MODULE_TAG,
- .version_major = 3,
- .version_minor = 0,
- .id = HWC_HARDWARE_MODULE_ID,
- .name = "QTI Hardware Composer Module",
- .author = "CodeAurora Forum",
- .methods = &g_hwc_module_methods,
- .dso = 0,
- .reserved = {0},
- }
-};
-
namespace sdm {
static HWCUEvent g_hwc_uevent_;
@@ -150,13 +134,13 @@
uevent_listener_ = uevent_listener;
}
-HWCSession::HWCSession(const hw_module_t *module) {
- hwc2_device_t::common.tag = HARDWARE_DEVICE_TAG;
- hwc2_device_t::common.version = HWC_DEVICE_API_VERSION_2_0;
- hwc2_device_t::common.module = const_cast<hw_module_t *>(module);
- hwc2_device_t::common.close = Close;
- hwc2_device_t::getCapabilities = GetCapabilities;
- hwc2_device_t::getFunction = GetFunction;
+HWCSession::HWCSession() {}
+
+HWCSession *HWCSession::GetInstance() {
+ // executed only once for the very first call.
+ // GetInstance called multiple times from Composer and ComposerClient
+ static HWCSession *hwc_session = new HWCSession();
+ return hwc_session;
}
int HWCSession::Init() {
@@ -353,47 +337,7 @@
return INT(map_info->client_id);
}
-int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
- if (!module || !name || !device) {
- DLOGE("Invalid parameters.");
- return -EINVAL;
- }
-
- if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
- HWCSession *hwc_session = new HWCSession(module);
- if (!hwc_session) {
- return -ENOMEM;
- }
-
- int status = hwc_session->Init();
- if (status != 0) {
- delete hwc_session;
- hwc_session = NULL;
- return status;
- }
-
- hwc2_device_t *composer_device = hwc_session;
- *device = reinterpret_cast<hw_device_t *>(composer_device);
- }
-
- return 0;
-}
-
-int HWCSession::Close(hw_device_t *device) {
- if (!device) {
- return -EINVAL;
- }
-
- hwc2_device_t *composer_device = reinterpret_cast<hwc2_device_t *>(device);
- HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
-
- hwc_session->Deinit();
-
- return 0;
-}
-
-void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
- int32_t *outCapabilities) {
+void HWCSession::GetCapabilities(uint32_t *outCount, int32_t *outCapabilities) {
if (!outCount) {
return;
}
@@ -423,32 +367,28 @@
// HWC2 functions returned in GetFunction
// Defined in the same order as in the HWC2 header
-int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
+int32_t HWCSession::AcceptDisplayChanges(hwc2_display_t display) {
+ return CallDisplayFunction(display, &HWCDisplay::AcceptDisplayChanges);
}
-int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
+int32_t HWCSession::CreateLayer(hwc2_display_t display,
hwc2_layer_t *out_layer_id) {
if (!out_layer_id) {
return HWC2_ERROR_BAD_PARAMETER;
}
- return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
+ return CallDisplayFunction(display, &HWCDisplay::CreateLayer, out_layer_id);
}
-int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
- int32_t *format, hwc2_display_t *out_display_id) {
+int32_t HWCSession::CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t *format,
+ hwc2_display_t *out_display_id) {
// TODO(user): Handle concurrency with HDMI
- if (!device) {
- return HWC2_ERROR_BAD_DISPLAY;
- }
if (!out_display_id || !width || !height || !format) {
return HWC2_ERROR_BAD_PARAMETER;
}
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- auto status = hwc_session->CreateVirtualDisplayObj(width, height, format, out_display_id);
+ auto status = CreateVirtualDisplayObj(width, height, format, out_display_id);
if (status == HWC2::Error::None) {
DLOGI("Created virtual display id:% " PRIu64 ", res: %dx%d", *out_display_id, width, height);
} else {
@@ -457,34 +397,32 @@
return INT32(status);
}
-int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer) {
- return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
+int32_t HWCSession::DestroyLayer(hwc2_display_t display, hwc2_layer_t layer) {
+ return CallDisplayFunction(display, &HWCDisplay::DestroyLayer, layer);
}
-int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
- if (!device || display >= HWCCallbacks::kNumDisplays) {
+int32_t HWCSession::DestroyVirtualDisplay(hwc2_display_t display) {
+ if (display >= HWCCallbacks::kNumDisplays) {
return HWC2_ERROR_BAD_DISPLAY;
}
- auto *hwc_session = static_cast<HWCSession *>(device);
- hwc2_display_t active_builtin_disp_id = hwc_session->GetActiveBuiltinDisplay();
+ hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]);
std::bitset<kSecureMax> secure_sessions = 0;
- hwc_session->hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
+ hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
if (secure_sessions.any()) {
DLOGW("Secure session is active, defer destruction of virtual display id:%" PRIu64, display);
- hwc_session->destroy_virtual_disp_pending_ = true;
+ destroy_virtual_disp_pending_ = true;
return HWC2_ERROR_NONE;
}
}
- for (auto &map_info : hwc_session->map_info_virtual_) {
+ for (auto &map_info : map_info_virtual_) {
if (map_info.client_id == display) {
DLOGI("Destroying virtual display id:%" PRIu64, display);
- hwc_session->DestroyDisplay(&map_info);
+ DestroyDisplay(&map_info);
break;
}
}
@@ -492,12 +430,11 @@
return HWC2_ERROR_NONE;
}
-void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
- if (!device || !out_size) {
+void HWCSession::Dump(uint32_t *out_size, char *out_buffer) {
+ if (!out_size) {
return;
}
- auto *hwc_session = static_cast<HWCSession *>(device);
const size_t max_dump_size = 8192;
if (out_buffer == nullptr) {
@@ -506,8 +443,8 @@
std::string s {};
for (int id = 0; id < HWCCallbacks::kNumDisplays; id++) {
SCOPE_LOCK(locker_[id]);
- if (hwc_session->hwc_display_[id]) {
- s += hwc_session->hwc_display_[id]->Dump();
+ if (hwc_display_[id]) {
+ s += hwc_display_[id]->Dump();
}
}
auto copied = s.copy(out_buffer, std::min(s.size(), max_dump_size), 0);
@@ -515,49 +452,42 @@
}
}
-uint32_t HWCSession::GetMaxVirtualDisplayCount(hwc2_device_t *device) {
- if (device == nullptr) {
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
+uint32_t HWCSession::GetMaxVirtualDisplayCount() {
return 1;
}
-static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
- hwc2_config_t *out_config) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config);
+int32_t HWCSession::GetActiveConfig(hwc2_display_t display, hwc2_config_t *out_config) {
+ return CallDisplayFunction(display, &HWCDisplay::GetActiveConfig, out_config);
}
-static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
- uint32_t *out_num_elements, hwc2_layer_t *out_layers,
- int32_t *out_types) {
+int32_t HWCSession::GetChangedCompositionTypes(hwc2_display_t display, uint32_t *out_num_elements,
+ hwc2_layer_t *out_layers, int32_t *out_types) {
// null_ptr check only for out_num_elements, as out_layers and out_types can be null.
if (!out_num_elements) {
return HWC2_ERROR_BAD_PARAMETER;
}
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
- out_num_elements, out_layers, out_types);
+ return CallDisplayFunction(display, &HWCDisplay::GetChangedCompositionTypes, out_num_elements,
+ out_layers, out_types);
}
-static int32_t GetClientTargetSupport(hwc2_device_t *device, hwc2_display_t display, uint32_t width,
- uint32_t height, int32_t format, int32_t dataspace) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetClientTargetSupport,
- width, height, format, dataspace);
+int32_t HWCSession::GetClientTargetSupport(hwc2_display_t display, uint32_t width, uint32_t height,
+ int32_t format, int32_t dataspace) {
+ return CallDisplayFunction(display, &HWCDisplay::GetClientTargetSupport, width, height, format,
+ dataspace);
}
-static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
- int32_t /*ColorMode*/ *int_out_modes) {
+int32_t HWCSession::GetColorModes(hwc2_display_t display, uint32_t *out_num_modes,
+ int32_t /*ColorMode*/ *int_out_modes) {
auto out_modes = reinterpret_cast<ColorMode *>(int_out_modes);
if (out_num_modes == nullptr) {
return HWC2_ERROR_BAD_PARAMETER;
}
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes,
- out_modes);
+ return CallDisplayFunction(display, &HWCDisplay::GetColorModes, out_num_modes, out_modes);
}
-static int32_t GetRenderIntents(hwc2_device_t *device, hwc2_display_t display,
- int32_t /*ColorMode*/ int_mode, uint32_t *out_num_intents,
- int32_t /*RenderIntent*/ *int_out_intents) {
+int32_t HWCSession::GetRenderIntents(hwc2_display_t display, int32_t /*ColorMode*/ int_mode,
+ uint32_t *out_num_intents,
+ int32_t /*RenderIntent*/ *int_out_intents) {
auto mode = static_cast<ColorMode>(int_mode);
auto out_intents = reinterpret_cast<RenderIntent *>(int_out_intents);
if (out_num_intents == nullptr) {
@@ -568,15 +498,14 @@
DLOGE("Invalid ColorMode: %d", mode);
return HWC2_ERROR_BAD_PARAMETER;
}
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetRenderIntents, mode,
- out_num_intents, out_intents);
+ return CallDisplayFunction(display, &HWCDisplay::GetRenderIntents, mode, out_num_intents,
+ out_intents);
}
-static int32_t GetDataspaceSaturationMatrix(hwc2_device_t *device,
- int32_t /*Dataspace*/ int_dataspace,
- float *out_matrix) {
+int32_t HWCSession::GetDataspaceSaturationMatrix(int32_t /*Dataspace*/ int_dataspace,
+ float *out_matrix) {
auto dataspace = static_cast<Dataspace>(int_dataspace);
- if (device == nullptr || out_matrix == nullptr || dataspace != Dataspace::SRGB_LINEAR) {
+ if (out_matrix == nullptr || dataspace != Dataspace::SRGB_LINEAR) {
return HWC2_ERROR_BAD_PARAMETER;
}
// We only have the matrix for sRGB
@@ -595,91 +524,82 @@
return HWC2_ERROR_NONE;
}
-static int32_t GetPerFrameMetadataKeys(hwc2_device_t *device, hwc2_display_t display,
- uint32_t *out_num_keys, int32_t *int_out_keys) {
+int32_t HWCSession::GetPerFrameMetadataKeys(hwc2_display_t display, uint32_t *out_num_keys,
+ int32_t *int_out_keys) {
auto out_keys = reinterpret_cast<PerFrameMetadataKey *>(int_out_keys);
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetPerFrameMetadataKeys,
- out_num_keys, out_keys);
+ return CallDisplayFunction(display, &HWCDisplay::GetPerFrameMetadataKeys, out_num_keys,
+ out_keys);
}
-static int32_t SetLayerPerFrameMetadata(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer, uint32_t num_elements,
- const int32_t *int_keys, const float *metadata) {
+int32_t HWCSession::SetLayerPerFrameMetadata(hwc2_display_t display, hwc2_layer_t layer,
+ uint32_t num_elements, const int32_t *int_keys,
+ const float *metadata) {
auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPerFrameMetadata,
- num_elements, keys, metadata);
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerPerFrameMetadata, num_elements,
+ keys, metadata);
}
-static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
- hwc2_config_t config, int32_t int_attribute,
- int32_t *out_value) {
+int32_t HWCSession::GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
+ int32_t int_attribute, int32_t *out_value) {
if (out_value == nullptr || int_attribute < HWC2_ATTRIBUTE_INVALID ||
int_attribute > HWC2_ATTRIBUTE_DPI_Y) {
return HWC2_ERROR_BAD_PARAMETER;
}
auto attribute = static_cast<HWC2::Attribute>(int_attribute);
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayAttribute, config,
- attribute, out_value);
+ return CallDisplayFunction(display, &HWCDisplay::GetDisplayAttribute, config, attribute,
+ out_value);
}
-static int32_t GetDisplayConfigs(hwc2_device_t *device, hwc2_display_t display,
- uint32_t *out_num_configs, hwc2_config_t *out_configs) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayConfigs,
- out_num_configs, out_configs);
+int32_t HWCSession::GetDisplayConfigs(hwc2_display_t display, uint32_t *out_num_configs,
+ hwc2_config_t *out_configs) {
+ return CallDisplayFunction(display, &HWCDisplay::GetDisplayConfigs, out_num_configs,
+ out_configs);
}
-static int32_t GetDisplayName(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_size,
- char *out_name) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayName, out_size,
- out_name);
+int32_t HWCSession::GetDisplayName(hwc2_display_t display, uint32_t *out_size, char *out_name) {
+ return CallDisplayFunction(display, &HWCDisplay::GetDisplayName, out_size, out_name);
}
-static int32_t GetDisplayRequests(hwc2_device_t *device, hwc2_display_t display,
- int32_t *out_display_requests, uint32_t *out_num_elements,
- hwc2_layer_t *out_layers, int32_t *out_layer_requests) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayRequests,
- out_display_requests, out_num_elements, out_layers,
- out_layer_requests);
+int32_t HWCSession::GetDisplayRequests(hwc2_display_t display, int32_t *out_display_requests,
+ uint32_t *out_num_elements, hwc2_layer_t *out_layers,
+ int32_t *out_layer_requests) {
+ return CallDisplayFunction(display, &HWCDisplay::GetDisplayRequests, out_display_requests,
+ out_num_elements, out_layers, out_layer_requests);
}
-static int32_t GetDisplayType(hwc2_device_t *device, hwc2_display_t display, int32_t *out_type) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayType, out_type);
+int32_t HWCSession::GetDisplayType(hwc2_display_t display, int32_t *out_type) {
+ return CallDisplayFunction(display, &HWCDisplay::GetDisplayType, out_type);
}
-static int32_t GetHdrCapabilities(hwc2_device_t* device, hwc2_display_t display,
- uint32_t* out_num_types, int32_t* out_types,
- float* out_max_luminance, float* out_max_average_luminance,
- float* out_min_luminance) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetHdrCapabilities,
- out_num_types, out_types, out_max_luminance,
- out_max_average_luminance, out_min_luminance);
+int32_t HWCSession::GetHdrCapabilities(hwc2_display_t display, uint32_t* out_num_types,
+ int32_t* out_types, float* out_max_luminance,
+ float* out_max_average_luminance,
+ float* out_min_luminance) {
+ return CallDisplayFunction(display, &HWCDisplay::GetHdrCapabilities, out_num_types, out_types,
+ out_max_luminance, out_max_average_luminance, out_min_luminance);
}
-static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
- uint32_t *out_num_elements, hwc2_layer_t *out_layers,
- int32_t *out_fences) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetReleaseFences,
- out_num_elements, out_layers, out_fences);
+int32_t HWCSession::GetReleaseFences(hwc2_display_t display, uint32_t *out_num_elements,
+ hwc2_layer_t *out_layers, int32_t *out_fences) {
+ return CallDisplayFunction(display, &HWCDisplay::GetReleaseFences, out_num_elements, out_layers,
+ out_fences);
}
-int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
- int32_t *out_retire_fence) {
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
+int32_t HWCSession::PresentDisplay(hwc2_display_t display, int32_t *out_retire_fence) {
auto status = HWC2::Error::BadDisplay;
DTRACE_SCOPED();
- if (!hwc_session || (display >= HWCCallbacks::kNumDisplays)) {
- DLOGW("Invalid Display : hwc session = %s display = %" PRIu64,
- hwc_session ? "Valid" : "NULL", display);
+ if (display >= HWCCallbacks::kNumDisplays) {
+ DLOGW("Invalid Display : display = %" PRIu64, display);
return HWC2_ERROR_BAD_DISPLAY;
}
- hwc_session->HandleSecureSession();
+ HandleSecureSession();
{
SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
- if (!hwc_session->hwc_display_[display]) {
+ if (!hwc_display_[display]) {
DLOGW("Removed Display : display = %" PRIu64, display);
return HWC2_ERROR_BAD_DISPLAY;
}
@@ -691,14 +611,14 @@
if (power_on_pending_[display]) {
status = HWC2::Error::None;
} else {
- status = hwc_session->PresentDisplayInternal(display, out_retire_fence);
+ status = PresentDisplayInternal(display, out_retire_fence);
if (status == HWC2::Error::None) {
// Check if hwc's refresh trigger is getting exercised.
- if (hwc_session->callbacks_.NeedsRefresh(display)) {
- hwc_session->hwc_display_[display]->SetPendingRefresh();
- hwc_session->callbacks_.ResetRefresh(display);
+ if (callbacks_.NeedsRefresh(display)) {
+ hwc_display_[display]->SetPendingRefresh();
+ callbacks_.ResetRefresh(display);
}
- status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
+ status = hwc_display_[display]->Present(out_retire_fence);
}
}
}
@@ -707,9 +627,9 @@
SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
}
- hwc_session->HandlePowerOnPending(display, *out_retire_fence);
- hwc_session->HandleHotplugPending(display, *out_retire_fence);
- hwc_session->HandlePendingRefresh();
+ HandlePowerOnPending(display, *out_retire_fence);
+ HandleHotplugPending(display, *out_retire_fence);
+ HandlePendingRefresh();
return INT32(status);
}
@@ -729,67 +649,59 @@
pending_refresh_.reset();
}
-int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
- hwc2_callback_data_t callback_data,
- hwc2_function_pointer_t pointer) {
- if (!device) {
- return HWC2_ERROR_BAD_PARAMETER;
- }
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- SCOPE_LOCK(hwc_session->callbacks_lock_);
+void HWCSession::RegisterCallback(int32_t descriptor, hwc2_callback_data_t callback_data,
+ hwc2_function_pointer_t pointer) {
+ SCOPE_LOCK(callbacks_lock_);
auto desc = static_cast<HWC2::Callback>(descriptor);
- auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
+ auto error = callbacks_.Register(desc, callback_data, pointer);
if (error != HWC2::Error::None) {
- return INT32(error);
+ return;
}
DLOGD("%s callback: %s", pointer ? "Registering" : "Deregistering", to_string(desc).c_str());
if (descriptor == HWC2_CALLBACK_HOTPLUG) {
- if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
DLOGI("Hotplugging primary...");
- hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
+ callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
}
// Create displays since they should now have their final display indices set.
DLOGI("Handling built-in displays...");
- if (hwc_session->HandleBuiltInDisplays()) {
+ if (HandleBuiltInDisplays()) {
DLOGW("Failed handling built-in displays.");
}
DLOGI("Handling pluggable displays...");
- int32_t err = hwc_session->HandlePluggableDisplays(false);
+ int32_t err = HandlePluggableDisplays(false);
if (err) {
DLOGW("All displays could not be created. Error %d '%s'. Hotplug handling %s.", err,
- strerror(abs(err)), hwc_session->hotplug_pending_event_ == kHotPlugEvent ? "deferred" :
+ strerror(abs(err)), hotplug_pending_event_ == kHotPlugEvent ? "deferred" :
"dropped");
}
- hwc_session->client_connected_ = true;
+ client_connected_ = true;
}
- hwc_session->need_invalidate_ = false;
- hwc_session->callbacks_lock_.Broadcast();
- return HWC2_ERROR_NONE;
+ need_invalidate_ = false;
+ callbacks_lock_.Broadcast();
}
-static int32_t SetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
- hwc2_config_t config) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfig, config);
+int32_t HWCSession::SetActiveConfig(hwc2_display_t display, hwc2_config_t config) {
+ return CallDisplayFunction(display, &HWCDisplay::SetActiveConfig, config);
}
-static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
- buffer_handle_t target, int32_t acquire_fence,
- int32_t dataspace, hwc_region_t damage) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetClientTarget, target,
- acquire_fence, dataspace, damage);
+int32_t HWCSession::SetClientTarget(hwc2_display_t display, buffer_handle_t target,
+ int32_t acquire_fence, int32_t dataspace,
+ hwc_region_t damage) {
+ return CallDisplayFunction(display, &HWCDisplay::SetClientTarget, target, acquire_fence,
+ dataspace, damage);
}
-int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
- int32_t /*ColorMode*/ int_mode) {
+int32_t HWCSession::SetColorMode(hwc2_display_t display, int32_t /*ColorMode*/ int_mode) {
auto mode = static_cast<ColorMode>(int_mode);
if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_BT2020) {
return HWC2_ERROR_BAD_PARAMETER;
}
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
+ return CallDisplayFunction(display, &HWCDisplay::SetColorMode, mode);
}
-int32_t HWCSession::SetColorModeWithRenderIntent(hwc2_device_t *device, hwc2_display_t display,
+int32_t HWCSession::SetColorModeWithRenderIntent(hwc2_display_t display,
int32_t /*ColorMode*/ int_mode,
int32_t /*RenderIntent*/ int_render_intent) {
auto mode = static_cast<ColorMode>(int_mode);
@@ -803,128 +715,108 @@
}
auto render_intent = static_cast<RenderIntent>(int_render_intent);
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent,
- mode, render_intent);
+ return CallDisplayFunction(display, &HWCDisplay::SetColorModeWithRenderIntent, mode,
+ render_intent);
}
-int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
- const float *matrix,
+int32_t HWCSession::SetColorTransform(hwc2_display_t display, const float *matrix,
int32_t /*android_color_transform_t*/ hint) {
if (!matrix || hint < HAL_COLOR_TRANSFORM_IDENTITY ||
hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA) {
return HWC2_ERROR_BAD_PARAMETER;
}
android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
- transform_hint);
+ return CallDisplayFunction(display, &HWCDisplay::SetColorTransform, matrix, transform_hint);
}
-static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- int32_t x, int32_t y) {
+int32_t HWCSession::SetCursorPosition(hwc2_display_t display, hwc2_layer_t layer, int32_t x,
+ int32_t y) {
auto status = INT32(HWC2::Error::None);
- status = HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetCursorPosition,
- layer, x, y);
+ status = CallDisplayFunction(display, &HWCDisplay::SetCursorPosition, layer, x, y);
if (status == INT32(HWC2::Error::None)) {
// Update cursor position
- HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetCursorPosition, x, y);
+ CallLayerFunction(display, layer, &HWCLayer::SetCursorPosition, x, y);
}
return status;
}
-static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- int32_t int_mode) {
+int32_t HWCSession::SetLayerBlendMode(hwc2_display_t display, hwc2_layer_t layer,
+ int32_t int_mode) {
if (int_mode < HWC2_BLEND_MODE_INVALID || int_mode > HWC2_BLEND_MODE_COVERAGE) {
return HWC2_ERROR_BAD_PARAMETER;
}
auto mode = static_cast<HWC2::BlendMode>(int_mode);
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBlendMode, mode);
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerBlendMode, mode);
}
-static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- buffer_handle_t buffer, int32_t acquire_fence) {
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerBuffer, buffer,
- acquire_fence);
+int32_t HWCSession::SetLayerBuffer(hwc2_display_t display, hwc2_layer_t layer,
+ buffer_handle_t buffer, int32_t acquire_fence) {
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerBuffer, buffer, acquire_fence);
}
-static int32_t SetLayerColor(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- hwc_color_t color) {
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColor, color);
+int32_t HWCSession::SetLayerColor(hwc2_display_t display, hwc2_layer_t layer, hwc_color_t color) {
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerColor, color);
}
-static int32_t SetLayerCompositionType(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer, int32_t int_type) {
+int32_t HWCSession::SetLayerCompositionType(hwc2_display_t display, hwc2_layer_t layer,
+ int32_t int_type) {
auto type = static_cast<HWC2::Composition>(int_type);
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerCompositionType,
- type);
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerCompositionType, type);
}
-static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- int32_t dataspace) {
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDataspace,
- dataspace);
+int32_t HWCSession::SetLayerDataspace(hwc2_display_t display, hwc2_layer_t layer,
+ int32_t dataspace) {
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerDataspace, dataspace);
}
-static int32_t SetLayerDisplayFrame(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer, hwc_rect_t frame) {
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerDisplayFrame,
- frame);
+int32_t HWCSession::SetLayerDisplayFrame(hwc2_display_t display, hwc2_layer_t layer,
+ hwc_rect_t frame) {
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerDisplayFrame, frame);
}
-static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- float alpha) {
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPlaneAlpha,
- alpha);
+int32_t HWCSession::SetLayerPlaneAlpha(hwc2_display_t display, hwc2_layer_t layer, float alpha) {
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerPlaneAlpha, alpha);
}
-static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- hwc_frect_t crop) {
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSourceCrop, crop);
+int32_t HWCSession::SetLayerSourceCrop(hwc2_display_t display, hwc2_layer_t layer,
+ hwc_frect_t crop) {
+ return HWCSession::CallLayerFunction(display, layer, &HWCLayer::SetLayerSourceCrop, crop);
}
-static int32_t SetLayerSurfaceDamage(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer, hwc_region_t damage) {
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerSurfaceDamage,
- damage);
+int32_t HWCSession::SetLayerSurfaceDamage(hwc2_display_t display, hwc2_layer_t layer,
+ hwc_region_t damage) {
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerSurfaceDamage, damage);
}
-static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- int32_t int_transform) {
+int32_t HWCSession::SetLayerTransform(hwc2_display_t display, hwc2_layer_t layer,
+ int32_t int_transform) {
auto transform = static_cast<HWC2::Transform>(int_transform);
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerTransform,
- transform);
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerTransform, transform);
}
-static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer, hwc_region_t visible) {
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerVisibleRegion,
- visible);
+int32_t HWCSession::SetLayerVisibleRegion(hwc2_display_t display, hwc2_layer_t layer,
+ hwc_region_t visible) {
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerVisibleRegion, visible);
}
-static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
- uint32_t z) {
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
+int32_t HWCSession::SetLayerZOrder(hwc2_display_t display, hwc2_layer_t layer, uint32_t z) {
+ return CallDisplayFunction(display, &HWCDisplay::SetLayerZOrder, layer, z);
}
-static int32_t SetLayerColorTransform(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer, const float *matrix) {
- return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColorTransform,
- matrix);
+int32_t HWCSession::SetLayerColorTransform(hwc2_display_t display, hwc2_layer_t layer,
+ const float *matrix) {
+ return CallLayerFunction(display, layer, &HWCLayer::SetLayerColorTransform, matrix);
}
-int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
- buffer_handle_t buffer, int32_t releaseFence) {
- if (!device) {
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
- auto *hwc_session = static_cast<HWCSession *>(device);
- if (INT32(display) != hwc_session->GetDisplayIndex(qdutils::DISPLAY_VIRTUAL)) {
+int32_t HWCSession::SetOutputBuffer(hwc2_display_t display, buffer_handle_t buffer,
+ int32_t releaseFence) {
+ if (INT32(display) != GetDisplayIndex(qdutils::DISPLAY_VIRTUAL)) {
return HWC2_ERROR_UNSUPPORTED;
}
SCOPE_LOCK(locker_[display]);
- if (hwc_session->hwc_display_[display]) {
- auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
+ if (hwc_display_[display]) {
+ auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_display_[display]);
auto status = vds->SetOutputBuffer(buffer, releaseFence);
return INT32(status);
} else {
@@ -932,18 +824,17 @@
}
}
-int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
+int32_t HWCSession::SetPowerMode(hwc2_display_t display, int32_t int_mode) {
if (display >= HWCCallbacks::kNumDisplays) {
return HWC2_ERROR_BAD_DISPLAY;
}
// validate device and also avoid undefined behavior in cast to HWC2::PowerMode
- if (!device || int_mode < HWC2_POWER_MODE_OFF || int_mode > HWC2_POWER_MODE_DOZE_SUSPEND) {
+ if (int_mode < HWC2_POWER_MODE_OFF || int_mode > HWC2_POWER_MODE_DOZE_SUSPEND) {
return HWC2_ERROR_BAD_PARAMETER;
}
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- if (hwc_session->power_on_pending_[display]) {
+ if (power_on_pending_[display]) {
DLOGW("Set power mode is not allowed during secure display session");
return HWC2_ERROR_UNSUPPORTED;
}
@@ -952,7 +843,7 @@
// all displays support on/off. Check for doze modes
int support = 0;
- auto status = hwc_session->GetDozeSupport(device, display, &support);
+ auto status = GetDozeSupport(display, &support);
if (status != HWC2_ERROR_NONE) {
DLOGE("Failed to get doze support Error = %d", status);
return INT32(status);
@@ -962,30 +853,29 @@
return HWC2_ERROR_UNSUPPORTED;
}
- auto error = CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode,
- false /* teardown */);
- if (error != HWC2_ERROR_NONE) {
- return error;
+ auto error = CallDisplayFunction(display, &HWCDisplay::SetPowerMode, mode, false /* teardown */);
+ if (INT32(error) != HWC2_ERROR_NONE) {
+ return INT32(error);
}
// Reset idle pc ref count on suspend, as we enable idle pc during suspend.
if (mode == HWC2::PowerMode::Off) {
- hwc_session->idle_pc_ref_cnt_ = 0;
+ idle_pc_ref_cnt_ = 0;
}
- hwc_session->UpdateThrottlingRate();
+
+ UpdateThrottlingRate();
// Trigger refresh for doze mode to take effect.
if (mode == HWC2::PowerMode::Doze) {
- hwc_session->Refresh(display);
+ Refresh(display);
// Trigger one more refresh for PP features to take effect.
- hwc_session->pending_refresh_.set(UINT32(display));
+ pending_refresh_.set(UINT32(display));
}
return HWC2_ERROR_NONE;
}
-int32_t HWCSession::SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display,
- int32_t int_enabled) {
+int32_t HWCSession::SetVsyncEnabled(hwc2_display_t display, int32_t int_enabled) {
// avoid undefined behavior in cast to HWC2::Vsync
if (int_enabled < HWC2_VSYNC_INVALID || int_enabled > HWC2_VSYNC_DISABLE) {
return HWC2_ERROR_BAD_PARAMETER;
@@ -993,59 +883,50 @@
auto enabled = static_cast<HWC2::Vsync>(int_enabled);
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
-
if (int_enabled == HWC2_VSYNC_ENABLE) {
- hwc_session->callbacks_.UpdateVsyncSource(display);
+ callbacks_.UpdateVsyncSource(display);
}
- return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
+ return CallDisplayFunction(display, &HWCDisplay::SetVsyncEnabled, enabled);
}
-int32_t HWCSession::GetDozeSupport(hwc2_device_t *device, hwc2_display_t display,
- int32_t *out_support) {
- if (!device || !out_support) {
+int32_t HWCSession::GetDozeSupport(hwc2_display_t display, int32_t *out_support) {
+ if (!out_support) {
return HWC2_ERROR_BAD_PARAMETER;
}
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- HWCDisplay *hwc_display = hwc_session->hwc_display_[display];;
- if (display >= HWCCallbacks::kNumDisplays || (hwc_display == nullptr)) {
- DLOGE("Invalid Display %d Handle %s ", display, hwc_display ?
+ if (display >= HWCCallbacks::kNumDisplays || (hwc_display_[display] == nullptr)) {
+ DLOGE("Invalid Display %d Handle %s ", display, hwc_display_[display] ?
"Valid" : "NULL");
return HWC2_ERROR_BAD_DISPLAY;
}
*out_support = 0;
- if (hwc_display->GetDisplayClass() == DISPLAY_CLASS_BUILTIN) {
+ if (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN) {
*out_support = 1;
}
return HWC2_ERROR_NONE;
}
-int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
- uint32_t *out_num_types, uint32_t *out_num_requests) {
+int32_t HWCSession::ValidateDisplay(hwc2_display_t display, uint32_t *out_num_types,
+ uint32_t *out_num_requests) {
// out_num_types and out_num_requests will be non-NULL
- if (!device) {
- return HWC2_ERROR_BAD_PARAMETER;
- }
if (display >= HWCCallbacks::kNumDisplays) {
return HWC2_ERROR_BAD_DISPLAY;
}
DTRACE_SCOPED();
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
// TODO(user): Handle secure session, handle QDCM solid fill
auto status = HWC2::Error::BadDisplay;
- hwc_session->HandleSecureSession();
+ HandleSecureSession();
{
SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
if (power_on_pending_[display]) {
status = HWC2::Error::None;
- } else if (hwc_session->hwc_display_[display]) {
- hwc_session->hwc_display_[display]->SetFastPathComposition(false);
- status = hwc_session->ValidateDisplayInternal(display, out_num_types, out_num_requests);
+ } else if (hwc_display_[display]) {
+ hwc_display_[display]->SetFastPathComposition(false);
+ status = ValidateDisplayInternal(display, out_num_types, out_num_requests);
}
}
@@ -1057,133 +938,6 @@
return INT32(status);
}
-hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
- int32_t int_descriptor) {
- auto descriptor = static_cast<HWC2::FunctionDescriptor>(int_descriptor);
-
- switch (descriptor) {
- case HWC2::FunctionDescriptor::AcceptDisplayChanges:
- return AsFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(HWCSession::AcceptDisplayChanges);
- case HWC2::FunctionDescriptor::CreateLayer:
- return AsFP<HWC2_PFN_CREATE_LAYER>(CreateLayer);
- case HWC2::FunctionDescriptor::CreateVirtualDisplay:
- return AsFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(HWCSession::CreateVirtualDisplay);
- case HWC2::FunctionDescriptor::DestroyLayer:
- return AsFP<HWC2_PFN_DESTROY_LAYER>(DestroyLayer);
- case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
- return AsFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(HWCSession::DestroyVirtualDisplay);
- case HWC2::FunctionDescriptor::Dump:
- return AsFP<HWC2_PFN_DUMP>(HWCSession::Dump);
- case HWC2::FunctionDescriptor::GetActiveConfig:
- return AsFP<HWC2_PFN_GET_ACTIVE_CONFIG>(GetActiveConfig);
- case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
- return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
- case HWC2::FunctionDescriptor::GetClientTargetSupport:
- return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
- case HWC2::FunctionDescriptor::GetColorModes:
- return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes);
- case HWC2::FunctionDescriptor::GetDisplayAttribute:
- return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
- case HWC2::FunctionDescriptor::GetDisplayConfigs:
- return AsFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(GetDisplayConfigs);
- case HWC2::FunctionDescriptor::GetDisplayName:
- return AsFP<HWC2_PFN_GET_DISPLAY_NAME>(GetDisplayName);
- case HWC2::FunctionDescriptor::GetDisplayRequests:
- return AsFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(GetDisplayRequests);
- case HWC2::FunctionDescriptor::GetDisplayType:
- return AsFP<HWC2_PFN_GET_DISPLAY_TYPE>(GetDisplayType);
- case HWC2::FunctionDescriptor::GetHdrCapabilities:
- return AsFP<HWC2_PFN_GET_HDR_CAPABILITIES>(GetHdrCapabilities);
- case HWC2::FunctionDescriptor::GetDozeSupport:
- return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
- case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
- return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(HWCSession::GetMaxVirtualDisplayCount);
- case HWC2::FunctionDescriptor::GetReleaseFences:
- return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
- case HWC2::FunctionDescriptor::PresentDisplay:
- return AsFP<HWC2_PFN_PRESENT_DISPLAY>(PresentDisplay);
- case HWC2::FunctionDescriptor::RegisterCallback:
- return AsFP<HWC2_PFN_REGISTER_CALLBACK>(RegisterCallback);
- case HWC2::FunctionDescriptor::SetActiveConfig:
- return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
- case HWC2::FunctionDescriptor::SetClientTarget:
- return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
- case HWC2::FunctionDescriptor::SetColorMode:
- return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode);
- case HWC2::FunctionDescriptor::SetColorTransform:
- return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform);
- case HWC2::FunctionDescriptor::SetCursorPosition:
- return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
- case HWC2::FunctionDescriptor::SetLayerBlendMode:
- return AsFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(SetLayerBlendMode);
- case HWC2::FunctionDescriptor::SetLayerBuffer:
- return AsFP<HWC2_PFN_SET_LAYER_BUFFER>(SetLayerBuffer);
- case HWC2::FunctionDescriptor::SetLayerColor:
- return AsFP<HWC2_PFN_SET_LAYER_COLOR>(SetLayerColor);
- case HWC2::FunctionDescriptor::SetLayerCompositionType:
- return AsFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(SetLayerCompositionType);
- case HWC2::FunctionDescriptor::SetLayerDataspace:
- return AsFP<HWC2_PFN_SET_LAYER_DATASPACE>(SetLayerDataspace);
- case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
- return AsFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(SetLayerDisplayFrame);
- case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
- return AsFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(SetLayerPlaneAlpha);
- // Sideband stream is not supported
- // case HWC2::FunctionDescriptor::SetLayerSidebandStream:
- case HWC2::FunctionDescriptor::SetLayerSourceCrop:
- return AsFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(SetLayerSourceCrop);
- case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
- return AsFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(SetLayerSurfaceDamage);
- case HWC2::FunctionDescriptor::SetLayerTransform:
- return AsFP<HWC2_PFN_SET_LAYER_TRANSFORM>(SetLayerTransform);
- case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
- return AsFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(SetLayerVisibleRegion);
- case HWC2::FunctionDescriptor::SetLayerZOrder:
- return AsFP<HWC2_PFN_SET_LAYER_Z_ORDER>(SetLayerZOrder);
- case HWC2::FunctionDescriptor::SetOutputBuffer:
- return AsFP<HWC2_PFN_SET_OUTPUT_BUFFER>(SetOutputBuffer);
- case HWC2::FunctionDescriptor::SetPowerMode:
- return AsFP<HWC2_PFN_SET_POWER_MODE>(SetPowerMode);
- case HWC2::FunctionDescriptor::SetVsyncEnabled:
- return AsFP<HWC2_PFN_SET_VSYNC_ENABLED>(SetVsyncEnabled);
- case HWC2::FunctionDescriptor::ValidateDisplay:
- return AsFP<HWC2_PFN_VALIDATE_DISPLAY>(HWCSession::ValidateDisplay);
- case HWC2::FunctionDescriptor::SetReadbackBuffer:
- return AsFP<HWC2_PFN_SET_READBACK_BUFFER>(HWCSession::SetReadbackBuffer);
- case HWC2::FunctionDescriptor::GetReadbackBufferAttributes:
- return AsFP<HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES>(HWCSession::GetReadbackBufferAttributes);
- case HWC2::FunctionDescriptor::GetReadbackBufferFence:
- return AsFP<HWC2_PFN_GET_READBACK_BUFFER_FENCE>(HWCSession::GetReadbackBufferFence);
- case HWC2::FunctionDescriptor::GetRenderIntents:
- return AsFP<HWC2_PFN_GET_RENDER_INTENTS>(GetRenderIntents);
- case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
- return AsFP<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>
- (HWCSession::SetColorModeWithRenderIntent);
- case HWC2::FunctionDescriptor::GetDataspaceSaturationMatrix:
- return AsFP<HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX>(GetDataspaceSaturationMatrix);
- case HWC2::FunctionDescriptor::GetPerFrameMetadataKeys:
- return AsFP<HWC2_PFN_GET_PER_FRAME_METADATA_KEYS>(GetPerFrameMetadataKeys);
- case HWC2::FunctionDescriptor::SetLayerPerFrameMetadata:
- return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA>(SetLayerPerFrameMetadata);
- case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
- return AsFP<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>
- (HWCSession::GetDisplayIdentificationData);
- case HWC2::FunctionDescriptor::SetLayerColorTransform:
- return AsFP<HWC2_PFN_SET_LAYER_COLOR_TRANSFORM>(SetLayerColorTransform);
- case HWC2::FunctionDescriptor::GetDisplayCapabilities:
- return AsFP<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(HWCSession::GetDisplayCapabilities);
- case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
- return AsFP<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(HWCSession::GetDisplayBrightnessSupport);
- case HWC2::FunctionDescriptor::SetDisplayBrightness:
- return AsFP<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(HWCSession::SetDisplayBrightness);
- default:
- DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
- to_string(descriptor).c_str());
- return nullptr;
- }
- return nullptr;
-}
-
HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height, int32_t *format,
hwc2_display_t *out_display_id) {
if (!client_connected_) {
@@ -1457,11 +1211,10 @@
break;
}
int level = input_parcel->readInt32();
- hwc2_device_t *device = static_cast<hwc2_device_t *>(this);
if (level == 0) {
- status = SetDisplayBrightness(device, HWC_DISPLAY_PRIMARY, -1.0f);
+ status = SetDisplayBrightness(HWC_DISPLAY_PRIMARY, -1.0f);
} else {
- status = SetDisplayBrightness(device, HWC_DISPLAY_PRIMARY, (level - 1)/254.0f);
+ status = SetDisplayBrightness(HWC_DISPLAY_PRIMARY, (level - 1)/254.0f);
}
output_parcel->writeInt32(status);
}
@@ -1795,7 +1548,6 @@
android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
int display = static_cast<int>(input_parcel->readInt32());
auto mode = static_cast<ColorMode>(input_parcel->readInt32());
- auto device = static_cast<hwc2_device_t *>(this);
int disp_idx = GetDisplayIndex(display);
if (disp_idx == -1) {
@@ -1807,8 +1559,8 @@
DLOGE("Invalid ColorMode: %d", mode);
return HWC2_ERROR_BAD_PARAMETER;
}
- auto err = CallDisplayFunction(device, static_cast<hwc2_display_t>(disp_idx),
- &HWCDisplay::SetColorMode, mode);
+ auto err = CallDisplayFunction(static_cast<hwc2_display_t>(disp_idx), &HWCDisplay::SetColorMode,
+ mode);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
@@ -1828,9 +1580,8 @@
return static_cast<android::status_t>(SetDisplayDppsAdROI(display_id, h_s, h_e, v_s,
v_e, f_in, f_out));
#else
- auto err = CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id,
- &HWCDisplay::SetDisplayDppsAdROI, h_s, h_e, v_s, v_e,
- f_in, f_out);
+ auto err = CallDisplayFunction(display_id, &HWCDisplay::SetDisplayDppsAdROI,
+ h_s, h_e, v_s, v_e, f_in, f_out);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
@@ -1848,8 +1599,7 @@
return -EINVAL;
}
- auto err = CallDisplayFunction(static_cast<hwc2_device_t *>(this),
- static_cast<hwc2_display_t>(disp_idx),
+ auto err = CallDisplayFunction(static_cast<hwc2_display_t>(disp_idx),
&HWCDisplay::SetFrameTriggerMode, mode);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
@@ -1862,7 +1612,6 @@
auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
auto mode = static_cast<ColorMode>(input_parcel->readInt32());
auto int_intent = static_cast<int>(input_parcel->readInt32());
- auto device = static_cast<hwc2_device_t *>(this);
if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_BT2020) {
DLOGE("Invalid ColorMode: %d", mode);
@@ -1876,7 +1625,7 @@
auto intent = static_cast<RenderIntent>(int_intent);
auto err =
- CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent, mode, intent);
+ CallDisplayFunction(display, &HWCDisplay::SetColorModeWithRenderIntent, mode, intent);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
@@ -1885,7 +1634,6 @@
android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
int display = input_parcel->readInt32();
auto mode = input_parcel->readInt32();
- auto device = static_cast<hwc2_device_t *>(this);
int disp_idx = GetDisplayIndex(display);
if (disp_idx == -1) {
@@ -1893,7 +1641,7 @@
return -EINVAL;
}
- auto err = CallDisplayFunction(device, static_cast<hwc2_display_t>(disp_idx),
+ auto err = CallDisplayFunction(static_cast<hwc2_display_t>(disp_idx),
&HWCDisplay::SetColorModeById, mode);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
@@ -1904,7 +1652,6 @@
android::status_t HWCSession::SetColorModeFromClient(const android::Parcel *input_parcel) {
int display = input_parcel->readInt32();
auto mode = input_parcel->readInt32();
- auto device = static_cast<hwc2_device_t *>(this);
int disp_idx = GetDisplayIndex(display);
if (disp_idx == -1) {
@@ -1912,7 +1659,7 @@
return -EINVAL;
}
- auto err = CallDisplayFunction(device, static_cast<hwc2_display_t>(disp_idx),
+ auto err = CallDisplayFunction(static_cast<hwc2_display_t>(disp_idx),
&HWCDisplay::SetColorModeFromClientApi, mode);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
@@ -2017,9 +1764,7 @@
return ret;
}
- ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload,
- resp_payload,
- pending_action);
+ ret = hwc_display_[display_id]->ColorSVCRequestRoute(req_payload, resp_payload, pending_action);
return ret;
}
@@ -2105,13 +1850,11 @@
if (brightness == NULL) {
DLOGE("Brightness payload is Null");
} else {
- ret = INT(SetDisplayBrightness(static_cast<hwc2_device_t *>(this),
- static_cast<hwc2_display_t>(display_id), *brightness));
+ ret = INT(SetDisplayBrightness(static_cast<hwc2_display_t>(display_id), *brightness));
}
break;
case kEnableFrameCapture:
- ret = color_mgr_->SetFrameCapture(pending_action.params, true,
- hwc_display_[display_id]);
+ ret = color_mgr_->SetFrameCapture(pending_action.params, true, hwc_display_[display_id]);
Refresh(display_id);
break;
case kDisableFrameCapture:
@@ -2119,8 +1862,7 @@
hwc_display_[display_id]);
break;
case kConfigureDetailedEnhancer:
- ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
- hwc_display_[display_id]);
+ ret = color_mgr_->SetDetailedEnhancer(pending_action.params, hwc_display_[display_id]);
Refresh(display_id);
break;
case kModeSet:
@@ -2136,8 +1878,7 @@
if (id < HWCCallbacks::kNumDisplays && hwc_display_[id]) {
int result = 0;
resp_payload.DestroyPayload();
- result = hwc_display_[id]->ColorSVCRequestRoute(req_payload,
- &resp_payload,
+ result = hwc_display_[id]->ColorSVCRequestRoute(req_payload, &resp_payload,
&pending_action);
if (result) {
DLOGW("Failed to dispatch action to disp %d ret %d", id, result);
@@ -3013,9 +2754,9 @@
}
}
-int32_t HWCSession::GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_display_t display,
- int32_t *format, int32_t *dataspace) {
- if (!device || !format || !dataspace) {
+int32_t HWCSession::GetReadbackBufferAttributes(hwc2_display_t display, int32_t *format,
+ int32_t *dataspace) {
+ if (!format || !dataspace) {
return HWC2_ERROR_BAD_PARAMETER;
}
@@ -3023,8 +2764,7 @@
return HWC2_ERROR_BAD_DISPLAY;
}
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- HWCDisplay *hwc_display = hwc_session->hwc_display_[display];
+ HWCDisplay *hwc_display = hwc_display_[display];
if (hwc_display) {
*format = HAL_PIXEL_FORMAT_RGB_888;
@@ -3035,8 +2775,8 @@
return HWC2_ERROR_BAD_DISPLAY;
}
-int32_t HWCSession::SetReadbackBuffer(hwc2_device_t *device, hwc2_display_t display,
- const native_handle_t *buffer, int32_t acquire_fence) {
+int32_t HWCSession::SetReadbackBuffer(hwc2_display_t display, const native_handle_t *buffer,
+ int32_t acquire_fence) {
if (!buffer) {
return HWC2_ERROR_BAD_PARAMETER;
}
@@ -3045,18 +2785,16 @@
return HWC2_ERROR_BAD_DISPLAY;
}
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL] ||
- hwc_session->hwc_display_[qdutils::DISPLAY_VIRTUAL]) {
+ if (hwc_display_[HWC_DISPLAY_EXTERNAL] ||
+ hwc_display_[qdutils::DISPLAY_VIRTUAL]) {
return HWC2_ERROR_UNSUPPORTED;
}
- return CallDisplayFunction(device, display, &HWCDisplay::SetReadbackBuffer,
- buffer, acquire_fence, false);
+ return CallDisplayFunction(display, &HWCDisplay::SetReadbackBuffer, buffer, acquire_fence,
+ false);
}
-int32_t HWCSession::GetReadbackBufferFence(hwc2_device_t *device, hwc2_display_t display,
- int32_t *release_fence) {
+int32_t HWCSession::GetReadbackBufferFence(hwc2_display_t display, int32_t *release_fence) {
if (!release_fence) {
return HWC2_ERROR_BAD_PARAMETER;
}
@@ -3065,12 +2803,11 @@
return HWC2_ERROR_BAD_DISPLAY;
}
- return CallDisplayFunction(device, display, &HWCDisplay::GetReadbackBufferFence, release_fence);
+ return CallDisplayFunction(display, &HWCDisplay::GetReadbackBufferFence, release_fence);
}
-int32_t HWCSession::GetDisplayIdentificationData(hwc2_device_t *device, hwc2_display_t display,
- uint8_t *outPort, uint32_t *outDataSize,
- uint8_t *outData) {
+int32_t HWCSession::GetDisplayIdentificationData(hwc2_display_t display, uint8_t *outPort,
+ uint32_t *outDataSize, uint8_t *outData) {
if (!outPort || !outDataSize) {
return HWC2_ERROR_BAD_PARAMETER;
}
@@ -3079,14 +2816,13 @@
return HWC2_ERROR_BAD_DISPLAY;
}
- return CallDisplayFunction(device, display, &HWCDisplay::GetDisplayIdentificationData, outPort,
+ return CallDisplayFunction(display, &HWCDisplay::GetDisplayIdentificationData, outPort,
outDataSize, outData);
}
-int32_t HWCSession::GetDisplayCapabilities(hwc2_device_t *device, hwc2_display_t display,
- uint32_t *outNumCapabilities,
+int32_t HWCSession::GetDisplayCapabilities(hwc2_display_t display, uint32_t *outNumCapabilities,
uint32_t *outCapabilities) {
- if (!outNumCapabilities || !device) {
+ if (!outNumCapabilities) {
return HWC2_ERROR_BAD_PARAMETER;
}
@@ -3094,13 +2830,11 @@
return HWC2_ERROR_BAD_DISPLAY;
}
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- HWCDisplay *hwc_display = hwc_session->hwc_display_[display];
- if (!hwc_display) {
+ if (!hwc_display_[display]) {
DLOGE("Expected valid hwc_display");
return HWC2_ERROR_BAD_PARAMETER;
}
- bool isBuiltin = (hwc_display->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
+ bool isBuiltin = (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
if (!outCapabilities) {
*outNumCapabilities = 0;
if (isBuiltin) {
@@ -3119,9 +2853,8 @@
}
}
-int32_t HWCSession::GetDisplayBrightnessSupport(hwc2_device_t *device, hwc2_display_t display,
- bool *outSupport) {
- if (!device || !outSupport) {
+int32_t HWCSession::GetDisplayBrightnessSupport(hwc2_display_t display, bool *outSupport) {
+ if (!outSupport) {
return HWC2_ERROR_BAD_PARAMETER;
}
@@ -3129,24 +2862,20 @@
return HWC2_ERROR_BAD_DISPLAY;
}
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
- HWCDisplay *hwc_display = hwc_session->hwc_display_[display];
- if (!hwc_display) {
+ if (!hwc_display_[display]) {
DLOGE("Expected valid hwc_display");
return HWC2_ERROR_BAD_PARAMETER;
}
- *outSupport = (hwc_display->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
+ *outSupport = (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
return HWC2_ERROR_NONE;
}
-int32_t HWCSession::SetDisplayBrightness(hwc2_device_t *device, hwc2_display_t display,
- float brightness) {
- return CallDisplayFunction(device, display, &HWCDisplay::SetPanelBrightness, brightness);
+int32_t HWCSession::SetDisplayBrightness(hwc2_display_t display, float brightness) {
+ return CallDisplayFunction(display, &HWCDisplay::SetPanelBrightness, brightness);
}
android::status_t HWCSession::SetQSyncMode(const android::Parcel *input_parcel) {
auto mode = input_parcel->readInt32();
- auto device = static_cast<hwc2_device_t *>(this);
QSyncMode qsync_mode = kQSyncModeNone;
switch (mode) {
@@ -3163,7 +2892,7 @@
DLOGE("Qsync mode not supported %d", mode);
return -EINVAL;
}
- return CallDisplayFunction(device, HWC_DISPLAY_PRIMARY, &HWCDisplay::SetQSyncMode, qsync_mode);
+ return CallDisplayFunction(HWC_DISPLAY_PRIMARY, &HWCDisplay::SetQSyncMode, qsync_mode);
}
void HWCSession::UpdateThrottlingRate() {
diff --git a/composer/hwc_session.h b/composer/hwc_session.h
index e8ab1ff..7a858fa 100644
--- a/composer/hwc_session.h
+++ b/composer/hwc_session.h
@@ -121,64 +121,49 @@
class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qClient::BnQClient,
public HWCDisplayEventHandler {
public:
- struct HWCModuleMethods : public hw_module_methods_t {
- HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; }
- };
-
enum HotPlugEvent {
kHotPlugNone,
kHotPlugEvent,
};
- explicit HWCSession(const hw_module_t *module);
+ HWCSession();
int Init();
int Deinit();
HWC2::Error CreateVirtualDisplayObj(uint32_t width, uint32_t height, int32_t *format,
hwc2_display_t *out_display_id);
template <typename... Args>
- static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display,
- HWC2::Error (HWCDisplay::*member)(Args...), Args... args) {
- if (!device) {
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
+ int32_t CallDisplayFunction(hwc2_display_t display, HWC2::Error (HWCDisplay::*member)(Args...),
+ Args... args) {
if (display >= HWCCallbacks::kNumDisplays) {
return HWC2_ERROR_BAD_DISPLAY;
}
SCOPE_LOCK(locker_[display]);
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
auto status = HWC2::Error::BadDisplay;
- if (hwc_session->hwc_display_[display]) {
- auto hwc_display = hwc_session->hwc_display_[display];
+ if (hwc_display_[display]) {
+ auto hwc_display = hwc_display_[display];
status = (hwc_display->*member)(std::forward<Args>(args)...);
}
return INT32(status);
}
template <typename... Args>
- static int32_t CallLayerFunction(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args...),
- Args... args) {
- if (!device) {
- return HWC2_ERROR_BAD_PARAMETER;
- }
-
+ int32_t CallLayerFunction(hwc2_display_t display, hwc2_layer_t layer,
+ HWC2::Error (HWCLayer::*member)(Args...), Args... args) {
if (display >= HWCCallbacks::kNumDisplays) {
return HWC2_ERROR_BAD_DISPLAY;
}
SCOPE_LOCK(locker_[display]);
- HWCSession *hwc_session = static_cast<HWCSession *>(device);
auto status = HWC2::Error::BadDisplay;
- if (hwc_session->hwc_display_[display]) {
+ if (hwc_display_[display]) {
status = HWC2::Error::BadLayer;
- auto hwc_layer = hwc_session->hwc_display_[display]->GetHWCLayer(layer);
+ auto hwc_layer = hwc_display_[display]->GetHWCLayer(layer);
if (hwc_layer != nullptr) {
status = (hwc_layer->*member)(std::forward<Args>(args)...);
- if (hwc_session->hwc_display_[display]->GetGeometryChanges()) {
- hwc_session->hwc_display_[display]->ResetValidation();
+ if (hwc_display_[display]->GetGeometryChanges()) {
+ hwc_display_[display]->ResetValidation();
}
}
}
@@ -187,55 +172,97 @@
// HWC2 Functions that require a concrete implementation in hwc session
// and hence need to be member functions
- static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display);
- static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
- hwc2_layer_t *out_layer_id);
- static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
- int32_t *format, hwc2_display_t *out_display_id);
- static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer);
- static int32_t DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display);
- static void Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer);
- static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
- int32_t *out_retire_fence);
- static int32_t RegisterCallback(hwc2_device_t *device, int32_t descriptor,
- hwc2_callback_data_t callback_data,
- hwc2_function_pointer_t pointer);
- static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
- buffer_handle_t buffer, int32_t releaseFence);
- static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode);
- static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
- uint32_t *out_num_types, uint32_t *out_num_requests);
- static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display,
- int32_t /*ColorMode*/ int_mode);
- static int32_t SetColorModeWithRenderIntent(hwc2_device_t *device, hwc2_display_t display,
- int32_t /*ColorMode*/ int_mode,
- int32_t /*RenderIntent*/ int_render_intent);
- static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
- const float *matrix, int32_t /*android_color_transform_t*/ hint);
- static int32_t GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_display_t display,
- int32_t *format, int32_t *dataspace);
- static int32_t SetReadbackBuffer(hwc2_device_t *device, hwc2_display_t display,
- const native_handle_t *buffer, int32_t acquire_fence);
- static int32_t GetReadbackBufferFence(hwc2_device_t *device, hwc2_display_t display,
- int32_t *release_fence);
- static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device);
- static int32_t GetDisplayIdentificationData(hwc2_device_t *device, hwc2_display_t display,
- uint8_t *outPort, uint32_t *outDataSize,
- uint8_t *outData);
- static int32_t GetDisplayCapabilities(hwc2_device_t *device, hwc2_display_t display,
- uint32_t *outNumCapabilities, uint32_t *outCapabilities);
- static int32_t GetDisplayBrightnessSupport(hwc2_device_t *device, hwc2_display_t display,
- bool *outSupport);
- static int32_t SetDisplayBrightness(hwc2_device_t *device, hwc2_display_t display,
- float brightness);
+ static HWCSession *GetInstance();
+ void GetCapabilities(uint32_t *outCount, int32_t *outCapabilities);
+ void Dump(uint32_t *out_size, char *out_buffer);
+
+ int32_t AcceptDisplayChanges(hwc2_display_t display);
+ int32_t CreateLayer(hwc2_display_t display, hwc2_layer_t *out_layer_id);
+ int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t *format,
+ hwc2_display_t *out_display_id);
+ int32_t DestroyLayer(hwc2_display_t display, hwc2_layer_t layer);
+ int32_t DestroyVirtualDisplay(hwc2_display_t display);
+ int32_t PresentDisplay(hwc2_display_t display, int32_t *out_retire_fence);
+ void RegisterCallback(int32_t descriptor, hwc2_callback_data_t callback_data,
+ hwc2_function_pointer_t pointer);
+ int32_t SetOutputBuffer(hwc2_display_t display, buffer_handle_t buffer, int32_t releaseFence);
+ int32_t SetPowerMode(hwc2_display_t display, int32_t int_mode);
+ int32_t ValidateDisplay(hwc2_display_t display, uint32_t *out_num_types,
+ uint32_t *out_num_requests);
+ int32_t SetColorMode(hwc2_display_t display, int32_t /*ColorMode*/ int_mode);
+ int32_t SetColorModeWithRenderIntent(hwc2_display_t display, int32_t /*ColorMode*/ int_mode,
+ int32_t /*RenderIntent*/ int_render_intent);
+ int32_t SetColorTransform(hwc2_display_t display, const float *matrix,
+ int32_t /*android_color_transform_t*/ hint);
+ int32_t GetReadbackBufferAttributes(hwc2_display_t display,
+ int32_t *format, int32_t *dataspace);
+ int32_t SetReadbackBuffer(hwc2_display_t display, const native_handle_t *buffer,
+ int32_t acquire_fence);
+ int32_t GetReadbackBufferFence(hwc2_display_t display, int32_t *release_fence);
+ uint32_t GetMaxVirtualDisplayCount();
+ int32_t GetDisplayIdentificationData(hwc2_display_t display, uint8_t *outPort,
+ uint32_t *outDataSize, uint8_t *outData);
+ int32_t GetDisplayCapabilities(hwc2_display_t display, uint32_t *outNumCapabilities,
+ uint32_t *outCapabilities);
+ int32_t GetDisplayBrightnessSupport(hwc2_display_t display, bool *outSupport);
+ int32_t SetDisplayBrightness(hwc2_display_t display, float brightness);
+
+ // newly added
+ int32_t GetDisplayType(hwc2_display_t display, int32_t *out_type);
+ int32_t GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
+ int32_t int_attribute, int32_t *out_value);
+ int32_t GetActiveConfig(hwc2_display_t display, hwc2_config_t *out_config);
+ int32_t GetColorModes(hwc2_display_t display, uint32_t *out_num_modes,
+ int32_t /*ColorMode*/ *int_out_modes);
+ int32_t GetRenderIntents(hwc2_display_t display, int32_t /*ColorMode*/ int_mode,
+ uint32_t *out_num_intents, int32_t /*RenderIntent*/ *int_out_intents);
+ int32_t GetHdrCapabilities(hwc2_display_t display, uint32_t* out_num_types, int32_t* out_types,
+ float* out_max_luminance, float* out_max_average_luminance,
+ float* out_min_luminance);
+ int32_t GetPerFrameMetadataKeys(hwc2_display_t display, uint32_t *out_num_keys,
+ int32_t *int_out_keys);
+ int32_t GetClientTargetSupport(hwc2_display_t display, uint32_t width, uint32_t height,
+ int32_t format, int32_t dataspace);
+ int32_t GetDisplayName(hwc2_display_t display, uint32_t *out_size, char *out_name);
+ int32_t SetActiveConfig(hwc2_display_t display, hwc2_config_t config);
+ int32_t GetChangedCompositionTypes(hwc2_display_t display, uint32_t *out_num_elements,
+ hwc2_layer_t *out_layers, int32_t *out_types);
+ int32_t GetDisplayRequests(hwc2_display_t display, int32_t *out_display_requests,
+ uint32_t *out_num_elements, hwc2_layer_t *out_layers,
+ int32_t *out_layer_requests);
+ int32_t GetReleaseFences(hwc2_display_t display, uint32_t *out_num_elements,
+ hwc2_layer_t *out_layers, int32_t *out_fences);
+ int32_t SetClientTarget(hwc2_display_t display, buffer_handle_t target, int32_t acquire_fence,
+ int32_t dataspace, hwc_region_t damage);
+ int32_t SetCursorPosition(hwc2_display_t display, hwc2_layer_t layer, int32_t x, int32_t y);
+ int32_t GetDataspaceSaturationMatrix(int32_t /*Dataspace*/ int_dataspace, float *out_matrix);
+
+ // Layer functions
+ int32_t SetLayerBuffer(hwc2_display_t display, hwc2_layer_t layer, buffer_handle_t buffer,
+ int32_t acquire_fence);
+ int32_t SetLayerBlendMode(hwc2_display_t display, hwc2_layer_t layer, int32_t int_mode);
+ int32_t SetLayerDisplayFrame(hwc2_display_t display, hwc2_layer_t layer, hwc_rect_t frame);
+ int32_t SetLayerPlaneAlpha(hwc2_display_t display, hwc2_layer_t layer, float alpha);
+ int32_t SetLayerSourceCrop(hwc2_display_t display, hwc2_layer_t layer, hwc_frect_t crop);
+ int32_t SetLayerTransform(hwc2_display_t display, hwc2_layer_t layer, int32_t int_transform);
+ int32_t SetLayerZOrder(hwc2_display_t display, hwc2_layer_t layer, uint32_t z);
+ int32_t SetLayerSurfaceDamage(hwc2_display_t display, hwc2_layer_t layer, hwc_region_t damage);
+ int32_t SetLayerVisibleRegion(hwc2_display_t display, hwc2_layer_t layer, hwc_region_t damage);
+ int32_t SetLayerCompositionType(hwc2_display_t display, hwc2_layer_t layer, int32_t int_type);
+ int32_t SetLayerColor(hwc2_display_t display, hwc2_layer_t layer, hwc_color_t color);
+ int32_t SetLayerDataspace(hwc2_display_t display, hwc2_layer_t layer, int32_t dataspace);
+ int32_t SetLayerPerFrameMetadata(hwc2_display_t display, hwc2_layer_t layer,
+ uint32_t num_elements, const int32_t *int_keys,
+ const float *metadata);
+ int32_t SetLayerColorTransform(hwc2_display_t display, hwc2_layer_t layer, const float *matrix);
// HWCDisplayEventHandler
virtual void DisplayPowerReset();
- static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display,
- int32_t int_enabled);
- static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display,
- int32_t *out_support);
+ int32_t SetVsyncEnabled(hwc2_display_t display, int32_t int_enabled);
+ int32_t GetDozeSupport(hwc2_display_t display, int32_t *out_support);
+ int32_t GetDisplayConfigs(hwc2_display_t display, uint32_t *out_num_configs,
+ hwc2_config_t *out_configs);
static Locker locker_[HWCCallbacks::kNumDisplays];
@@ -258,12 +285,6 @@
uint32_t throttling_refresh_rate_ = 60;
void UpdateThrottlingRate();
void SetNewThrottlingRate(uint32_t new_rate);
- // hwc methods
- static int Open(const hw_module_t *module, const char *name, hw_device_t **device);
- static int Close(hw_device_t *device);
- static void GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
- int32_t *outCapabilities);
- static hwc2_function_pointer_t GetFunction(struct hwc2_device *device, int32_t descriptor);
// Uevent handler
virtual void UEventHandler(const char *uevent_data, int length);
@@ -298,9 +319,9 @@
Return<void> isDisplayConnected(IDisplayConfig::DisplayType dpy,
isDisplayConnected_cb _hidl_cb) override;
Return<int32_t> setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy,
- IDisplayConfig::DisplayExternalStatus status) override;
+ IDisplayConfig::DisplayExternalStatus status) override;
Return<int32_t> configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op,
- uint32_t refreshRate) override;
+ uint32_t refreshRate) override;
Return<void> getConfigCount(IDisplayConfig::DisplayType dpy,
getConfigCount_cb _hidl_cb) override;
Return<void> getActiveConfig(IDisplayConfig::DisplayType dpy,
@@ -450,7 +471,6 @@
float set_min_lum_ = -1.0;
std::bitset<HWCCallbacks::kNumDisplays> pending_refresh_;
};
-
} // namespace sdm
#endif // __HWC_SESSION_H__
diff --git a/composer/hwc_session_services.cpp b/composer/hwc_session_services.cpp
index fb5a8dc..8232b94 100644
--- a/composer/hwc_session_services.cpp
+++ b/composer/hwc_session_services.cpp
@@ -295,11 +295,10 @@
return -EINVAL;
}
- hwc2_device_t *device = static_cast<hwc2_device_t *>(this);
if (level == 0) {
- return INT32(SetDisplayBrightness(device, HWC_DISPLAY_PRIMARY, -1.0f));
+ return INT32(SetDisplayBrightness(HWC_DISPLAY_PRIMARY, -1.0f));
} else {
- return INT32(SetDisplayBrightness(device, HWC_DISPLAY_PRIMARY, (level - 1)/254.0f));
+ return INT32(SetDisplayBrightness(HWC_DISPLAY_PRIMARY, (level - 1)/254.0f));
}
}
@@ -548,7 +547,7 @@
#ifdef DISPLAY_CONFIG_1_1
Return<int32_t> HWCSession::setDisplayAnimating(uint64_t display_id, bool animating ) {
- return CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id,
+ return CallDisplayFunction(display_id,
&HWCDisplay::SetDisplayAnimating, animating);
}
#endif
@@ -639,7 +638,7 @@
Return<int32_t> HWCSession::SetDisplayDppsAdROI(uint32_t display_id, uint32_t h_start,
uint32_t h_end, uint32_t v_start, uint32_t v_end,
uint32_t factor_in, uint32_t factor_out) {
- return CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id,
+ return CallDisplayFunction(display_id,
&HWCDisplay::SetDisplayDppsAdROI, h_start, h_end, v_start, v_end,
factor_in, factor_out);
}
@@ -799,8 +798,7 @@
}
int32_t HWCSession::setDisplayBrightness(uint32_t display, float brightness) {
- return SetDisplayBrightness(static_cast<hwc2_device_t *>(this),
- static_cast<hwc2_display_t>(display), brightness);
+ return SetDisplayBrightness(static_cast<hwc2_display_t>(display), brightness);
}
#ifdef DISPLAY_CONFIG_1_9
diff --git a/composer/service.cpp b/composer/service.cpp
new file mode 100644
index 0000000..b0f757a
--- /dev/null
+++ b/composer/service.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <hidl/LegacySupport.h>
+#include "QtiComposer.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::ProcessState;
+using vendor::qti::hardware::display::composer::V1_0::implementation::QtiComposer;
+using vendor::qti::hardware::display::composer::V1_0::IQtiComposer;
+using android::hardware::graphics::composer::V2_3::IComposer;
+using android::sp;
+
+int main(int, char **) {
+ // TODO(user): double-check for SCHED_FIFO logic
+ // the conventional HAL might start binder services
+ ProcessState::initWithDriver("/dev/vndbinder");
+ sp<ProcessState> ps(ProcessState::self());
+ ps->setThreadPoolMaxThreadCount(4);
+ ps->startThreadPool();
+
+ // same as SF main thread
+ struct sched_param param = {0};
+ param.sched_priority = 2;
+ if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m) != 0) {
+ ALOGE("Couldn't set SCHED_FIFO: %d", errno);
+ }
+
+ sp<IQtiComposer> composer = QtiComposer::initialize();
+ if (composer == nullptr) {
+ ALOGE("Cannot initialize composer");
+ return -EINVAL;
+ }
+
+ configureRpcThreadpool(4, true /*callerWillJoin*/);
+ if (composer->registerAsService() != android::OK) {
+ ALOGE("Cannot register QTI composer service");
+ return -EINVAL;
+ }
+
+ ALOGI("Initialized qti-composer");
+ joinRpcThreadpool();
+ return 0;
+}
diff --git a/composer/vendor.qti.hardware.display.composer@1.0-service.rc b/composer/vendor.qti.hardware.display.composer@1.0-service.rc
new file mode 100644
index 0000000..ad56c05
--- /dev/null
+++ b/composer/vendor.qti.hardware.display.composer@1.0-service.rc
@@ -0,0 +1,6 @@
+service vendor.qti.hardware.display.composer /vendor/bin/hw/vendor.qti.hardware.display.composer@1.0-service
+ class hal animation
+ user system
+ group graphics drmrpc
+ capabilities SYS_NICE
+ onrestart restart surfaceflinger
diff --git a/config/display-product.mk b/config/display-product.mk
index a39e1c6..6831002 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -1,9 +1,8 @@
# Display product definitions
PRODUCT_PACKAGES += \
- android.hardware.graphics.composer@2.3-impl \
- android.hardware.graphics.composer@2.3-service \
android.hardware.graphics.mapper@2.0-impl-qti-display \
vendor.qti.hardware.display.allocator-service \
+ vendor.qti.hardware.display.composer@1.0-service \
android.hardware.memtrack@1.0-impl \
android.hardware.memtrack@1.0-service \
android.hardware.light@2.0-impl \