diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2020-06-22 02:02:32 -0700 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2020-06-22 02:02:32 -0700 |
commit | 072ccf579182603ace8585fa1e3877a4f67f0ee5 (patch) | |
tree | 45af16ac5d19a964f68c43da4013d8b52427e6b5 | |
parent | 5cb873b898548610e26cb6ab237d219321830b2f (diff) | |
parent | 682b9c031d4ad3c6bdca30e7c68465c0b2f727ef (diff) |
Merge 682b9c031d4ad3c6bdca30e7c68465c0b2f727ef on remote branch
Change-Id: I2ecf504b81e348b19f393445faac0d83fa8c7d4d
51 files changed, 3768 insertions, 670 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk index 3cb763d8..e3eda5b0 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -5,6 +5,9 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib64/hw/android.hardware.gr $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.graphics.composer@2.2-service) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.graphics.composer@2.2-service.rc) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib64/hw/android.hardware.graphics.composer@2.2-impl.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.graphics.composer@2.3-service) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.graphics.composer@2.3-service.rc) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib64/hw/android.hardware.graphics.composer@2.3-impl.so) # Clean old target objs diff --git a/config/display-board.mk b/config/display-board.mk index 29f540b9..db15d83c 100644 --- a/config/display-board.mk +++ b/config/display-board.mk @@ -17,3 +17,4 @@ TARGET_USE_COLOR_MANAGEMENT := true SF_WCG_COMPOSITION_DATA_SPACE := 143261696 TARGET_USES_QTI_MAPPER_2_0 := true TARGET_USES_QTI_MAPPER_EXTENSIONS_1_1 := true +TARGET_USES_GRALLOC4 := true diff --git a/config/display-product.mk b/config/display-product.mk index 4e8dcafb..fbab0028 100644 --- a/config/display-product.mk +++ b/config/display-product.mk @@ -1,8 +1,9 @@ # Display product definitions PRODUCT_PACKAGES += \ - android.hardware.graphics.composer@2.3-impl \ - android.hardware.graphics.composer@2.3-service \ + android.hardware.graphics.composer@2.4-impl \ + android.hardware.graphics.composer@2.4-service \ android.hardware.graphics.mapper@3.0-impl-qti-display \ + android.hardware.graphics.mapper@4.0-impl-qti-display \ vendor.qti.hardware.display.allocator-service \ android.hardware.memtrack@1.0-impl \ android.hardware.memtrack@1.0-service \ @@ -14,6 +15,7 @@ PRODUCT_PACKAGES += \ memtrack.$(TARGET_BOARD_PLATFORM) \ libqdMetaData.vendor \ libdisplayconfig.vendor \ + libdisplayconfig.qti.vendor \ vendor.display.config@1.0.vendor \ vendor.display.config@1.1.vendor \ vendor.display.config@1.2.vendor \ @@ -25,7 +27,9 @@ PRODUCT_PACKAGES += \ vendor.display.config@1.8.vendor \ vendor.display.config@1.9.vendor \ vendor.display.config@1.10.vendor \ + vendor.display.config@2.0.vendor \ vendor.qti.hardware.display.mapper@3.0 \ + vendor.qti.hardware.display.mapper@4.0.vendor \ modetest #QDCM calibration xml file for 2k panel diff --git a/config/talos.mk b/config/talos.mk index 93c1cf9a..3c5baceb 100644 --- a/config/talos.mk +++ b/config/talos.mk @@ -1,8 +1,8 @@ #Display related packages and configuration PRODUCT_PACKAGES += \ - android.hardware.graphics.composer@2.3-impl \ - android.hardware.graphics.composer@2.3-service \ + android.hardware.graphics.composer@2.4-impl \ + android.hardware.graphics.composer@2.4-service \ android.hardware.graphics.mapper@2.0-impl-qti-display \ vendor.qti.hardware.display.allocator-service \ android.hardware.memtrack@1.0-impl \ diff --git a/gralloc/Android.mk b/gralloc/Android.mk index e6f6c556..ebb3cd4e 100644 --- a/gralloc/Android.mk +++ b/gralloc/Android.mk @@ -15,8 +15,10 @@ LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libsync libgralloc libgralloccore \ android.hardware.graphics.mapper@2.0 \ android.hardware.graphics.mapper@2.1 \ - android.hardware.graphics.mapper@3.0 -LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wall -Werror + android.hardware.graphics.mapper@3.0 \ + android.hardware.graphics.mapper@4.0 +LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wall -Werror \ + -D__QTI_DISPLAY_GRALLOC__ LOCAL_CLANG := true LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_SRC_FILES := gr_device_impl.cpp @@ -30,10 +32,13 @@ LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes) LOCAL_HEADER_LIBRARIES := display_headers LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libdl \ + android.hardware.graphics.common@1.2 \ android.hardware.graphics.mapper@2.0 \ android.hardware.graphics.mapper@2.1 \ - android.hardware.graphics.mapper@3.0 -LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion + android.hardware.graphics.mapper@3.0 \ + android.hardware.graphics.mapper@4.0 +LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \ + -D__QTI_DISPLAY_GRALLOC__ LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_SRC_FILES := gr_utils.cpp gr_adreno_info.cpp include $(BUILD_SHARED_LIBRARY) @@ -48,13 +53,20 @@ LOCAL_C_INCLUDES := $(common_includes) \ $(kernel_includes) LOCAL_HEADER_LIBRARIES := display_headers -LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libdl libgrallocutils libion \ +LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libdl libgrallocutils libion libgralloctypes \ + libgralloc.qti libhidlbase \ android.hardware.graphics.mapper@2.1 \ - android.hardware.graphics.mapper@3.0 -LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion + android.hardware.graphics.mapper@3.0 \ + android.hardware.graphics.mapper@4.0 +LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \ + -D__QTI_DISPLAY_GRALLOC__ ifeq ($(ENABLE_HYP),true) LOCAL_CFLAGS += -DHYPERVISOR endif + +ifneq ($(TARGET_USES_GRALLOC4),false) +LOCAL_CFLAGS += -DTARGET_USES_GRALLOC4 +endif LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_SRC_FILES := gr_allocator.cpp gr_buf_mgr.cpp gr_ion_alloc.cpp include $(BUILD_SHARED_LIBRARY) @@ -79,12 +91,45 @@ LOCAL_SHARED_LIBRARIES := $(common_libs) \ android.hardware.graphics.mapper@2.1 \ vendor.qti.hardware.display.mapperextensions@1.1 \ android.hardware.graphics.mapper@3.0 -LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion +LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \ + -D__QTI_DISPLAY_GRALLOC__ LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_SRC_FILES := QtiMapper.cpp QtiMapperExtensions.cpp LOCAL_VINTF_FRAGMENTS := android.hardware.graphics.mapper-impl-qti-display.xml include $(BUILD_SHARED_LIBRARY) +ifneq ($(TARGET_USES_GRALLOC4),false) +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.graphics.mapper@4.0-impl-qti-display +LOCAL_SANITIZE := integer_overflow +LOCAL_VENDOR_MODULE := true +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_MODULE_TAGS := optional +LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes) +LOCAL_HEADER_LIBRARIES := display_headers +LOCAL_SHARED_LIBRARIES := $(common_libs) \ + libhidlbase \ + libhidltransport \ + libqdMetaData \ + libgrallocutils \ + libgralloccore \ + libsync \ + libgralloctypes \ + vendor.qti.hardware.display.mapper@4.0 \ + vendor.qti.hardware.display.mapperextensions@1.0 \ + android.hardware.graphics.mapper@2.0 \ + android.hardware.graphics.mapper@2.1 \ + vendor.qti.hardware.display.mapperextensions@1.1 \ + android.hardware.graphics.mapper@3.0 \ + android.hardware.graphics.mapper@4.0 +LOCAL_CFLAGS := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \ + -D__QTI_DISPLAY_GRALLOC__ +LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) +LOCAL_SRC_FILES := QtiMapper4.cpp QtiMapperExtensions.cpp +LOCAL_VINTF_FRAGMENTS := android.hardware.graphics.mapper-impl-qti-display.xml +include $(BUILD_SHARED_LIBRARY) +endif + #allocator include $(CLEAR_VARS) LOCAL_MODULE := vendor.qti.hardware.display.allocator-service @@ -97,11 +142,22 @@ LOCAL_SHARED_LIBRARIES := $(common_libs) \ libqdMetaData \ libgrallocutils \ libgralloccore \ + libgralloctypes \ + vendor.qti.hardware.display.allocator@4.0 \ vendor.qti.hardware.display.allocator@3.0 \ + vendor.qti.hardware.display.mapper@4.0 \ + vendor.qti.hardware.display.mapper@3.0 \ + android.hardware.graphics.mapper@4.0 \ android.hardware.graphics.mapper@3.0 \ android.hardware.graphics.mapper@2.1 \ - android.hardware.graphics.allocator@3.0 + android.hardware.graphics.allocator@4.0 \ + android.hardware.graphics.allocator@3.0 \ + vendor.qti.hardware.display.mapperextensions@1.0 \ + vendor.qti.hardware.display.mapperextensions@1.1 LOCAL_CFLAGS := -DLOG_TAG=\"qdgralloc\" $(common_flags) +ifneq ($(TARGET_USES_GRALLOC4),false) +LOCAL_CFLAGS += -DTARGET_USES_GRALLOC4 +endif LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes) LOCAL_SRC_FILES := QtiAllocator.cpp service.cpp diff --git a/gralloc/QtiAllocator.cpp b/gralloc/QtiAllocator.cpp index 44612c06..35145dc4 100644 --- a/gralloc/QtiAllocator.cpp +++ b/gralloc/QtiAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 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 @@ -30,11 +30,26 @@ #define DEBUG 0 #include "QtiAllocator.h" +#include <cutils/properties.h> #include <log/log.h> +#include <vendor/qti/hardware/display/mapper/3.0/IQtiMapper.h> +#include <vendor/qti/hardware/display/mapper/4.0/IQtiMapper.h> + #include <vector> +#include "QtiMapper.h" +#include "QtiMapper4.h" #include "gr_utils.h" +static void get_properties(gralloc::GrallocProperties *props) { + props->use_system_heap_for_sensors = + property_get_bool("vendor.gralloc.use_system_heap_for_sensors", 1); + + props->ubwc_disable = property_get_bool("vendor.gralloc.disable_ubwc", 0); + + props->ahardware_buffer_disable = property_get_bool("vendor.gralloc.disable_ahardware_buffer", 0); +} + namespace vendor { namespace qti { namespace hardware { @@ -45,9 +60,14 @@ namespace implementation { using android::hardware::hidl_handle; using gralloc::BufferDescriptor; +using IMapper_3_0_Error = android::hardware::graphics::mapper::V3_0::Error; +using gralloc::Error; QtiAllocator::QtiAllocator() { + gralloc::GrallocProperties properties; + get_properties(&properties); buf_mgr_ = BufferManager::GetInstance(); + buf_mgr_->SetGrallocDebugProperties(properties); } // Methods from ::android::hardware::graphics::allocator::V2_0::IAllocator follow. @@ -65,9 +85,10 @@ Return<void> QtiAllocator::allocate(const hidl_vec<uint32_t> &descriptor, uint32 ALOGD_IF(DEBUG, "Allocating buffers count: %d", count); gralloc::BufferDescriptor desc; - auto err = desc.Decode(descriptor); + auto err = ::vendor::qti::hardware::display::mapper::V3_0::implementation::QtiMapper::Decode( + descriptor, &desc); if (err != Error::NONE) { - hidl_cb(err, 0, hidl_vec<hidl_handle>()); + hidl_cb(static_cast<IMapper_3_0_Error>(err), 0, hidl_vec<hidl_handle>()); return Void(); } @@ -89,7 +110,7 @@ Return<void> QtiAllocator::allocate(const hidl_vec<uint32_t> &descriptor, uint32 stride = static_cast<uint32_t>(PRIV_HANDLE_CONST(buffers[0].getNativeHandle())->width); hidl_buffers.setToExternal(buffers.data(), buffers.size()); } - hidl_cb(err, stride, hidl_buffers); + hidl_cb(static_cast<IMapper_3_0_Error>(err), stride, hidl_buffers); for (const auto &b : buffers) { buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(b.getNativeHandle())); @@ -98,14 +119,75 @@ Return<void> QtiAllocator::allocate(const hidl_vec<uint32_t> &descriptor, uint32 return Void(); } -// Methods from ::android::hidl::base::V1_0::IBase follow. +} // namespace implementation +} // namespace V3_0 +} // namespace allocator +} // namespace display +} // namespace hardware +} // namespace qti +} // namespace vendor + +namespace vendor { +namespace qti { +namespace hardware { +namespace display { +namespace allocator { +namespace V4_0 { +namespace implementation { + +using android::hardware::hidl_handle; +using gralloc::BufferDescriptor; +using IMapper_4_0_Error = android::hardware::graphics::mapper::V4_0::Error; +using gralloc::Error; -IQtiAllocator *HIDL_FETCH_IQtiAllocator(const char * /* name */) { - return new QtiAllocator(); +QtiAllocator::QtiAllocator() { + gralloc::GrallocProperties properties; + get_properties(&properties); + buf_mgr_ = BufferManager::GetInstance(); + buf_mgr_->SetGrallocDebugProperties(properties); +} + +Return<void> QtiAllocator::allocate(const hidl_vec<uint8_t> &descriptor, uint32_t count, + allocate_cb hidl_cb) { + ALOGD_IF(DEBUG, "Allocating buffers count: %d", count); + gralloc::BufferDescriptor desc; + + auto err = ::vendor::qti::hardware::display::mapper::V4_0::implementation::QtiMapper::Decode( + descriptor, &desc); + if (err != Error::NONE) { + hidl_cb(static_cast<IMapper_4_0_Error>(err), 0, hidl_vec<hidl_handle>()); + return Void(); + } + + std::vector<hidl_handle> buffers; + buffers.reserve(count); + for (uint32_t i = 0; i < count; i++) { + buffer_handle_t buffer; + ALOGD_IF(DEBUG, "buffer: %p", &buffer); + err = buf_mgr_->AllocateBuffer(desc, &buffer); + if (err != Error::NONE) { + break; + } + buffers.emplace_back(hidl_handle(buffer)); + } + + uint32_t stride = 0; + hidl_vec<hidl_handle> hidl_buffers; + if (err == Error::NONE && buffers.size() > 0) { + stride = static_cast<uint32_t>(PRIV_HANDLE_CONST(buffers[0].getNativeHandle())->width); + hidl_buffers.setToExternal(buffers.data(), buffers.size()); + } + hidl_cb(static_cast<IMapper_4_0_Error>(err), stride, hidl_buffers); + + for (const auto &b : buffers) { + buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(b.getNativeHandle())); + } + + return Void(); } } // namespace implementation -} // namespace V3_0 +} // namespace V4_0 } // namespace allocator } // namespace display } // namespace hardware diff --git a/gralloc/QtiAllocator.h b/gralloc/QtiAllocator.h index 7bf17059..918c6b9c 100644 --- a/gralloc/QtiAllocator.h +++ b/gralloc/QtiAllocator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 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 @@ -33,8 +33,10 @@ #include <hidl/MQDescriptor.h> #include <hidl/Status.h> #include <vendor/qti/hardware/display/allocator/3.0/IQtiAllocator.h> +#include <vendor/qti/hardware/display/allocator/4.0/IQtiAllocator.h> #include "gr_buf_mgr.h" +#include "gr_utils.h" namespace vendor { namespace qti { @@ -51,16 +53,16 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; -using ::android::hardware::graphics::allocator::V3_0::IAllocator; -using ::android::hardware::graphics::mapper::V3_0::Error; +using android::hardware::graphics::allocator::V3_0::IAllocator; using ::android::hidl::base::V1_0::DebugInfo; using ::android::hidl::base::V1_0::IBase; using gralloc::BufferManager; -using ::vendor::qti::hardware::display::allocator::V3_0::IQtiAllocator; +using vendor::qti::hardware::display::allocator::V3_0::IQtiAllocator; class QtiAllocator : public IQtiAllocator { public: QtiAllocator(); + // Methods from ::android::hardware::graphics::allocator::V2_0::IAllocator follow. Return<void> dumpDebugInfo(dumpDebugInfo_cb _hidl_cb) override; Return<void> allocate(const hidl_vec<uint32_t> &descriptor, uint32_t count, @@ -71,8 +73,6 @@ class QtiAllocator : public IQtiAllocator { BufferManager *buf_mgr_ = nullptr; }; -extern "C" IQtiAllocator *HIDL_FETCH_IQtiAllocator(const char *name); - } // namespace implementation } // namespace V3_0 } // namespace allocator @@ -81,4 +81,46 @@ extern "C" IQtiAllocator *HIDL_FETCH_IQtiAllocator(const char *name); } // namespace qti } // namespace vendor +namespace vendor { +namespace qti { +namespace hardware { +namespace display { +namespace allocator { +namespace V4_0 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using android::hardware::graphics::allocator::V4_0::IAllocator; +using ::android::hidl::base::V1_0::DebugInfo; +using ::android::hidl::base::V1_0::IBase; +using gralloc::BufferManager; +using vendor::qti::hardware::display::allocator::V4_0::IQtiAllocator; + +class QtiAllocator : public IQtiAllocator { + public: + QtiAllocator(); + + // Methods from ::android::hardware::graphics::allocator::V4_0::IAllocator follow. + Return<void> allocate(const hidl_vec<uint8_t> &descriptor, uint32_t count, + allocate_cb _hidl_cb) override; + + // Methods from ::android::hidl::base::V1_0::IBase follow. + private: + BufferManager *buf_mgr_ = nullptr; +}; + +} // namespace implementation +} // namespace V4_0 +} // namespace allocator +} // namespace display +} // namespace hardware +} // namespace qti +} // namespace vendor + #endif // __QTIALLOCATOR_H__ diff --git a/gralloc/QtiMapper.cpp b/gralloc/QtiMapper.cpp index a1ac903a..d8dd6750 100644 --- a/gralloc/QtiMapper.cpp +++ b/gralloc/QtiMapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 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 @@ -40,6 +40,7 @@ namespace qti { namespace hardware { namespace display { namespace mapper { +namespace V3_0 { namespace implementation { using gralloc::BufferInfo; @@ -67,7 +68,7 @@ Error QtiMapper::CreateDescriptor(const BufferDescriptorInfo_3_0 &descriptor_inf static_cast<uint32_t>(descriptor_info.format), descriptor_info.layerCount); if (ValidDescriptor(descriptor_info)) { - auto vec = gralloc::BufferDescriptor::Encode(descriptor_info); + auto vec = Encode(descriptor_info); *descriptor = vec; return Error::NONE; } else { @@ -105,7 +106,8 @@ Return<void> QtiMapper::importBuffer(const hidl_handle &raw_handle, importBuffer return Void(); } - auto error = buf_mgr_->RetainBuffer(PRIV_HANDLE_CONST(buffer_handle)); + auto error = + static_cast<IMapper_3_0_Error>(buf_mgr_->RetainBuffer(PRIV_HANDLE_CONST(buffer_handle))); if (error != Error::NONE) { ALOGE("%s: Unable to retain handle: %p", __FUNCTION__, buffer_handle); native_handle_close(buffer_handle); @@ -124,7 +126,7 @@ Return<Error> QtiMapper::freeBuffer(void *buffer) { if (!buffer) { return Error::BAD_BUFFER; } - return buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(buffer)); + return static_cast<IMapper_3_0_Error>(buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(buffer))); } bool QtiMapper::GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd) { @@ -169,7 +171,7 @@ Error QtiMapper::LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acq auto hnd = PRIV_HANDLE_CONST(buffer); - return buf_mgr_->LockBuffer(hnd, usage); + return static_cast<IMapper_3_0_Error>(buf_mgr_->LockBuffer(hnd, usage)); } Return<void> QtiMapper::lock(void *buffer, uint64_t cpu_usage, @@ -183,7 +185,8 @@ Return<void> QtiMapper::lock(void *buffer, uint64_t cpu_usage, auto hnd = PRIV_HANDLE_CONST(buffer); auto *out_data = reinterpret_cast<void *>(hnd->base); - hidl_cb(err, out_data, gralloc::GetBpp(hnd->format), hnd->width); + hidl_cb(err, out_data, gralloc::GetBpp(hnd->format), + (hnd->width) * (gralloc::GetBpp(hnd->format))); return Void(); } @@ -215,7 +218,7 @@ Return<void> QtiMapper::lockYCbCr(void *buffer, uint64_t cpu_usage, Return<void> QtiMapper::unlock(void *buffer, unlock_cb hidl_cb) { auto err = Error::BAD_BUFFER; if (buffer != nullptr) { - err = buf_mgr_->UnlockBuffer(PRIV_HANDLE_CONST(buffer)); + err = static_cast<IMapper_3_0_Error>(buf_mgr_->UnlockBuffer(PRIV_HANDLE_CONST(buffer))); } // We don't have a release fence hidl_cb(err, hidl_handle(nullptr)); @@ -228,14 +231,14 @@ Return<Error> QtiMapper::validateBufferSize(void *buffer, auto err = Error::BAD_BUFFER; auto hnd = static_cast<private_handle_t *>(buffer); if (buffer != nullptr && private_handle_t::validate(hnd) == 0) { - if (buf_mgr_->IsBufferImported(hnd) != Error::NONE) { + if (static_cast<IMapper_3_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) { return Error::BAD_BUFFER; } auto info = gralloc::BufferInfo(descriptor_info.width, descriptor_info.height, static_cast<uint32_t>(descriptor_info.format), static_cast<uint64_t>(descriptor_info.usage)); info.layer_count = descriptor_info.layerCount; - err = buf_mgr_->ValidateBufferSize(hnd, info); + err = static_cast<IMapper_3_0_Error>(buf_mgr_->ValidateBufferSize(hnd, info)); } return err; } @@ -245,7 +248,7 @@ Return<void> QtiMapper::getTransportSize(void *buffer, IMapper_3_0::getTransport auto hnd = static_cast<private_handle_t *>(buffer); uint32_t num_fds = 0, num_ints = 0; if (buffer != nullptr && private_handle_t::validate(hnd) == 0) { - if (buf_mgr_->IsBufferImported(hnd) != Error::NONE) { + if (static_cast<IMapper_3_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) { hidl_cb(err, num_fds, num_ints); return Void(); } @@ -269,14 +272,14 @@ Return<void> QtiMapper::isSupported(const BufferDescriptorInfo_3_0 &descriptor_i } gralloc::BufferDescriptor desc; - err = desc.Decode(descriptor); + err = static_cast<IMapper_3_0_Error>(Decode(descriptor, &desc)); if (err != Error::NONE) { hidl_cb(err, false); return Void(); } buffer_handle_t buffer; - err = buf_mgr_->AllocateBuffer(desc, &buffer, 0, true); + err = static_cast<IMapper_3_0_Error>(buf_mgr_->AllocateBuffer(desc, &buffer, 0, true)); if (err != Error::NONE) { hidl_cb(err, false); } else { @@ -299,18 +302,19 @@ Return<void> QtiMapper::getMapperExtensions(QtiMapper::getMapperExtensions_cb hi // When we are in passthrough mode, this method is used // by hidl to obtain the SP HAL object -IMapper_3_0 *HIDL_FETCH_IMapper(const char * /* name */) { +extern "C" IMapper_3_0 *HIDL_FETCH_IMapper(const char * /* name */) { ALOGD_IF(DEBUG, "Fetching IMapper from QtiMapper"); auto mapper = new QtiMapper(); return static_cast<IMapper_3_0 *>(mapper); } -IQtiMapper *HIDL_FETCH_IQtiMapper(const char * /* name */) { +extern "C" IQtiMapper *HIDL_FETCH_IQtiMapper(const char * /* name */) { ALOGD_IF(DEBUG, "Fetching QtiMapper"); return new QtiMapper(); } } // namespace implementation +} // namespace V3_0 } // namespace mapper } // namespace display } // namespace hardware diff --git a/gralloc/QtiMapper.h b/gralloc/QtiMapper.h index cf17d9e5..0c191f5a 100644 --- a/gralloc/QtiMapper.h +++ b/gralloc/QtiMapper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 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 @@ -36,11 +36,14 @@ #include "QtiMapperExtensions.h" #include "gr_buf_mgr.h" +#include "gr_utils.h" + namespace vendor { namespace qti { namespace hardware { namespace display { namespace mapper { +namespace V3_0 { namespace implementation { using ::android::sp; @@ -66,6 +69,7 @@ using IMapper_3_0 = android::hardware::graphics::mapper::V3_0::IMapper; using BufferDescriptorInfo_3_0 = android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo; using IMapperBufferDescriptor = android::hardware::graphics::mapper::V3_0::BufferDescriptor; +using IMapper_3_0_Error = ::android::hardware::graphics::mapper::V3_0::Error; class QtiMapper : public IQtiMapper { public: @@ -91,6 +95,34 @@ class QtiMapper : public IQtiMapper { Return<void> getMapperExtensions(getMapperExtensions_cb hidl_cb); sp<mapperextensions::V1_1::IQtiMapperExtensions> extensions_ = nullptr; + hidl_vec<uint32_t> Encode(const IMapper_3_0::BufferDescriptorInfo &bd_info) { + hidl_vec<uint32_t> out; + out.resize(gralloc::kBufferDescriptorSize); + out[0] = gralloc::kMagicVersion; + out[1] = bd_info.width; + out[2] = bd_info.height; + out[3] = bd_info.layerCount; + out[4] = static_cast<uint32_t>(bd_info.format); + out[5] = static_cast<uint32_t>(bd_info.usage); + out[6] = static_cast<uint32_t>(bd_info.usage >> 32); + return out; + } + static gralloc::Error Decode(const hidl_vec<uint32_t> &in, + gralloc::BufferDescriptor *buf_descriptor) { + if (in.size() != gralloc::kBufferDescriptorSize || in[0] != gralloc::kMagicVersion) { + return gralloc::Error::BAD_DESCRIPTOR; + } + int32_t width = static_cast<int32_t>(in[1]); + int32_t height = static_cast<int32_t>(in[2]); + buf_descriptor->SetDimensions(width, height); + uint32_t layer_count = in[3]; + buf_descriptor->SetLayerCount(layer_count); + int32_t format = static_cast<int32_t>(in[4]); + buf_descriptor->SetColorFormat(format); + uint64_t usage = static_cast<uint64_t>(in[6]) << 32 | in[5]; + buf_descriptor->SetUsage(usage); + return gralloc::Error::NONE; + } private: BufferManager *buf_mgr_ = nullptr; @@ -102,10 +134,8 @@ class QtiMapper : public IQtiMapper { Error LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence); }; -extern "C" IMapper_3_0 *HIDL_FETCH_IMapper(const char *name); -extern "C" IQtiMapper *HIDL_FETCH_IQtiMapper(const char *name); - } // namespace implementation +} // namespace V3_0 } // namespace mapper } // namespace display } // namespace hardware diff --git a/gralloc/QtiMapper4.cpp b/gralloc/QtiMapper4.cpp new file mode 100644 index 00000000..fe12dd0c --- /dev/null +++ b/gralloc/QtiMapper4.cpp @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2018-2020 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. + */ + +#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL) +#define DEBUG 0 +#include "QtiMapper4.h" + +#include <cutils/trace.h> +#include <qdMetaData.h> +#include <sync/sync.h> + +#include <vector> + +#include "gr_utils.h" + +namespace vendor { +namespace qti { +namespace hardware { +namespace display { +namespace mapper { +namespace V4_0 { +namespace implementation { + +using gralloc::BufferInfo; + +using aidl::android::hardware::graphics::common::StandardMetadataType; +QtiMapper::QtiMapper() { + extensions_ = new QtiMapperExtensions(); + buf_mgr_ = BufferManager::GetInstance(); + ALOGD_IF(DEBUG, "Created QtiMapper instance"); +} + +bool QtiMapper::ValidDescriptor(const BufferDescriptorInfo_4_0 &bd) { + if (bd.width == 0 || bd.height == 0 || (static_cast<int32_t>(bd.format) <= 0) || + bd.layerCount <= 0) { + return false; + } + + return true; +} + +Error QtiMapper::CreateDescriptor(const BufferDescriptorInfo_4_0 &descriptor_info, + IMapperBufferDescriptor *descriptor) { + ALOGD_IF(DEBUG, + "BufferDescriptorInfo: name %s wxh: %dx%d usage: 0x%" PRIu64 + " format: %d layer_count: %d", + descriptor_info.name.c_str(), descriptor_info.width, descriptor_info.height, + descriptor_info.usage, static_cast<uint32_t>(descriptor_info.format), + descriptor_info.layerCount); + + if (ValidDescriptor(descriptor_info)) { + auto vec = Encode(descriptor_info); + *descriptor = vec; + return Error::NONE; + } else { + return Error::BAD_VALUE; + } +} + +// Methods from ::android::hardware::graphics::mapper::V2_0::IMapper follow. +Return<void> QtiMapper::createDescriptor(const BufferDescriptorInfo_4_0 &descriptor_info, + createDescriptor_cb hidl_cb) { + IMapperBufferDescriptor descriptor; + auto info_4_0 = BufferDescriptorInfo_4_0{descriptor_info.name, + descriptor_info.width, + descriptor_info.height, + descriptor_info.layerCount, + static_cast<PixelFormat>(descriptor_info.format), + descriptor_info.usage, + descriptor_info.reservedSize}; + auto err = CreateDescriptor(info_4_0, &descriptor); + hidl_cb(err, descriptor); + return Void(); +} + +Return<void> QtiMapper::importBuffer(const hidl_handle &raw_handle, importBuffer_cb hidl_cb) { + if (!raw_handle.getNativeHandle()) { + ALOGE("%s: Unable to import handle", __FUNCTION__); + hidl_cb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + native_handle_t *buffer_handle = native_handle_clone(raw_handle.getNativeHandle()); + if (!buffer_handle) { + ALOGE("%s: Unable to clone handle", __FUNCTION__); + hidl_cb(Error::NO_RESOURCES, nullptr); + return Void(); + } + + auto error = + static_cast<IMapper_4_0_Error>(buf_mgr_->RetainBuffer(PRIV_HANDLE_CONST(buffer_handle))); + if (error != Error::NONE) { + ALOGE("%s: Unable to retain handle: %p", __FUNCTION__, buffer_handle); + native_handle_close(buffer_handle); + native_handle_delete(buffer_handle); + + hidl_cb(error, nullptr); + return Void(); + } + ALOGD_IF(DEBUG, "Imported handle: %p id: %" PRIu64, buffer_handle, + PRIV_HANDLE_CONST(buffer_handle)->id); + hidl_cb(Error::NONE, buffer_handle); + return Void(); +} + +Return<Error> QtiMapper::freeBuffer(void *buffer) { + if (!buffer) { + return Error::BAD_BUFFER; + } + return static_cast<IMapper_4_0_Error>(buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(buffer))); +} + +bool QtiMapper::GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd) { + auto handle = fence_handle.getNativeHandle(); + if (handle && handle->numFds > 1) { + ALOGE("invalid fence handle with %d fds", handle->numFds); + return false; + } + + *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1; + return true; +} + +void QtiMapper::WaitFenceFd(int fence_fd) { + if (fence_fd < 0) { + return; + } + + const int timeout = 3000; + ATRACE_BEGIN("fence wait"); + const int error = sync_wait(fence_fd, timeout); + ATRACE_END(); + if (error < 0) { + ALOGE("QtiMapper: lock fence %d didn't signal in %u ms - error: %s", fence_fd, timeout, + strerror(errno)); + } +} + +Error QtiMapper::LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence, + const IMapper::Rect &access_region) { + if (!buffer) { + return Error::BAD_BUFFER; + } + + int fence_fd; + if (!GetFenceFd(acquire_fence, &fence_fd)) { + return Error::BAD_VALUE; + } + + if (fence_fd > 0) { + WaitFenceFd(fence_fd); + } + + auto hnd = PRIV_HANDLE_CONST(buffer); + + if (access_region.top < 0 || access_region.left < 0 || access_region.width < 0 || + access_region.height < 0 || access_region.width > hnd->width || + access_region.height > hnd->height) { + return Error::BAD_VALUE; + } + return static_cast<IMapper_4_0_Error>(buf_mgr_->LockBuffer(hnd, usage)); +} + +Return<void> QtiMapper::lock(void *buffer, uint64_t cpu_usage, const IMapper::Rect &access_region, + const hidl_handle &acquire_fence, lock_cb hidl_cb) { + auto err = LockBuffer(buffer, cpu_usage, acquire_fence, access_region); + if (err != Error::NONE) { + hidl_cb(err, nullptr); + return Void(); + } + + auto hnd = PRIV_HANDLE_CONST(buffer); + auto *out_data = reinterpret_cast<void *>(hnd->base); + + hidl_cb(err, out_data); + return Void(); +} + +Return<void> QtiMapper::unlock(void *buffer, unlock_cb hidl_cb) { + auto err = Error::BAD_BUFFER; + if (buffer != nullptr) { + err = static_cast<IMapper_4_0_Error>(buf_mgr_->UnlockBuffer(PRIV_HANDLE_CONST(buffer))); + } + // We don't have a release fence + hidl_cb(err, hidl_handle(nullptr)); + return Void(); +} + +Return<Error> QtiMapper::validateBufferSize(void *buffer, + const BufferDescriptorInfo_4_0 &descriptor_info, + uint32_t /*stride*/) { + auto err = Error::BAD_BUFFER; + auto hnd = static_cast<private_handle_t *>(buffer); + if (buffer != nullptr && private_handle_t::validate(hnd) == 0) { + if (static_cast<IMapper_4_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) { + return Error::BAD_BUFFER; + } + auto info = gralloc::BufferInfo(descriptor_info.width, descriptor_info.height, + static_cast<uint32_t>(descriptor_info.format), + static_cast<uint64_t>(descriptor_info.usage)); + info.layer_count = descriptor_info.layerCount; + err = static_cast<IMapper_4_0_Error>(buf_mgr_->ValidateBufferSize(hnd, info)); + } + return err; +} + +Return<void> QtiMapper::getTransportSize(void *buffer, getTransportSize_cb hidl_cb) { + auto err = Error::BAD_BUFFER; + auto hnd = static_cast<private_handle_t *>(buffer); + uint32_t num_fds = 0, num_ints = 0; + if (buffer != nullptr && private_handle_t::validate(hnd) == 0) { + if (static_cast<IMapper_4_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) { + hidl_cb(err, num_fds, num_ints); + return Void(); + } + num_fds = 2; + // TODO(user): reduce to transported values; + num_ints = static_cast<uint32_t>(hnd->numInts); + err = Error::NONE; + } + ALOGD_IF(DEBUG, "GetTransportSize: num fds: %d num ints: %d err:%d", num_fds, num_ints, err); + hidl_cb(err, num_fds, num_ints); + return Void(); +} + +Return<void> QtiMapper::get(void *buffer, const MetadataType &metadataType, get_cb hidl_cb) { + auto err = Error::BAD_BUFFER; + hidl_vec<uint8_t> metadata; + if (buffer != nullptr) { + if (metadataType.name != GRALLOC4_STANDARD_METADATA_TYPE && + metadataType.name != qtigralloc::VENDOR_QTI) { + hidl_cb(Error::UNSUPPORTED, metadata); + return Void(); + } + auto hnd = static_cast<private_handle_t *>(buffer); + err = static_cast<IMapper_4_0_Error>(buf_mgr_->GetMetadata(hnd, metadataType.value, &metadata)); + } + hidl_cb(err, metadata); + return Void(); +} + +Return<Error> QtiMapper::set(void *buffer, const MetadataType &metadataType, + const hidl_vec<uint8_t> &metadata) { + auto err = Error::BAD_BUFFER; + if (buffer != nullptr) { + auto hnd = static_cast<private_handle_t *>(buffer); + err = static_cast<IMapper_4_0_Error>(buf_mgr_->SetMetadata(hnd, metadataType.value, metadata)); + } + return err; +} + +Return<void> QtiMapper::getFromBufferDescriptorInfo(const BufferDescriptorInfo &description, + const MetadataType &metadataType, + getFromBufferDescriptorInfo_cb hidl_cb) { + hidl_vec<uint8_t> out; + auto err = Error::UNSUPPORTED; + switch (metadataType.value) { + case static_cast<int64_t>(StandardMetadataType::NAME): + err = static_cast<IMapper_4_0_Error>(android::gralloc4::encodeName(description.name, &out)); + break; + case static_cast<int64_t>(StandardMetadataType::WIDTH): + err = static_cast<IMapper_4_0_Error>(android::gralloc4::encodeWidth(description.width, &out)); + break; + case static_cast<int64_t>(StandardMetadataType::HEIGHT): + err = + static_cast<IMapper_4_0_Error>(android::gralloc4::encodeHeight(description.height, &out)); + break; + case static_cast<int64_t>(StandardMetadataType::LAYER_COUNT): + err = static_cast<IMapper_4_0_Error>( + android::gralloc4::encodeLayerCount(description.layerCount, &out)); + break; + case static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_REQUESTED): + err = static_cast<IMapper_4_0_Error>( + android::gralloc4::encodePixelFormatRequested(description.format, &out)); + break; + case static_cast<int64_t>(StandardMetadataType::USAGE): + err = static_cast<IMapper_4_0_Error>(android::gralloc4::encodeUsage(description.usage, &out)); + break; + case static_cast<int64_t>(StandardMetadataType::COMPRESSION): { + int format = + gralloc::GetImplDefinedFormat(description.usage, static_cast<int>(description.format)); + if (gralloc::IsUBwcEnabled(format, description.usage)) { + err = static_cast<IMapper_4_0_Error>( + android::gralloc4::encodeCompression(qtigralloc::Compression_QtiUBWC, &out)); + } else { + err = static_cast<IMapper_4_0_Error>( + android::gralloc4::encodeCompression(android::gralloc4::Compression_None, &out)); + } + break; + } + case static_cast<int64_t>(StandardMetadataType::PROTECTED_CONTENT): { + uint64_t protected_content = 0; + if (description.usage & GRALLOC_USAGE_PROTECTED && + !(description.usage & GRALLOC_USAGE_SW_READ_MASK) && + !(description.usage & GRALLOC_USAGE_SW_WRITE_MASK)) { + protected_content = 1; + } + err = static_cast<IMapper_4_0_Error>( + android::gralloc4::encodeProtectedContent(protected_content, &out)); + break; + } + case static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_FOURCC): + case static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_MODIFIER): { + int format = + gralloc::GetImplDefinedFormat(description.usage, static_cast<int>(description.format)); + uint32_t drm_format; + uint64_t drm_format_modifier; + if (gralloc::IsUBwcEnabled(format, description.usage)) { + gralloc::GetDRMFormat(format, private_handle_t::PRIV_FLAGS_UBWC_ALIGNED, &drm_format, + &drm_format_modifier); + } else { + gralloc::GetDRMFormat(format, 0, &drm_format, &drm_format_modifier); + } + if (metadataType.value == static_cast<int64_t>(StandardMetadataType::PIXEL_FORMAT_FOURCC)) { + err = static_cast<IMapper_4_0_Error>( + android::gralloc4::encodePixelFormatFourCC(drm_format, &out)); + } else { + err = static_cast<IMapper_4_0_Error>( + android::gralloc4::encodePixelFormatModifier(drm_format_modifier, &out)); + } + break; + } + default: + break; + } + + hidl_cb(err, out); + return Void(); +} +Return<void> QtiMapper::flushLockedBuffer(void *buffer, flushLockedBuffer_cb hidl_cb) { + auto err = Error::BAD_BUFFER; + if (buffer != nullptr) { + err = static_cast<IMapper_4_0_Error>(buf_mgr_->FlushBuffer(PRIV_HANDLE_CONST(buffer))); + } + // We don't have a release fence + hidl_cb(err, hidl_handle(nullptr)); + return Void(); +} + +Return<Error> QtiMapper::rereadLockedBuffer(void *buffer) { + auto err = Error::BAD_BUFFER; + if (buffer != nullptr) { + err = static_cast<IMapper_4_0_Error>(buf_mgr_->RereadBuffer(PRIV_HANDLE_CONST(buffer))); + } + return err; +} + +Return<void> QtiMapper::getReservedRegion(void *buffer, getReservedRegion_cb hidl_cb) { + auto hnd = static_cast<private_handle_t *>(buffer); + void *reserved_region = nullptr; + uint64_t reserved_size = 0; + if (static_cast<IMapper_4_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) { + hidl_cb(Error::BAD_BUFFER, reserved_region, reserved_size); + } + auto err = static_cast<IMapper_4_0_Error>( + buf_mgr_->GetReservedRegion(hnd, &reserved_region, &reserved_size)); + + hidl_cb(err, reserved_region, reserved_size); + return Void(); +} + +Error QtiMapper::DumpBufferMetadata(const private_handle_t *buffer, BufferDump *outBufferDump) { + outBufferDump->metadataDump.resize(metadata_type_descriptions_.size()); + for (int i = 0; i < static_cast<int>(metadata_type_descriptions_.size()); i++) { + auto type = metadata_type_descriptions_[i].metadataType; + hidl_vec<uint8_t> metadata; + if (static_cast<IMapper_4_0_Error>(buf_mgr_->GetMetadata( + const_cast<private_handle_t *>(buffer), type.value, &metadata)) == Error::BAD_BUFFER) { + // If buffer is deleted during metadata dump, return BAD_BUFFER + return Error::BAD_BUFFER; + } + MetadataDump metadata_dump = {type, metadata}; + outBufferDump->metadataDump[i] = metadata_dump; + } + return Error::NONE; +} +Return<void> QtiMapper::dumpBuffer(void *buffer, dumpBuffer_cb hidl_cb) { + BufferDump buffer_dump; + auto hnd = PRIV_HANDLE_CONST(buffer); + if (buffer != nullptr) { + if (DumpBufferMetadata(hnd, &buffer_dump) == Error::NONE) { + hidl_cb(Error::NONE, buffer_dump); + return Void(); + } + } + hidl_cb(Error::BAD_BUFFER, buffer_dump); + return Void(); +} +Return<void> QtiMapper::dumpBuffers(dumpBuffers_cb hidl_cb) { + hidl_vec<BufferDump> buffers_dump; + std::vector<const private_handle_t *> handle_list; + if (static_cast<IMapper_4_0_Error>(buf_mgr_->GetAllHandles(&handle_list)) != Error::NONE) { + hidl_cb(Error::NO_RESOURCES, buffers_dump); + } + buffers_dump.resize(handle_list.size()); + for (int i = 0; i < handle_list.size(); i++) { + BufferDump buffer_dump; + if (DumpBufferMetadata(handle_list[i], &buffer_dump) != Error::NONE) { + continue; + } + buffers_dump[i] = buffer_dump; + } + hidl_cb(Error::NONE, buffers_dump); + return Void(); +} + +Return<void> QtiMapper::listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidl_cb) { + hidl_cb(Error::NONE, metadata_type_descriptions_); + return Void(); +} + +Return<void> QtiMapper::isSupported(const BufferDescriptorInfo_4_0 &descriptor_info, + isSupported_cb hidl_cb) { + IMapperBufferDescriptor descriptor; + auto err = CreateDescriptor(descriptor_info, &descriptor); + if (err != Error::NONE) { + hidl_cb(err, false); + return Void(); + } + + gralloc::BufferDescriptor desc; + err = static_cast<Error>(Decode(descriptor, &desc)); + if (err != Error::NONE) { + hidl_cb(err, false); + return Void(); + } + + buffer_handle_t buffer; + err = static_cast<IMapper_4_0_Error>(buf_mgr_->AllocateBuffer(desc, &buffer, 0, true)); + if (err != Error::NONE) { + hidl_cb(err, false); + } else { + hidl_cb(err, true); + } + + return Void(); +} + +Return<void> QtiMapper::getMapperExtensions(QtiMapper::getMapperExtensions_cb hidl_cb) { + if (extensions_ != nullptr) { + hidl_cb(Error::NONE, extensions_); + } else { + hidl_cb(Error::UNSUPPORTED, extensions_); + } + return Void(); +} + +// Methods from ::android::hidl::base::V1_0::IBase follow. + +// When we are in passthrough mode, this method is used +// by hidl to obtain the SP HAL object +extern "C" IMapper *HIDL_FETCH_IMapper(const char * /* name */) { + ALOGD_IF(DEBUG, "Fetching IMapper from QtiMapper"); + auto mapper = new QtiMapper(); + return static_cast<IMapper *>(mapper); +} + +extern "C" IQtiMapper *HIDL_FETCH_IQtiMapper(const char * /* name */) { + ALOGD_IF(DEBUG, "Fetching QtiMapper"); + return new QtiMapper(); +} + +} // namespace implementation +} // namespace V4_0 +} // namespace mapper +} // namespace display +} // namespace hardware +} // namespace qti +} // namespace vendor diff --git a/gralloc/QtiMapper4.h b/gralloc/QtiMapper4.h new file mode 100644 index 00000000..7fa27b13 --- /dev/null +++ b/gralloc/QtiMapper4.h @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2018-2020 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 __QTIMAPPER4_H__ +#define __QTIMAPPER4_H__ + +#include <QtiGralloc.h> +#include <gralloctypes/Gralloc4.h> +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> +#include <vendor/qti/hardware/display/mapper/4.0/IQtiMapper.h> + +#include <algorithm> +#include <string> + +#include "QtiMapperExtensions.h" +#include "gr_buf_mgr.h" +namespace vendor { +namespace qti { +namespace hardware { +namespace display { +namespace mapper { +namespace V4_0 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_handle; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::graphics::common::V1_2::PixelFormat; +using ::android::hardware::graphics::mapper::V4_0::Error; +using ::android::hardware::graphics::mapper::V4_0::IMapper; +using ::android::hidl::base::V1_0::DebugInfo; +using ::android::hidl::base::V1_0::IBase; +using gralloc::BufferManager; +using ::vendor::qti::hardware::display::mapper::V4_0::IQtiMapper; +using ::vendor::qti::hardware::display::mapperextensions::V1_1::IQtiMapperExtensions; +using ::vendor::qti::hardware::display::mapperextensions::V1_1::implementation::QtiMapperExtensions; + +using android::hardware::graphics::mapper::V4_0::IMapper; +using BufferDescriptorInfo_4_0 = + android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo; +using IMapperBufferDescriptor = android::hardware::graphics::mapper::V4_0::BufferDescriptor; +using MetadataType = ::android::hardware::graphics::mapper::V4_0::IMapper::MetadataType; +using MetadataTypeDescription = + ::android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription; +using IMapper_4_0_Error = ::android::hardware::graphics::mapper::V4_0::Error; + +class QtiMapper : public IQtiMapper { + public: + QtiMapper(); + // Methods from ::android::hardware::graphics::mapper::V2_0::IMapper follow. + Return<void> createDescriptor(const BufferDescriptorInfo_4_0 &descriptor_info, + createDescriptor_cb hidl_cb) override; + Return<void> importBuffer(const hidl_handle &raw_handle, importBuffer_cb hidl_cb) override; + Return<Error> freeBuffer(void *buffer) override; + Return<void> lock(void *buffer, uint64_t cpu_usage, const IMapper::Rect &access_region, + const hidl_handle &acquire_fence, lock_cb hidl_cb) override; + Return<void> unlock(void *buffer, unlock_cb hidl_cb) override; + + // Methods from ::android::hardware::graphics::mapper::V2_1::IMapper follow. + Return<Error> validateBufferSize(void *buffer, const BufferDescriptorInfo_4_0 &descriptorInfo, + uint32_t stride) override; + Return<void> getTransportSize(void *buffer, getTransportSize_cb hidl_cb) override; + + Return<void> isSupported(const BufferDescriptorInfo_4_0 &descriptor_info, + isSupported_cb hidl_cb) override; + + Return<void> getMapperExtensions(getMapperExtensions_cb hidl_cb); + sp<mapperextensions::V1_1::IQtiMapperExtensions> extensions_ = nullptr; + + // Methods from ::android::hardware::graphics::mapper::V4:0::IMapper follow. + Return<void> get(void *buffer, const MetadataType &metadataType, get_cb hidl_cb) override; + Return<Error> set(void *buffer, const MetadataType &metadataType, + const hidl_vec<uint8_t> &metadata) override; + Return<void> getFromBufferDescriptorInfo(const BufferDescriptorInfo &description, + const MetadataType &metadataType, + getFromBufferDescriptorInfo_cb hidl_cb) override; + Return<void> flushLockedBuffer(void *buffer, flushLockedBuffer_cb hidl_cb); + Return<Error> rereadLockedBuffer(void *buffer); + Return<void> listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidl_cb); + Return<void> getReservedRegion(void *buffer, getReservedRegion_cb _hidl_cb); + Return<void> dumpBuffer(void *buffer, dumpBuffer_cb _hidl_cb); + Return<void> dumpBuffers(dumpBuffers_cb _hidl_cb); + + hidl_vec<uint8_t> Encode(const BufferDescriptorInfo_4_0 &bd_info) { + hidl_vec<uint8_t> out; + + uint64_t name_size = bd_info.name.size(); + + /* Name length is variable, need to store string prepended with size + * The rest of the packet size is constant + */ + out.resize(gralloc::kBufferDescriptorSizeV4 + sizeof(name_size) + + static_cast<size_t>(name_size)); + + size_t index = 0; + uint32_t magic_version = gralloc::kMagicVersion; + std::memcpy(&out[index], &magic_version, sizeof(magic_version)); + index += sizeof(magic_version); + + std::memcpy(&out[index], &name_size, sizeof(name_size)); + index += sizeof(name_size); + + std::memcpy(&out[index], bd_info.name.c_str(), bd_info.name.size()); + index += name_size; + + std::memcpy(&out[index], &bd_info.width, sizeof(bd_info.width)); + index += sizeof(bd_info.width); + + std::memcpy(&out[index], &bd_info.height, sizeof(bd_info.height)); + index += sizeof(bd_info.height); + + std::memcpy(&out[index], &bd_info.layerCount, sizeof(bd_info.layerCount)); + index += sizeof(bd_info.layerCount); + + std::memcpy(&out[index], &bd_info.format, sizeof(bd_info.format)); + index += sizeof(bd_info.format); + + std::memcpy(&out[index], &bd_info.usage, sizeof(bd_info.usage)); + index += sizeof(bd_info.usage); + + // Cap the reserved region size at one page (4096 bytes) + uint64_t reserved_size = std::min(bd_info.reservedSize, (uint64_t)4096); + std::memcpy(&out[index], &reserved_size, sizeof(reserved_size)); + + return out; + } + static gralloc::Error Decode(const hidl_vec<uint8_t> &in, + gralloc::BufferDescriptor *buf_descriptor) { + // First check is to avoid dereferencing if the vector is too short + if (in.size() < gralloc::kBufferDescriptorSizeV4) { + return gralloc::Error::BAD_DESCRIPTOR; + } + + size_t index = 0; + uint32_t magic_version; + std::memcpy(&magic_version, &in[index], sizeof(magic_version)); + index += sizeof(magic_version); + + uint64_t name_size; + std::memcpy(&name_size, &in[index], sizeof(name_size)); + index += sizeof(name_size); + + // The second check validates that the size and magic version are correct + if (in.size() != (gralloc::kBufferDescriptorSizeV4 + name_size + sizeof(name_size)) || + magic_version != gralloc::kMagicVersion) { + return gralloc::Error::BAD_DESCRIPTOR; + } + + std::string name; + + name.resize(static_cast<size_t>(name_size)); + std::memcpy(name.data(), &in[index], name.size()); + index += name_size; + buf_descriptor->SetName(name); + + int32_t width, height; + std::memcpy(&width, &in[index], sizeof(width)); + + index += sizeof(width); + std::memcpy(&height, &in[index], sizeof(height)); + index += sizeof(height); + buf_descriptor->SetDimensions(width, height); + + uint32_t layer_count; + std::memcpy(&layer_count, &in[index], sizeof(layer_count)); + index += sizeof(layer_count); + buf_descriptor->SetLayerCount(layer_count); + + int32_t format; + std::memcpy(&format, &in[index], sizeof(format)); + index += sizeof(format); + buf_descriptor->SetColorFormat(format); + + uint64_t usage; + std::memcpy(&usage, &in[index], sizeof(usage)); + index += sizeof(usage); + buf_descriptor->SetUsage(usage); + + uint64_t reserved_size; + std::memcpy(&reserved_size, &in[index], sizeof(reserved_size)); + index += sizeof(reserved_size); + + buf_descriptor->SetReservedSize(reserved_size); + return gralloc::Error::NONE; + } + + private: + BufferManager *buf_mgr_ = nullptr; + Error CreateDescriptor(const BufferDescriptorInfo_4_0 &descriptor_info, + IMapperBufferDescriptor *descriptor); + bool ValidDescriptor(const IMapper::BufferDescriptorInfo &bd); + bool GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd); + void WaitFenceFd(int fence_fd); + Error LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence, + const IMapper::Rect &access_region); + + Error DumpBufferMetadata(const private_handle_t *buffer, BufferDump *outBufferDump); + + hidl_vec<MetadataTypeDescription> metadata_type_descriptions_ = { + // MetadataType, description, gettable, settable + {android::gralloc4::MetadataType_BufferId, "", true, false}, + {android::gralloc4::MetadataType_Name, "", true, false}, + {android::gralloc4::MetadataType_Width, "", true, false}, + {android::gralloc4::MetadataType_Height, "", true, false}, + {android::gralloc4::MetadataType_LayerCount, "", true, false}, + {android::gralloc4::MetadataType_PixelFormatRequested, "", true, false}, + {android::gralloc4::MetadataType_PixelFormatFourCC, "", true, false}, + {android::gralloc4::MetadataType_PixelFormatModifier, "", true, false}, + {android::gralloc4::MetadataType_Usage, "", true, false}, + {android::gralloc4::MetadataType_AllocationSize, "", true, false}, + {android::gralloc4::MetadataType_ProtectedContent, "", true, false}, + {android::gralloc4::MetadataType_ChromaSiting, "", true, false}, + {android::gralloc4::MetadataType_Compression, "", true, false}, + {android::gralloc4::MetadataType_Interlaced, "", true, false}, + {android::gralloc4::MetadataType_PlaneLayouts, "", true, false}, + {android::gralloc4::MetadataType_Dataspace, "", true, true}, + {android::gralloc4::MetadataType_BlendMode, "", true, true}, + {android::gralloc4::MetadataType_Smpte2086, "", true, true}, + {android::gralloc4::MetadataType_Cta861_3, "", true, true}, + {android::gralloc4::MetadataType_Smpte2094_40, "", true, true}, + {android::gralloc4::MetadataType_Crop, "", true, true}, + {qtigralloc::MetadataType_VTTimestamp, "VT Timestamp", true, true}, + {qtigralloc::MetadataType_ColorMetadata, "Color metadata", true, true}, + {qtigralloc::MetadataType_PPParamInterlaced, "Interlaced", true, true}, + {qtigralloc::MetadataType_VideoPerfMode, "Video perf mode", true, true}, + {qtigralloc::MetadataType_GraphicsMetadata, "Graphics metadata", true, true}, + {qtigralloc::MetadataType_UBWCCRStatsInfo, "UBWC stats", true, true}, + {qtigralloc::MetadataType_RefreshRate, "Refresh rate", true, true}, + {qtigralloc::MetadataType_MapSecureBuffer, "Secure buffer mappable", true, true}, + {qtigralloc::MetadataType_LinearFormat, "Linear format", true, true}, + {qtigralloc::MetadataType_SingleBufferMode, "Single buffer mode flag", true, true}, + {qtigralloc::MetadataType_CVPMetadata, "CVP metadata", true, true}, + {qtigralloc::MetadataType_VideoHistogramStats, "Video histogram stats", true, true}, + {qtigralloc::MetadataType_FD, "fd from private_handle_t", true, false}, + {qtigralloc::MetadataType_PrivateFlags, "Flags in private_handle_t", true, false}, + {qtigralloc::MetadataType_AlignedWidthInPixels, "width in private_handle_t", true, false}, + {qtigralloc::MetadataType_AlignedHeightInPixels, "height in private_handle_t", true, false} + }; +}; + +} // namespace implementation +} // namespace V4_0 +} // namespace mapper +} // namespace display +} // namespace hardware +} // namespace qti +} // namespace vendor + +#endif // __QTIMAPPER4_H__ diff --git a/gralloc/QtiMapperExtensions.h b/gralloc/QtiMapperExtensions.h index 1e2a4ad1..5f1df064 100644 --- a/gralloc/QtiMapperExtensions.h +++ b/gralloc/QtiMapperExtensions.h @@ -52,7 +52,6 @@ using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::hardware::graphics::common::V1_2::PixelFormat; -using ::android::hardware::graphics::mapper::V3_0::IMapper; using ::android::hidl::base::V1_0::DebugInfo; using ::android::hidl::base::V1_0::IBase; using gralloc::BufferManager; diff --git a/gralloc/android.hardware.graphics.mapper-impl-qti-display.xml b/gralloc/android.hardware.graphics.mapper-impl-qti-display.xml index d62a64ea..4e5c3ad8 100644 --- a/gralloc/android.hardware.graphics.mapper-impl-qti-display.xml +++ b/gralloc/android.hardware.graphics.mapper-impl-qti-display.xml @@ -1,5 +1,5 @@ <!-- -Copyright (c) 2019, The Linux Foundation. All rights reserved. +Copyright (c) 2019-2020, 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 @@ -31,6 +31,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <name>vendor.qti.hardware.display.mapper</name> <transport arch="32+64">passthrough</transport> <version>3.0</version> + <version>4.0</version> <interface> <name>IQtiMapper</name> <instance>default</instance> @@ -39,8 +40,8 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <hal format="hidl"> <name>android.hardware.graphics.mapper</name> <transport arch="32+64">passthrough</transport> - <impl level="generic"></impl> <version>3.0</version> + <version>4.0</version> <interface> <name>IMapper</name> <instance>default</instance> diff --git a/gralloc/gr_adreno_info.cpp b/gralloc/gr_adreno_info.cpp index d33f7db6..924020ae 100644 --- a/gralloc/gr_adreno_info.cpp +++ b/gralloc/gr_adreno_info.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020, 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 @@ -77,21 +77,6 @@ AdrenoMemInfo::AdrenoMemInfo() { } else { ALOGE(" Failed to load libadreno_utils.so"); } - - // Check if the overriding property debug.gralloc.gfx_ubwc_disable - // that disables UBWC allocations for the graphics stack is set - char property[PROPERTY_VALUE_MAX]; - property_get(DISABLE_UBWC_PROP, property, "0"); - if (!(strncmp(property, "1", PROPERTY_VALUE_MAX)) || - !(strncmp(property, "true", PROPERTY_VALUE_MAX))) { - gfx_ubwc_disable_ = true; - } - - property_get(DISABLE_AHARDWAREBUFFER_PROP, property, "0"); - if (!(strncmp(property, "1", PROPERTY_VALUE_MAX)) || - !(strncmp(property, "true", PROPERTY_VALUE_MAX))) { - gfx_ahardware_buffer_disable_ = true; - } } AdrenoMemInfo::~AdrenoMemInfo() { @@ -100,6 +85,11 @@ AdrenoMemInfo::~AdrenoMemInfo() { } } +void AdrenoMemInfo::AdrenoSetProperties(gralloc::GrallocProperties props) { + gfx_ubwc_disable_ = props.ubwc_disable; + gfx_ahardware_buffer_disable_ = props.ahardware_buffer_disable; +} + void AdrenoMemInfo::AlignUnCompressedRGB(int width, int height, int format, int tile_enabled, unsigned int *aligned_w, unsigned int *aligned_h) { *aligned_w = (unsigned int)ALIGN(width, 32); diff --git a/gralloc/gr_adreno_info.h b/gralloc/gr_adreno_info.h index 436e0c03..6c9c3e31 100644 --- a/gralloc/gr_adreno_info.h +++ b/gralloc/gr_adreno_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020, 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 @@ -32,6 +32,8 @@ #include <media/msm_media_info.h> +#include "gr_utils.h" + namespace gralloc { // Adreno Pixel Formats @@ -190,6 +192,8 @@ class AdrenoMemInfo { */ bool AdrenoSizeAPIAvaliable(); + void AdrenoSetProperties(gralloc::GrallocProperties props); + static AdrenoMemInfo *GetInstance(); private: diff --git a/gralloc/gr_allocator.cpp b/gralloc/gr_allocator.cpp index 64211572..a8073195 100644 --- a/gralloc/gr_allocator.cpp +++ b/gralloc/gr_allocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020, 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 @@ -92,11 +92,6 @@ Allocator::Allocator() : ion_allocator_(nullptr) {} bool Allocator::Init() { ion_allocator_ = new IonAlloc(); - char property[PROPERTY_VALUE_MAX]; - property_get(USE_SYSTEM_HEAP_FOR_SENSORS, property, "1"); - if (!(strncmp(property, "0", PROPERTY_VALUE_MAX))) { - use_system_heap_for_sensors_ = false; - } if (!ion_allocator_->Init()) { return false; @@ -111,6 +106,10 @@ Allocator::~Allocator() { } } +void Allocator::SetProperties(gralloc::GrallocProperties props) { + use_system_heap_for_sensors_ = props.use_system_heap_for_sensors; +} + int Allocator::AllocateMem(AllocData *alloc_data, uint64_t usage, int format) { int ret; alloc_data->uncached = UseUncached(format, usage); diff --git a/gralloc/gr_allocator.h b/gralloc/gr_allocator.h index 630151ac..8a9ba64f 100644 --- a/gralloc/gr_allocator.h +++ b/gralloc/gr_allocator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018, 2020, 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 @@ -44,6 +44,7 @@ class Allocator { Allocator(); ~Allocator(); bool Init(); + void SetProperties(gralloc::GrallocProperties props); int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd); int ImportBuffer(int fd); int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, int handle); diff --git a/gralloc/gr_buf_descriptor.h b/gralloc/gr_buf_descriptor.h index 06b6986c..bd50259d 100644 --- a/gralloc/gr_buf_descriptor.h +++ b/gralloc/gr_buf_descriptor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, 2020, 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 @@ -30,47 +30,21 @@ #ifndef __GR_BUF_DESCRIPTOR_H__ #define __GR_BUF_DESCRIPTOR_H__ -#include <android/hardware/graphics/mapper/3.0/IMapper.h> #include <atomic> +#include <string> + +#include "gr_utils.h" namespace gralloc { using android::hardware::hidl_vec; -using android::hardware::graphics::mapper::V3_0::Error; -using android::hardware::graphics::mapper::V3_0::IMapper; - const uint32_t kBufferDescriptorSize = 7; +const uint32_t kBufferDescriptorSizeV4 = 42; const uint32_t kMagicVersion = 0x76312E30; // v1.0 class BufferDescriptor { public: BufferDescriptor() {} explicit BufferDescriptor(uint64_t id) : id_(id) {} - - static hidl_vec<uint32_t> Encode(const IMapper::BufferDescriptorInfo &bd_info) { - hidl_vec<uint32_t> out; - out.resize(kBufferDescriptorSize); - out[0] = kMagicVersion; - out[1] = bd_info.width; - out[2] = bd_info.height; - out[3] = bd_info.layerCount; - out[4] = static_cast<uint32_t>(bd_info.format); - out[5] = static_cast<uint32_t>(bd_info.usage); - out[6] = static_cast<uint32_t>(bd_info.usage >> 32); - return out; - } - - Error Decode(const hidl_vec<uint32_t> &in) { - if (in.size() != kBufferDescriptorSize || in[0] != kMagicVersion) { - return Error::BAD_DESCRIPTOR; - } - width_ = static_cast<int32_t>(in[1]); - height_ = static_cast<int32_t>(in[2]); - layer_count_ = in[3]; - format_ = static_cast<int32_t>(in[4]); - usage_ = static_cast<uint64_t>(in[6]) << 32 | in[5]; - return Error::NONE; - } - void SetUsage(uint64_t usage) { usage_ |= usage; } void SetDimensions(int w, int h) { @@ -82,6 +56,10 @@ class BufferDescriptor { void SetLayerCount(uint32_t layer_count) { layer_count_ = layer_count; } + void SetName(std::string name) { name_ = name; } + + void SetReservedSize(uint64_t reserved_size) { reserved_size_ = reserved_size; } + uint64_t GetUsage() const { return usage_; } int GetWidth() const { return width_; } @@ -94,13 +72,19 @@ class BufferDescriptor { uint64_t GetId() const { return id_; } + uint64_t GetReservedSize() const { return reserved_size_; } + + std::string GetName() const { return name_; } + private: + std::string name_ = ""; int width_ = -1; int height_ = -1; int format_ = -1; uint32_t layer_count_ = 1; uint64_t usage_ = 0; const uint64_t id_ = 0; + uint64_t reserved_size_ = 0; }; }; // namespace gralloc #endif // __GR_BUF_DESCRIPTOR_H__ diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp index 86d730ec..a557886c 100644 --- a/gralloc/gr_buf_mgr.cpp +++ b/gralloc/gr_buf_mgr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018, 2020 The Linux Foundation. All rights reserved. * Not a Contribution * * Copyright (C) 2010 The Android Open Source Project @@ -19,24 +19,591 @@ #define DEBUG 0 +#include "gr_buf_mgr.h" + +#include <QtiGralloc.h> +#include <QtiGrallocPriv.h> +#include <gralloctypes/Gralloc4.h> +#include <sys/mman.h> + #include <iomanip> #include <sstream> +#include <string> #include <utility> #include <vector> +#include "gr_adreno_info.h" #include "gr_buf_descriptor.h" -#include "gr_buf_mgr.h" #include "gr_priv_handle.h" +#include "gr_utils.h" #include "qdMetaData.h" #include "qd_utils.h" namespace gralloc { +using aidl::android::hardware::graphics::common::BlendMode; +using aidl::android::hardware::graphics::common::Cta861_3; +using aidl::android::hardware::graphics::common::Dataspace; +using aidl::android::hardware::graphics::common::PlaneLayout; +using aidl::android::hardware::graphics::common::PlaneLayoutComponent; +using aidl::android::hardware::graphics::common::Rect; +using aidl::android::hardware::graphics::common::Smpte2086; +using aidl::android::hardware::graphics::common::StandardMetadataType; +using aidl::android::hardware::graphics::common::XyColor; +using ::android::hardware::graphics::common::V1_2::PixelFormat; static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) { return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(), descriptor.GetUsage()); } +// duplicate from qdmetadata +static uint32_t getMetaDataSize() { + return static_cast<uint32_t>(ROUND_UP_PAGESIZE(sizeof(MetaData_t))); +} + +static int validateAndMap(private_handle_t *handle) { + if (private_handle_t::validate(handle)) { + ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle); + return -1; + } + if (handle->fd_metadata < 0) { + // Silently return, metadata cannot be used + return -1; + } + + if (!handle->base_metadata) { + auto size = getMetaDataSize(); + void *base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd_metadata, 0); + if (base == reinterpret_cast<void *>(MAP_FAILED)) { + ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s", __func__, handle, + handle->fd_metadata, strerror(errno)); + + return -1; + } + handle->base_metadata = (uintptr_t)base; + } + return 0; +} + +static void unmapAndReset(private_handle_t *handle) { + if (private_handle_t::validate(handle) == 0 && handle->base_metadata) { + munmap(reinterpret_cast<void *>(handle->base_metadata), getMetaDataSize()); + handle->base_metadata = 0; + } +} + +static Error dataspaceToColorMetadata(Dataspace dataspace, ColorMetaData *color_metadata) { + ColorMetaData out; + uint32_t primaries = (uint32_t)dataspace & (uint32_t)Dataspace::STANDARD_MASK; + uint32_t transfer = (uint32_t)dataspace & (uint32_t)Dataspace::TRANSFER_MASK; + uint32_t range = (uint32_t)dataspace & (uint32_t)Dataspace::RANGE_MASK; + + switch (primaries) { + case (uint32_t)Dataspace::STANDARD_BT709: + out.colorPrimaries = ColorPrimaries_BT709_5; + break; + // TODO(tbalacha): verify this is equivalent + case (uint32_t)Dataspace::STANDARD_BT470M: + out.colorPrimaries = ColorPrimaries_BT470_6M; + break; + case (uint32_t)Dataspace::STANDARD_BT601_625: + case (uint32_t)Dataspace::STANDARD_BT601_625_UNADJUSTED: + out.colorPrimaries = ColorPrimaries_BT601_6_625; + break; + case (uint32_t)Dataspace::STANDARD_BT601_525: + case (uint32_t)Dataspace::STANDARD_BT601_525_UNADJUSTED: + out.colorPrimaries = ColorPrimaries_BT601_6_525; + break; + case (uint32_t)Dataspace::STANDARD_FILM: + out.colorPrimaries = ColorPrimaries_GenericFilm; + break; + case (uint32_t)Dataspace::STANDARD_BT2020: + out.colorPrimaries = ColorPrimaries_BT2020; + break; + case (uint32_t)Dataspace::STANDARD_ADOBE_RGB: + out.colorPrimaries = ColorPrimaries_AdobeRGB; + break; + case (uint32_t)Dataspace::STANDARD_DCI_P3: + out.colorPrimaries = ColorPrimaries_DCIP3; + break; + default: + return Error::UNSUPPORTED; + /* + ColorPrimaries_SMPTE_240M; + ColorPrimaries_SMPTE_ST428; + ColorPrimaries_EBU3213; + */ + } + + switch (transfer) { + case (uint32_t)Dataspace::TRANSFER_SRGB: + out.transfer = Transfer_sRGB; + break; + case (uint32_t)Dataspace::TRANSFER_GAMMA2_2: + out.transfer = Transfer_Gamma2_2; + break; + case (uint32_t)Dataspace::TRANSFER_GAMMA2_8: + out.transfer = Transfer_Gamma2_8; + break; + case (uint32_t)Dataspace::TRANSFER_SMPTE_170M: + out.transfer = Transfer_SMPTE_170M; + break; + case (uint32_t)Dataspace::TRANSFER_LINEAR: + out.transfer = Transfer_Linear; + break; + case (uint32_t)Dataspace::TRANSFER_HLG: + out.transfer = Transfer_HLG; + break; + default: + return Error::UNSUPPORTED; + /* + Transfer_SMPTE_240M + Transfer_Log + Transfer_Log_Sqrt + Transfer_XvYCC + Transfer_BT1361 + Transfer_sYCC + Transfer_BT2020_2_1 + Transfer_BT2020_2_2 + Transfer_SMPTE_ST2084 + Transfer_ST_428 + */ + } + + switch (range) { + case (uint32_t)Dataspace::RANGE_FULL: + out.range = Range_Full; + break; + case (uint32_t)Dataspace::RANGE_LIMITED: + out.range = Range_Limited; + break; + case (uint32_t)Dataspace::RANGE_EXTENDED: + out.range = Range_Extended; + break; + default: + return Error::UNSUPPORTED; + } + + color_metadata->colorPrimaries = out.colorPrimaries; + color_metadata->transfer = out.transfer; + color_metadata->range = out.range; + return Error::NONE; +} +static Error colorMetadataToDataspace(ColorMetaData color_metadata, Dataspace *dataspace) { + Dataspace primaries, transfer, range = Dataspace::UNKNOWN; + + switch (color_metadata.colorPrimaries) { + case ColorPrimaries_BT709_5: + primaries = Dataspace::STANDARD_BT709; + break; + // TODO(tbalacha): verify this is equivalent + case ColorPrimaries_BT470_6M: + primaries = Dataspace::STANDARD_BT470M; + break; + case ColorPrimaries_BT601_6_625: + primaries = Dataspace::STANDARD_BT601_625; + break; + case ColorPrimaries_BT601_6_525: + primaries = Dataspace::STANDARD_BT601_525; + break; + case ColorPrimaries_GenericFilm: + primaries = Dataspace::STANDARD_FILM; + break; + case ColorPrimaries_BT2020: + primaries = Dataspace::STANDARD_BT2020; + break; + case ColorPrimaries_AdobeRGB: + primaries = Dataspace::STANDARD_ADOBE_RGB; + break; + case ColorPrimaries_DCIP3: + primaries = Dataspace::STANDARD_DCI_P3; + break; + default: + return Error::UNSUPPORTED; + /* + ColorPrimaries_SMPTE_240M; + ColorPrimaries_SMPTE_ST428; + ColorPrimaries_EBU3213; + */ + } + + switch (color_metadata.transfer) { + case Transfer_sRGB: + transfer = Dataspace::TRANSFER_SRGB; + break; + case Transfer_Gamma2_2: + transfer = Dataspace::TRANSFER_GAMMA2_2; + break; + case Transfer_Gamma2_8: + transfer = Dataspace::TRANSFER_GAMMA2_8; + break; + case Transfer_SMPTE_170M: + transfer = Dataspace::TRANSFER_SMPTE_170M; + break; + case Transfer_Linear: + transfer = Dataspace::TRANSFER_LINEAR; + break; + case Transfer_HLG: + transfer = Dataspace::TRANSFER_HLG; + break; + default: + return Error::UNSUPPORTED; + /* + Transfer_SMPTE_240M + Transfer_Log + Transfer_Log_Sqrt + Transfer_XvYCC + Transfer_BT1361 + Transfer_sYCC + Transfer_BT2020_2_1 + Transfer_BT2020_2_2 + Transfer_SMPTE_ST2084 + Transfer_ST_428 + */ + } + + switch (color_metadata.range) { + case Range_Full: + range = Dataspace::RANGE_FULL; + break; + case Range_Limited: + range = Dataspace::RANGE_LIMITED; + break; + case Range_Extended: + range = Dataspace::RANGE_EXTENDED; + break; + default: + return Error::UNSUPPORTED; + } + + *dataspace = (Dataspace)((uint32_t)primaries | (uint32_t)transfer | (uint32_t)range); + return Error::NONE; +} + +static void getComponentSizeAndOffset(int32_t format, PlaneLayoutComponent &comp) { + switch (format) { + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_8888): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBX_8888): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGB_888): + comp.sizeInBits = 8; + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.offsetInBits = 8; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.offsetInBits = 16; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) { + comp.offsetInBits = 24; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGB_565): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.offsetInBits = 0; + comp.sizeInBits = 5; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.offsetInBits = 5; + comp.sizeInBits = 6; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.offsetInBits = 11; + comp.sizeInBits = 5; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGR_565): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.offsetInBits = 11; + comp.sizeInBits = 5; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.offsetInBits = 5; + comp.sizeInBits = 6; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.offsetInBits = 0; + comp.sizeInBits = 5; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRA_8888): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRX_8888): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGR_888): + comp.sizeInBits = 8; + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.offsetInBits = 16; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.offsetInBits = 8; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) { + comp.offsetInBits = 24; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_5551): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.sizeInBits = 5; + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.sizeInBits = 5; + comp.offsetInBits = 5; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.sizeInBits = 5; + comp.offsetInBits = 10; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) { + comp.sizeInBits = 1; + comp.offsetInBits = 15; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_4444): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.sizeInBits = 4; + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.sizeInBits = 4; + comp.offsetInBits = 4; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.sizeInBits = 4; + comp.offsetInBits = 8; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) { + comp.sizeInBits = 4; + comp.offsetInBits = 12; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_R_8): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RG_88): + comp.sizeInBits = 8; + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.offsetInBits = 8; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_1010102): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBX_1010102): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 10; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 20; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) { + comp.sizeInBits = 2; + comp.offsetInBits = 30; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_ARGB_2101010): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_XRGB_2101010): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 2; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 12; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 22; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) { + comp.sizeInBits = 2; + comp.offsetInBits = 0; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRA_1010102): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_BGRX_1010102): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 20; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 10; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) { + comp.sizeInBits = 2; + comp.offsetInBits = 30; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_ABGR_2101010): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_XBGR_2101010): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 22; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 12; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.sizeInBits = 10; + comp.offsetInBits = 2; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) { + comp.sizeInBits = 2; + comp.offsetInBits = 0; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_FP16): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_R.value) { + comp.sizeInBits = 16; + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_G.value) { + comp.sizeInBits = 16; + comp.offsetInBits = 16; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_B.value) { + comp.sizeInBits = 16; + comp.offsetInBits = 32; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_A.value) { + comp.sizeInBits = 16; + comp.offsetInBits = 48; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_SP): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_422_SP): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_NV12_ENCODEABLE): + comp.sizeInBits = 8; + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value || + comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value) { + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) { + comp.offsetInBits = 8; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_422_SP): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS): + case static_cast<int32_t>(HAL_PIXEL_FORMAT_NV21_ZSL): + comp.sizeInBits = 8; + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value || + comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) { + comp.offsetInBits = 0; + } else if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value) { + comp.offsetInBits = 8; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_Y16): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value) { + comp.offsetInBits = 0; + comp.sizeInBits = 16; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_YV12): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value || + comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value || + comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) { + comp.offsetInBits = 0; + comp.sizeInBits = 8; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_Y8): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value) { + comp.offsetInBits = 0; + comp.sizeInBits = 8; + } + break; + case static_cast<int32_t>(HAL_PIXEL_FORMAT_YCbCr_420_P010): + if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_Y.value || + comp.type.value == android::gralloc4::PlaneLayoutComponentType_CB.value || + comp.type.value == android::gralloc4::PlaneLayoutComponentType_CR.value) { + comp.offsetInBits = 0; + comp.sizeInBits = 10; + } + break; + default: + break; + } +} + +static void grallocToStandardPlaneLayoutComponentType(uint32_t in, + std::vector<PlaneLayoutComponent> *components, + int32_t format) { + PlaneLayoutComponent comp; + comp.offsetInBits = -1; + comp.sizeInBits = -1; + + if (in & PLANE_COMPONENT_Y) { + comp.type = android::gralloc4::PlaneLayoutComponentType_Y; + getComponentSizeAndOffset(format, comp); + components->push_back(comp); + } + + if (in & PLANE_COMPONENT_Cb) { + comp.type = android::gralloc4::PlaneLayoutComponentType_CB; + getComponentSizeAndOffset(format, comp); + components->push_back(comp); + } + + if (in & PLANE_COMPONENT_Cr) { + comp.type = android::gralloc4::PlaneLayoutComponentType_CR; + getComponentSizeAndOffset(format, comp); + components->push_back(comp); + } + + if (in & PLANE_COMPONENT_R) { + comp.type = android::gralloc4::PlaneLayoutComponentType_R; + getComponentSizeAndOffset(format, comp); + components->push_back(comp); + } + + if (in & PLANE_COMPONENT_G) { + comp.type = android::gralloc4::PlaneLayoutComponentType_G; + getComponentSizeAndOffset(format, comp); + components->push_back(comp); + } + + if (in & PLANE_COMPONENT_B) { + comp.type = android::gralloc4::PlaneLayoutComponentType_B; + getComponentSizeAndOffset(format, comp); + components->push_back(comp); + } + + if (in & PLANE_COMPONENT_A) { + comp.type = android::gralloc4::PlaneLayoutComponentType_A; + getComponentSizeAndOffset(format, comp); + components->push_back(comp); + } + + if (in & PLANE_COMPONENT_RAW) { + comp.type = qtigralloc::PlaneLayoutComponentType_Raw; + components->push_back(comp); + } + + if (in & PLANE_COMPONENT_META) { + comp.type = qtigralloc::PlaneLayoutComponentType_Meta; + components->push_back(comp); + } +} + +static Error getFormatLayout(private_handle_t *handle, std::vector<PlaneLayout> *out) { + std::vector<PlaneLayout> plane_info; + int plane_count = 0; + BufferInfo info(handle->unaligned_width, handle->unaligned_height, handle->format, handle->usage); + + gralloc::PlaneLayoutInfo plane_layout[8] = {}; + if (gralloc::IsYuvFormat(handle->format)) { + gralloc::GetYUVPlaneInfo(info, handle->format, handle->width, handle->height, handle->flags, + &plane_count, plane_layout); + } else if (gralloc::IsUncompressedRGBFormat(handle->format) || + gralloc::IsCompressedRGBFormat(handle->format)) { + gralloc::GetRGBPlaneInfo(info, handle->format, handle->width, handle->height, handle->flags, + &plane_count, plane_layout); + } else { + return Error::BAD_BUFFER; + } + plane_info.resize(plane_count); + for (int i = 0; i < plane_count; i++) { + std::vector<PlaneLayoutComponent> components; + grallocToStandardPlaneLayoutComponentType(plane_layout[i].component, &plane_info[i].components, + handle->format); + plane_info[i].horizontalSubsampling = (1ull << plane_layout[i].h_subsampling); + plane_info[i].verticalSubsampling = (1ull << plane_layout[i].v_subsampling); + plane_info[i].offsetInBytes = static_cast<int64_t>(plane_layout[i].offset); + plane_info[i].sampleIncrementInBits = static_cast<int64_t>(plane_layout[i].step * 8); + plane_info[i].strideInBytes = static_cast<int64_t>(plane_layout[i].stride_bytes); + plane_info[i].totalSizeInBytes = static_cast<int64_t>(plane_layout[i].size); + plane_info[i].widthInSamples = handle->unaligned_width; + plane_info[i].heightInSamples = handle->unaligned_height; + } + *out = plane_info; + return Error::NONE; +} + BufferManager::BufferManager() : next_id_(0) { handles_map_.clear(); allocator_ = new Allocator(); @@ -54,6 +621,11 @@ BufferManager::~BufferManager() { } } +void BufferManager::SetGrallocDebugProperties(gralloc::GrallocProperties props) { + allocator_->SetProperties(props); + AdrenoMemInfo::GetInstance()->AdrenoSetProperties(props); +} + Error BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) { auto hnd = buf->handle; ALOGD_IF(DEBUG, "FreeBuffer handle:%p", hnd); @@ -68,7 +640,7 @@ Error BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) { return Error::BAD_BUFFER; } - unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE); + auto meta_size = getMetaDataSize(); if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size, hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) { return Error::BAD_BUFFER; @@ -235,6 +807,42 @@ Error BufferManager::LockBuffer(const private_handle_t *hnd, uint64_t usage) { return err; } +Error BufferManager::FlushBuffer(const private_handle_t *handle) { + std::lock_guard<std::mutex> lock(buffer_lock_); + auto status = Error::NONE; + + private_handle_t *hnd = const_cast<private_handle_t *>(handle); + auto buf = GetBufferFromHandleLocked(hnd); + if (buf == nullptr) { + return Error::BAD_BUFFER; + } + + if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset, + buf->ion_handle_main, CACHE_CLEAN, hnd->fd) != 0) { + status = Error::BAD_BUFFER; + } + + return status; +} + +Error BufferManager::RereadBuffer(const private_handle_t *handle) { + std::lock_guard<std::mutex> lock(buffer_lock_); + auto status = Error::NONE; + + private_handle_t *hnd = const_cast<private_handle_t *>(handle); + auto buf = GetBufferFromHandleLocked(hnd); + if (buf == nullptr) { + return Error::BAD_BUFFER; + } + + if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset, + buf->ion_handle_main, CACHE_INVALIDATE, hnd->fd) != 0) { + status = Error::BAD_BUFFER; + } + + return status; +} + Error BufferManager::UnlockBuffer(const private_handle_t *handle) { std::lock_guard<std::mutex> lock(buffer_lock_); auto status = Error::NONE; @@ -309,7 +917,7 @@ Error BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_h // Allocate memory for MetaData AllocData e_data; - e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size); + e_data.size = getMetaDataSize(); e_data.handle = data.handle; e_data.align = page_size; @@ -331,7 +939,9 @@ Error BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_h hnd->base = 0; hnd->base_metadata = 0; hnd->layer_count = layer_count; + // set default csc as 709, but for video(yuv) its 601L + ColorSpace_t colorSpace = (buffer_type == BUFFER_TYPE_VIDEO) ? ITU_R_601 : ITU_R_709; setMetaDataAndUnmap(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace)); @@ -340,7 +950,27 @@ Error BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_h setMetaDataAndUnmap(hnd, SET_GRAPHICS_METADATA, reinterpret_cast<void *>(&graphics_metadata)); } + auto error = validateAndMap(hnd); + if (error != 0) { + ALOGE("validateAndMap failed"); + return Error::BAD_BUFFER; + } + auto metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata); + auto nameLength = std::min(descriptor.GetName().size(), size_t(MAX_NAME_LEN - 1)); + nameLength = descriptor.GetName().copy(metadata->name, nameLength); + metadata->name[nameLength] = '\0'; + + metadata->reservedRegion.size = static_cast<uint32_t>(descriptor.GetReservedSize()); + + metadata->crop.top = 0; + metadata->crop.left = 0; + metadata->crop.right = hnd->width; + metadata->crop.bottom = hnd->height; + + unmapAndReset(hnd); + *handle = hnd; + RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle); ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id); if (DEBUG) { @@ -373,4 +1003,445 @@ Error BufferManager::Dump(std::ostringstream *os) { } return Error::NONE; } + +// Get list of private handles in handles_map_ +Error BufferManager::GetAllHandles(std::vector<const private_handle_t *> *out_handle_list) { + std::lock_guard<std::mutex> lock(buffer_lock_); + if (handles_map_.empty()) { + return Error::NO_RESOURCES; + } + out_handle_list->reserve(handles_map_.size()); + for (auto handle : handles_map_) { + out_handle_list->push_back(handle.first); + } + return Error::NONE; +} + +Error BufferManager::GetReservedRegion(private_handle_t *handle, void **reserved_region, + uint64_t *reserved_region_size) { + std::lock_guard<std::mutex> lock(buffer_lock_); + if (!handle) + return Error::BAD_BUFFER; + + auto buf = GetBufferFromHandleLocked(handle); + if (buf == nullptr) + return Error::BAD_BUFFER; + + auto err = validateAndMap(handle); + if (err != 0) + return Error::BAD_BUFFER; + auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata); + + *reserved_region = reinterpret_cast<void *>(&(metadata->reservedRegion.data)); + *reserved_region_size = metadata->reservedRegion.size; + + return Error::NONE; +} + +Error BufferManager::GetMetadata(private_handle_t *handle, int64_t metadatatype_value, + hidl_vec<uint8_t> *out) { + std::lock_guard<std::mutex> lock(buffer_lock_); + if (!handle) + return Error::BAD_BUFFER; + auto buf = GetBufferFromHandleLocked(handle); + if (buf == nullptr) + return Error::BAD_BUFFER; + + auto err = validateAndMap(handle); + if (err != 0) + return Error::BAD_BUFFER; + + auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata); + + Error error = Error::NONE; + switch (metadatatype_value) { + case (int64_t)StandardMetadataType::BUFFER_ID: + android::gralloc4::encodeBufferId((uint64_t)handle->id, out); + break; + case (int64_t)StandardMetadataType::NAME: { + std::string name(metadata->name); + android::gralloc4::encodeName(name, out); + break; + } + case (int64_t)StandardMetadataType::WIDTH: + android::gralloc4::encodeWidth((uint64_t)handle->unaligned_width, out); + break; + case (int64_t)StandardMetadataType::HEIGHT: + android::gralloc4::encodeHeight((uint64_t)handle->unaligned_height, out); + break; + case (int64_t)StandardMetadataType::LAYER_COUNT: + android::gralloc4::encodeLayerCount((uint64_t)handle->layer_count, out); + break; + case (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED: + // TODO(tbalacha): need to return IMPLEMENTATION_DEFINED, + // which wouldn't be known from private_handle_t + android::gralloc4::encodePixelFormatRequested((PixelFormat)handle->format, out); + break; + case (int64_t)StandardMetadataType::PIXEL_FORMAT_FOURCC: { + uint32_t drm_format = 0; + uint64_t drm_format_modifier = 0; + GetDRMFormat(handle->format, handle->flags, &drm_format, &drm_format_modifier); + android::gralloc4::encodePixelFormatFourCC(drm_format, out); + break; + } + case (int64_t)StandardMetadataType::PIXEL_FORMAT_MODIFIER: { + uint32_t drm_format = 0; + uint64_t drm_format_modifier = 0; + GetDRMFormat(handle->format, handle->flags, &drm_format, &drm_format_modifier); + android::gralloc4::encodePixelFormatModifier(drm_format_modifier, out); + break; + } + case (int64_t)StandardMetadataType::USAGE: + android::gralloc4::encodeUsage((uint64_t)handle->usage, out); + break; + case (int64_t)StandardMetadataType::ALLOCATION_SIZE: + android::gralloc4::encodeAllocationSize((uint64_t)handle->size, out); + break; + case (int64_t)StandardMetadataType::PROTECTED_CONTENT: { + uint64_t protected_content = (handle->flags & qtigralloc::PRIV_FLAGS_SECURE_BUFFER) ? 1 : 0; + android::gralloc4::encodeProtectedContent(protected_content, out); + break; + } + case (int64_t)StandardMetadataType::CHROMA_SITING: + android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None, out); + break; + case (int64_t)StandardMetadataType::DATASPACE: + Dataspace dataspace; + colorMetadataToDataspace(metadata->color, &dataspace); + android::gralloc4::encodeDataspace(dataspace, out); + break; + case (int64_t)StandardMetadataType::INTERLACED: + android::gralloc4::encodeInterlaced(qtigralloc::Interlaced_Qti, out); + break; + case (int64_t)StandardMetadataType::COMPRESSION: + if (handle->flags & qtigralloc::PRIV_FLAGS_UBWC_ALIGNED || + handle->flags & qtigralloc::PRIV_FLAGS_UBWC_ALIGNED_PI) { + android::gralloc4::encodeCompression(qtigralloc::Compression_QtiUBWC, out); + } else { + android::gralloc4::encodeCompression(android::gralloc4::Compression_None, out); + } + break; + case (int64_t)StandardMetadataType::PLANE_LAYOUTS: { + std::vector<PlaneLayout> plane_layouts; + getFormatLayout(handle, &plane_layouts); + android::gralloc4::encodePlaneLayouts(plane_layouts, out); + break; + } + case (int64_t)StandardMetadataType::BLEND_MODE: + android::gralloc4::encodeBlendMode((BlendMode)metadata->blendMode, out); + break; + case (int64_t)StandardMetadataType::SMPTE2086: { + if (metadata->color.masteringDisplayInfo.colorVolumeSEIEnabled) { + Smpte2086 mastering_display_values; + mastering_display_values.primaryRed = { + static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][0]) / + 50000.0f, + static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][1]) / + 50000.0f}; + mastering_display_values.primaryGreen = { + static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][0]) / + 50000.0f, + static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][1]) / + 50000.0f}; + mastering_display_values.primaryBlue = { + static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][0]) / + 50000.0f, + static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][1]) / + 50000.0f}; + mastering_display_values.whitePoint = { + static_cast<float>(metadata->color.masteringDisplayInfo.primaries.whitePoint[0]) / + 50000.0f, + static_cast<float>(metadata->color.masteringDisplayInfo.primaries.whitePoint[1]) / + 50000.0f}; + mastering_display_values.maxLuminance = + static_cast<float>(metadata->color.masteringDisplayInfo.maxDisplayLuminance); + mastering_display_values.minLuminance = + static_cast<float>(metadata->color.masteringDisplayInfo.minDisplayLuminance) / 10000.0f; + android::gralloc4::encodeSmpte2086(mastering_display_values, out); + } else { + android::gralloc4::encodeSmpte2086(std::nullopt, out); + } + break; + } + case (int64_t)StandardMetadataType::CTA861_3: { + if (metadata->color.contentLightLevel.lightLevelSEIEnabled) { + Cta861_3 content_light_level; + content_light_level.maxContentLightLevel = + static_cast<float>(metadata->color.contentLightLevel.maxContentLightLevel); + content_light_level.maxFrameAverageLightLevel = + static_cast<float>(metadata->color.contentLightLevel.minPicAverageLightLevel) / + 10000.0f; + android::gralloc4::encodeCta861_3(content_light_level, out); + } else { + android::gralloc4::encodeCta861_3(std::nullopt, out); + } + break; + } + case (int64_t)StandardMetadataType::SMPTE2094_40: { + if (metadata->color.dynamicMetaDataValid && + metadata->color.dynamicMetaDataLen <= HDR_DYNAMIC_META_DATA_SZ) { + std::vector<uint8_t> dynamic_metadata_payload; + dynamic_metadata_payload.resize(metadata->color.dynamicMetaDataLen); + dynamic_metadata_payload.assign( + metadata->color.dynamicMetaDataPayload, + metadata->color.dynamicMetaDataPayload + metadata->color.dynamicMetaDataLen); + android::gralloc4::encodeSmpte2094_40(dynamic_metadata_payload, out); + } else { + android::gralloc4::encodeSmpte2094_40(std::nullopt, out); + } + break; + } + case (int64_t)StandardMetadataType::CROP: { + // Crop is the same for all planes + std::vector<Rect> out_crop = {{metadata->crop.left, metadata->crop.top, metadata->crop.right, + metadata->crop.bottom}}; + android::gralloc4::encodeCrop(out_crop, out); + break; + } + case QTI_VT_TIMESTAMP: + android::gralloc4::encodeUint64(qtigralloc::MetadataType_VTTimestamp, metadata->vtTimeStamp, + out); + break; + case QTI_COLOR_METADATA: + qtigralloc::encodeColorMetadata(metadata->color, out); + break; + case QTI_PP_PARAM_INTERLACED: + android::gralloc4::encodeInt32(qtigralloc::MetadataType_PPParamInterlaced, + metadata->interlaced, out); + break; + case QTI_VIDEO_PERF_MODE: + android::gralloc4::encodeUint32(qtigralloc::MetadataType_VideoPerfMode, + metadata->isVideoPerfMode, out); + break; + case QTI_GRAPHICS_METADATA: + qtigralloc::encodeGraphicsMetadata(metadata->graphics_metadata, out); + break; + case QTI_UBWC_CR_STATS_INFO: + qtigralloc::encodeUBWCStats(metadata->ubwcCRStats, out); + break; + case QTI_REFRESH_RATE: + android::gralloc4::encodeFloat(qtigralloc::MetadataType_RefreshRate, metadata->refreshrate, + out); + break; + case QTI_MAP_SECURE_BUFFER: + android::gralloc4::encodeInt32(qtigralloc::MetadataType_MapSecureBuffer, + metadata->mapSecureBuffer, out); + break; + case QTI_LINEAR_FORMAT: + android::gralloc4::encodeUint32(qtigralloc::MetadataType_LinearFormat, metadata->linearFormat, + out); + break; + case QTI_SINGLE_BUFFER_MODE: + android::gralloc4::encodeUint32(qtigralloc::MetadataType_SingleBufferMode, + metadata->isSingleBufferMode, out); + break; + case QTI_CVP_METADATA: + qtigralloc::encodeCVPMetadata(metadata->cvpMetadata, out); + break; + case QTI_VIDEO_HISTOGRAM_STATS: + qtigralloc::encodeVideoHistogramMetadata(metadata->video_histogram_stats, out); + break; + case QTI_FD: + android::gralloc4::encodeInt32(qtigralloc::MetadataType_FD, handle->fd, out); + break; + case QTI_PRIVATE_FLAGS: + android::gralloc4::encodeInt32(qtigralloc::MetadataType_PrivateFlags, handle->flags, out); + break; + case QTI_ALIGNED_WIDTH_IN_PIXELS: + android::gralloc4::encodeUint32(qtigralloc::MetadataType_AlignedWidthInPixels, handle->width, + out); + break; + case QTI_ALIGNED_HEIGHT_IN_PIXELS: + android::gralloc4::encodeUint32(qtigralloc::MetadataType_AlignedHeightInPixels, + handle->height, out); + break; + default: + error = Error::UNSUPPORTED; + } + + return error; +} + +Error BufferManager::SetMetadata(private_handle_t *handle, int64_t metadatatype_value, + hidl_vec<uint8_t> in) { + std::lock_guard<std::mutex> lock(buffer_lock_); + if (!handle) + return Error::BAD_BUFFER; + + auto buf = GetBufferFromHandleLocked(handle); + if (buf == nullptr) + return Error::BAD_BUFFER; + + int err = validateAndMap(handle); + if (err != 0) + return Error::BAD_BUFFER; + + if (in.size() == 0) { + return Error::UNSUPPORTED; + } + + auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata); + + switch (metadatatype_value) { + // These are constant (unchanged after allocation) + case (int64_t)StandardMetadataType::BUFFER_ID: + case (int64_t)StandardMetadataType::NAME: + case (int64_t)StandardMetadataType::WIDTH: + case (int64_t)StandardMetadataType::HEIGHT: + case (int64_t)StandardMetadataType::LAYER_COUNT: + case (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED: + case (int64_t)StandardMetadataType::USAGE: + return Error::BAD_VALUE; + case (int64_t)StandardMetadataType::PIXEL_FORMAT_FOURCC: + case (int64_t)StandardMetadataType::PIXEL_FORMAT_MODIFIER: + case (int64_t)StandardMetadataType::PROTECTED_CONTENT: + case (int64_t)StandardMetadataType::ALLOCATION_SIZE: + case (int64_t)StandardMetadataType::PLANE_LAYOUTS: + case (int64_t)StandardMetadataType::CHROMA_SITING: + case (int64_t)StandardMetadataType::INTERLACED: + case (int64_t)StandardMetadataType::COMPRESSION: + case QTI_FD: + case QTI_PRIVATE_FLAGS: + case QTI_ALIGNED_WIDTH_IN_PIXELS: + case QTI_ALIGNED_HEIGHT_IN_PIXELS: + return Error::UNSUPPORTED; + case (int64_t)StandardMetadataType::DATASPACE: + Dataspace dataspace; + android::gralloc4::decodeDataspace(in, &dataspace); + dataspaceToColorMetadata(dataspace, &metadata->color); + break; + case (int64_t)StandardMetadataType::BLEND_MODE: + BlendMode mode; + android::gralloc4::decodeBlendMode(in, &mode); + metadata->blendMode = (int32_t)mode; + break; + case (int64_t)StandardMetadataType::SMPTE2086: { + std::optional<Smpte2086> mastering_display_values; + android::gralloc4::decodeSmpte2086(in, &mastering_display_values); + if (mastering_display_values != std::nullopt) { + metadata->color.masteringDisplayInfo.colorVolumeSEIEnabled = true; + + metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][0] = + static_cast<uint32_t>(mastering_display_values->primaryRed.x * 50000.0f); + metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][1] = + static_cast<uint32_t>(mastering_display_values->primaryRed.y * 50000.0f); + + metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][0] = + static_cast<uint32_t>(mastering_display_values->primaryGreen.x * 50000.0f); + metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][1] = + static_cast<uint32_t>(mastering_display_values->primaryGreen.y * 50000.0f); + + metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][0] = + static_cast<uint32_t>(mastering_display_values->primaryBlue.x * 50000.0f); + metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][1] = + static_cast<uint32_t>(mastering_display_values->primaryBlue.y * 50000.0f); + + metadata->color.masteringDisplayInfo.primaries.whitePoint[0] = + static_cast<uint32_t>(mastering_display_values->whitePoint.x * 50000.0f); + metadata->color.masteringDisplayInfo.primaries.whitePoint[1] = + static_cast<uint32_t>(mastering_display_values->whitePoint.y * 50000.0f); + + metadata->color.masteringDisplayInfo.maxDisplayLuminance = + static_cast<uint32_t>(mastering_display_values->maxLuminance); + metadata->color.masteringDisplayInfo.minDisplayLuminance = + static_cast<uint32_t>(mastering_display_values->minLuminance * 10000.0f); + } else { + metadata->color.masteringDisplayInfo.colorVolumeSEIEnabled = false; + } + break; + } + case (int64_t)StandardMetadataType::CTA861_3: { + std::optional<Cta861_3> content_light_level; + android::gralloc4::decodeCta861_3(in, &content_light_level); + if (content_light_level != std::nullopt) { + metadata->color.contentLightLevel.lightLevelSEIEnabled = true; + metadata->color.contentLightLevel.maxContentLightLevel = + static_cast<uint32_t>(content_light_level->maxContentLightLevel); + metadata->color.contentLightLevel.minPicAverageLightLevel = + static_cast<uint32_t>(content_light_level->maxFrameAverageLightLevel * 10000.0f); + } else { + metadata->color.contentLightLevel.lightLevelSEIEnabled = false; + } + break; + } + case (int64_t)StandardMetadataType::SMPTE2094_40: { + std::optional<std::vector<uint8_t>> dynamic_metadata_payload; + android::gralloc4::decodeSmpte2094_40(in, &dynamic_metadata_payload); + if (dynamic_metadata_payload != std::nullopt) { + if (dynamic_metadata_payload->size() > HDR_DYNAMIC_META_DATA_SZ) + return Error::BAD_VALUE; + + metadata->color.dynamicMetaDataLen = static_cast<uint32_t>(dynamic_metadata_payload->size()); + std::copy(dynamic_metadata_payload->begin(), dynamic_metadata_payload->end(), + metadata->color.dynamicMetaDataPayload); + metadata->color.dynamicMetaDataValid = true; + } else { + // Reset metadata by passing in std::nullopt + metadata->color.dynamicMetaDataValid = false; + } + break; + } + case (int64_t)StandardMetadataType::CROP: { + std::vector<Rect> in_crop; + android::gralloc4::decodeCrop(in, &in_crop); + if (in_crop.size() != 1) + return Error::UNSUPPORTED; + + metadata->crop.left = in_crop[0].left; + metadata->crop.top = in_crop[0].top; + metadata->crop.right = in_crop[0].right; + metadata->crop.bottom = in_crop[0].bottom; + break; + } + case QTI_VT_TIMESTAMP: + android::gralloc4::decodeUint64(qtigralloc::MetadataType_VTTimestamp, in, + &metadata->vtTimeStamp); + break; + case QTI_COLOR_METADATA: + ColorMetaData color; + qtigralloc::decodeColorMetadata(in, &color); + metadata->color = color; + break; + case QTI_PP_PARAM_INTERLACED: + android::gralloc4::decodeInt32(qtigralloc::MetadataType_PPParamInterlaced, in, + &metadata->interlaced); + break; + case QTI_VIDEO_PERF_MODE: + android::gralloc4::decodeUint32(qtigralloc::MetadataType_VideoPerfMode, in, + &metadata->isVideoPerfMode); + break; + case QTI_GRAPHICS_METADATA: + qtigralloc::decodeGraphicsMetadata(in, &metadata->graphics_metadata); + break; + case QTI_UBWC_CR_STATS_INFO: + qtigralloc::decodeUBWCStats(in, &metadata->ubwcCRStats[0]); + break; + case QTI_REFRESH_RATE: + android::gralloc4::decodeFloat(qtigralloc::MetadataType_RefreshRate, in, + &metadata->refreshrate); + break; + case QTI_MAP_SECURE_BUFFER: + android::gralloc4::decodeInt32(qtigralloc::MetadataType_MapSecureBuffer, in, + &metadata->mapSecureBuffer); + break; + case QTI_LINEAR_FORMAT: + android::gralloc4::decodeUint32(qtigralloc::MetadataType_LinearFormat, in, + &metadata->linearFormat); + break; + case QTI_SINGLE_BUFFER_MODE: + android::gralloc4::decodeUint32(qtigralloc::MetadataType_SingleBufferMode, in, + &metadata->isSingleBufferMode); + break; + case QTI_CVP_METADATA: + qtigralloc::decodeCVPMetadata(in, &metadata->cvpMetadata); + break; + case QTI_VIDEO_HISTOGRAM_STATS: + qtigralloc::decodeVideoHistogramMetadata(in, &metadata->video_histogram_stats); + break; + default: + return Error::BAD_VALUE; + } + return Error::NONE; +} + } // namespace gralloc diff --git a/gralloc/gr_buf_mgr.h b/gralloc/gr_buf_mgr.h index 1ff54550..9c5794c9 100644 --- a/gralloc/gr_buf_mgr.h +++ b/gralloc/gr_buf_mgr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018, 2020 The Linux Foundation. All rights reserved. * Not a Contribution * * Copyright (C) 2008 The Android Open Source Project @@ -21,20 +21,20 @@ #define __GR_BUF_MGR_H__ #include <pthread.h> + #include <mutex> #include <unordered_map> #include <unordered_set> #include <utility> +#include <vector> #include "gr_allocator.h" -#include "gr_utils.h" #include "gr_buf_descriptor.h" +#include "gr_utils.h" #include "gralloc_priv.h" namespace gralloc { - -using android::hardware::graphics::mapper::V3_0::Error; - +using gralloc::Error; class BufferManager { public: ~BufferManager(); @@ -49,6 +49,14 @@ class BufferManager { Error ValidateBufferSize(private_handle_t const *hnd, BufferInfo info); Error IsBufferImported(const private_handle_t *hnd); static BufferManager *GetInstance(); + Error GetMetadata(private_handle_t *handle, int64_t metadatatype_value, hidl_vec<uint8_t> *out); + Error SetMetadata(private_handle_t *handle, int64_t metadatatype_value, hidl_vec<uint8_t> in); + Error GetReservedRegion(private_handle_t *handle, void **reserved_region, + uint64_t *reserved_region_size); + Error FlushBuffer(const private_handle_t *handle); + Error RereadBuffer(const private_handle_t *handle); + Error GetAllHandles(std::vector<const private_handle_t *> *out_handle_list); + void SetGrallocDebugProperties(gralloc::GrallocProperties props); private: BufferManager(); diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp index 05a63628..3dc91d5b 100644 --- a/gralloc/gr_utils.cpp +++ b/gralloc/gr_utils.cpp @@ -28,6 +28,9 @@ */ #include <media/msm_media_info.h> + +#include <drm/drm_fourcc.h> + #include <algorithm> #include "gr_adreno_info.h" @@ -1640,4 +1643,124 @@ void GetRGBPlaneInfo(const BufferInfo &info, int32_t format, int32_t width, int3 plane_info->scanlines = height; } +// TODO(tbalacha): tile vs ubwc -- may need to find a diff way to differentiate +void GetDRMFormat(uint32_t format, uint32_t flags, uint32_t *drm_format, + uint64_t *drm_format_modifier) { + bool compressed = (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) ? true : false; + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + *drm_format = DRM_FORMAT_ABGR8888; + break; + case HAL_PIXEL_FORMAT_RGBA_5551: + *drm_format = DRM_FORMAT_ABGR1555; + break; + case HAL_PIXEL_FORMAT_RGBA_4444: + *drm_format = DRM_FORMAT_ABGR4444; + break; + case HAL_PIXEL_FORMAT_BGRA_8888: + *drm_format = DRM_FORMAT_ARGB8888; + break; + case HAL_PIXEL_FORMAT_RGBX_8888: + *drm_format = DRM_FORMAT_XBGR8888; + if (compressed) + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + break; + case HAL_PIXEL_FORMAT_BGRX_8888: + *drm_format = DRM_FORMAT_XRGB8888; + break; + case HAL_PIXEL_FORMAT_RGB_888: + *drm_format = DRM_FORMAT_BGR888; + break; + case HAL_PIXEL_FORMAT_RGB_565: + *drm_format = DRM_FORMAT_BGR565; + break; + case HAL_PIXEL_FORMAT_BGR_565: + *drm_format = DRM_FORMAT_BGR565; + if (compressed) + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + break; + case HAL_PIXEL_FORMAT_RGBA_1010102: + *drm_format = DRM_FORMAT_ABGR2101010; + if (compressed) + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + break; + case HAL_PIXEL_FORMAT_ARGB_2101010: + *drm_format = DRM_FORMAT_BGRA1010102; + break; + case HAL_PIXEL_FORMAT_RGBX_1010102: + *drm_format = DRM_FORMAT_XBGR2101010; + if (compressed) + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + break; + case HAL_PIXEL_FORMAT_XRGB_2101010: + *drm_format = DRM_FORMAT_BGRX1010102; + break; + case HAL_PIXEL_FORMAT_BGRA_1010102: + *drm_format = DRM_FORMAT_ARGB2101010; + break; + case HAL_PIXEL_FORMAT_ABGR_2101010: + *drm_format = DRM_FORMAT_RGBA1010102; + break; + case HAL_PIXEL_FORMAT_BGRX_1010102: + *drm_format = DRM_FORMAT_XRGB2101010; + break; + case HAL_PIXEL_FORMAT_XBGR_2101010: + *drm_format = DRM_FORMAT_RGBX1010102; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + *drm_format = DRM_FORMAT_NV12; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + *drm_format = DRM_FORMAT_NV12; + if (compressed) { + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + } else { + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE; + } + break; + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + *drm_format = DRM_FORMAT_NV21; + break; + case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: + *drm_format = DRM_FORMAT_NV21; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS: + *drm_format = DRM_FORMAT_NV12; + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: + *drm_format = DRM_FORMAT_NV12; + if (compressed) { + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED | DRM_FORMAT_MOD_QCOM_DX; + } else { + *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE | DRM_FORMAT_MOD_QCOM_DX; + } + break; + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + *drm_format = DRM_FORMAT_NV12; + if (compressed) { + *drm_format_modifier = + DRM_FORMAT_MOD_QCOM_COMPRESSED | DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT; + } else { + *drm_format_modifier = + DRM_FORMAT_MOD_QCOM_TILE | DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT; + } + break; + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + *drm_format = DRM_FORMAT_NV16; + break; + /* + TODO: No HAL_PIXEL_FORMAT equivalent? + case kFormatYCrCb422H2V1SemiPlanar: + *drm_format = DRM_FORMAT_NV61; + break;*/ + case HAL_PIXEL_FORMAT_YV12: + *drm_format = DRM_FORMAT_YVU420; + break; + default: + ALOGE("Unsupported format %d", format); + } +} + } // namespace gralloc diff --git a/gralloc/gr_utils.h b/gralloc/gr_utils.h index bdde659c..e21f92b8 100644 --- a/gralloc/gr_utils.h +++ b/gralloc/gr_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016,2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2016,2018-2020, 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 @@ -63,11 +63,44 @@ struct BufferInfo { uint64_t usage; }; +struct GrallocProperties { + bool use_system_heap_for_sensors = true; + bool ubwc_disable = false; + bool ahardware_buffer_disable = false; +}; + template <class Type1, class Type2> inline Type1 ALIGN(Type1 x, Type2 align) { return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1)); } +enum class Error : int32_t { + /** + * No error. + */ + NONE = 0, + /** + * Invalid BufferDescriptor. + */ + BAD_DESCRIPTOR = 1, + /** + * Invalid buffer handle. + */ + BAD_BUFFER = 2, + /** + * Invalid HardwareBufferDescription. + */ + BAD_VALUE = 3, + /** + * Resource unavailable. + */ + NO_RESOURCES = 5, + /** + * Permanent failure. + */ + UNSUPPORTED = 7, +}; + enum PlaneComponent { /* luma */ PLANE_COMPONENT_Y = 1 << 0, @@ -183,6 +216,9 @@ int GetCustomFormatFlags(int format, uint64_t usage, int *custom_format, uint64_ int GetBufferType(int inputFormat); bool IsGPUFlagSupported(uint64_t usage); bool HasAlphaComponent(int32_t format); + +void GetDRMFormat(uint32_t format, uint32_t flags, uint32_t *drm_format, + uint64_t *drm_format_modifier); } // namespace gralloc #endif // __GR_UTILS_H__ diff --git a/gralloc/service.cpp b/gralloc/service.cpp index 7ea1e3af..2b890ffd 100644 --- a/gralloc/service.cpp +++ b/gralloc/service.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 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 @@ -27,21 +27,36 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <hidl/LegacySupport.h> + #include "QtiAllocator.h" using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; -using vendor::qti::hardware::display::allocator::V3_0::IQtiAllocator; -using vendor::qti::hardware::display::allocator::V3_0::implementation::QtiAllocator; +using IQtiAllocator3 = vendor::qti::hardware::display::allocator::V3_0::IQtiAllocator; +using IQtiAllocator4 = vendor::qti::hardware::display::allocator::V4_0::IQtiAllocator; int main(int, char **) { - android::sp<IQtiAllocator> service = new QtiAllocator(); + android::sp<IQtiAllocator3> service3 = + new vendor::qti::hardware::display::allocator::V3_0::implementation::QtiAllocator(); + configureRpcThreadpool(4, true /*callerWillJoin*/); - if (service->registerAsService() != android::OK) { - ALOGE("Cannot register QTI Allocator service"); + if (service3->registerAsService() != android::OK) { + ALOGE("Cannot register QTI Allocator 3 service"); return -EINVAL; } - ALOGI("Initialized qti-allocator"); + ALOGI("Initialized qti-allocator 3"); + +#ifdef TARGET_USES_GRALLOC4 + android::sp<IQtiAllocator4> service4 = + new vendor::qti::hardware::display::allocator::V4_0::implementation::QtiAllocator(); + if (service4->registerAsService() != android::OK) { + ALOGE("Cannot register QTI Allocator 4 service"); + return -EINVAL; + } + ALOGI("Initialized qti-allocator 4"); +#endif + joinRpcThreadpool(); + return 0; } diff --git a/gralloc/vendor.qti.hardware.display.allocator-service.xml b/gralloc/vendor.qti.hardware.display.allocator-service.xml index 5c072ea3..506c58b5 100644 --- a/gralloc/vendor.qti.hardware.display.allocator-service.xml +++ b/gralloc/vendor.qti.hardware.display.allocator-service.xml @@ -1,5 +1,5 @@ <!-- -Copyright (c) 2019, The Linux Foundation. All rights reserved. +Copyright (c) 2019-2020 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 @@ -30,8 +30,8 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <hal format="hidl"> <name>android.hardware.graphics.allocator</name> <transport>hwbinder</transport> - <impl level="generic"></impl> <version>3.0</version> + <version>4.0</version> <interface> <name>IAllocator</name> <instance>default</instance> @@ -41,6 +41,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <name>vendor.qti.hardware.display.allocator</name> <transport>hwbinder</transport> <version>3.0</version> + <version>4.0</version> <interface> <name>IQtiAllocator</name> <instance>default</instance> diff --git a/include/display_properties.h b/include/display_properties.h index 06ab31db..0e57f344 100644 --- a/include/display_properties.h +++ b/include/display_properties.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2018 - 2019, The Linux Foundation. All rights reserved. +* Copyright (c) 2018 - 2020, 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 @@ -121,7 +121,6 @@ #define VIRTUAL_BASEID_AND_SIZE_PROP DISPLAY_PROP("virtual_baseid_and_size") #define ENABLE_QDCM_DIAG DISPLAY_PROP("enable_qdcm_diag") #define QDCM_DISABLE_FACTORY_MODE_PROP DISPLAY_PROP("qdcm.disable_factory_mode") -#define DISABLE_DEFER_POWER_STATE DISPLAY_PROP("disable_defer_power_state") #define ZERO_SWAP_INTERVAL "vendor.debug.egl.swapinterval" #define ENABLE_OPTIMIZE_REFRESH DISPLAY_PROP("enable_optimize_refresh") @@ -130,5 +129,8 @@ #define DISABLE_PARALLEL_CACHE DISPLAY_PROP("disable_parallel_cache") #define ENABLE_FORCE_SPLIT DISPLAY_PROP("enable_force_split") #define DEFER_FPS_FRAME_COUNT DISPLAY_PROP("defer_fps_frame_count") +#define DISABLE_IDLE_TIME_VIDEO DISPLAY_PROP("disable_idle_time_video") +#define DISABLE_IDLE_TIME_HDR DISPLAY_PROP("disable_idle_time_hdr") +#define ENABLE_POMS_DURING_DOZE DISPLAY_PROP("enable_poms_during_doze") #endif // __DISPLAY_PROPERTIES_H__ diff --git a/libqdutils/qd_utils.cpp b/libqdutils/qd_utils.cpp index 5fff1cb7..9e8cad79 100644 --- a/libqdutils/qd_utils.cpp +++ b/libqdutils/qd_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013, 2018, 2020, 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 @@ -84,91 +84,6 @@ static int getExternalNode(const char *type) { return -1; } -static int querySDEInfoDRM(HWQueryType type, int *value) { - char property[PROPERTY_VALUE_MAX] = {0}; - - // TODO(user): If future targets don't support WB UBWC, add separate - // properties in target specific system.prop and have clients like WFD - // directly rely on those. - switch(type) { - case HAS_UBWC: - case HAS_WB_UBWC: // WFD stack still uses this - *value = 1; - property_get(DISABLE_UBWC_PROP, property, "0"); - if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) || - !(strncmp(property, "true", PROPERTY_VALUE_MAX))) { - *value = 0; - } - break; - default: - ALOGE("Invalid query type %d", type); - return -EINVAL; - } - - return 0; -} - -static int querySDEInfoFB(HWQueryType type, int *value) { - FILE *fileptr = NULL; - const char *featureName; - char stringBuffer[MAX_STRING_LENGTH]; - uint32_t tokenCount = 0; - const uint32_t maxCount = 10; - char *tokens[maxCount] = { NULL }; - - switch(type) { - case HAS_UBWC: - featureName = "ubwc"; - break; - case HAS_WB_UBWC: - featureName = "wb_ubwc"; - break; - default: - ALOGE("Invalid query type %d", type); - return -EINVAL; - } - - fileptr = fopen("/sys/devices/virtual/graphics/fb0/mdp/caps", "rb"); - if (!fileptr) { - ALOGE("File '%s' not found", stringBuffer); - return -EINVAL; - } - - size_t len = MAX_STRING_LENGTH; - ssize_t read; - char *line = stringBuffer; - while ((read = getline(&line, &len, fileptr)) != -1) { - // parse the line and update information accordingly - if (parseLine(line, tokens, maxCount, &tokenCount)) { - continue; - } - - if (strncmp(tokens[0], "features", strlen("features"))) { - continue; - } - - for (uint32_t i = 0; i < tokenCount; i++) { - if (!strncmp(tokens[i], featureName, strlen(featureName))) { - *value = 1; - } - } - } - fclose(fileptr); - - return 0; -} - -int querySDEInfo(HWQueryType type, int *value) { - if (!value) { - return -EINVAL; - } - - if (getDriverType() == DriverType::DRM) { - return querySDEInfoDRM(type, value); - } - - return querySDEInfoFB(type, value); -} bool isDPConnected() { char connectPath[MAX_FRAME_BUFFER_NAME_SIZE]; diff --git a/libqdutils/qd_utils.h b/libqdutils/qd_utils.h index d83f2733..0b0816a0 100644 --- a/libqdutils/qd_utils.h +++ b/libqdutils/qd_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013, 2017 The Linux Foundation. All rights reserved. + * Copyright (C) 2013, 2017, 2020 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 @@ -58,7 +58,6 @@ enum { MAX_STRING_LENGTH = 1024, }; -int querySDEInfo(HWQueryType type, int *value); int getEdidRawData(char *buffer); int getHDMINode(void); bool isDPConnected(); diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h index 080afcb5..8341f528 100644 --- a/sdm/include/core/display_interface.h +++ b/sdm/include/core/display_interface.h @@ -198,19 +198,28 @@ struct DisplayConfigFixedInfo { @sa DisplayInterface::GetConfig @sa DisplayInterface::SetConfig */ -struct DisplayConfigVariableInfo { +struct DisplayConfigGroupInfo { uint32_t x_pixels = 0; //!< Total number of pixels in X-direction on the display panel. uint32_t y_pixels = 0; //!< Total number of pixels in Y-direction on the display panel. float x_dpi = 0.0f; //!< Dots per inch in X-direction. float y_dpi = 0.0f; //!< Dots per inch in Y-direction. + bool is_yuv = false; //!< If the display output is in YUV format. + bool smart_panel = false; //!< If the display config has smart panel. + + bool operator==(const DisplayConfigGroupInfo& info) const { + return ((x_pixels == info.x_pixels) && (y_pixels == info.y_pixels) && (x_dpi == info.x_dpi) && + (y_dpi == info.y_dpi) && (is_yuv == info.is_yuv) && (smart_panel == info.smart_panel)); + } +}; + +struct DisplayConfigVariableInfo : public DisplayConfigGroupInfo { uint32_t fps = 0; //!< Frame rate per second. uint32_t vsync_period_ns = 0; //!< VSync period in nanoseconds. - bool is_yuv = false; //!< If the display output is in YUV format. bool operator==(const DisplayConfigVariableInfo& info) const { return ((x_pixels == info.x_pixels) && (y_pixels == info.y_pixels) && (x_dpi == info.x_dpi) && (y_dpi == info.y_dpi) && (fps == info.fps) && (vsync_period_ns == info.vsync_period_ns) - && (is_yuv == info.is_yuv)); + && (is_yuv == info.is_yuv) && (smart_panel == info.smart_panel)); } }; diff --git a/sdm/include/core/sdm_types.h b/sdm/include/core/sdm_types.h index 58175392..6ba1538d 100644 --- a/sdm/include/core/sdm_types.h +++ b/sdm/include/core/sdm_types.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2019, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2020, 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 @@ -60,6 +60,7 @@ enum DisplayError { kErrorCriticalResource, //!< Critical resource allocation has failed. kErrorDeviceRemoved, //!< A device was removed unexpectedly. kErrorDriverData, //!< Expected information from the driver is missing + kErrorDeferred, //!< Call's intended action is being deferred to a later time }; /*! @brief This structure is defined for client and library compatibility check purpose only. This diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk index f8a58d19..c934de06 100644 --- a/sdm/libs/core/Android.mk +++ b/sdm/libs/core/Android.mk @@ -22,6 +22,10 @@ ifeq ($(TARGET_USES_DRM_PP),true) LOCAL_CFLAGS += -DPP_DRM_ENABLE endif +ifeq ($(ENABLE_HYP),true) + LOCAL_CFLAGS += -DHYPERVISOR +endif + LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_SRC_FILES := core_interface.cpp \ core_impl.cpp \ diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp index 72751e51..cc2855e1 100755 --- a/sdm/libs/core/display_base.cpp +++ b/sdm/libs/core/display_base.cpp @@ -283,17 +283,10 @@ DisplayError DisplayBase::Prepare(LayerStack *layer_stack) { lock_guard<recursive_mutex> obj(recursive_mutex_); DisplayError error = kErrorNone; needs_validate_ = true; - if (defer_power_state_ && power_state_pending_ != kStateOff) { - defer_power_state_ = false; - error = SetDisplayState(power_state_pending_, false, NULL); - if (error != kErrorNone) { - return error; - } - power_state_pending_ = kStateOff; - } DTRACE_SCOPED(); - if (!active_) { + // Allow prepare as pending doze/pending_power_on is handled as a part of draw cycle + if (!active_ && !pending_doze_ && !pending_power_on_) { return kErrorPermission; } @@ -357,7 +350,8 @@ DisplayError DisplayBase::Commit(LayerStack *layer_stack) { lock_guard<recursive_mutex> obj(recursive_mutex_); DisplayError error = kErrorNone; - if (!active_) { + // Allow commit as pending doze/pending_power_on is handled as a part of draw cycle + if (!active_ && !pending_doze_ && !pending_power_on_) { needs_validate_ = true; return kErrorPermission; } @@ -433,9 +427,22 @@ DisplayError DisplayBase::Commit(LayerStack *layer_stack) { safe_mode_in_fast_path_ = false; } + // Reset pending power state if any after the commit + error = HandlePendingPowerState(layer_stack->retire_fence_fd); + if (error != kErrorNone) { + return error; + } + + // Handle pending vsync enable if any after the commit + error = HandlePendingVSyncEnable(layer_stack->retire_fence_fd); + if (error != kErrorNone) { + return error; + } + + DLOGI_IF(kTagDisplay, "Exiting commit for display: %d-%d", display_id_, display_type_); - return kErrorNone; + return error; } DisplayError DisplayBase::Flush(LayerStack *layer_stack) { @@ -532,14 +539,6 @@ DisplayError DisplayBase::GetVSyncState(bool *enabled) { DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown, int *release_fence) { lock_guard<recursive_mutex> obj(recursive_mutex_); - if (defer_power_state_) { - if (state == kStateOff) { - DLOGE("State cannot be PowerOff on first cycle"); - return kErrorParameters; - } - power_state_pending_ = state; - return kErrorNone; - } DisplayError error = kErrorNone; bool active = false; @@ -551,6 +550,14 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown, return kErrorNone; } + // If vsync is enabled, disable vsync before power off/Doze suspend + if (vsync_enable_ && (state == kStateOff || state == kStateDozeSuspend)) { + error = SetVSyncState(false /* enable */); + if (error == kErrorNone) { + vsync_enable_pending_ = true; + } + } + switch (state) { case kStateOff: hw_layers_.info.hw_layers.clear(); @@ -563,7 +570,12 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown, case kStateOn: error = hw_intf_->PowerOn(default_qos_data_, release_fence); if (error != kErrorNone) { - return error; + if (error == kErrorDeferred) { + pending_power_on_ = true; + error = kErrorNone; + } else { + return error; + } } error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, @@ -578,6 +590,14 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown, case kStateDoze: error = hw_intf_->Doze(default_qos_data_, release_fence); + if (error != kErrorNone) { + if (error == kErrorDeferred) { + pending_doze_ = true; + error = kErrorNone; + } else { + return error; + } + } active = true; break; @@ -597,20 +617,35 @@ DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown, return kErrorParameters; } + error = ReconfigureDisplay(); + if (error != kErrorNone) { + return error; + } + DisablePartialUpdateOneFrame(); if (error == kErrorNone) { - active_ = active; - state_ = state; + if (!pending_doze_ && !pending_power_on_) { + active_ = active; + state_ = state; + } comp_manager_->SetDisplayState(display_comp_ctx_, state, release_fence ? *release_fence : -1); + // If previously requested doze state is still pending reset it on any new display state request + // and handle the new request. + if (state != kStateDoze) { + pending_doze_ = false; + } + // If previously requested power on state is still pending reset it on any new display state + // request and handle the new request. + if (state != kStateOn) { + pending_power_on_ = false; + } } - if (vsync_state_change_pending_ && (state_ != kStateOff || state_ != kStateStandby)) { - error = SetVSyncState(requested_vsync_state_); - if (error != kErrorNone) { - return error; - } - vsync_state_change_pending_ = false; + // Handle vsync pending on resume, Since the power on commit is synchronous we pass -1 as retire + // fence otherwise pass valid retire fence + if (state_ == kStateOn) { + return HandlePendingVSyncEnable(-1 /* retire fence */); } return error; @@ -1126,14 +1161,28 @@ DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate, return error; } +DisplayError DisplayBase::HandlePendingVSyncEnable(int32_t retire_fence) { + if (vsync_enable_pending_) { + // Retire fence signalling confirms that CRTC enabled, hence wait for retire fence before + // we enable vsync + buffer_sync_handler_->SyncWait(retire_fence); + + DisplayError error = SetVSyncState(true /* enable */); + if (error != kErrorNone) { + return error; + } + vsync_enable_pending_ = false; + } + return kErrorNone; +} + DisplayError DisplayBase::SetVSyncState(bool enable) { lock_guard<recursive_mutex> obj(recursive_mutex_); - if (state_ == kStateOff) { - DLOGW("Can't %s vsync when power state is off for display %d-%d," \ - "Defer it when display is active", enable ? "enable":"disable", + + if (state_ == kStateOff && enable) { + DLOGW("Can't enable vsync when display %d-%d is powered off!! Defer it when display is active", display_id_, display_type_); - vsync_state_change_pending_ = true; - requested_vsync_state_ = enable; + vsync_enable_pending_ = true; return kErrorNone; } DisplayError error = kErrorNone; @@ -1150,6 +1199,7 @@ DisplayError DisplayBase::SetVSyncState(bool enable) { vsync_enable_ = enable; } } + vsync_enable_pending_ = !enable ? false : vsync_enable_pending_; return error; } @@ -1953,4 +2003,29 @@ void DisplayBase::SetLutSwapFlag() { return; } +DisplayError DisplayBase::HandlePendingPowerState(int32_t retire_fence) { + if (pending_doze_ || pending_power_on_) { + // Retire fence signalling confirms that CRTC enabled, hence wait for retire fence before + // we enable vsync + buffer_sync_handler_->SyncWait(retire_fence); + + if (pending_doze_) { + state_ = kStateDoze; + DisplayError error = ReconfigureDisplay(); + if (error != kErrorNone) { + return error; + } + event_handler_->Refresh(); + } + if (pending_power_on_) { + state_ = kStateOn; + } + active_ = true; + + pending_doze_ = false; + pending_power_on_ = false; + } + return kErrorNone; +} + } // namespace sdm diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h index 4ca62544..d18d4a4a 100644 --- a/sdm/libs/core/display_base.h +++ b/sdm/libs/core/display_base.h @@ -183,6 +183,8 @@ class DisplayBase : public DisplayInterface { PrimariesTransfer GetBlendSpaceFromColorMode(); bool IsHdrMode(const AttrVal &attr); void InsertBT2020PqHlgModes(); + DisplayError HandlePendingVSyncEnable(int32_t retire_fence); + DisplayError HandlePendingPowerState(int32_t retire_fence); recursive_mutex recursive_mutex_; int32_t display_id_ = -1; @@ -232,13 +234,12 @@ class DisplayBase : public DisplayInterface { uint32_t current_refresh_rate_ = 0; bool drop_skewed_vsync_ = false; bool custom_mixer_resolution_ = false; - DisplayState power_state_pending_ = kStateOff; - bool vsync_state_change_pending_ = false; - bool requested_vsync_state_ = false; - bool defer_power_state_ = false; + bool vsync_enable_pending_ = false; QSyncMode qsync_mode_ = kQSyncModeNone; bool needs_avr_update_ = false; bool safe_mode_in_fast_path_ = false; + bool pending_doze_ = false; + bool pending_power_on_ = false; static Locker display_power_reset_lock_; static bool display_power_reset_pending_; diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp index 25af21ea..2bd90042 100644 --- a/sdm/libs/core/display_builtin.cpp +++ b/sdm/libs/core/display_builtin.cpp @@ -60,7 +60,6 @@ DisplayBuiltIn::~DisplayBuiltIn() { DisplayError DisplayBuiltIn::Init() { lock_guard<recursive_mutex> obj(recursive_mutex_); - int32_t disable_defer_power_state = 0; DisplayError error = HWInterface::Create(display_id_, kBuiltIn, hw_info_intf_, buffer_sync_handler_, buffer_allocator_, &hw_intf_); @@ -90,6 +89,7 @@ DisplayError DisplayBuiltIn::Init() { if (hw_panel_info_.mode == kModeCommand) { event_list_ = {HWEvent::VSYNC, HWEvent::EXIT, + HWEvent::IDLE_NOTIFY, HWEvent::SHOW_BLANK_EVENT, HWEvent::THERMAL_LEVEL, HWEvent::IDLE_POWER_COLLAPSE, @@ -115,10 +115,6 @@ DisplayError DisplayBuiltIn::Init() { current_refresh_rate_ = hw_panel_info_.max_fps; - Debug::GetProperty(DISABLE_DEFER_POWER_STATE, &disable_defer_power_state); - defer_power_state_ = !disable_defer_power_state; - DLOGI("defer_power_state %d", defer_power_state_); - int value = 0; Debug::Get()->GetProperty(DEFER_FPS_FRAME_COUNT, &value); deferred_config_.frame_count = (value > 0) ? UINT32(value) : 0; @@ -197,6 +193,7 @@ DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) { lock_guard<recursive_mutex> obj(recursive_mutex_); DisplayError error = kErrorNone; uint32_t app_layer_count = hw_layers_.info.app_layer_count; + HWDisplayMode panel_mode = hw_panel_info_.mode; DTRACE_SCOPED(); @@ -225,6 +222,11 @@ DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) { if (error != kErrorNone) { return error; } + if (pending_brightness_) { + buffer_sync_handler_->SyncWait(layer_stack->retire_fence_fd); + SetPanelBrightness(cached_brightness_); + pending_brightness_ = false; + } if (commit_event_enabled_) { dpps_info_.DppsNotifyOps(kDppsCommitEvent, &display_type_, sizeof(display_type_)); @@ -250,6 +252,9 @@ DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) { ControlPartialUpdate(true /* enable */, &pending); } + if (panel_mode != hw_panel_info_.mode) { + UpdateDisplayModeParams(); + } dpps_info_.Init(this, hw_panel_info_.panel_name); if (qsync_mode_ == kQsyncModeOneShot) { @@ -271,10 +276,22 @@ DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) { return error; } +void DisplayBuiltIn::UpdateDisplayModeParams() { + if (hw_panel_info_.mode == kModeVideo) { + uint32_t pending = 0; + ControlPartialUpdate(false /* enable */, &pending); + } else if (hw_panel_info_.mode == kModeCommand) { + // Flush idle timeout value currently set. + comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, 0); + switch_to_cmd_ = true; + } +} + DisplayError DisplayBuiltIn::SetDisplayState(DisplayState state, bool teardown, int *release_fence) { lock_guard<recursive_mutex> obj(recursive_mutex_); DisplayError error = kErrorNone; + HWDisplayMode panel_mode = hw_panel_info_.mode; if ((state == kStateOn) && deferred_config_.IsDeferredState()) { SetDeferredFpsConfig(); @@ -285,11 +302,19 @@ DisplayError DisplayBuiltIn::SetDisplayState(DisplayState state, bool teardown, return error; } + if (hw_panel_info_.mode != panel_mode) { + UpdateDisplayModeParams(); + } + // Set vsync enable state to false, as driver disables vsync during display power off. if (state == kStateOff) { vsync_enable_ = false; } + if (pending_doze_ || pending_power_on_) { + event_handler_->Refresh(); + } + return kErrorNone; } @@ -330,6 +355,8 @@ DisplayError DisplayBuiltIn::SetDisplayMode(uint32_t mode) { return error; } + DisplayBase::ReconfigureDisplay(); + if (mode == kModeVideo) { ControlPartialUpdate(false /* enable */, &pending); } else if (mode == kModeCommand) { @@ -359,7 +386,7 @@ DisplayError DisplayBuiltIn::SetPanelBrightness(float brightness) { } // -1.0f = off, 0.0f = min, 1.0f = max - level_remainder_ = 0.0f; + float level_remainder = 0.0f; int level = 0; if (brightness == -1.0f) { level = 0; @@ -373,13 +400,21 @@ DisplayError DisplayBuiltIn::SetPanelBrightness(float brightness) { } float t = (brightness * (max - min)) + min; level = static_cast<int>(t); - level_remainder_ = t - level; + level_remainder = t - level; } - DisplayError err = kErrorNone; - if ((err = hw_intf_->SetPanelBrightness(level)) == kErrorNone) { + DisplayError err = hw_intf_->SetPanelBrightness(level); + if (err == kErrorNone) { + level_remainder_ = level_remainder; DLOGI_IF(kTagDisplay, "Setting brightness to level %d (%f percent)", level, brightness * 100); + } else if (err == kErrorDeferred) { + // TODO(user): I8508d64a55c3b30239c6ed2886df391407d22f25 causes mismatch between perceived + // power state and actual panel power state. Requires a rework. Below check will set up + // deferment of brightness operation if DAL reports defer use case. + cached_brightness_ = brightness; + pending_brightness_ = true; + return kErrorNone; } return err; diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h index a6a272e7..6da7a87f 100644 --- a/sdm/libs/core/display_builtin.h +++ b/sdm/libs/core/display_builtin.h @@ -145,6 +145,7 @@ class DisplayBuiltIn : public DisplayBase, HWEventHandler, DppsPropIntf { bool CanDeferFpsConfig(uint32_t fps); void SetDeferredFpsConfig(); void GetFpsConfig(HWDisplayAttributes *display_attributes, HWPanelInfo *panel_info); + void UpdateDisplayModeParams(); std::vector<HWEvent> event_list_; bool avr_prop_disabled_ = false; @@ -159,6 +160,8 @@ class DisplayBuiltIn : public DisplayBase, HWEventHandler, DppsPropIntf { DeferFpsConfig deferred_config_ = {}; float level_remainder_ = 0.0f; recursive_mutex brightness_lock_; + float cached_brightness_ = 0.0f; + bool pending_brightness_ = false; }; } // namespace sdm diff --git a/sdm/libs/core/display_pluggable.cpp b/sdm/libs/core/display_pluggable.cpp index 4e184e84..06a34ac4 100644 --- a/sdm/libs/core/display_pluggable.cpp +++ b/sdm/libs/core/display_pluggable.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2014 - 2019, The Linux Foundation. All rights reserved. +* Copyright (c) 2014 - 2020, 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: @@ -130,12 +130,6 @@ DisplayError DisplayPluggable::Init() { current_refresh_rate_ = hw_panel_info_.max_fps; - if (IsPrimaryDisplay()) { - int32_t disable_defer_power_state = 0; - Debug::GetProperty(DISABLE_DEFER_POWER_STATE, &disable_defer_power_state); - defer_power_state_ = !disable_defer_power_state; - } - return error; } diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp index 95d58451..007cb2a9 100644 --- a/sdm/libs/core/drm/hw_device_drm.cpp +++ b/sdm/libs/core/drm/hw_device_drm.cpp @@ -572,6 +572,7 @@ void HWDeviceDRM::InitializeConfigs() { } PopulateDisplayAttributes(i); } + SetDisplaySwitchMode(current_mode_index_); } DisplayError HWDeviceDRM::PopulateDisplayAttributes(uint32_t index) { @@ -595,6 +596,9 @@ DisplayError HWDeviceDRM::PopulateDisplayAttributes(uint32_t index) { mm_width = connector_info_.mmWidth; mm_height = connector_info_.mmHeight; topology = connector_info_.modes[index].topology; + if (mode.flags & DRM_MODE_FLAG_CMD_MODE_PANEL) { + display_attributes_[index].smart_panel = true; + } } display_attributes_[index].x_pixels = mode.hdisplay; @@ -724,6 +728,13 @@ void HWDeviceDRM::PopulateHWPanelInfo() { GetHWDisplayPortAndMode(); GetHWPanelMaxBrightness(); + if (current_mode.flags & DRM_MODE_FLAG_CMD_MODE_PANEL) { + hw_panel_info_.mode = kModeCommand; + } + if (current_mode.flags & DRM_MODE_FLAG_VID_MODE_PANEL) { + hw_panel_info_.mode = kModeVideo; + } + DLOGI_IF(kTagDisplay, "%s, Panel Interface = %s, Panel Mode = %s, Is Primary = %d", device_name_, interface_str_.c_str(), hw_panel_info_.mode == kModeVideo ? "Video" : "Command", hw_panel_info_.is_primary_panel); @@ -828,39 +839,108 @@ DisplayError HWDeviceDRM::GetHWPanelInfo(HWPanelInfo *panel_info) { return kErrorNone; } -DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) { - if (index >= display_attributes_.size()) { - DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size())); - return kErrorParameters; - } - +void HWDeviceDRM::SetDisplaySwitchMode(uint32_t index) { + uint32_t mode_flag = 0; + uint32_t curr_mode_flag = 0, switch_mode_flag = 0; drmModeModeInfo to_set = connector_info_.modes[index].mode; + drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode; uint64_t current_bit_clk = connector_info_.modes[current_mode_index_].bit_clk_rate; + uint32_t switch_index = 0; + + if (to_set.flags & DRM_MODE_FLAG_CMD_MODE_PANEL) { + mode_flag = DRM_MODE_FLAG_CMD_MODE_PANEL; + switch_mode_flag = DRM_MODE_FLAG_VID_MODE_PANEL; + } else if (to_set.flags & DRM_MODE_FLAG_VID_MODE_PANEL) { + mode_flag = DRM_MODE_FLAG_VID_MODE_PANEL; + switch_mode_flag = DRM_MODE_FLAG_CMD_MODE_PANEL; + } + + if (current_mode.flags & DRM_MODE_FLAG_CMD_MODE_PANEL) { + curr_mode_flag = DRM_MODE_FLAG_CMD_MODE_PANEL; + } else if (current_mode.flags & DRM_MODE_FLAG_VID_MODE_PANEL) { + curr_mode_flag = DRM_MODE_FLAG_VID_MODE_PANEL; + } + + if (curr_mode_flag != mode_flag) { + panel_mode_changed_ = mode_flag; + } + for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) { if ((to_set.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) && (to_set.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) && (to_set.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) && - (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate)) { + (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) && + (mode_flag & connector_info_.modes[mode_index].mode.flags)) { index = mode_index; break; } } current_mode_index_ = index; + + switch_mode_valid_ = false; + for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) { + if ((to_set.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) && + (to_set.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) && + (to_set.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) && + (switch_mode_flag & connector_info_.modes[mode_index].mode.flags)) { + switch_index = mode_index; + switch_mode_valid_ = true; + break; + } + } + + if (!switch_mode_valid_) { + // in case there is no corresponding switch mode with same fps, try for a switch + // mode with lowest fps. This is to handle cases where there are multiple video mode fps + // but only one command mode for doze like 30 fps. + uint32_t refresh_rate = 0; + for (uint32_t mode_index = 0; mode_index < connector_info_.modes.size(); mode_index++) { + if ((to_set.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) && + (to_set.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) && + (switch_mode_flag & connector_info_.modes[mode_index].mode.flags)) { + if (!refresh_rate || (refresh_rate > connector_info_.modes[mode_index].mode.vrefresh)) { + switch_index = mode_index; + switch_mode_valid_ = true; + refresh_rate = connector_info_.modes[mode_index].mode.vrefresh; + } + } + } + } + + if (switch_mode_valid_) { + if (mode_flag & DRM_MODE_FLAG_VID_MODE_PANEL) { + video_mode_index_ = current_mode_index_; + cmd_mode_index_ = switch_index; + } else { + video_mode_index_ = switch_index; + cmd_mode_index_ = current_mode_index_; + } + } +} + +DisplayError HWDeviceDRM::SetDisplayAttributes(uint32_t index) { + if (index >= display_attributes_.size()) { + DLOGE("Invalid mode index %d mode size %d", index, UINT32(display_attributes_.size())); + return kErrorParameters; + } + + SetDisplaySwitchMode(index); PopulateHWPanelInfo(); UpdateMixerAttributes(); - DLOGI_IF( - kTagDisplay, - "Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," - " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d", - index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels, - display_attributes_[index].x_dpi, display_attributes_[index].y_dpi, - display_attributes_[index].fps, display_attributes_[index].is_device_split, - display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch, - display_attributes_[index].v_pulse_width, display_attributes_[index].v_total, - display_attributes_[index].h_total, display_attributes_[index].clock_khz, - display_attributes_[index].topology); + DLOGI_IF(kTagDriverConfig, + "Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \ + " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, " \ + "TOPOLOGY: %d, PanelMode %s", index, display_attributes_[index].x_pixels, + display_attributes_[index].y_pixels, display_attributes_[index].x_dpi, + display_attributes_[index].y_dpi, display_attributes_[index].fps, + display_attributes_[index].is_device_split, display_attributes_[index].v_back_porch, + display_attributes_[index].v_front_porch, display_attributes_[index].v_pulse_width, + display_attributes_[index].v_total, display_attributes_[index].h_total, + display_attributes_[index].clock_khz, display_attributes_[index].topology, + (connector_info_.modes[index].mode.flags & DRM_MODE_FLAG_VID_MODE_PANEL) ? + "Video" : "Command"); return kErrorNone; } @@ -877,13 +957,7 @@ DisplayError HWDeviceDRM::PowerOn(const HWQosData &qos_data, int *release_fence) SetQOSData(qos_data); int64_t release_fence_t = -1; - update_mode_ = true; - if (first_cycle_) { - drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id); - drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode; - drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, ¤t_mode); - } drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON); if (release_fence) { @@ -937,7 +1011,7 @@ DisplayError HWDeviceDRM::Doze(const HWQosData &qos_data, int *release_fence) { if (first_cycle_ || last_power_mode_ != DRMPowerMode::OFF) { pending_doze_ = true; - return kErrorNone; + return kErrorDeferred; } SetQOSData(qos_data); @@ -1187,6 +1261,21 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level); } + if (reset_output_fence_offset_ && !validate) { + // Change back the fence_offset + drm_atomic_intf_->Perform(DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET, token_.crtc_id, 0); + reset_output_fence_offset_ = false; + } + + // Set panel mode + if (panel_mode_changed_ & DRM_MODE_FLAG_VID_MODE_PANEL) { + if (!validate) { + // Switch to video mode, corresponding change the fence_offset + drm_atomic_intf_->Perform(DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET, token_.crtc_id, 1); + } + SetFullROI(); + } + if (hw_layers->hw_avr_info.update) { sde_drm::DRMQsyncMode mode = sde_drm::DRMQsyncMode::NONE; if (hw_layers->hw_avr_info.mode == kContinuousMode) { @@ -1217,6 +1306,7 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) && (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) && (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) && + (current_mode.flags == connector_info_.modes[mode_index].mode.flags) && (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) { current_mode = connector_info_.modes[mode_index].mode; break; @@ -1229,6 +1319,7 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) && (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) && (current_mode.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) && + (current_mode.flags == connector_info_.modes[mode_index].mode.flags) && (bit_clk_rate_ == connector_info_.modes[mode_index].bit_clk_rate)) { current_mode = connector_info_.modes[mode_index].mode; break; @@ -1241,19 +1332,17 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) { topology_control_); drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id); - DRMPowerMode power_mode = pending_doze_ ? DRMPowerMode::DOZE : DRMPowerMode::ON; - drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, power_mode); - last_power_mode_ = power_mode; + drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON); + last_power_mode_ = DRMPowerMode::ON; } else if (pending_doze_ && !validate) { drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1); drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE); - pending_doze_ = false; synchronous_commit_ = true; last_power_mode_ = DRMPowerMode::DOZE; } // Set CRTC mode, only if display config changes - if (vrefresh_ || update_mode_) { + if (first_cycle_ || vrefresh_ || update_mode_ || panel_mode_changed_) { drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, ¤t_mode); } @@ -1319,6 +1408,7 @@ DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) { if (ret) { DLOGE("failed with error %d for %s", ret, device_name_); vrefresh_ = 0; + panel_mode_changed_ = 0; err = kErrorHardware; } @@ -1400,6 +1490,7 @@ DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) { if (ret) { DLOGE("%s failed with error %d crtc %d", __FUNCTION__, ret, token_.crtc_id); vrefresh_ = 0; + panel_mode_changed_ = 0; CloseFd(&release_fence); CloseFd(&retire_fence); release_fence_ = -1; @@ -1436,6 +1527,7 @@ DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) { (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) && (vrefresh_ == connector_info_.modes[mode_index].mode.vrefresh)) { current_mode_index_ = mode_index; + SetDisplaySwitchMode(mode_index); break; } } @@ -1451,12 +1543,22 @@ DisplayError HWDeviceDRM::AtomicCommit(HWLayers *hw_layers) { (current_mode.vrefresh == connector_info_.modes[mode_index].mode.vrefresh) && (bit_clk_rate_ == connector_info_.modes[mode_index].bit_clk_rate)) { current_mode_index_ = mode_index; + SetDisplaySwitchMode(mode_index); break; } } bit_clk_rate_ = 0; } + if (panel_mode_changed_ & DRM_MODE_FLAG_CMD_MODE_PANEL) { + panel_mode_changed_ = 0; + synchronous_commit_ = false; + } else if (panel_mode_changed_ & DRM_MODE_FLAG_VID_MODE_PANEL) { + panel_mode_changed_ = 0; + synchronous_commit_ = false; + reset_output_fence_offset_ = true; + } + first_cycle_ = false; update_mode_ = false; hw_layers->updates_mask = 0; @@ -1663,7 +1765,25 @@ void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) { } DisplayError HWDeviceDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) { - return kErrorNotSupported; + if (!switch_mode_valid_) { + return kErrorNotSupported; + } + + uint32_t mode_flag = 0; + + if (hw_display_mode == kModeCommand) { + mode_flag = DRM_MODE_FLAG_CMD_MODE_PANEL; + current_mode_index_ = cmd_mode_index_; + DLOGI_IF(kTagDriverConfig, "switch panel mode to command"); + } else if (hw_display_mode == kModeVideo) { + mode_flag = DRM_MODE_FLAG_VID_MODE_PANEL; + current_mode_index_ = video_mode_index_; + DLOGI_IF(kTagDriverConfig, "switch panel mode to video"); + } + PopulateHWPanelInfo(); + panel_mode_changed_ = mode_flag; + synchronous_commit_ = true; + return kErrorNone; } DisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) { @@ -1680,6 +1800,7 @@ DisplayError HWDeviceDRM::SetRefreshRate(uint32_t refresh_rate) { if ((current_mode.vdisplay == connector_info_.modes[mode_index].mode.vdisplay) && (current_mode.hdisplay == connector_info_.modes[mode_index].mode.hdisplay) && (current_bit_clk == connector_info_.modes[mode_index].bit_clk_rate) && + (current_mode.flags == connector_info_.modes[mode_index].mode.flags) && (refresh_rate == connector_info_.modes[mode_index].mode.vrefresh)) { vrefresh_ = refresh_rate; DLOGV_IF(kTagDriverConfig, "Set refresh rate to %d", refresh_rate); @@ -2051,7 +2172,7 @@ void HWDeviceDRM::DumpConnectorModeInfo() { void HWDeviceDRM::SetFullROI() { // Reset the CRTC ROI and connector ROI only for the panel that supports partial update - if (!hw_panel_info_.partial_update) { + if (!hw_panel_info_.partial_update && !panel_mode_changed_) { return; } uint32_t index = current_mode_index_; diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h index fe3dbc1b..5933347c 100644 --- a/sdm/libs/core/drm/hw_device_drm.h +++ b/sdm/libs/core/drm/hw_device_drm.h @@ -223,16 +223,26 @@ class HWDeviceDRM : public HWInterface { bool synchronous_commit_ = false; uint32_t topology_control_ = 0; uint32_t vrefresh_ = 0; + uint32_t panel_mode_changed_ = 0; + bool reset_output_fence_offset_ = false; uint64_t bit_clk_rate_ = 0; bool update_mode_ = false; + uint32_t video_mode_index_ = 0; + uint32_t cmd_mode_index_ = 0; + bool switch_mode_valid_ = false; + bool doze_poms_switch_done_ = false; + bool pending_poms_switch_ = false; + bool active_ = false; DRMPowerMode last_power_mode_ = DRMPowerMode::OFF; + bool pending_doze_ = false; private: + void SetDisplaySwitchMode(uint32_t index); + std::string interface_str_ = "DSI"; bool resolution_switch_enabled_ = false; bool autorefresh_ = false; std::unique_ptr<HWColorManagerDrm> hw_color_mgr_ = {}; - bool pending_doze_ = false; }; } // namespace sdm diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp index e0ebad4d..85ec982f 100644 --- a/sdm/libs/core/drm/hw_peripheral_drm.cpp +++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp @@ -105,6 +105,10 @@ DisplayError HWPeripheralDRM::SetDynamicDSIClock(uint64_t bit_clk_rate) { return kErrorNotSupported; } + if (doze_poms_switch_done_ || pending_poms_switch_) { + return kErrorNotSupported; + } + bit_clk_rate_ = bit_clk_rate; update_mode_ = true; @@ -118,6 +122,38 @@ DisplayError HWPeripheralDRM::GetDynamicDSIClock(uint64_t *bit_clk_rate) { return kErrorNone; } + +DisplayError HWPeripheralDRM::SetRefreshRate(uint32_t refresh_rate) { + if (doze_poms_switch_done_ || pending_poms_switch_) { + // poms switch in progress + // Defer any refresh rate setting. + return kErrorNotSupported; + } + + DisplayError error = HWDeviceDRM::SetRefreshRate(refresh_rate); + if (error != kErrorNone) { + return error; + } + + return kErrorNone; +} + +DisplayError HWPeripheralDRM::SetDisplayMode(const HWDisplayMode hw_display_mode) { + if (doze_poms_switch_done_ || pending_poms_switch_) { + return kErrorNotSupported; + } + + DisplayError error = HWDeviceDRM::SetDisplayMode(hw_display_mode); + if (error != kErrorNone) { + return error; + } + + // update bit clk rates. + hw_panel_info_.bitclk_rates = bitclk_rates_; + + return kErrorNone; +} + DisplayError HWPeripheralDRM::Validate(HWLayers *hw_layers) { HWLayersInfo &hw_layer_info = hw_layers->info; SetDestScalarData(hw_layer_info, true); @@ -144,6 +180,16 @@ DisplayError HWPeripheralDRM::Commit(HWLayers *hw_layers) { // Initialize to default after successful commit synchronous_commit_ = false; + active_ = true; + + if (pending_poms_switch_) { + HWDeviceDRM::SetDisplayMode(kModeCommand); + hw_panel_info_.bitclk_rates = bitclk_rates_; + doze_poms_switch_done_ = true; + pending_poms_switch_ = false; + } + + idle_pc_state_ = sde_drm::DRMIdlePCState::NONE; return error; } @@ -428,15 +474,14 @@ void HWPeripheralDRM::PostCommitConcurrentWriteback(LayerBuffer *output_buffer) } DisplayError HWPeripheralDRM::ControlIdlePowerCollapse(bool enable, bool synchronous) { - sde_drm::DRMIdlePCState idle_pc_state = - enable ? sde_drm::DRMIdlePCState::ENABLE : sde_drm::DRMIdlePCState::DISABLE; - if (idle_pc_state == idle_pc_state_) { + if (enable == idle_pc_enabled_) { return kErrorNone; } + idle_pc_state_ = enable ? sde_drm::DRMIdlePCState::ENABLE : sde_drm::DRMIdlePCState::DISABLE; // As idle PC is disabled after subsequent commit, Make sure to have synchrounous commit and // ensure TA accesses the display_cc registers after idle PC is disabled. - idle_pc_state_ = idle_pc_state; synchronous_commit_ = !enable ? synchronous : false; + idle_pc_enabled_ = enable; return kErrorNone; } @@ -448,20 +493,97 @@ DisplayError HWPeripheralDRM::PowerOn(const HWQosData &qos_data, int *release_fe } if (first_cycle_) { - return kErrorNone; + return kErrorDeferred; + } + + if (switch_mode_valid_ && doze_poms_switch_done_ && (current_mode_index_ == cmd_mode_index_)) { + HWDeviceDRM::SetDisplayMode(kModeVideo); + hw_panel_info_.bitclk_rates = bitclk_rates_; + doze_poms_switch_done_ = false; + } + + if (!idle_pc_enabled_) { + drm_atomic_intf_->Perform(sde_drm::DRMOps::CRTC_SET_IDLE_PC_STATE, token_.crtc_id, + sde_drm::DRMIdlePCState::ENABLE); } - drm_atomic_intf_->Perform(sde_drm::DRMOps::CRTC_SET_IDLE_PC_STATE, token_.crtc_id, - sde_drm::DRMIdlePCState::ENABLE); DisplayError err = HWDeviceDRM::PowerOn(qos_data, release_fence); if (err != kErrorNone) { return err; } - idle_pc_state_ = sde_drm::DRMIdlePCState::ENABLE; + idle_pc_state_ = sde_drm::DRMIdlePCState::NONE; + idle_pc_enabled_ = true; + pending_poms_switch_ = false; + active_ = true; + + return kErrorNone; +} + +DisplayError HWPeripheralDRM::PowerOff(bool teardown) { + DTRACE_SCOPED(); + + DisplayError err = HWDeviceDRM::PowerOff(teardown); + if (err != kErrorNone) { + return err; + } + + pending_poms_switch_ = false; + active_ = false; + + return kErrorNone; +} + +DisplayError HWPeripheralDRM::Doze(const HWQosData &qos_data, int *release_fence) { + DTRACE_SCOPED(); + + if (!first_cycle_ && switch_mode_valid_ && !doze_poms_switch_done_ && + (current_mode_index_ == video_mode_index_)) { + if (active_) { + HWDeviceDRM::SetDisplayMode(kModeCommand); + hw_panel_info_.bitclk_rates = bitclk_rates_; + doze_poms_switch_done_ = true; + } else { + pending_poms_switch_ = true; + } + } + + DisplayError err = HWDeviceDRM::Doze(qos_data, release_fence); + if (err != kErrorNone) { + return err; + } + + if (first_cycle_) { + active_ = true; + } + + return kErrorNone; +} + +DisplayError HWPeripheralDRM::DozeSuspend(const HWQosData &qos_data, int *release_fence) { + DTRACE_SCOPED(); + + if (switch_mode_valid_ && !doze_poms_switch_done_ && + (current_mode_index_ == video_mode_index_)) { + HWDeviceDRM::SetDisplayMode(kModeCommand); + hw_panel_info_.bitclk_rates = bitclk_rates_; + doze_poms_switch_done_ = true; + } + + DisplayError err = HWDeviceDRM::DozeSuspend(qos_data, release_fence); + if (err != kErrorNone) { + return err; + } + + pending_poms_switch_ = false; + active_ = true; return kErrorNone; } DisplayError HWPeripheralDRM::SetDisplayAttributes(uint32_t index) { + if (doze_poms_switch_done_ || pending_poms_switch_) { + return kErrorNotSupported; + } + HWDeviceDRM::SetDisplayAttributes(index); // update bit clk rates. hw_panel_info_.bitclk_rates = bitclk_rates_; @@ -492,6 +614,11 @@ DisplayError HWPeripheralDRM::SetDisplayDppsAdROI(void *payload) { } DisplayError HWPeripheralDRM::SetPanelBrightness(int level) { + if (pending_doze_) { + DLOGI("Doze state pending!! Skip for now"); + return kErrorDeferred; + } + char buffer[kMaxSysfsCommandLength] = {0}; if (brightness_base_path_.empty()) { diff --git a/sdm/libs/core/drm/hw_peripheral_drm.h b/sdm/libs/core/drm/hw_peripheral_drm.h index 5df95ddc..92aa90db 100644 --- a/sdm/libs/core/drm/hw_peripheral_drm.h +++ b/sdm/libs/core/drm/hw_peripheral_drm.h @@ -57,10 +57,15 @@ class HWPeripheralDRM : public HWDeviceDRM { virtual DisplayError HandleSecureEvent(SecureEvent secure_event, HWLayers *hw_layers); virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous); virtual DisplayError PowerOn(const HWQosData &qos_data, int *release_fence); + virtual DisplayError PowerOff(bool teardown); + virtual DisplayError Doze(const HWQosData &qos_data, int *release_fence); + virtual DisplayError DozeSuspend(const HWQosData &qos_data, int *release_fence); virtual DisplayError SetDisplayDppsAdROI(void *payload); virtual DisplayError SetDynamicDSIClock(uint64_t bit_clk_rate); virtual DisplayError GetDynamicDSIClock(uint64_t *bit_clk_rate); virtual DisplayError SetDisplayAttributes(uint32_t index); + virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode); + virtual DisplayError SetRefreshRate(uint32_t refresh_rate); virtual DisplayError TeardownConcurrentWriteback(void); virtual DisplayError SetPanelBrightness(int level); virtual DisplayError GetPanelBrightness(int *level); @@ -87,6 +92,7 @@ class HWPeripheralDRM : public HWDeviceDRM { std::vector<SDEScaler> scalar_data_ = {}; CWBConfig cwb_config_ = {}; sde_drm::DRMIdlePCState idle_pc_state_ = sde_drm::DRMIdlePCState::NONE; + bool idle_pc_enabled_ = true; std::vector<DestScalarCache> dest_scalar_cache_ = {}; drm_msm_ad4_roi_cfg ad4_roi_cfg_ = {}; bool needs_ds_update_ = false; diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp index 4b2dc897..dfe481f4 100644 --- a/sdm/libs/core/drm/hw_tv_drm.cpp +++ b/sdm/libs/core/drm/hw_tv_drm.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +* Copyright (c) 2017-2020, 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 @@ -190,6 +190,10 @@ DisplayError HWTVDRM::PowerOff(bool teardown) { return kErrorNone; } +#ifdef HYPERVISOR + teardown = true; +#endif + if (teardown) { // LP connecter prop N/A for External drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0); @@ -356,6 +360,12 @@ DisplayError HWTVDRM::PowerOn(const HWQosData &qos_data, int *release_fence) { return kErrorUndefined; } + if (first_cycle_) { + drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id); + drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode; + drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, ¤t_mode); + } + return HWDeviceDRM::PowerOn(qos_data, release_fence); } diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk index 306ff72a..bdaeeb23 100644 --- a/sdm/libs/hwc2/Android.mk +++ b/sdm/libs/hwc2/Android.mk @@ -21,7 +21,7 @@ LOCAL_CLANG := true LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware libhardware_legacy \ libutils libcutils libsync libqdutils libqdMetaData \ libdisplaydebug libsdmutils libc++ liblog libgrallocutils libui \ - libgpu_tonemapper libhidlbase libhidltransport \ + libgpu_tonemapper libhidlbase libhidltransport libdisplayconfig.qti \ android.hardware.graphics.mapper@2.0 \ android.hardware.graphics.mapper@2.1 \ android.hardware.graphics.mapper@3.0 \ @@ -29,6 +29,7 @@ LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware li android.hardware.graphics.allocator@3.0 \ android.hardware.graphics.composer@2.2 \ android.hardware.graphics.composer@2.3 \ + android.hardware.graphics.composer@2.4 \ vendor.display.config@1.0 \ vendor.display.config@1.1 \ vendor.display.config@1.2 \ @@ -40,7 +41,8 @@ LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware li vendor.display.config@1.8 \ vendor.display.config@1.9 \ vendor.display.config@1.10 \ - vendor.display.config@1.11 + vendor.display.config@1.11 \ + vendor.display.config@2.0 ifeq ($(TARGET_BOARD_AUTO), true) LOCAL_CFLAGS += -DCONFIG_BASEID_FROM_PROP @@ -64,6 +66,7 @@ LOCAL_SRC_FILES := hwc_session.cpp \ display_null.cpp \ hwc_socket_handler.cpp \ hwc_buffer_allocator.cpp +LOCAL_VINTF_FRAGMENTS := android.hardware.graphics.composer-qti-display.xml include $(BUILD_SHARED_LIBRARY) endif diff --git a/sdm/libs/hwc2/android.hardware.graphics.composer-qti-display.xml b/sdm/libs/hwc2/android.hardware.graphics.composer-qti-display.xml new file mode 100644 index 00000000..66c85ab9 --- /dev/null +++ b/sdm/libs/hwc2/android.hardware.graphics.composer-qti-display.xml @@ -0,0 +1,48 @@ +<!-- +Copyright (c) 2020, 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. +--> +<manifest version="1.0" type="device"> + <hal format="hidl"> + <name>android.hardware.graphics.composer</name> + <transport>hwbinder</transport> + <version>2.4</version> + <interface> + <name>IComposer</name> + <instance>default</instance> + </interface> + </hal> + <hal format="hidl"> + <name>vendor.display.config</name> + <transport>hwbinder</transport> + <version>2.0</version> + <interface> + <name>IDisplayConfig</name> + <instance>default</instance> + </interface> + </hal> +</manifest> diff --git a/sdm/libs/hwc2/hwc_callbacks.cpp b/sdm/libs/hwc2/hwc_callbacks.cpp index d1345ee9..aec1d327 100644 --- a/sdm/libs/hwc2/hwc_callbacks.cpp +++ b/sdm/libs/hwc2/hwc_callbacks.cpp @@ -60,6 +60,37 @@ HWC2::Error HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) { return HWC2::Error::None; } +HWC2::Error HWCCallbacks::Vsync_2_4(hwc2_display_t display, int64_t timestamp, uint32_t period) { + DTRACE_SCOPED(); + if (!vsync_2_4_) { + return HWC2::Error::NoResources; + } + + vsync_2_4_(vsync_2_4_data_, display, timestamp, period); + return HWC2::Error::None; +} + +HWC2::Error HWCCallbacks::VsyncPeriodTimingChanged( + hwc2_display_t display, hwc_vsync_period_change_timeline_t *updated_timeline) { + DTRACE_SCOPED(); + if (!vsync_period_timing_changed_) { + return HWC2::Error::NoResources; + } + + vsync_period_timing_changed_(vsync_period_timing_changed_data_, display, updated_timeline); + return HWC2::Error::None; +} + +HWC2::Error HWCCallbacks::SeamlessPossible(hwc2_display_t display) { + DTRACE_SCOPED(); + if (!seamless_possible_) { + return HWC2::Error::NoResources; + } + + seamless_possible_(seamless_possible_data_, display); + return HWC2::Error::None; +} + HWC2::Error HWCCallbacks::Register(HWC2::Callback descriptor, hwc2_callback_data_t callback_data, hwc2_function_pointer_t pointer) { switch (descriptor) { @@ -75,6 +106,19 @@ HWC2::Error HWCCallbacks::Register(HWC2::Callback descriptor, hwc2_callback_data vsync_data_ = callback_data; vsync_ = reinterpret_cast<HWC2_PFN_VSYNC>(pointer); break; + case HWC2::Callback::Vsync_2_4: + vsync_2_4_data_ = callback_data; + vsync_2_4_ = reinterpret_cast<HWC2_PFN_VSYNC_2_4>(pointer); + break; + case HWC2::Callback::VsyncPeriodTimingChanged: + vsync_period_timing_changed_data_ = callback_data; + vsync_period_timing_changed_ = + reinterpret_cast<HWC2_PFN_VSYNC_PERIOD_TIMING_CHANGED>(pointer); + break; + case HWC2::Callback::SeamlessPossible: + seamless_possible_data_ = callback_data; + seamless_possible_ = reinterpret_cast<HWC2_PFN_SEAMLESS_POSSIBLE>(pointer); + break; default: return HWC2::Error::BadParameter; } diff --git a/sdm/libs/hwc2/hwc_callbacks.h b/sdm/libs/hwc2/hwc_callbacks.h index 2e4bdba4..5e59550b 100644 --- a/sdm/libs/hwc2/hwc_callbacks.h +++ b/sdm/libs/hwc2/hwc_callbacks.h @@ -53,6 +53,10 @@ class HWCCallbacks { HWC2::Error Hotplug(hwc2_display_t display, HWC2::Connection state); HWC2::Error Refresh(hwc2_display_t display); HWC2::Error Vsync(hwc2_display_t display, int64_t timestamp); + HWC2::Error Vsync_2_4(hwc2_display_t display, int64_t timestamp, uint32_t period); + HWC2::Error VsyncPeriodTimingChanged(hwc2_display_t display, + hwc_vsync_period_change_timeline_t *updated_timeline); + HWC2::Error SeamlessPossible(hwc2_display_t display); HWC2::Error Register(HWC2::Callback, hwc2_callback_data_t callback_data, hwc2_function_pointer_t pointer); void UpdateVsyncSource(hwc2_display_t from) { @@ -61,6 +65,7 @@ class HWCCallbacks { hwc2_display_t GetVsyncSource() { return vsync_source_; } bool VsyncCallbackRegistered() { return (vsync_ != nullptr && vsync_data_ != nullptr); } + bool Vsync_2_4CallbackRegistered() { return (vsync_2_4_ != nullptr); } bool NeedsRefresh(hwc2_display_t display) { return pending_refresh_.test(UINT32(display)); } void ResetRefresh(hwc2_display_t display) { pending_refresh_.reset(UINT32(display)); } @@ -68,10 +73,16 @@ class HWCCallbacks { hwc2_callback_data_t hotplug_data_ = nullptr; hwc2_callback_data_t refresh_data_ = nullptr; hwc2_callback_data_t vsync_data_ = nullptr; + hwc2_callback_data_t vsync_2_4_data_ = nullptr; + hwc2_callback_data_t vsync_period_timing_changed_data_ = nullptr; + hwc2_callback_data_t seamless_possible_data_ = nullptr; HWC2_PFN_HOTPLUG hotplug_ = nullptr; HWC2_PFN_REFRESH refresh_ = nullptr; HWC2_PFN_VSYNC vsync_ = nullptr; + HWC2_PFN_VSYNC_2_4 vsync_2_4_ = nullptr; + HWC2_PFN_VSYNC_PERIOD_TIMING_CHANGED vsync_period_timing_changed_ = nullptr; + HWC2_PFN_SEAMLESS_POSSIBLE seamless_possible_ = nullptr; hwc2_display_t vsync_source_ = HWC_DISPLAY_PRIMARY; // hw vsync is active on this display std::bitset<kNumDisplays> pending_refresh_; // Displays waiting to get refreshed }; diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp index 7b9e36b9..3eb900d6 100644 --- a/sdm/libs/hwc2/hwc_display.cpp +++ b/sdm/libs/hwc2/hwc_display.cpp @@ -52,6 +52,7 @@ namespace sdm { uint32_t HWCDisplay::throttling_refresh_rate_ = 60; +constexpr uint32_t kVsyncTimeDriftNs = 1000000; bool NeedsToneMap(const LayerStack &layer_stack) { for (Layer *layer : layer_stack.layers) { @@ -62,6 +63,10 @@ bool NeedsToneMap(const LayerStack &layer_stack) { return false; } +bool IsTimeAfterOrEqualVsyncTime(int64_t time, int64_t vsync_time) { + return ((vsync_time != INT64_MAX) && ((time - (vsync_time - kVsyncTimeDriftNs)) >= 0)); +} + HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {} HWC2::Error HWCColorMode::Init() { @@ -856,7 +861,8 @@ HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) { ATRACE_INT("SetVsyncState ", enabled == HWC2::Vsync::Enable ? 1 : 0); DisplayError error = kErrorNone; - if (shutdown_pending_ || !callbacks_->VsyncCallbackRegistered()) { + if (shutdown_pending_ || + (!callbacks_->VsyncCallbackRegistered() && !callbacks_->Vsync_2_4CallbackRegistered())) { return HWC2::Error::None; } @@ -1055,6 +1061,9 @@ HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribut case HWC2::Attribute::DpiY: *out_value = INT32(variable_config.y_dpi * 1000.0f); break; + case HWC2::Attribute::ConfigGroup: + *out_value = GetDisplayConfigGroupId(variable_config); + break; default: DLOGW("Spurious attribute type = %s", to_string(attribute).c_str()); *out_value = -1; @@ -1219,7 +1228,17 @@ HWC2::PowerMode HWCDisplay::GetCurrentPowerMode() { } DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) { - callbacks_->Vsync(id_, vsync.timestamp); + if (callbacks_->Vsync_2_4CallbackRegistered()) { + hwc2_vsync_period_t vsync_period; + if (GetDisplayVsyncPeriod(&vsync_period) != HWC2::Error::None) { + vsync_period = 0; + } + ATRACE_INT("VsyncPeriod", INT32(vsync_period)); + callbacks_->Vsync_2_4(id_, vsync.timestamp, vsync_period); + } else { + callbacks_->Vsync(id_, vsync.timestamp); + } + return kErrorNone; } @@ -2424,4 +2443,208 @@ void HWCDisplay::UpdateActiveConfig() { pending_config_ = false; } +int32_t HWCDisplay::GetDisplayConfigGroupId(const DisplayConfigGroupInfo &variable_config) { + for (auto &config : variable_config_map_) { + DisplayConfigGroupInfo const &group_info = config.second; + if (group_info == variable_config) { + return INT32(config.first); + } + } + + return -1; +} + +HWC2::Error HWCDisplay::GetDisplayVsyncPeriod(hwc2_vsync_period_t *vsync_period) { + if (GetTransientVsyncPeriod(vsync_period)) { + return HWC2::Error::None; + } + + return GetVsyncPeriodByActiveConfig(vsync_period); +} + +HWC2::Error HWCDisplay::SetActiveConfigWithConstraints(hwc2_config_t config, + hwc_vsync_period_change_constraints_t *vsync_period_change_constraints, + hwc_vsync_period_change_timeline_t *out_timeline) { + if (variable_config_map_.find(config) == variable_config_map_.end()) { + DLOGE("Invalid config: %d", config); + return HWC2::Error::BadConfig; + } + + if (vsync_period_change_constraints->seamlessRequired && !AllowSeamless(config)) { + DLOGE("Seamless switch to the config: %d, is not allowed!", config); + return HWC2::Error::SeamlessNotAllowed; + } + + hwc2_vsync_period_t vsync_period; + if (GetDisplayVsyncPeriod(&vsync_period) != HWC2::Error::None) { + return HWC2::Error::BadConfig; + } + + std::tie(out_timeline->refreshTimeNanos, out_timeline->newVsyncAppliedTimeNanos) = + RequestActiveConfigChange(config, vsync_period, + vsync_period_change_constraints->desiredTimeNanos); + + out_timeline->refreshRequired = true; + return HWC2::Error::None; +} + +void HWCDisplay::ProcessActiveConfigChange() { + if (!IsActiveConfigReadyToSubmit(systemTime(SYSTEM_TIME_MONOTONIC))) { + return; + } + + DTRACE_SCOPED(); + hwc2_vsync_period_t vsync_period; + if (GetVsyncPeriodByActiveConfig(&vsync_period) == HWC2::Error::None) { + SubmitActiveConfigChange(vsync_period); + } +} + +HWC2::Error HWCDisplay::GetVsyncPeriodByActiveConfig(hwc2_vsync_period_t *vsync_period) { + hwc2_config_t active_config; + + auto error = GetActiveConfig(&active_config); + if (error != HWC2::Error::None) { + DLOGE("Failed to get active config!"); + return error; + } + + int32_t active_vsync_period; + error = GetDisplayAttribute(active_config, HWC2::Attribute::VsyncPeriod, &active_vsync_period); + if (error != HWC2::Error::None) { + DLOGE("Failed to get VsyncPeriod of config: %d", active_config); + return error; + } + + *vsync_period = static_cast<hwc2_vsync_period_t>(active_vsync_period); + return HWC2::Error::None; +} + +bool HWCDisplay::GetTransientVsyncPeriod(hwc2_vsync_period_t *vsync_period) { + std::lock_guard<std::mutex> lock(transient_refresh_rate_lock_); + auto now = systemTime(SYSTEM_TIME_MONOTONIC); + + while (!transient_refresh_rate_info_.empty()) { + if (IsActiveConfigApplied(now, transient_refresh_rate_info_.front().vsync_applied_time)) { + transient_refresh_rate_info_.pop_front(); + } else { + *vsync_period = transient_refresh_rate_info_.front().transient_vsync_period; + return true; + } + } + + return false; +} + +std::tuple<int64_t, int64_t> HWCDisplay::RequestActiveConfigChange( + hwc2_config_t config, hwc2_vsync_period_t current_vsync_period, int64_t desired_time) { + int64_t refresh_time, applied_time; + std::tie(refresh_time, applied_time) = + EstimateVsyncPeriodChangeTimeline(current_vsync_period, desired_time); + + pending_refresh_rate_config_ = config; + pending_refresh_rate_refresh_time_ = refresh_time; + pending_refresh_rate_applied_time_ = applied_time; + + return std::make_tuple(refresh_time, applied_time); +} + +std::tuple<int64_t, int64_t> HWCDisplay::EstimateVsyncPeriodChangeTimeline( + hwc2_vsync_period_t current_vsync_period, int64_t desired_time) { + const auto now = systemTime(SYSTEM_TIME_MONOTONIC); + const auto delta = desired_time - now; + const auto refresh_rate_activate_period = current_vsync_period * vsyncs_to_apply_rate_change_; + nsecs_t refresh_time; + + if (delta < 0) { + refresh_time = now + (delta % current_vsync_period); + } else if (delta < refresh_rate_activate_period) { + refresh_time = now + (delta % current_vsync_period) - current_vsync_period; + } else { + refresh_time = desired_time - refresh_rate_activate_period; + } + + const auto applied_time = refresh_time + refresh_rate_activate_period; + return std::make_tuple(refresh_time, applied_time); +} + +void HWCDisplay::SubmitActiveConfigChange(hwc2_vsync_period_t current_vsync_period) { + HWC2::Error error = SubmitDisplayConfig(pending_refresh_rate_config_); + if (error != HWC2::Error::None) { + return; + } + + std::lock_guard<std::mutex> lock(transient_refresh_rate_lock_); + hwc_vsync_period_change_timeline_t timeline; + std::tie(timeline.refreshTimeNanos, timeline.newVsyncAppliedTimeNanos) = + EstimateVsyncPeriodChangeTimeline(current_vsync_period, pending_refresh_rate_refresh_time_); + + transient_refresh_rate_info_.push_back({current_vsync_period, timeline.newVsyncAppliedTimeNanos}); + if (timeline.newVsyncAppliedTimeNanos != pending_refresh_rate_applied_time_) { + timeline.refreshRequired = false; + callbacks_->VsyncPeriodTimingChanged(id_, &timeline); + } + + pending_refresh_rate_config_ = UINT_MAX; + pending_refresh_rate_refresh_time_ = INT64_MAX; + pending_refresh_rate_applied_time_ = INT64_MAX; +} + +bool HWCDisplay::IsActiveConfigReadyToSubmit(int64_t time) { + return ((pending_refresh_rate_config_ != UINT_MAX) && + IsTimeAfterOrEqualVsyncTime(time, pending_refresh_rate_refresh_time_)); +} + +bool HWCDisplay::IsActiveConfigApplied(int64_t time, int64_t vsync_applied_time) { + return IsTimeAfterOrEqualVsyncTime(time, vsync_applied_time); +} + +bool HWCDisplay::IsSameGroup(hwc2_config_t config_id1, hwc2_config_t config_id2) { + const auto &variable_config1 = variable_config_map_.find(config_id1); + const auto &variable_config2 = variable_config_map_.find(config_id2); + + if ((variable_config1 == variable_config_map_.end()) || + (variable_config2 == variable_config_map_.end())) { + DLOGE("Invalid config: %u, %u", config_id1, config_id2); + return false; + } + + const DisplayConfigGroupInfo &config_group1 = variable_config1->second; + const DisplayConfigGroupInfo &config_group2 = variable_config2->second; + + return (config_group1 == config_group2); +} + +bool HWCDisplay::AllowSeamless(hwc2_config_t config) { + hwc2_config_t active_config; + auto error = GetActiveConfig(&active_config); + if (error != HWC2::Error::None) { + DLOGE("Failed to get active config!"); + return false; + } + + return IsSameGroup(active_config, config); +} + +HWC2::Error HWCDisplay::SubmitDisplayConfig(hwc2_config_t config) { + DTRACE_SCOPED(); + + hwc2_config_t current_config = 0; + GetActiveConfig(¤t_config); + if (current_config == config) { + return HWC2::Error::None; + } + + DisplayError error = display_intf_->SetActiveConfig(config); + if (error != kErrorNone) { + DLOGE("Failed to set %d config! Error: %d", config, error); + return HWC2::Error::BadConfig; + } + + validated_ = false; + DLOGI("Active configuration changed to: %d", config); + + return HWC2::Error::None; +} + } // namespace sdm diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h index e3eae09e..5c6bce9e 100644 --- a/sdm/libs/hwc2/hwc_display.h +++ b/sdm/libs/hwc2/hwc_display.h @@ -65,6 +65,11 @@ enum SecureSessionType { kSecureMax, }; +struct TransientRefreshRateInfo { + uint32_t transient_vsync_period; + int64_t vsync_applied_time; +}; + class HWCColorMode { public: explicit HWCColorMode(DisplayInterface *display_intf); @@ -195,6 +200,14 @@ class HWCDisplay : public DisplayEventHandler { return HWC2::Error::Unsupported; } + virtual bool IsSmartPanelConfig(uint32_t config_id) { + return false; + } + + virtual bool HasSmartPanelConfig(void) { + return false; + } + // Display Configurations static uint32_t GetThrottlingRefreshRate() { return HWCDisplay::throttling_refresh_rate_; } static void SetThrottlingRefreshRate(uint32_t newRefreshRate) @@ -244,6 +257,7 @@ class HWCDisplay : public DisplayEventHandler { return HWC2::Error::Unsupported; } bool IsFirstCommitDone() { return !first_cycle_; } + virtual void ProcessActiveConfigChange(); // HWC2 APIs virtual HWC2::Error AcceptDisplayChanges(void); @@ -345,6 +359,10 @@ class HWCDisplay : public DisplayEventHandler { virtual void SetLayerStack(HWCLayerStack *stack); virtual void PostPowerMode(); virtual void NotifyClientStatus(bool connected) { client_connected_ = connected; } + virtual HWC2::Error GetDisplayVsyncPeriod(hwc2_vsync_period_t *vsync_period); + virtual HWC2::Error SetActiveConfigWithConstraints(hwc2_config_t config, + hwc_vsync_period_change_constraints_t *vsync_period_change_constraints, + hwc_vsync_period_change_timeline_t *out_timeline); protected: static uint32_t throttling_refresh_rate_; @@ -376,6 +394,21 @@ class HWCDisplay : public DisplayEventHandler { uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate); virtual void GetUnderScanConfig() { } int32_t SetClientTargetDataSpace(int32_t dataspace); + int32_t GetDisplayConfigGroupId(const DisplayConfigGroupInfo &variable_config); + HWC2::Error GetVsyncPeriodByActiveConfig(hwc2_vsync_period_t *vsync_period); + bool GetTransientVsyncPeriod(hwc2_vsync_period_t *vsync_period); + std::tuple<int64_t, int64_t> RequestActiveConfigChange(hwc2_config_t config, + hwc2_vsync_period_t current_vsync_period, + int64_t desired_time); + std::tuple<int64_t, int64_t> EstimateVsyncPeriodChangeTimeline( + hwc2_vsync_period_t current_vsync_period, int64_t desired_time); + void SubmitActiveConfigChange(hwc2_vsync_period_t current_vsync_period); + bool IsActiveConfigReadyToSubmit(int64_t time); + bool IsActiveConfigApplied(int64_t time, int64_t vsync_applied_time); + bool IsSameGroup(hwc2_config_t config_id1, hwc2_config_t config_id2); + bool AllowSeamless(hwc2_config_t request_config); + void SetVsyncsApplyRateChange(uint32_t vsyncs) { vsyncs_to_apply_rate_change_ = vsyncs; } + HWC2::Error SubmitDisplayConfig(hwc2_config_t config); enum { INPUT_LAYER_DUMP, @@ -436,6 +469,12 @@ class HWCDisplay : public DisplayEventHandler { bool fast_path_composition_ = false; bool client_connected_ = true; bool pending_config_ = false; + uint32_t vsyncs_to_apply_rate_change_ = 1; + hwc2_config_t pending_refresh_rate_config_ = UINT_MAX; + int64_t pending_refresh_rate_refresh_time_ = INT64_MAX; + int64_t pending_refresh_rate_applied_time_ = INT64_MAX; + std::deque<TransientRefreshRateInfo> transient_refresh_rate_info_; + std::mutex transient_refresh_rate_lock_; private: void DumpInputBuffers(void); diff --git a/sdm/libs/hwc2/hwc_display_builtin.cpp b/sdm/libs/hwc2/hwc_display_builtin.cpp index c85b772c..bbec3f75 100644 --- a/sdm/libs/hwc2/hwc_display_builtin.cpp +++ b/sdm/libs/hwc2/hwc_display_builtin.cpp @@ -166,12 +166,26 @@ int HWCDisplayBuiltIn::Init() { HWCDebugHandler::Get()->GetProperty(ENABLE_DEFAULT_COLOR_MODE, &default_mode_status_); - int optimize_refresh = 0; - HWCDebugHandler::Get()->GetProperty(ENABLE_OPTIMIZE_REFRESH, &optimize_refresh); - enable_optimize_refresh_ = (optimize_refresh == 1); + int value = 0; + HWCDebugHandler::Get()->GetProperty(ENABLE_OPTIMIZE_REFRESH, &value); + enable_optimize_refresh_ = (value == 1); if (enable_optimize_refresh_) { DLOGI("Drop redundant drawcycles %d", id_); } + + value = 0; + HWCDebugHandler::Get()->GetProperty(ENABLE_POMS_DURING_DOZE, &value); + enable_poms_during_doze_ = (value == 1); + if (enable_poms_during_doze_) { + DLOGI("Enable POMS during Doze mode %" PRIu64 , id_); + } + + int vsyncs = 0; + HWCDebugHandler::Get()->GetProperty(DEFER_FPS_FRAME_COUNT, &vsyncs); + if (vsyncs > 0) { + SetVsyncsApplyRateChange(UINT32(vsyncs)); + } + pmic_intf_ = new PMICInterface(); pmic_intf_->Init(); @@ -303,6 +317,33 @@ bool HWCDisplayBuiltIn::CanSkipCommit() { return skip_commit; } +void HWCDisplayBuiltIn::SetPartialUpdate(DisplayConfigFixedInfo fixed_info) { + partial_update_enabled_ = fixed_info.partial_update || (!fixed_info.is_cmdmode); + for (auto hwc_layer : layer_set_) { + hwc_layer->SetPartialUpdate(partial_update_enabled_); + } + client_target_->SetPartialUpdate(partial_update_enabled_); +} + +HWC2::Error HWCDisplayBuiltIn::SetPowerMode(HWC2::PowerMode mode, bool teardown) { + DisplayConfigFixedInfo fixed_info = {}; + display_intf_->GetConfig(&fixed_info); + bool command_mode = fixed_info.is_cmdmode; + + auto status = HWCDisplay::SetPowerMode(mode, teardown); + if (status != HWC2::Error::None) { + return status; + } + + display_intf_->GetConfig(&fixed_info); + is_cmd_mode_ = fixed_info.is_cmdmode; + if (is_cmd_mode_ != command_mode) { + SetPartialUpdate(fixed_info); + } + + return HWC2::Error::None; +} + HWC2::Error HWCDisplayBuiltIn::Present(int32_t *out_retire_fence) { auto status = HWC2::Error::None; @@ -322,12 +363,24 @@ HWC2::Error HWCDisplayBuiltIn::Present(int32_t *out_retire_fence) { DLOGE("Flush failed. Error = %d", error); } } else { + DisplayConfigFixedInfo fixed_info = {}; + display_intf_->GetConfig(&fixed_info); + bool command_mode = fixed_info.is_cmdmode; + status = CommitLayerStack(); if (status == HWC2::Error::None) { HandleFrameOutput(); SolidFillCommit(); status = PostCommitLayerStack(out_retire_fence); } + + if (status == HWC2::Error::None) { + display_intf_->GetConfig(&fixed_info); + is_cmd_mode_ = fixed_info.is_cmdmode; + if (is_cmd_mode_ != command_mode) { + SetPartialUpdate(fixed_info); + } + } } CloseFd(&output_buffer_.acquire_fence_fd); @@ -994,4 +1047,30 @@ HWC2::Error HWCDisplayBuiltIn::GetPanelBrightness(float *brightness) { return HWC2::Error::None; } + +bool HWCDisplayBuiltIn::IsSmartPanelConfig(uint32_t config_id) { + if (config_id < hwc_config_map_.size()) { + uint32_t index = hwc_config_map_.at(config_id); + return variable_config_map_.at(index).smart_panel; + } + + return false; +} + +bool HWCDisplayBuiltIn::HasSmartPanelConfig(void) { + if (!enable_poms_during_doze_) { + uint32_t config = 0; + GetActiveDisplayConfig(&config); + return IsSmartPanelConfig(config); + } + + for (auto &config : variable_config_map_) { + if (config.second.smart_panel) { + return true; + } + } + + return false; +} + } // namespace sdm diff --git a/sdm/libs/hwc2/hwc_display_builtin.h b/sdm/libs/hwc2/hwc_display_builtin.h index 1ec970a5..232c31a1 100644 --- a/sdm/libs/hwc2/hwc_display_builtin.h +++ b/sdm/libs/hwc2/hwc_display_builtin.h @@ -99,6 +99,9 @@ class HWCDisplayBuiltIn : public HWCDisplay { } virtual HWC2::Error UpdatePowerMode(HWC2::PowerMode mode); virtual HWC2::Error PostCommitLayerStack(int32_t *out_retire_fence); + virtual bool IsSmartPanelConfig(uint32_t config_id); + virtual bool HasSmartPanelConfig(void); + virtual HWC2::Error SetPowerMode(HWC2::PowerMode mode, bool teardown); private: HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator, @@ -117,6 +120,7 @@ class HWCDisplayBuiltIn : public HWCDisplay { bool CanSkipCommit(); DisplayError SetMixerResolution(uint32_t width, uint32_t height); DisplayError GetMixerResolution(uint32_t *width, uint32_t *height); + void SetPartialUpdate(DisplayConfigFixedInfo fixed_info); class PMICInterface { public: PMICInterface() { } @@ -147,6 +151,7 @@ class HWCDisplayBuiltIn : public HWCDisplay { bool pending_refresh_ = true; bool enable_optimize_refresh_ = false; bool hdr_present_ = false; + bool enable_poms_during_doze_ = false; // Members for 1 frame capture in a client provided buffer bool frame_capture_buffer_queued_ = false; diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp index 87ded3a0..8a51ea78 100644 --- a/sdm/libs/hwc2/hwc_session.cpp +++ b/sdm/libs/hwc2/hwc_session.cpp @@ -691,7 +691,7 @@ static int32_t GetDisplayAttribute(hwc2_device_t *device, 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) { + int_attribute > HWC2_ATTRIBUTE_CONFIG_GROUP) { return HWC2_ERROR_BAD_PARAMETER; } auto attribute = static_cast<HWC2::Attribute>(int_attribute); @@ -776,6 +776,7 @@ int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display if (power_on_pending_[display]) { status = HWC2::Error::None; } else { + hwc_session->hwc_display_[display]->ProcessActiveConfigChange(); status = hwc_session->PresentDisplayInternal(display, out_retire_fence); if (status == HWC2::Error::None) { // Check if hwc's refresh trigger is getting exercised. @@ -1097,9 +1098,7 @@ int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, hwc_session->UpdateThrottlingRate(); - // Trigger refresh for doze mode to take effect. if (mode == HWC2::PowerMode::Doze) { - hwc_session->Refresh(display); // Trigger one more refresh for PP features to take effect. hwc_session->pending_refresh_.set(UINT32(display)); } else { @@ -1143,10 +1142,19 @@ int32_t HWCSession::GetDozeSupport(hwc2_device_t *device, hwc2_display_t display } *out_support = 0; - if (hwc_display->GetDisplayClass() == DISPLAY_CLASS_BUILTIN) { - *out_support = 1; + + if (display != qdutils::DISPLAY_PRIMARY) { + return HWC2_ERROR_NONE; + } + + SCOPE_LOCK(locker_[display]); + if (!hwc_session->hwc_display_[display]) { + DLOGE("Display %d is not created yet.", INT32(display)); + return HWC2_ERROR_NONE; } + *out_support = hwc_session->hwc_display_[display]->HasSmartPanelConfig() ? 1 : 0; + return HWC2_ERROR_NONE; } @@ -1179,6 +1187,7 @@ int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t displa if (power_on_pending_[display]) { status = HWC2::Error::None; } else if (hwc_session->hwc_display_[display]) { + hwc_session->hwc_display_[display]->ProcessActiveConfigChange(); hwc_session->hwc_display_[display]->SetFastPathComposition(false); status = hwc_session->ValidateDisplayInternal(display, out_num_types, out_num_requests); } @@ -1311,6 +1320,13 @@ hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device, return AsFP<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(HWCSession::GetDisplayBrightnessSupport); case HWC2::FunctionDescriptor::SetDisplayBrightness: return AsFP<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(HWCSession::SetDisplayBrightness); + case HWC2::FunctionDescriptor::GetDisplayConnectionType: + return AsFP<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(HWCSession::GetDisplayConnectionType); + case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod: + return AsFP<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(HWCSession::GetDisplayVsyncPeriod); + case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints: + return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS> + (HWCSession::SetActiveConfigWithConstraints); default: DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor, to_string(descriptor).c_str()); @@ -1437,7 +1453,7 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pa DLOGE("QService command = %d: input_parcel needed.", command); break; } - status = setIdleTimeout(UINT32(input_parcel->readInt32())); + status = SetIdleTimeout(UINT32(input_parcel->readInt32())); break; case qService::IQService::SET_FRAME_DUMP_CONFIG: @@ -1472,7 +1488,7 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pa int disp_id = INT(input_parcel->readInt32()); HWCDisplay::DisplayStatus disp_status = static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32()); - status = SetSecondaryDisplayStatus(disp_id, disp_status); + status = SetDisplayStatus(disp_id, disp_status); output_parcel->writeInt32(status); } break; @@ -1495,7 +1511,7 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pa break; } int32_t input = input_parcel->readInt32(); - status = toggleScreenUpdate(input == 1); + status = ToggleScreenUpdate(input == 1); output_parcel->writeInt32(status); } break; @@ -1621,7 +1637,7 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pa break; } uint32_t camera_status = UINT32(input_parcel->readInt32()); - status = setCameraLaunchStatus(camera_status); + status = SetCameraLaunchStatus(camera_status); } break; @@ -3197,7 +3213,7 @@ int32_t HWCSession::GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_disp } if (display != HWC_DISPLAY_PRIMARY) { - return HWC2_ERROR_BAD_DISPLAY; + return HWC2_ERROR_UNSUPPORTED; } HWCSession *hwc_session = static_cast<HWCSession *>(device); @@ -3222,7 +3238,7 @@ int32_t HWCSession::SetReadbackBuffer(hwc2_device_t *device, hwc2_display_t disp } if (display != HWC_DISPLAY_PRIMARY) { - return HWC2_ERROR_BAD_DISPLAY; + return HWC2_ERROR_UNSUPPORTED; } HWCSession *hwc_session = static_cast<HWCSession *>(device); @@ -3248,7 +3264,7 @@ int32_t HWCSession::GetReadbackBufferFence(hwc2_device_t *device, hwc2_display_t } if (display != HWC_DISPLAY_PRIMARY) { - return HWC2_ERROR_BAD_DISPLAY; + return HWC2_ERROR_UNSUPPORTED; } return CallDisplayFunction(device, display, &HWCDisplay::GetReadbackBufferFence, release_fence); @@ -3296,15 +3312,65 @@ int32_t HWCSession::GetDisplayCapabilities(hwc2_device_t *device, hwc2_display_t } else { if (isBuiltin) { // TODO(user): Handle SKIP_CLIENT_COLOR_TRANSFORM based on DSPP availability - outCapabilities[0] = HWC2_DISPLAY_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM; - outCapabilities[1] = HWC2_DISPLAY_CAPABILITY_DOZE; - outCapabilities[2] = HWC2_DISPLAY_CAPABILITY_BRIGHTNESS; - *outNumCapabilities = 3; + uint32_t index = 0; + outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM; + int32_t has_doze_support = 0; + GetDozeSupport(device, display, &has_doze_support); + if (has_doze_support) { + outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_DOZE; + } + outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_BRIGHTNESS; + *outNumCapabilities = index; } return HWC2_ERROR_NONE; } } +int32_t HWCSession::GetDisplayConnectionType(hwc2_device_t* device, hwc2_display_t display, + uint32_t *outType) { + if (!outType || !device) { + return HWC2_ERROR_BAD_PARAMETER; + } + + if (display >= HWCCallbacks::kNumDisplays) { + return HWC2_ERROR_BAD_DISPLAY; + } + + HWCSession *hwc_session = static_cast<HWCSession *>(device); + HWCDisplay *hwc_display = hwc_session->hwc_display_[display]; + if (!hwc_display) { + DLOGE("Expected valid hwc_display"); + return HWC2_ERROR_BAD_PARAMETER; + } + + *outType = HWC2_DISPLAY_CONNECTION_TYPE_EXTERNAL; + if (hwc_display->GetDisplayClass() == DISPLAY_CLASS_BUILTIN) { + *outType = HWC2_DISPLAY_CONNECTION_TYPE_INTERNAL; + } + + return HWC2_ERROR_NONE; +} + +int32_t HWCSession::GetDisplayVsyncPeriod(hwc2_device_t *device, hwc2_display_t display, + hwc2_vsync_period_t *out_vsync_period) { + if (!out_vsync_period || !device) { + return HWC2_ERROR_BAD_PARAMETER; + } + + return CallDisplayFunction(device, display, &HWCDisplay::GetDisplayVsyncPeriod, out_vsync_period); +} + +int32_t HWCSession::SetActiveConfigWithConstraints(hwc2_device_t *device, hwc2_display_t display, + hwc2_config_t config, + hwc_vsync_period_change_constraints_t *vsync_period_change_constraints, + hwc_vsync_period_change_timeline_t *out_timeline) { + if (!vsync_period_change_constraints || !out_timeline || !device) { + return HWC2_ERROR_BAD_PARAMETER; + } + + return CallDisplayFunction(device, display, &HWCDisplay::SetActiveConfigWithConstraints, config, + vsync_period_change_constraints, out_timeline); +} int32_t HWCSession::GetDisplayBrightnessSupport(hwc2_device_t *device, hwc2_display_t display, bool *outSupport) { @@ -3394,7 +3460,7 @@ android::status_t HWCSession::SetIdlePC(const android::Parcel *input_parcel) { auto enable = input_parcel->readInt32(); auto synchronous = input_parcel->readInt32(); - return static_cast<android::status_t>(controlIdlePowerCollapse(enable, synchronous)); + return static_cast<android::status_t>(ControlIdlePowerCollapse(enable, synchronous)); } hwc2_display_t HWCSession::GetActiveBuiltinDisplay() { diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h index dfc3bbba..50b79bcc 100644 --- a/sdm/libs/hwc2/hwc_session.h +++ b/sdm/libs/hwc2/hwc_session.h @@ -20,8 +20,8 @@ #ifndef __HWC_SESSION_H__ #define __HWC_SESSION_H__ -#include <vendor/display/config/1.11/IDisplayConfig.h> - +#include <cutils/native_handle.h> +#include <config/device_interface.h> #include <core/core_interface.h> #include <utils/locker.h> #include <qd_utils.h> @@ -29,6 +29,7 @@ #include <vector> #include <utility> #include <map> +#include <string> #include "hwc_callbacks.h" #include "hwc_layers.h" @@ -45,9 +46,6 @@ namespace sdm { -using vendor::display::config::V1_11::IDisplayConfig; -using vendor::display::config::V1_10::IDisplayCWBCallback; - using ::android::hardware::Return; using ::android::hardware::hidl_string; using android::hardware::hidl_handle; @@ -55,6 +53,8 @@ using ::android::hardware::hidl_vec; int32_t GetDataspaceFromColorMode(ColorMode mode); +typedef DisplayConfig::DisplayType DispType; + // Create a singleton uevent listener thread valid for life of hardware composer process. // This thread blocks on uevents poll inside uevent library implementation. This poll exits // only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle @@ -84,8 +84,8 @@ constexpr int32_t kDataspaceSaturationMatrixCount = 16; constexpr int32_t kDataspaceSaturationPropertyElements = 9; constexpr int32_t kPropertyMax = 256; -class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qClient::BnQClient, - public HWCDisplayEventHandler { +class HWCSession : hwc2_device_t, HWCUEventListener, public qClient::BnQClient, + public HWCDisplayEventHandler, public DisplayConfig::ClientContext { public: struct HWCModuleMethods : public hw_module_methods_t { HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; } @@ -210,6 +210,18 @@ class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qCli bool *outSupport); static int32_t SetDisplayBrightness(hwc2_device_t *device, hwc2_display_t display, float brightness); + static int32_t GetDisplayConnectionType(hwc2_device_t *device, hwc2_display_t display, + uint32_t *outType); + static int32_t GetDisplayVsyncPeriod(hwc2_device_t *device, hwc2_display_t display, + hwc2_vsync_period_t *out_vsync_period); + static int32_t SetActiveConfigWithConstraints(hwc2_device_t *device, hwc2_display_t display, + hwc2_config_t config, + hwc_vsync_period_change_constraints_t *vsync_period_change_constraints, + hwc_vsync_period_change_timeline_t *out_timeline); + + virtual int RegisterClientContext(std::shared_ptr<DisplayConfig::ConfigCallback> callback, + DisplayConfig::ConfigInterface **intf); + virtual void UnRegisterClientContext(DisplayConfig::ConfigInterface *intf); // HWCDisplayEventHandler virtual void DisplayPowerReset(); @@ -224,6 +236,62 @@ class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qCli static Locker display_config_locker_; private: + + class DisplayConfigImpl: public DisplayConfig::ConfigInterface { + public: + explicit DisplayConfigImpl(std::weak_ptr<DisplayConfig::ConfigCallback> callback, + HWCSession *hwc_session); + + private: + virtual int IsDisplayConnected(DispType dpy, bool *connected); + virtual int SetDisplayStatus(DispType dpy, DisplayConfig::ExternalStatus status); + virtual int ConfigureDynRefreshRate(DisplayConfig::DynRefreshRateOp op, uint32_t refresh_rate); + virtual int GetConfigCount(DispType dpy, uint32_t *count); + virtual int GetActiveConfig(DispType dpy, uint32_t *config); + virtual int SetActiveConfig(DispType dpy, uint32_t config); + virtual int GetDisplayAttributes(uint32_t config_index, DispType dpy, + DisplayConfig::Attributes *attributes); + virtual int SetPanelBrightness(uint32_t level); + virtual int GetPanelBrightness(uint32_t *level); + virtual int MinHdcpEncryptionLevelChanged(DispType dpy, uint32_t min_enc_level); + virtual int RefreshScreen(); + virtual int ControlPartialUpdate(DispType dpy, bool enable); + virtual int ToggleScreenUpdate(bool on); + virtual int SetIdleTimeout(uint32_t value); + virtual int GetHDRCapabilities(DispType dpy, DisplayConfig::HDRCapsParams *caps); + virtual int SetCameraLaunchStatus(uint32_t on); + virtual int DisplayBWTransactionPending(bool *status); + virtual int SetDisplayAnimating(uint64_t display_id, bool animating); + virtual int ControlIdlePowerCollapse(bool enable, bool synchronous); + virtual int GetWriteBackCapabilities(bool *is_wb_ubwc_supported); + virtual int 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); + virtual int UpdateVSyncSourceOnPowerModeOff(); + virtual int UpdateVSyncSourceOnPowerModeDoze(); + virtual int SetPowerMode(uint32_t disp_id, DisplayConfig::PowerMode power_mode); + virtual int IsPowerModeOverrideSupported(uint32_t disp_id, bool *supported); + virtual int IsHDRSupported(uint32_t disp_id, bool *supported); + virtual int IsWCGSupported(uint32_t disp_id, bool *supported); + virtual int SetLayerAsMask(uint32_t disp_id, uint64_t layer_id); + virtual int GetDebugProperty(const std::string prop_name, std::string value) {return -EINVAL;} + virtual int GetDebugProperty(const std::string prop_name, std::string *value); + virtual int GetActiveBuiltinDisplayAttributes(DisplayConfig::Attributes *attr); + virtual int SetPanelLuminanceAttributes(uint32_t disp_id, float min_lum, float max_lum); + virtual int IsBuiltInDisplay(uint32_t disp_id, bool *is_builtin); + virtual int GetSupportedDSIBitClks(uint32_t disp_id, + std::vector<uint64_t> bit_clks) {return -EINVAL;} + virtual int GetSupportedDSIBitClks(uint32_t disp_id, std::vector<uint64_t> *bit_clks); + virtual int GetDSIClk(uint32_t disp_id, uint64_t *bit_clk); + virtual int SetDSIClk(uint32_t disp_id, uint64_t bit_clk); + virtual int SetCWBOutputBuffer(uint32_t disp_id, const DisplayConfig::Rect rect, + bool post_processed, const native_handle_t *buffer); + virtual int SetQsyncMode(uint32_t disp_id, DisplayConfig::QsyncMode mode); + + std::weak_ptr<DisplayConfig::ConfigCallback> callback_; + HWCSession *hwc_session_ = nullptr; + }; + struct DisplayMapInfo { hwc2_display_t client_id = HWCCallbacks::kNumDisplays; // mapped sf id for this display int32_t sdm_id = -1; // sdm id for this display @@ -264,78 +332,30 @@ class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qCli void DestroyPluggableDisplay(DisplayMapInfo *map_info); void DestroyNonPluggableDisplay(DisplayMapInfo *map_info); int GetVsyncPeriod(int disp); - int32_t GetConfigCount(int disp_id, uint32_t *count); - int32_t GetActiveConfigIndex(int disp_id, uint32_t *config); - int32_t SetActiveConfigIndex(int disp_id, uint32_t config); - int32_t ControlPartialUpdate(int dpy, bool enable); - int32_t DisplayBWTransactionPending(bool *status); - int32_t SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status); - int32_t MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level); - int32_t IsWbUbwcSupported(int *value); + int GetConfigCount(int disp_id, uint32_t *count); + int GetActiveConfigIndex(int disp_id, uint32_t *config); + int SetActiveConfigIndex(int disp_id, uint32_t config); + int ControlPartialUpdate(int dpy, bool enable); + int DisplayBWTransactionPending(bool *status); + int SetDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status); + int MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level); + int IsWbUbwcSupported(bool *value); + int SetIdleTimeout(uint32_t value); + int ToggleScreenUpdate(bool on); + int SetCameraLaunchStatus(uint32_t on); + int 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); + int ControlIdlePowerCollapse(bool enable, bool synchronous); int32_t SetDynamicDSIClock(int64_t disp_id, uint32_t bitrate); bool HasHDRSupport(HWCDisplay *hwc_display); int32_t getDisplayBrightness(uint32_t display, float *brightness); int32_t setDisplayBrightness(uint32_t display, float brightness); + bool isSmartPanelConfig(uint32_t disp_id, uint32_t config_id); // service methods void StartServices(); - // Methods from ::android::hardware::display::config::V1_0::IDisplayConfig follow. - Return<void> isDisplayConnected(IDisplayConfig::DisplayType dpy, - isDisplayConnected_cb _hidl_cb) override; - Return<int32_t> setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy, - IDisplayConfig::DisplayExternalStatus status) override; - Return<int32_t> configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op, - uint32_t refreshRate) override; - Return<void> getConfigCount(IDisplayConfig::DisplayType dpy, - getConfigCount_cb _hidl_cb) override; - Return<void> getActiveConfig(IDisplayConfig::DisplayType dpy, - getActiveConfig_cb _hidl_cb) override; - Return<int32_t> setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) override; - Return<void> getDisplayAttributes(uint32_t configIndex, IDisplayConfig::DisplayType dpy, - getDisplayAttributes_cb _hidl_cb) override; - Return<int32_t> setPanelBrightness(uint32_t level) override; - Return<void> getPanelBrightness(getPanelBrightness_cb _hidl_cb) override; - Return<int32_t> minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy, - uint32_t min_enc_level) override; - Return<int32_t> refreshScreen() override; - Return<int32_t> controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) override; - Return<int32_t> toggleScreenUpdate(bool on) override; - Return<int32_t> setIdleTimeout(uint32_t value) override; - Return<void> getHDRCapabilities(IDisplayConfig::DisplayType dpy, - getHDRCapabilities_cb _hidl_cb) override; - Return<int32_t> setCameraLaunchStatus(uint32_t on) override; - Return<void> displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) override; - Return<int32_t> setDisplayAnimating(uint64_t display_id, bool animating) override; - Return<int32_t> setDisplayIndex(IDisplayConfig::DisplayTypeExt disp_type, - uint32_t base, uint32_t count) override; - Return<int32_t> controlIdlePowerCollapse(bool enable, bool synchronous) override; - Return<void> getWriteBackCapabilities(getWriteBackCapabilities_cb _hidl_cb) override; - Return<int32_t> SetDisplayDppsAdROI(uint32_t dispaly_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) override; - Return<int32_t> updateVSyncSourceOnPowerModeOff() override; - Return<int32_t> updateVSyncSourceOnPowerModeDoze() override; - Return<int32_t> setPowerMode(uint32_t disp_id, PowerMode power_mode) override; - Return<bool> isPowerModeOverrideSupported(uint32_t disp_id) override; - Return<bool> isHDRSupported(uint32_t disp_id) override; - Return<bool> isWCGSupported(uint32_t disp_id) override; - Return<int32_t> setLayerAsMask(uint32_t disp_id, uint64_t layer_id) override; - Return<void> getDebugProperty(const hidl_string &prop_name, - getDebugProperty_cb _hidl_cb) override; - Return<void> getActiveBuiltinDisplayAttributes(getDisplayAttributes_cb _hidl_cb) override; - Return<int32_t> setPanelLuminanceAttributes(uint32_t disp_id, float min_lum, - float max_lum) override; - Return<bool> isBuiltInDisplay(uint32_t disp_id) override; - Return<void> getSupportedDSIBitClks(uint32_t disp_id, - getSupportedDSIBitClks_cb _hidl_cb) override; - Return<uint64_t> getDSIClk(uint32_t disp_id) override; - Return<int32_t> setDSIClk(uint32_t disp_id, uint64_t bit_clk) override; - Return<int32_t> setCWBOutputBuffer(const ::android::sp<IDisplayCWBCallback> &callback, - uint32_t disp_id, const Rect &rect, bool post_processed, - const hidl_handle& buffer) override; - Return<int32_t> setQsyncMode(uint32_t disp_id, IDisplayConfig::QsyncMode mode) override; - // QClient methods virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel, android::Parcel *output_parcel); diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp index abd27866..a46c13b0 100644 --- a/sdm/libs/hwc2/hwc_session_services.cpp +++ b/sdm/libs/hwc2/hwc_session_services.cpp @@ -32,6 +32,8 @@ #include <sync/sync.h> #include <vector> #include <string> +#include <errno.h> +#include <math.h> #include "hwc_buffer_sync_handler.h" #include "hwc_session.h" @@ -41,26 +43,24 @@ namespace sdm { -using ::android::hardware::Void; - void HWCSession::StartServices() { - android::status_t status = IDisplayConfig::registerAsService(); - if (status != android::OK) { - DLOGW("Could not register IDisplayConfig as service (%d).", status); + int error = DisplayConfig::DeviceInterface::RegisterDevice(this); + if (error) { + DLOGW("Could not register IDisplayConfig as service (%d).", error); } else { DLOGI("IDisplayConfig service registration completed."); } } -int MapDisplayType(IDisplayConfig::DisplayType dpy) { +int MapDisplayType(DispType dpy) { switch (dpy) { - case IDisplayConfig::DisplayType::DISPLAY_PRIMARY: + case DispType::kPrimary: return qdutils::DISPLAY_PRIMARY; - case IDisplayConfig::DisplayType::DISPLAY_EXTERNAL: + case DispType::kExternal: return qdutils::DISPLAY_EXTERNAL; - case IDisplayConfig::DisplayType::DISPLAY_VIRTUAL: + case DispType::kVirtual: return qdutils::DISPLAY_VIRTUAL; default: @@ -70,18 +70,18 @@ int MapDisplayType(IDisplayConfig::DisplayType dpy) { return -EINVAL; } -HWCDisplay::DisplayStatus MapExternalStatus(IDisplayConfig::DisplayExternalStatus status) { +HWCDisplay::DisplayStatus MapExternalStatus(DisplayConfig::ExternalStatus status) { switch (status) { - case IDisplayConfig::DisplayExternalStatus::EXTERNAL_OFFLINE: + case DisplayConfig::ExternalStatus::kOffline: return HWCDisplay::kDisplayStatusOffline; - case IDisplayConfig::DisplayExternalStatus::EXTERNAL_ONLINE: + case DisplayConfig::ExternalStatus::kOnline: return HWCDisplay::kDisplayStatusOnline; - case IDisplayConfig::DisplayExternalStatus::EXTERNAL_PAUSE: + case DisplayConfig::ExternalStatus::kPause: return HWCDisplay::kDisplayStatusPause; - case IDisplayConfig::DisplayExternalStatus::EXTERNAL_RESUME: + case DisplayConfig::ExternalStatus::kResume: return HWCDisplay::kDisplayStatusResume; default: @@ -91,27 +91,47 @@ HWCDisplay::DisplayStatus MapExternalStatus(IDisplayConfig::DisplayExternalStatu return HWCDisplay::kDisplayStatusInvalid; } -// Methods from ::vendor::hardware::display::config::V1_0::IDisplayConfig follow. -Return<void> HWCSession::isDisplayConnected(IDisplayConfig::DisplayType dpy, - isDisplayConnected_cb _hidl_cb) { - int32_t error = -EINVAL; - bool connected = false; +int HWCSession::RegisterClientContext(std::shared_ptr<DisplayConfig::ConfigCallback> callback, + DisplayConfig::ConfigInterface **intf) { + if (!intf) { + DLOGE("Invalid DisplayConfigIntf location"); + return -EINVAL; + } + + std::weak_ptr<DisplayConfig::ConfigCallback> wp_callback = callback; + DisplayConfigImpl *impl = new DisplayConfigImpl(wp_callback, this); + *intf = impl; + + return 0; +} + +void HWCSession::UnRegisterClientContext(DisplayConfig::ConfigInterface *intf) { + delete static_cast<DisplayConfigImpl *>(intf); +} + +HWCSession::DisplayConfigImpl::DisplayConfigImpl( + std::weak_ptr<DisplayConfig::ConfigCallback> callback, + HWCSession *hwc_session) { + callback_ = callback; + hwc_session_ = hwc_session; +} + +int HWCSession::DisplayConfigImpl::IsDisplayConnected(DispType dpy, bool *connected) { int disp_id = MapDisplayType(dpy); - int disp_idx = GetDisplayIndex(disp_id); + int disp_idx = hwc_session_->GetDisplayIndex(disp_id); if (disp_idx == -1) { DLOGE("Invalid display = %d", disp_id); + return -EINVAL; } else { - SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]); - connected = hwc_display_[disp_idx]; - error = 0; + SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[disp_idx]); + *connected = hwc_session_->hwc_display_[disp_idx]; } - _hidl_cb(error, connected); - return Void(); + return 0; } -int32_t HWCSession::SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status) { +int HWCSession::SetDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status) { int disp_idx = GetDisplayIndex(disp_id); int err = -EINVAL; if (disp_idx == -1) { @@ -151,15 +171,15 @@ int32_t HWCSession::SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplaySt return err; } -Return<int32_t> HWCSession::setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy, - IDisplayConfig::DisplayExternalStatus status) { - return SetSecondaryDisplayStatus(MapDisplayType(dpy), MapExternalStatus(status)); +int HWCSession::DisplayConfigImpl::SetDisplayStatus(DispType dpy, + DisplayConfig::ExternalStatus status) { + return hwc_session_->SetDisplayStatus(MapDisplayType(dpy), MapExternalStatus(status)); } -Return<int32_t> HWCSession::configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op, - uint32_t refreshRate) { - SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); - HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY]; +int HWCSession::DisplayConfigImpl::ConfigureDynRefreshRate(DisplayConfig::DynRefreshRateOp op, + uint32_t refresh_rate) { + SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[HWC_DISPLAY_PRIMARY]); + HWCDisplay *hwc_display = hwc_session_->hwc_display_[HWC_DISPLAY_PRIMARY]; if (!hwc_display) { DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY); @@ -167,14 +187,14 @@ Return<int32_t> HWCSession::configureDynRefeshRate(IDisplayConfig::DisplayDynRef } switch (op) { - case IDisplayConfig::DisplayDynRefreshRateOp::DISABLE_METADATA_DYN_REFRESH_RATE: + case DisplayConfig::DynRefreshRateOp::kDisableMetadata: return hwc_display->Perform(HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, false); - case IDisplayConfig::DisplayDynRefreshRateOp::ENABLE_METADATA_DYN_REFRESH_RATE: + case DisplayConfig::DynRefreshRateOp::kEnableMetadata: return hwc_display->Perform(HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, true); - case IDisplayConfig::DisplayDynRefreshRateOp::SET_BINDER_DYN_REFRESH_RATE: - return hwc_display->Perform(HWCDisplayBuiltIn::SET_BINDER_DYN_REFRESH_RATE, refreshRate); + case DisplayConfig::DynRefreshRateOp::kSetBinder: + return hwc_display->Perform(HWCDisplayBuiltIn::SET_BINDER_DYN_REFRESH_RATE, refresh_rate); default: DLOGW("Invalid operation %d", op); @@ -184,7 +204,7 @@ Return<int32_t> HWCSession::configureDynRefeshRate(IDisplayConfig::DisplayDynRef return 0; } -int32_t HWCSession::GetConfigCount(int disp_id, uint32_t *count) { +int HWCSession::GetConfigCount(int disp_id, uint32_t *count) { int disp_idx = GetDisplayIndex(disp_id); if (disp_idx == -1) { DLOGE("Invalid display = %d", disp_id); @@ -200,17 +220,11 @@ int32_t HWCSession::GetConfigCount(int disp_id, uint32_t *count) { return -EINVAL; } -Return<void> HWCSession::getConfigCount(IDisplayConfig::DisplayType dpy, - getConfigCount_cb _hidl_cb) { - uint32_t count = 0; - int32_t error = GetConfigCount(MapDisplayType(dpy), &count); - - _hidl_cb(error, count); - - return Void(); +int HWCSession::DisplayConfigImpl::GetConfigCount(DispType dpy, uint32_t *count) { + return hwc_session_->GetConfigCount(MapDisplayType(dpy), count); } -int32_t HWCSession::GetActiveConfigIndex(int disp_id, uint32_t *config) { +int HWCSession::GetActiveConfigIndex(int disp_id, uint32_t *config) { int disp_idx = GetDisplayIndex(disp_id); if (disp_idx == -1) { DLOGE("Invalid display = %d", disp_id); @@ -226,17 +240,11 @@ int32_t HWCSession::GetActiveConfigIndex(int disp_id, uint32_t *config) { return -EINVAL; } -Return<void> HWCSession::getActiveConfig(IDisplayConfig::DisplayType dpy, - getActiveConfig_cb _hidl_cb) { - uint32_t config = 0; - int32_t error = GetActiveConfigIndex(MapDisplayType(dpy), &config); - - _hidl_cb(error, config); - - return Void(); +int HWCSession::DisplayConfigImpl::GetActiveConfig(DispType dpy, uint32_t *config) { + return hwc_session_->GetActiveConfigIndex(MapDisplayType(dpy), config); } -int32_t HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) { +int HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) { int disp_idx = GetDisplayIndex(disp_id); if (disp_idx == -1) { DLOGE("Invalid display = %d", disp_id); @@ -244,7 +252,7 @@ int32_t HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) { } SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]); - int32_t error = -EINVAL; + int error = -EINVAL; if (hwc_display_[disp_idx]) { error = hwc_display_[disp_idx]->SetActiveDisplayConfig(config); if (!error) { @@ -255,69 +263,69 @@ int32_t HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) { return error; } -Return<int32_t> HWCSession::setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) { - return SetActiveConfigIndex(MapDisplayType(dpy), config); +int HWCSession::DisplayConfigImpl::SetActiveConfig(DispType dpy, uint32_t config) { + return hwc_session_->SetActiveConfigIndex(MapDisplayType(dpy), config); } -Return<void> HWCSession::getDisplayAttributes(uint32_t configIndex, - IDisplayConfig::DisplayType dpy, - getDisplayAttributes_cb _hidl_cb) { - int32_t error = -EINVAL; - IDisplayConfig::DisplayAttributes display_attributes = {}; +int HWCSession::DisplayConfigImpl::GetDisplayAttributes(uint32_t config_index, DispType dpy, + DisplayConfig::Attributes *attributes) { + int error = -EINVAL; + int disp_id = MapDisplayType(dpy); - int disp_idx = GetDisplayIndex(disp_id); + int disp_idx = hwc_session_->GetDisplayIndex(disp_id); if (disp_idx == -1) { DLOGE("Invalid display = %d", disp_id); } else { - SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]); - if (hwc_display_[disp_idx]) { + SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[disp_idx]); + if (hwc_session_->hwc_display_[disp_idx]) { DisplayConfigVariableInfo var_info; - error = hwc_display_[disp_idx]->GetDisplayAttributesForConfig(INT(configIndex), &var_info); + error = hwc_session_->hwc_display_[disp_idx]->GetDisplayAttributesForConfig(INT(config_index), + &var_info); if (!error) { - display_attributes.vsyncPeriod = var_info.vsync_period_ns; - display_attributes.xRes = var_info.x_pixels; - display_attributes.yRes = var_info.y_pixels; - display_attributes.xDpi = var_info.x_dpi; - display_attributes.yDpi = var_info.y_dpi; - display_attributes.panelType = IDisplayConfig::DisplayPortType::DISPLAY_PORT_DEFAULT; - display_attributes.isYuv = var_info.is_yuv; + attributes->vsync_period = var_info.vsync_period_ns; + attributes->x_res = var_info.x_pixels; + attributes->y_res = var_info.y_pixels; + attributes->x_dpi = var_info.x_dpi; + attributes->y_dpi = var_info.y_dpi; + attributes->panel_type = DisplayConfig::DisplayPortType::kDefault; + attributes->is_yuv = var_info.is_yuv; } } } - _hidl_cb(error, display_attributes); - return Void(); + return error; } -Return<int32_t> HWCSession::setPanelBrightness(uint32_t level) { +int HWCSession::DisplayConfigImpl::SetPanelBrightness(uint32_t level) { if (!(0 <= level && level <= 255)) { return -EINVAL; } - hwc2_device_t *device = static_cast<hwc2_device_t *>(this); + hwc2_device_t *device = static_cast<hwc2_device_t *>(hwc_session_); if (level == 0) { - return INT32(SetDisplayBrightness(device, HWC_DISPLAY_PRIMARY, -1.0f)); + return INT32(hwc_session_->SetDisplayBrightness(device, HWC_DISPLAY_PRIMARY, -1.0f)); } else { - return INT32(SetDisplayBrightness(device, HWC_DISPLAY_PRIMARY, (level - 1)/254.0f)); + return INT32(hwc_session_->SetDisplayBrightness(device, HWC_DISPLAY_PRIMARY, + (level - 1)/254.0f)); } } -Return<void> HWCSession::getPanelBrightness(getPanelBrightness_cb _hidl_cb) { +int HWCSession::DisplayConfigImpl::GetPanelBrightness(uint32_t *level) { float brightness = -1.0f; int32_t error = -EINVAL; - error = getDisplayBrightness(HWC_DISPLAY_PRIMARY, &brightness); + error = hwc_session_->getDisplayBrightness(HWC_DISPLAY_PRIMARY, &brightness); if (brightness == -1.0f) { - _hidl_cb(error, 0); + *level = 0; } else { - _hidl_cb(error, static_cast<uint32_t>(254.0f*brightness + 1)); + *level = static_cast<uint32_t>(254.0f*brightness + 1); } - return Void(); + return error; } -int32_t HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level) { +int HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level) { DLOGI("Display %d", disp_id); int disp_idx = GetDisplayIndex(disp_id); @@ -338,19 +346,18 @@ int32_t HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_ return -EINVAL; } -Return<int32_t> HWCSession::minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy, - uint32_t min_enc_level) { - return MinHdcpEncryptionLevelChanged(MapDisplayType(dpy), min_enc_level); +int HWCSession::DisplayConfigImpl::MinHdcpEncryptionLevelChanged(DispType dpy, + uint32_t min_enc_level) { + return hwc_session_->MinHdcpEncryptionLevelChanged(MapDisplayType(dpy), min_enc_level); } -Return<int32_t> HWCSession::refreshScreen() { - SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); - Refresh(HWC_DISPLAY_PRIMARY); - +int HWCSession::DisplayConfigImpl::RefreshScreen() { + SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[HWC_DISPLAY_PRIMARY]); + hwc_session_->Refresh(HWC_DISPLAY_PRIMARY); return 0; } -int32_t HWCSession::ControlPartialUpdate(int disp_id, bool enable) { +int HWCSession::ControlPartialUpdate(int disp_id, bool enable) { int disp_idx = GetDisplayIndex(disp_id); if (disp_idx == -1) { DLOGE("Invalid display = %d", disp_id); @@ -386,16 +393,16 @@ int32_t HWCSession::ControlPartialUpdate(int disp_id, bool enable) { Refresh(HWC_DISPLAY_PRIMARY); // Wait until partial update control is complete - int32_t error = locker_[disp_idx].WaitFinite(kCommitDoneTimeoutMs); + int error = locker_[disp_idx].WaitFinite(kCommitDoneTimeoutMs); return error; } -Return<int32_t> HWCSession::controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) { - return ControlPartialUpdate(MapDisplayType(dpy), enable); +int HWCSession::DisplayConfigImpl::ControlPartialUpdate(DispType dpy, bool enable) { + return hwc_session_->ControlPartialUpdate(MapDisplayType(dpy), enable); } -Return<int32_t> HWCSession::toggleScreenUpdate(bool on) { +int HWCSession::ToggleScreenUpdate(bool on) { SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); int32_t error = -EINVAL; @@ -409,7 +416,11 @@ Return<int32_t> HWCSession::toggleScreenUpdate(bool on) { return error; } -Return<int32_t> HWCSession::setIdleTimeout(uint32_t value) { +int HWCSession::DisplayConfigImpl::ToggleScreenUpdate(bool on) { + return hwc_session_->ToggleScreenUpdate(on); +} + +int HWCSession::SetIdleTimeout(uint32_t value) { SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); if (hwc_display_[HWC_DISPLAY_PRIMARY]) { @@ -421,26 +432,24 @@ Return<int32_t> HWCSession::setIdleTimeout(uint32_t value) { return -ENODEV; } -Return<void> HWCSession::getHDRCapabilities(IDisplayConfig::DisplayType dpy, - getHDRCapabilities_cb _hidl_cb) { - int32_t error = -EINVAL; - IDisplayConfig::DisplayHDRCapabilities hdr_caps = {}; +int HWCSession::DisplayConfigImpl::SetIdleTimeout(uint32_t value) { + return hwc_session_->SetIdleTimeout(value); +} - do { - if (!_hidl_cb) { - DLOGE("_hidl_cb callback not provided."); - break; - } +int HWCSession::DisplayConfigImpl::GetHDRCapabilities(DispType dpy, + DisplayConfig::HDRCapsParams *caps) { + int error = -EINVAL; + do { int disp_id = MapDisplayType(dpy); - int disp_idx = GetDisplayIndex(disp_id); + int disp_idx = hwc_session_->GetDisplayIndex(disp_id); if (disp_idx == -1) { DLOGE("Invalid display = %d", disp_id); break; } - SCOPE_LOCK(locker_[disp_id]); - HWCDisplay *hwc_display = hwc_display_[disp_idx]; + SCOPE_LOCK(hwc_session_->locker_[disp_id]); + HWCDisplay *hwc_display = hwc_session_->hwc_display_[disp_idx]; if (!hwc_display) { DLOGW("Display = %d is not connected.", disp_idx); error = -ENODEV; @@ -463,21 +472,19 @@ Return<void> HWCSession::getHDRCapabilities(IDisplayConfig::DisplayType dpy, } // query hdr caps - hdr_caps.supportedHdrTypes.resize(out_num_types); + caps->supported_hdr_types.resize(out_num_types); - if (hwc_display->GetHdrCapabilities(&out_num_types, hdr_caps.supportedHdrTypes.data(), + if (hwc_display->GetHdrCapabilities(&out_num_types, caps->supported_hdr_types.data(), &out_max_luminance, &out_max_average_luminance, &out_min_luminance) == HWC2::Error::None) { error = 0; } } while (false); - _hidl_cb(error, hdr_caps); - - return Void(); + return error; } -Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) { +int HWCSession::SetCameraLaunchStatus(uint32_t on) { hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay(); if (active_builtin_disp_id >= HWCCallbacks::kNumDisplays) { DLOGE("No active displays"); @@ -515,7 +522,11 @@ Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) { return 0; } -int32_t HWCSession::DisplayBWTransactionPending(bool *status) { +int HWCSession::DisplayConfigImpl::SetCameraLaunchStatus(uint32_t on) { + return hwc_session_->SetCameraLaunchStatus(on); +} + +int HWCSession::DisplayBWTransactionPending(bool *status) { SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); if (hwc_display_[HWC_DISPLAY_PRIMARY]) { @@ -531,32 +542,16 @@ int32_t HWCSession::DisplayBWTransactionPending(bool *status) { return -ENODEV; } -Return<void> HWCSession::displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) { - bool status = true; - - if (!_hidl_cb) { - DLOGE("_hidl_cb callback not provided."); - return Void(); - } - - int32_t error = DisplayBWTransactionPending(&status); - - _hidl_cb(error, status); - - return Void(); -} - -Return<int32_t> HWCSession::setDisplayAnimating(uint64_t display_id, bool animating ) { - return CallDisplayFunction(static_cast<hwc2_device_t *>(this), display_id, - &HWCDisplay::SetDisplayAnimating, animating); +int HWCSession::DisplayConfigImpl::DisplayBWTransactionPending(bool *status) { + return hwc_session_->DisplayBWTransactionPending(status); } -Return<int32_t> HWCSession::setDisplayIndex(IDisplayConfig::DisplayTypeExt disp_type, - uint32_t base, uint32_t count) { - return -1; +int HWCSession::DisplayConfigImpl::SetDisplayAnimating(uint64_t display_id, bool animating) { + return hwc_session_->CallDisplayFunction(static_cast<hwc2_device_t *>(hwc_session_), display_id, + &HWCDisplay::SetDisplayAnimating, animating); } -Return<int32_t> HWCSession::controlIdlePowerCollapse(bool enable, bool synchronous) { +int HWCSession::ControlIdlePowerCollapse(bool enable, bool synchronous) { hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay(); if (active_builtin_disp_id >= HWCCallbacks::kNumDisplays) { DLOGE("No active displays"); @@ -573,7 +568,7 @@ Return<int32_t> HWCSession::controlIdlePowerCollapse(bool enable, bool synchrono return (err == kErrorNotSupported) ? 0 : -EINVAL; } Refresh(active_builtin_disp_id); - int32_t error = locker_[active_builtin_disp_id].WaitFinite(kCommitDoneTimeoutMs); + int error = locker_[active_builtin_disp_id].WaitFinite(kCommitDoneTimeoutMs); if (error == ETIMEDOUT) { DLOGE("Timed out!! Next frame commit done event not received!!"); return error; @@ -599,7 +594,11 @@ Return<int32_t> HWCSession::controlIdlePowerCollapse(bool enable, bool synchrono return -ENODEV; } -int32_t HWCSession::IsWbUbwcSupported(int *value) { +int HWCSession::DisplayConfigImpl::ControlIdlePowerCollapse(bool enable, bool synchronous) { + return hwc_session_->ControlIdlePowerCollapse(enable, synchronous); +} + +int HWCSession::IsWbUbwcSupported(bool *value) { HWDisplaysInfo hw_displays_info = {}; DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info); if (error != kErrorNone) { @@ -616,118 +615,128 @@ int32_t HWCSession::IsWbUbwcSupported(int *value) { return error; } -Return<void> HWCSession::getWriteBackCapabilities(getWriteBackCapabilities_cb _hidl_cb) { - int value = 0; - IDisplayConfig::WriteBackCapabilities wb_caps = {}; - int32_t error = IsWbUbwcSupported(&value); - wb_caps.isWbUbwcSupported = value; - _hidl_cb(error, wb_caps); - - return Void(); +int HWCSession::DisplayConfigImpl::GetWriteBackCapabilities(bool *isWbUbwcSupported) { + return hwc_session_->IsWbUbwcSupported(isWbUbwcSupported); } -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) { +int 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, &HWCDisplay::SetDisplayDppsAdROI, h_start, h_end, v_start, v_end, factor_in, factor_out); } -Return<int32_t> HWCSession::updateVSyncSourceOnPowerModeOff() { +int HWCSession::DisplayConfigImpl::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 hwc_session_->SetDisplayDppsAdROI(display_id, h_start, h_end, v_start, v_end, + factor_in, factor_out); +} + +int HWCSession::DisplayConfigImpl::UpdateVSyncSourceOnPowerModeOff() { return 0; } -Return<int32_t> HWCSession::updateVSyncSourceOnPowerModeDoze() { +int HWCSession::DisplayConfigImpl::UpdateVSyncSourceOnPowerModeDoze() { return 0; } -Return<bool> HWCSession::isPowerModeOverrideSupported(uint32_t disp_id) { - if (!async_powermode_ || (disp_id > HWCCallbacks::kNumRealDisplays)) { - return false; +int HWCSession::DisplayConfigImpl::IsPowerModeOverrideSupported(uint32_t disp_id, + bool *supported) { + if (!hwc_session_->async_powermode_ || (disp_id > HWCCallbacks::kNumRealDisplays)) { + *supported = false; + } else { + *supported = true; } - return true; + return 0; } -Return<int32_t> HWCSession::setPowerMode(uint32_t disp_id, PowerMode power_mode) { - SCOPE_LOCK(display_config_locker_); +int HWCSession::DisplayConfigImpl::SetPowerMode(uint32_t disp_id, + DisplayConfig::PowerMode power_mode) { + SCOPE_LOCK(hwc_session_->display_config_locker_); - if (!isPowerModeOverrideSupported(disp_id)) { + bool supported = false; + IsPowerModeOverrideSupported(disp_id, &supported); + if (!supported) { return 0; } DLOGI("disp_id: %d power_mode: %d", disp_id, power_mode); HWCDisplay::HWCLayerStack stack = {}; - hwc2_display_t dummy_disp_id = map_hwc_display_.at(disp_id); + hwc2_display_t dummy_disp_id = hwc_session_->map_hwc_display_.at(disp_id); { // Power state transition start. - Locker::ScopeLock lock_power(power_state_[disp_id]); - Locker::ScopeLock lock_primary(locker_[disp_id]); - Locker::ScopeLock lock_dummy(locker_[dummy_disp_id]); + Locker::ScopeLock lock_power(hwc_session_->power_state_[disp_id]); + Locker::ScopeLock lock_primary(hwc_session_->locker_[disp_id]); + Locker::ScopeLock lock_dummy(hwc_session_->locker_[dummy_disp_id]); - power_state_transition_[disp_id] = true; + hwc_session_->power_state_transition_[disp_id] = true; // Pass on the complete stack to dummy display. - hwc_display_[disp_id]->GetLayerStack(&stack); + hwc_session_->hwc_display_[disp_id]->GetLayerStack(&stack); // Update the same stack onto dummy display. - hwc_display_[dummy_disp_id]->SetLayerStack(&stack); + hwc_session_->hwc_display_[dummy_disp_id]->SetLayerStack(&stack); } { - SCOPE_LOCK(locker_[disp_id]); + SCOPE_LOCK(hwc_session_->locker_[disp_id]); auto mode = static_cast<HWC2::PowerMode>(power_mode); - hwc_display_[disp_id]->SetPowerMode(mode, false /* teardown */); + hwc_session_->hwc_display_[disp_id]->SetPowerMode(mode, false /* teardown */); } { // Power state transition end. - Locker::ScopeLock lock_power(power_state_[disp_id]); - Locker::ScopeLock lock_primary(locker_[disp_id]); - Locker::ScopeLock lock_dummy(locker_[dummy_disp_id]); + Locker::ScopeLock lock_power(hwc_session_->power_state_[disp_id]); + Locker::ScopeLock lock_primary(hwc_session_->locker_[disp_id]); + Locker::ScopeLock lock_dummy(hwc_session_->locker_[dummy_disp_id]); // Pass on the layer stack to real display. - hwc_display_[dummy_disp_id]->GetLayerStack(&stack); + hwc_session_->hwc_display_[dummy_disp_id]->GetLayerStack(&stack); // Update the same stack onto real display. - hwc_display_[disp_id]->SetLayerStack(&stack); + hwc_session_->hwc_display_[disp_id]->SetLayerStack(&stack); // Read display has got layerstack. Update the fences. - hwc_display_[disp_id]->PostPowerMode(); + hwc_session_->hwc_display_[disp_id]->PostPowerMode(); - power_state_transition_[disp_id] = false; + hwc_session_->power_state_transition_[disp_id] = false; } return 0; } -Return<bool> HWCSession::isHDRSupported(uint32_t disp_id) { +int HWCSession::DisplayConfigImpl::IsHDRSupported(uint32_t disp_id, bool *supported) { if (disp_id < 0 || disp_id >= HWCCallbacks::kNumDisplays) { DLOGE("Not valid display"); - return false; + return -EINVAL; } - SCOPE_LOCK(locker_[disp_id]); + SCOPE_LOCK(hwc_session_->locker_[disp_id]); - if (is_hdr_display_.size() <= disp_id) { + if (hwc_session_->is_hdr_display_.size() <= disp_id) { DLOGW("is_hdr_display_ is not initialized for display %d!! Reporting it as HDR not supported", disp_id); - return false; + *supported = false; + return 0; } - return static_cast<bool>(is_hdr_display_[disp_id]); + *supported = static_cast<bool>(hwc_session_->is_hdr_display_[disp_id]); + return 0; } -Return<bool> HWCSession::isWCGSupported(uint32_t disp_id) { +int HWCSession::DisplayConfigImpl::IsWCGSupported(uint32_t disp_id, bool *supported) { // todo(user): Query wcg from sdm. For now assume them same. - return isHDRSupported(disp_id); + return IsHDRSupported(disp_id, supported); } -Return<int32_t> HWCSession::setLayerAsMask(uint32_t disp_id, uint64_t layer_id) { - SCOPE_LOCK(locker_[disp_id]); - HWCDisplay *hwc_display = hwc_display_[disp_id]; +int HWCSession::DisplayConfigImpl::SetLayerAsMask(uint32_t disp_id, uint64_t layer_id) { + SCOPE_LOCK(hwc_session_->locker_[disp_id]); + HWCDisplay *hwc_display = hwc_session_->hwc_display_[disp_id]; if (!hwc_display) { DLOGW("Display = %d is not connected.", disp_id); return -EINVAL; } - if (disable_mask_layer_hint_) { + if (hwc_session_->disable_mask_layer_hint_) { DLOGW("Mask layer hint is disabled!"); return -EINVAL; } @@ -742,153 +751,162 @@ Return<int32_t> HWCSession::setLayerAsMask(uint32_t disp_id, uint64_t layer_id) return 0; } -Return<void> HWCSession::getDebugProperty(const hidl_string &prop_name, - getDebugProperty_cb _hidl_cb) { +int HWCSession::DisplayConfigImpl::GetDebugProperty(const std::string prop_name, + std::string *value) { std::string vendor_prop_name = DISP_PROP_PREFIX; - char value[64] = {}; - hidl_string result = ""; - int32_t error = -EINVAL; + int error = -EINVAL; + char val[64] = {}; vendor_prop_name += prop_name.c_str(); - if (HWCDebugHandler::Get()->GetProperty(vendor_prop_name.c_str(), value) == kErrorNone) { - result = value; + if (HWCDebugHandler::Get()->GetProperty(vendor_prop_name.c_str(), val) == kErrorNone) { + *value = val; error = 0; } - _hidl_cb(result, error); - - return Void(); + return error; } -Return<void> HWCSession::getActiveBuiltinDisplayAttributes( - getDisplayAttributes_cb _hidl_cb) { - int32_t error = -EINVAL; - IDisplayConfig::DisplayAttributes display_attributes = {}; - hwc2_display_t disp_id = GetActiveBuiltinDisplay(); +int HWCSession::DisplayConfigImpl::GetActiveBuiltinDisplayAttributes( + DisplayConfig::Attributes *attr) { + int error = -EINVAL; + hwc2_display_t disp_id = hwc_session_->GetActiveBuiltinDisplay(); if (disp_id >= HWCCallbacks::kNumDisplays) { DLOGE("Invalid display = %d", disp_id); } else { - if (hwc_display_[disp_id]) { + if (hwc_session_->hwc_display_[disp_id]) { uint32_t config_index = 0; - HWC2::Error ret = hwc_display_[disp_id]->GetActiveConfig(&config_index); + HWC2::Error ret = hwc_session_->hwc_display_[disp_id]->GetActiveConfig(&config_index); if (ret != HWC2::Error::None) { goto err; } DisplayConfigVariableInfo var_info; - error = hwc_display_[disp_id]->GetDisplayAttributesForConfig(INT(config_index), &var_info); + error = hwc_session_->hwc_display_[disp_id]->GetDisplayAttributesForConfig(INT(config_index), + &var_info); if (!error) { - display_attributes.vsyncPeriod = var_info.vsync_period_ns; - display_attributes.xRes = var_info.x_pixels; - display_attributes.yRes = var_info.y_pixels; - display_attributes.xDpi = var_info.x_dpi; - display_attributes.yDpi = var_info.y_dpi; - display_attributes.panelType = IDisplayConfig::DisplayPortType::DISPLAY_PORT_DEFAULT; - display_attributes.isYuv = var_info.is_yuv; + attr->vsync_period = var_info.vsync_period_ns; + attr->x_res = var_info.x_pixels; + attr->y_res = var_info.y_pixels; + attr->x_dpi = var_info.x_dpi; + attr->y_dpi = var_info.y_dpi; + attr->panel_type = DisplayConfig::DisplayPortType::kDefault; + attr->is_yuv = var_info.is_yuv; } } } err: - _hidl_cb(error, display_attributes); - - return Void(); + return error; } -Return<int32_t> HWCSession::setPanelLuminanceAttributes(uint32_t disp_id, float pan_min_lum, - float pan_max_lum) { +int HWCSession::DisplayConfigImpl::SetPanelLuminanceAttributes(uint32_t disp_id, float pan_min_lum, + float pan_max_lum) { // currently doing only for virtual display if (disp_id != qdutils::DISPLAY_VIRTUAL) { return -EINVAL; } - std::lock_guard<std::mutex> obj(mutex_lum_); - set_min_lum_ = pan_min_lum; - set_max_lum_ = pan_max_lum; - DLOGI("set max_lum %f, min_lum %f", set_max_lum_, set_min_lum_); + std::lock_guard<std::mutex> obj(hwc_session_->mutex_lum_); + hwc_session_->set_min_lum_ = pan_min_lum; + hwc_session_->set_max_lum_ = pan_max_lum; + DLOGI("set max_lum %f, min_lum %f", pan_max_lum, pan_min_lum); return 0; } -Return<bool> HWCSession::isBuiltInDisplay(uint32_t disp_id) { - if ((map_info_primary_.client_id == disp_id) && (map_info_primary_.disp_type == kBuiltIn)) - return true; +int HWCSession::DisplayConfigImpl::IsBuiltInDisplay(uint32_t disp_id, bool *is_builtin) { + if ((hwc_session_->map_info_primary_.client_id == disp_id) && + (hwc_session_->map_info_primary_.disp_type == kBuiltIn)) { + *is_builtin = true; + return 0; + } - for (auto &info : map_info_builtin_) { + for (auto &info : hwc_session_->map_info_builtin_) { if (disp_id == info.client_id) { - return true; + *is_builtin = true; + return 0; } } - return false; + *is_builtin = false; + return 0; } -Return<void> HWCSession::getSupportedDSIBitClks(uint32_t disp_id, - getSupportedDSIBitClks_cb _hidl_cb) { - SCOPE_LOCK(locker_[disp_id]); - if (!hwc_display_[disp_id]) { - return Void(); +int HWCSession::DisplayConfigImpl::GetSupportedDSIBitClks(uint32_t disp_id, + std::vector<uint64_t> *bit_clks) { + SCOPE_LOCK(hwc_session_->locker_[disp_id]); + if (!hwc_session_->hwc_display_[disp_id]) { + return -EINVAL; } - std::vector<uint64_t> bit_clks; - hwc_display_[disp_id]->GetSupportedDSIClock(&bit_clks); - - hidl_vec<uint64_t> hidl_bit_clks = bit_clks; - _hidl_cb(hidl_bit_clks); - - return Void(); + hwc_session_->hwc_display_[disp_id]->GetSupportedDSIClock(bit_clks); + return 0; } -Return<uint64_t> HWCSession::getDSIClk(uint32_t disp_id) { - SCOPE_LOCK(locker_[disp_id]); - if (!hwc_display_[disp_id]) { - return 0; +int HWCSession::DisplayConfigImpl::GetDSIClk(uint32_t disp_id, uint64_t *bit_clk) { + SCOPE_LOCK(hwc_session_->locker_[disp_id]); + if (!hwc_session_->hwc_display_[disp_id]) { + return -EINVAL; } - uint64_t bit_clk = 0; - hwc_display_[disp_id]->GetDynamicDSIClock(&bit_clk); + hwc_session_->hwc_display_[disp_id]->GetDynamicDSIClock(bit_clk); - return bit_clk; + return 0; } -Return<int32_t> HWCSession::setDSIClk(uint32_t disp_id, uint64_t bit_clk) { - SCOPE_LOCK(locker_[disp_id]); - if (!hwc_display_[disp_id]) { +int HWCSession::DisplayConfigImpl::SetDSIClk(uint32_t disp_id, uint64_t bit_clk) { + SCOPE_LOCK(hwc_session_->locker_[disp_id]); + if (!hwc_session_->hwc_display_[disp_id]) { return -1; } - return hwc_display_[disp_id]->SetDynamicDSIClock(bit_clk); + return hwc_session_->hwc_display_[disp_id]->SetDynamicDSIClock(bit_clk); } -Return<int32_t> HWCSession::setCWBOutputBuffer(const ::android::sp<IDisplayCWBCallback> &callback, - uint32_t disp_id, const Rect &rect, - bool post_processed, const hidl_handle& buffer) { +int HWCSession::DisplayConfigImpl::SetCWBOutputBuffer(uint32_t disp_id, + const DisplayConfig::Rect rect, + bool post_processed, + const native_handle_t *buffer) { return -1; } -Return<int32_t> HWCSession::setQsyncMode(uint32_t disp_id, IDisplayConfig::QsyncMode mode) { - SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]); +bool HWCSession::isSmartPanelConfig(uint32_t disp_id, uint32_t config_id) { + if (disp_id != qdutils::DISPLAY_PRIMARY) { + return false; + } + + SCOPE_LOCK(locker_[disp_id]); if (!hwc_display_[disp_id]) { + DLOGE("Display %d is not created yet.", disp_id); + return false; + } + + return hwc_display_[disp_id]->IsSmartPanelConfig(config_id); +} + +int HWCSession::DisplayConfigImpl::SetQsyncMode(uint32_t disp_id, DisplayConfig::QsyncMode mode) { + SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[disp_id]); + if (!hwc_session_->hwc_display_[disp_id]) { return -1; } QSyncMode qsync_mode = kQSyncModeNone; switch (mode) { - case IDisplayConfig::QsyncMode::NONE: + case DisplayConfig::QsyncMode::kNone: qsync_mode = kQSyncModeNone; break; - case IDisplayConfig::QsyncMode::WAIT_FOR_FENCES_ONE_FRAME: + case DisplayConfig::QsyncMode::kWaitForFencesOneFrame: qsync_mode = kQsyncModeOneShot; break; - case IDisplayConfig::QsyncMode::WAIT_FOR_FENCES_EACH_FRAME: + case DisplayConfig::QsyncMode::kWaitForFencesEachFrame: qsync_mode = kQsyncModeOneShotContinuous; break; - case IDisplayConfig::QsyncMode::WAIT_FOR_COMMIT_EACH_FRAME: + case DisplayConfig::QsyncMode::kWaitForCommitEachFrame: qsync_mode = kQSyncModeContinuous; break; } - hwc_display_[disp_id]->SetQSyncMode(qsync_mode); + hwc_session_->hwc_display_[disp_id]->SetQSyncMode(qsync_mode); return 0; } |