drm_hwcomposer: Add getter/setter for Colorspace
Optionally, get the Colorspace drm property and populate an enum mapping
for the property types. Add implementation to HwcDisplay::SetColorMode
to set this property and map between HAL_COLOR_MODE types to Colorspace
formats.
Change-Id: Id532e94207c1b1a2623b7d77db239735df18b30f
Signed-off-by: Sasha McIntosh <sashamcintosh@google.com>
diff --git a/compositor/ColorInfo.h b/compositor/ColorInfo.h
new file mode 100644
index 0000000..1afda07
--- /dev/null
+++ b/compositor/ColorInfo.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 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
+
+#include <cstdint>
+
+enum class Colorspace : int32_t {
+ kDefault,
+ kSmpte170MYcc,
+ kBt709Ycc,
+ kXvycc601,
+ kXvycc709,
+ kSycc601,
+ kOpycc601,
+ kOprgb,
+ kBt2020Cycc,
+ kBt2020Rgb,
+ kBt2020Ycc,
+ kDciP3RgbD65,
+ kDciP3RgbTheater,
+ kRgbWideFixed,
+ kRgbWideFloat,
+ kBt601Ycc,
+};
diff --git a/drm/DrmAtomicStateManager.cpp b/drm/DrmAtomicStateManager.cpp
index 32cc68e..bb26189 100644
--- a/drm/DrmAtomicStateManager.cpp
+++ b/drm/DrmAtomicStateManager.cpp
@@ -139,6 +139,12 @@
return -EINVAL;
}
+ if (args.colorspace && connector->GetColorspaceProperty()) {
+ if (!connector->GetColorspaceProperty()
+ .AtomicSet(*pset, connector->GetColorspacePropertyValue(*args.colorspace)))
+ return -EINVAL;
+ }
+
if (args.content_type && connector->GetContentTypeProperty()) {
if (!connector->GetContentTypeProperty().AtomicSet(*pset, *args.content_type))
return -EINVAL;
diff --git a/drm/DrmAtomicStateManager.h b/drm/DrmAtomicStateManager.h
index d1af6e0..c8736f2 100644
--- a/drm/DrmAtomicStateManager.h
+++ b/drm/DrmAtomicStateManager.h
@@ -21,6 +21,7 @@
#include <memory>
#include <optional>
+#include "compositor/ColorInfo.h"
#include "compositor/DrmKmsPlan.h"
#include "compositor/LayerData.h"
#include "drm/DrmPlane.h"
@@ -36,6 +37,7 @@
std::optional<bool> active;
std::shared_ptr<DrmKmsPlan> composition;
std::shared_ptr<drm_color_ctm> color_matrix;
+ std::optional<Colorspace> colorspace;
std::optional<int32_t> content_type;
std::shared_ptr<DrmFbIdHandle> writeback_fb;
diff --git a/drm/DrmConnector.cpp b/drm/DrmConnector.cpp
index 4ae8bef..8b92407 100644
--- a/drm/DrmConnector.cpp
+++ b/drm/DrmConnector.cpp
@@ -96,6 +96,42 @@
return false;
}
+ if (GetConnectorProperty("Colorspace", &colorspace_property_,
+ /*is_optional=*/true)) {
+ colorspace_property_.AddEnumToMap("Default", Colorspace::kDefault,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("SMPTE_170M_YCC", Colorspace::kSmpte170MYcc,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("BT709_YCC", Colorspace::kBt709Ycc,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("XVYCC_601", Colorspace::kXvycc601,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("XVYCC_709", Colorspace::kXvycc709,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("SYCC_601", Colorspace::kSycc601,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("opYCC_601", Colorspace::kOpycc601,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("opRGB", Colorspace::kOprgb,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("BT2020_CYCC", Colorspace::kBt2020Cycc,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("BT2020_RGB", Colorspace::kBt2020Rgb,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("BT2020_YCC", Colorspace::kBt2020Ycc,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("DCI-P3_RGB_D65", Colorspace::kDciP3RgbD65,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("DCI-P3_RGB_Theater", Colorspace::kDciP3RgbTheater,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("RGB_WIDE_FIXED", Colorspace::kRgbWideFixed,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("RGB_WIDE_FLOAT", Colorspace::kRgbWideFloat,
+ colorspace_enum_map_);
+ colorspace_property_.AddEnumToMap("BT601_YCC", Colorspace::kBt601Ycc,
+ colorspace_enum_map_);
+ }
+
GetConnectorProperty("content type", &content_type_property_,
/*is_optional=*/true);
diff --git a/drm/DrmConnector.h b/drm/DrmConnector.h
index 6140e6c..8063fd8 100644
--- a/drm/DrmConnector.h
+++ b/drm/DrmConnector.h
@@ -27,6 +27,8 @@
#include "DrmProperty.h"
#include "DrmUnique.h"
+#include "compositor/ColorInfo.h"
+
namespace android {
class DrmDevice;
@@ -94,6 +96,14 @@
return edid_property_;
}
+ auto &GetColorspaceProperty() const {
+ return colorspace_property_;
+ }
+
+ auto GetColorspacePropertyValue(Colorspace c) {
+ return colorspace_enum_map_[c];
+ }
+
auto &GetContentTypeProperty() const {
return content_type_property_;
}
@@ -138,10 +148,13 @@
DrmProperty dpms_property_;
DrmProperty crtc_id_property_;
DrmProperty edid_property_;
+ DrmProperty colorspace_property_;
DrmProperty content_type_property_;
DrmProperty writeback_pixel_formats_;
DrmProperty writeback_fb_id_;
DrmProperty writeback_out_fence_;
+
+ std::map<Colorspace, uint64_t> colorspace_enum_map_;
};
} // namespace android
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index be3e90d..af3c85e 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -463,6 +463,7 @@
a_args.color_matrix = color_matrix_;
a_args.content_type = content_type_;
+ a_args.colorspace = colorspace_;
uint32_t prev_vperiod_ns = 0;
GetDisplayVsyncPeriod(&prev_vperiod_ns);
@@ -672,11 +673,35 @@
}
HWC2::Error HwcDisplay::SetColorMode(int32_t mode) {
- if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
+ /* 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)
return HWC2::Error::BadParameter;
- if (mode != HAL_COLOR_MODE_NATIVE)
- return HWC2::Error::Unsupported;
+ switch (mode) {
+ case HAL_COLOR_MODE_NATIVE:
+ 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:
+ // 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:
+ colorspace_ = Colorspace::kBt709Ycc;
+ break;
+ case HAL_COLOR_MODE_DCI_P3:
+ case HAL_COLOR_MODE_DISPLAY_P3:
+ colorspace_ = Colorspace::kDciP3RgbD65;
+ break;
+ case HAL_COLOR_MODE_ADOBE_RGB:
+ default:
+ return HWC2::Error::Unsupported;
+ }
color_mode_ = mode;
return HWC2::Error::None;
@@ -1018,16 +1043,12 @@
intent > HAL_RENDER_INTENT_TONE_MAP_ENHANCE)
return HWC2::Error::BadParameter;
- if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
- return HWC2::Error::BadParameter;
-
- if (mode != HAL_COLOR_MODE_NATIVE)
- return HWC2::Error::Unsupported;
-
if (intent != HAL_RENDER_INTENT_COLORIMETRIC)
return HWC2::Error::Unsupported;
- color_mode_ = mode;
+ auto err = SetColorMode(mode);
+ if (err != HWC2::Error::None) return err;
+
return HWC2::Error::None;
}
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index be97623..7f2d400 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -23,6 +23,7 @@
#include <sstream>
#include "HwcDisplayConfigs.h"
+#include "compositor/ColorInfo.h"
#include "compositor/FlatteningController.h"
#include "compositor/LayerData.h"
#include "drm/DrmAtomicStateManager.h"
@@ -234,6 +235,7 @@
std::shared_ptr<drm_color_ctm> color_matrix_;
android_color_transform_t color_transform_hint_{};
int32_t content_type_{};
+ Colorspace colorspace_{};
std::shared_ptr<DrmKmsPlan> current_plan_;