drm_hwcomposer: Implement getHdrCapabilities and getColorModes
Retrieve color and HDR information from the EDID. Change-Id: I1aac27644d5c4fd5d5f295ca32b69ed69e94e0c6 Signed-off-by: Sasha McIntosh <sashamcintosh@google.com>
This commit is contained in:
parent
f9062b6964
commit
851ea4dc26
8 changed files with 162 additions and 30 deletions
|
|
@ -102,9 +102,9 @@ filegroup {
|
|||
"hwc2_device/HwcLayer.cpp",
|
||||
"hwc2_device/hwc2_device.cpp",
|
||||
|
||||
"utils/LibdisplayEdidWrapper.cpp",
|
||||
"utils/fd.cpp",
|
||||
"utils/properties.cpp",
|
||||
"utils/LibdisplayEdidWrapper.cpp",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,31 @@
|
|||
|
||||
#include <cstdint>
|
||||
|
||||
/*
|
||||
* Display colorimetry enums.
|
||||
*/
|
||||
// NOLINTBEGIN(readability-identifier-naming)
|
||||
enum class Colormode : int32_t {
|
||||
kNative,
|
||||
kBt601_625,
|
||||
kBt601_625Unadjusted,
|
||||
kBt601_525,
|
||||
kBt601_525Unadjusted,
|
||||
kBt709,
|
||||
kDciP3,
|
||||
kSrgb,
|
||||
kAdobeRgb,
|
||||
kDisplayP3,
|
||||
kBt2020,
|
||||
kBt2100Pq,
|
||||
kBt2100Hlg,
|
||||
kDisplayBt2020,
|
||||
};
|
||||
// NOLINTEND(readability-identifier-naming)
|
||||
|
||||
/**
|
||||
* Display panel colorspace property values.
|
||||
*/
|
||||
enum class Colorspace : int32_t {
|
||||
kDefault,
|
||||
kSmpte170MYcc,
|
||||
|
|
|
|||
|
|
@ -613,11 +613,23 @@ HWC2::Error HwcDisplay::GetClientTargetSupport(uint32_t width, uint32_t height,
|
|||
}
|
||||
|
||||
HWC2::Error HwcDisplay::GetColorModes(uint32_t *num_modes, int32_t *modes) {
|
||||
if (!modes)
|
||||
*num_modes = 1;
|
||||
if (!modes) {
|
||||
std::vector<Colormode> temp_modes;
|
||||
GetEdid()->GetColorModes(temp_modes);
|
||||
*num_modes = temp_modes.size();
|
||||
return HWC2::Error::None;
|
||||
}
|
||||
|
||||
if (modes)
|
||||
*modes = HAL_COLOR_MODE_NATIVE;
|
||||
std::vector<Colormode> temp_modes;
|
||||
std::vector<int32_t> out_modes(modes, modes + *num_modes);
|
||||
GetEdid()->GetColorModes(temp_modes);
|
||||
if (temp_modes.empty()) {
|
||||
out_modes.emplace_back(HAL_COLOR_MODE_NATIVE);
|
||||
return HWC2::Error::None;
|
||||
}
|
||||
|
||||
for (auto &c : temp_modes)
|
||||
out_modes.emplace_back(static_cast<int32_t>(c));
|
||||
|
||||
return HWC2::Error::None;
|
||||
}
|
||||
|
|
@ -733,12 +745,35 @@ HWC2::Error HwcDisplay::GetDozeSupport(int32_t *support) {
|
|||
return HWC2::Error::None;
|
||||
}
|
||||
|
||||
HWC2::Error HwcDisplay::GetHdrCapabilities(uint32_t *num_types,
|
||||
int32_t * /*types*/,
|
||||
float * /*max_luminance*/,
|
||||
float * /*max_average_luminance*/,
|
||||
float * /*min_luminance*/) {
|
||||
*num_types = 0;
|
||||
HWC2::Error HwcDisplay::GetHdrCapabilities(uint32_t *num_types, int32_t *types,
|
||||
float *max_luminance,
|
||||
float *max_average_luminance,
|
||||
float *min_luminance) {
|
||||
if (!types) {
|
||||
std::vector<ui::Hdr> temp_types;
|
||||
float lums[3] = {0.F};
|
||||
GetEdid()->GetHdrCapabilities(temp_types, &lums[0], &lums[1], &lums[2]);
|
||||
*num_types = temp_types.size();
|
||||
return HWC2::Error::None;
|
||||
}
|
||||
|
||||
std::vector<ui::Hdr> temp_types;
|
||||
std::vector<int32_t> out_types(types, types + *num_types);
|
||||
GetEdid()->GetHdrCapabilities(temp_types, max_luminance,
|
||||
max_average_luminance, min_luminance);
|
||||
for (auto &t : temp_types) {
|
||||
switch (t) {
|
||||
case ui::Hdr::HDR10:
|
||||
out_types.emplace_back(HAL_HDR_HDR10);
|
||||
break;
|
||||
case ui::Hdr::HLG:
|
||||
out_types.emplace_back(HAL_HDR_HLG);
|
||||
break;
|
||||
default:
|
||||
// Ignore any other HDR types
|
||||
break;
|
||||
}
|
||||
}
|
||||
return HWC2::Error::None;
|
||||
}
|
||||
|
||||
|
|
@ -983,18 +1018,6 @@ HWC2::Error HwcDisplay::SetActiveConfigInternal(uint32_t config,
|
|||
staged_mode_change_time_ = change_time;
|
||||
staged_mode_config_id_ = config;
|
||||
|
||||
std::vector<ui::Hdr> hdr_types;
|
||||
GetEdid()->GetSupportedHdrTypes(hdr_types);
|
||||
if (hdr_types.empty()) {
|
||||
hdr_metadata_.reset();
|
||||
colorspace_ = Colorspace::kDefault;
|
||||
} else {
|
||||
auto ret = SetHdrOutputMetadata(hdr_types.front());
|
||||
if (ret != HWC2::Error::None)
|
||||
return ret;
|
||||
colorspace_ = Colorspace::kBt2020Rgb;
|
||||
}
|
||||
|
||||
return HWC2::Error::None;
|
||||
}
|
||||
|
||||
|
|
@ -1056,29 +1079,47 @@ HWC2::Error HwcDisplay::SetColorMode(int32_t mode) {
|
|||
/* Maps to the Colorspace DRM connector property:
|
||||
* https://elixir.bootlin.com/linux/v6.11/source/include/drm/drm_connector.h#L538
|
||||
*/
|
||||
if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_P3)
|
||||
if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_BT2020)
|
||||
return HWC2::Error::BadParameter;
|
||||
|
||||
switch (mode) {
|
||||
case HAL_COLOR_MODE_NATIVE:
|
||||
hdr_metadata_.reset();
|
||||
colorspace_ = Colorspace::kDefault;
|
||||
break;
|
||||
case HAL_COLOR_MODE_STANDARD_BT601_625:
|
||||
case HAL_COLOR_MODE_STANDARD_BT601_625_UNADJUSTED:
|
||||
case HAL_COLOR_MODE_STANDARD_BT601_525:
|
||||
case HAL_COLOR_MODE_STANDARD_BT601_525_UNADJUSTED:
|
||||
hdr_metadata_.reset();
|
||||
// The DP spec does not say whether this is the 525 or the 625 line version.
|
||||
colorspace_ = Colorspace::kBt601Ycc;
|
||||
break;
|
||||
case HAL_COLOR_MODE_STANDARD_BT709:
|
||||
case HAL_COLOR_MODE_SRGB:
|
||||
hdr_metadata_.reset();
|
||||
colorspace_ = Colorspace::kBt709Ycc;
|
||||
break;
|
||||
case HAL_COLOR_MODE_DCI_P3:
|
||||
case HAL_COLOR_MODE_DISPLAY_P3:
|
||||
hdr_metadata_.reset();
|
||||
colorspace_ = Colorspace::kDciP3RgbD65;
|
||||
break;
|
||||
case HAL_COLOR_MODE_DISPLAY_BT2020: {
|
||||
std::vector<ui::Hdr> hdr_types;
|
||||
GetEdid()->GetSupportedHdrTypes(hdr_types);
|
||||
if (!hdr_types.empty()) {
|
||||
auto ret = SetHdrOutputMetadata(hdr_types.front());
|
||||
if (ret != HWC2::Error::None)
|
||||
return ret;
|
||||
}
|
||||
colorspace_ = Colorspace::kBt2020Rgb;
|
||||
break;
|
||||
}
|
||||
case HAL_COLOR_MODE_ADOBE_RGB:
|
||||
case HAL_COLOR_MODE_BT2020:
|
||||
case HAL_COLOR_MODE_BT2100_PQ:
|
||||
case HAL_COLOR_MODE_BT2100_HLG:
|
||||
default:
|
||||
return HWC2::Error::Unsupported;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#include <optional>
|
||||
#include <sstream>
|
||||
|
||||
#include <ui/GraphicTypes.h>
|
||||
|
||||
#include "HwcDisplayConfigs.h"
|
||||
#include "compositor/DisplayInfo.h"
|
||||
#include "compositor/FlatteningController.h"
|
||||
|
|
|
|||
|
|
@ -941,8 +941,28 @@ ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t display_id,
|
|||
return ToBinderStatus(hwc3::Error::kBadDisplay);
|
||||
}
|
||||
|
||||
/* No HDR capabilities */
|
||||
caps->types.clear();
|
||||
uint32_t num_types = 0;
|
||||
hwc3::Error error = Hwc2toHwc3Error(
|
||||
display->GetHdrCapabilities(&num_types, nullptr, nullptr, nullptr,
|
||||
nullptr));
|
||||
if (error != hwc3::Error::kNone) {
|
||||
return ToBinderStatus(error);
|
||||
}
|
||||
|
||||
std::vector<int32_t> out_types(num_types);
|
||||
error = Hwc2toHwc3Error(
|
||||
display->GetHdrCapabilities(&num_types, out_types.data(),
|
||||
&caps->maxLuminance,
|
||||
&caps->maxAverageLuminance,
|
||||
&caps->minLuminance));
|
||||
if (error != hwc3::Error::kNone) {
|
||||
return ToBinderStatus(error);
|
||||
}
|
||||
|
||||
caps->types.reserve(num_types);
|
||||
for (const auto type : out_types)
|
||||
caps->types.emplace_back(Hwc2HdrTypeToHwc3(type));
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
|
|
|
|||
11
hwc3/Utils.h
11
hwc3/Utils.h
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/graphics/common/Hdr.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
|
||||
#include <hardware/hwcomposer2.h>
|
||||
#include <log/log.h>
|
||||
|
|
@ -165,4 +166,12 @@ inline int32_t Hwc3DataspaceToHwc2(common::Dataspace dataspace) {
|
|||
return static_cast<int32_t>(dataspace);
|
||||
}
|
||||
|
||||
}; // namespace aidl::android::hardware::graphics::composer3
|
||||
// Values appear to match.
|
||||
// https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/graphics/common/aidl/android/hardware/graphics/common/Hdr.aidl
|
||||
// https://cs.android.com/android/platform/superproject/main/+/main:system/core/libsystem/include/system/graphics-base-v1.0.h;l=130;drc=7d940ae4afa450696afa25e07982f3a95e17e9b2
|
||||
// https://cs.android.com/android/platform/superproject/main/+/main:system/core/libsystem/include/system/graphics-base-v1.2.h;l=12;drc=af7be7616859f8e9e57710b9c37c66cf880a6643
|
||||
inline common::Hdr Hwc2HdrTypeToHwc3(int32_t hdr_type) {
|
||||
return static_cast<common::Hdr>(hdr_type);
|
||||
}
|
||||
|
||||
}; // namespace aidl::android::hardware::graphics::composer3
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define LOG_TAG "drmhwc"
|
||||
|
||||
#if HAS_LIBDISPLAY_INFO
|
||||
extern "C" {
|
||||
#include <libdisplay-info/info.h>
|
||||
|
|
@ -26,8 +24,8 @@ extern "C" {
|
|||
|
||||
#include <ui/GraphicTypes.h>
|
||||
|
||||
#include "compositor/DisplayInfo.h"
|
||||
#include "drm/DrmUnique.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
@ -47,6 +45,9 @@ class EdidWrapper {
|
|||
const float * /*min_luminance*/) {
|
||||
GetSupportedHdrTypes(types);
|
||||
};
|
||||
virtual void GetColorModes(std::vector<Colormode> &color_modes) {
|
||||
color_modes.clear();
|
||||
};
|
||||
};
|
||||
|
||||
#if HAS_LIBDISPLAY_INFO
|
||||
|
|
@ -67,6 +68,8 @@ class LibdisplayEdidWrapper final : public EdidWrapper {
|
|||
const float *max_average_luminance,
|
||||
const float *min_luminance) override;
|
||||
|
||||
void GetColorModes(std::vector<Colormode> &color_modes) override;
|
||||
|
||||
private:
|
||||
LibdisplayEdidWrapper(di_info *info) : info_(std::move(info)) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#define LOG_TAG "drmhwc"
|
||||
|
||||
#if HAS_LIBDISPLAY_INFO
|
||||
|
||||
#include "utils/EdidWrapper.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
|
|
@ -63,5 +64,36 @@ void LibdisplayEdidWrapper::GetHdrCapabilities(
|
|||
min_luminance = &hdr_static_meta->desired_content_min_luminance;
|
||||
}
|
||||
|
||||
void LibdisplayEdidWrapper::GetColorModes(std::vector<Colormode> &color_modes) {
|
||||
color_modes.clear();
|
||||
color_modes.emplace_back(Colormode::kNative);
|
||||
|
||||
const auto *hdr_static_meta = di_info_get_hdr_static_metadata(info_);
|
||||
const auto *colorimetries = di_info_get_supported_signal_colorimetry(info_);
|
||||
|
||||
/* Rec. ITU-R BT.2020 constant luminance YCbCr */
|
||||
/* Rec. ITU-R BT.2020 non-constant luminance YCbCr */
|
||||
if (colorimetries->bt2020_cycc || colorimetries->bt2020_ycc)
|
||||
color_modes.emplace_back(Colormode::kBt2020);
|
||||
|
||||
/* Rec. ITU-R BT.2020 RGB */
|
||||
if (colorimetries->bt2020_rgb)
|
||||
color_modes.emplace_back(Colormode::kDisplayBt2020);
|
||||
|
||||
/* SMPTE ST 2113 RGB: P3D65 and P3DCI */
|
||||
if (colorimetries->st2113_rgb) {
|
||||
color_modes.emplace_back(Colormode::kDciP3);
|
||||
color_modes.emplace_back(Colormode::kDisplayP3);
|
||||
}
|
||||
|
||||
/* Rec. ITU-R BT.2100 ICtCp HDR (with PQ and/or HLG) */
|
||||
if (colorimetries->ictcp) {
|
||||
if (hdr_static_meta->pq)
|
||||
color_modes.emplace_back(Colormode::kBt2100Pq);
|
||||
if (hdr_static_meta->hlg)
|
||||
color_modes.emplace_back(Colormode::kBt2100Hlg);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue