drm_hwcomposer: Add wrapper for EDID parsing Use libdisplay-info to parse display EDID. Wrap the parsing logic in a class to extract specific EDID information. Change-Id: I20376eb96ebcd0073155cedf1e8f055bbf8dfb49 Signed-off-by: Sasha McIntosh <sashamcintosh@google.com>
diff --git a/Android.bp b/Android.bp index e7a77bd..a8d95eb 100644 --- a/Android.bp +++ b/Android.bp
@@ -39,6 +39,7 @@ static_libs: [ "libaidlcommonsupport", + "libdisplay_info", ], header_libs: [ @@ -51,6 +52,7 @@ ], cppflags: [ + "-DHAS_LIBDISPLAY_INFO", "-DHWC2_INCLUDE_STRINGIFICATION", "-DHWC2_USE_CPP11", ],
diff --git a/drm/DrmConnector.cpp b/drm/DrmConnector.cpp index 6dbe3c5..6be4067 100644 --- a/drm/DrmConnector.cpp +++ b/drm/DrmConnector.cpp
@@ -89,6 +89,12 @@ } UpdateEdidProperty(); +#if HAS_LIBDISPLAY_INFO + auto edid = LibdisplayEdidWrapper::Create(GetEdidBlob()); + edid_wrapper_ = edid ? std::move(edid) : std::make_unique<EdidWrapper>(); +#else + edid_wrapper_ = std::make_unique<EdidWrapper>(); +#endif if (IsWriteback() && (!GetConnectorProperty("WRITEBACK_PIXEL_FORMATS", @@ -128,7 +134,8 @@ colorspace_enum_map_); colorspace_property_.AddEnumToMap("RGB_WIDE_FIXED", Colorspace::kRgbWideFixed, colorspace_enum_map_); - colorspace_property_.AddEnumToMap("RGB_WIDE_FLOAT", Colorspace::kRgbWideFloat, + colorspace_property_.AddEnumToMap("RGB_WIDE_FLOAT", + Colorspace::kRgbWideFloat, colorspace_enum_map_); colorspace_property_.AddEnumToMap("BT601_YCC", Colorspace::kBt601Ycc, colorspace_enum_map_);
diff --git a/drm/DrmConnector.h b/drm/DrmConnector.h index e49cee0..fc17206 100644 --- a/drm/DrmConnector.h +++ b/drm/DrmConnector.h
@@ -27,11 +27,14 @@ #include "DrmProperty.h" #include "DrmUnique.h" #include "compositor/DisplayInfo.h" +#include "utils/EdidWrapper.h" namespace android { class DrmDevice; +using EdidWrapperUnique = std::unique_ptr<EdidWrapper>; + class DrmConnector : public PipelineBindable<DrmConnector> { public: static auto CreateInstance(DrmDevice &dev, uint32_t connector_id, @@ -42,6 +45,9 @@ int UpdateEdidProperty(); auto GetEdidBlob() -> DrmModePropertyBlobUnique; + auto GetParsedEdid() -> EdidWrapperUnique & { + return edid_wrapper_; + } auto GetDev() const -> DrmDevice & { return *drm_; @@ -152,6 +158,8 @@ return GetConnectorProperty(prop_name, property, /*is_optional=*/true); } + EdidWrapperUnique edid_wrapper_; + const uint32_t index_in_res_array_; std::vector<DrmMode> modes_;
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h index ad58ae8..01ea33d 100644 --- a/hwc2_device/HwcDisplay.h +++ b/hwc2_device/HwcDisplay.h
@@ -297,6 +297,9 @@ HWC2::Error Init(); HWC2::Error SetActiveConfigInternal(uint32_t config, int64_t change_time); + auto GetEdid() -> EdidWrapperUnique & { + return GetPipe().connector->Get()->GetParsedEdid(); + } }; } // namespace android
diff --git a/utils/EdidWrapper.h b/utils/EdidWrapper.h new file mode 100644 index 0000000..3552001 --- /dev/null +++ b/utils/EdidWrapper.h
@@ -0,0 +1,69 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#define LOG_TAG "drmhwc" + +#if HAS_LIBDISPLAY_INFO +extern "C" { +#include <libdisplay-info/info.h> +} +#endif + +#include "drm/DrmUnique.h" +#include "utils/log.h" + +namespace android { + +// Stub wrapper class for edid parsing +class EdidWrapper { + public: + EdidWrapper() = default; + EdidWrapper(const EdidWrapper &) = delete; + virtual ~EdidWrapper() = default; +}; + +#if HAS_LIBDISPLAY_INFO +// Wrapper class for that uses libdisplay-info to parse edids +class LibdisplayEdidWrapper final : public EdidWrapper { + public: + LibdisplayEdidWrapper() = delete; + LibdisplayEdidWrapper(di_info *info) : info_(info) { + } + ~LibdisplayEdidWrapper() override { + di_info_destroy(info_); + } + static auto Create(DrmModePropertyBlobUnique blob) + -> std::unique_ptr<LibdisplayEdidWrapper> { + if (!blob) + return nullptr; + + auto *info = di_info_parse_edid(blob->data, blob->length); + if (!info) { + ALOGW("Failed to parse edid blob."); + return nullptr; + } + + return std::make_unique<LibdisplayEdidWrapper>(std::move(info)); + } + + private: + di_info *info_{}; +}; +#endif + +} // namespace android