OSDN Git Service

drm_hwcomposer: Add support for color encoding and range properties
authorMatvii Zorin <matvii.zorin@globallogic.com>
Tue, 8 Sep 2020 13:12:51 +0000 (16:12 +0300)
committerMatvii Zorin <matvii.zorin@globallogic.com>
Sat, 30 Jan 2021 13:50:41 +0000 (15:50 +0200)
Starting from the linux-v4.17, the DRM module has support for different
non-RGB color encodings that are controlled through plane-specific
COLOR_ENCODING and COLOR_RANGE properties.

This patch creates a matching between the HWC layer dataspace which is
supported by DRM driver and DRM plane properties.

Signed-off-by: Matvii Zorin <matvii.zorin@globallogic.com>
DrmHwcTwo.cpp
compositor/DrmDisplayCompositor.cpp
drm/DrmPlane.cpp
drm/DrmPlane.h
include/drmhwcomposer.h

index 93b6fa7..b5b460e 100644 (file)
@@ -1099,6 +1099,7 @@ void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
   layer->alpha = static_cast<uint16_t>(65535.0f * alpha_ + 0.5f);
   layer->SetSourceCrop(source_crop_);
   layer->SetTransform(static_cast<int32_t>(transform_));
+  layer->dataspace = dataspace_;
 }
 
 void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) {
index ba0d56b..3ae42ef 100644 (file)
@@ -342,6 +342,8 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
     uint64_t rotation = 0;
     uint64_t alpha = 0xFFFF;
     uint64_t blend;
+    uint64_t color_encoding = UINT64_MAX;
+    uint64_t color_range = UINT64_MAX;
 
     if (comp_plane.type() != DrmCompositionPlane::Type::kDisable) {
       if (source_layers.size() > 1) {
@@ -427,6 +429,45 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
           break;
         }
       }
+
+      if (plane->color_encoding_propery().id()) {
+        switch (layer.dataspace & HAL_DATASPACE_STANDARD_MASK) {
+          case HAL_DATASPACE_STANDARD_BT709:
+            std::tie(color_encoding,
+                     ret) = plane->color_encoding_propery()
+                                .GetEnumValueWithName("ITU-R BT.709 YCbCr");
+            break;
+          case HAL_DATASPACE_STANDARD_BT601_625:
+          case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
+          case HAL_DATASPACE_STANDARD_BT601_525:
+          case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
+            std::tie(color_encoding,
+                     ret) = plane->color_encoding_propery()
+                                .GetEnumValueWithName("ITU-R BT.601 YCbCr");
+            break;
+          case HAL_DATASPACE_STANDARD_BT2020:
+          case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
+            std::tie(color_encoding,
+                     ret) = plane->color_encoding_propery()
+                                .GetEnumValueWithName("ITU-R BT.2020 YCbCr");
+            break;
+        }
+      }
+
+      if (plane->color_range_property().id()) {
+        switch (layer.dataspace & HAL_DATASPACE_RANGE_MASK) {
+          case HAL_DATASPACE_RANGE_FULL:
+            std::tie(color_range,
+                     ret) = plane->color_range_property()
+                                .GetEnumValueWithName("YCbCr full range");
+            break;
+          case HAL_DATASPACE_RANGE_LIMITED:
+            std::tie(color_range,
+                     ret) = plane->color_range_property()
+                                .GetEnumValueWithName("YCbCr limited range");
+            break;
+        }
+      }
     }
 
     // Disable the plane if there's no framebuffer
@@ -509,6 +550,28 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
         break;
       }
     }
+
+    if (plane->color_encoding_propery().id() && color_encoding != UINT64_MAX) {
+      ret = drmModeAtomicAddProperty(pset, plane->id(),
+                                     plane->color_encoding_propery().id(),
+                                     color_encoding) < 0;
+      if (ret) {
+        ALOGE("Failed to add COLOR_ENCODING property %d to plane %d",
+              plane->color_encoding_propery().id(), plane->id());
+        break;
+      }
+    }
+
+    if (plane->color_range_property().id() && color_range != UINT64_MAX) {
+      ret = drmModeAtomicAddProperty(pset, plane->id(),
+                                     plane->color_range_property().id(),
+                                     color_range) < 0;
+      if (ret) {
+        ALOGE("Failed to add COLOR_RANGE property %d to plane %d",
+              plane->color_range_property().id(), plane->id());
+        break;
+      }
+    }
   }
 
   if (!ret) {
index f994252..65bd8be 100644 (file)
@@ -17,6 +17,7 @@
 #define LOG_TAG "hwc-drm-plane"
 
 #include "DrmPlane.h"
+#include "bufferinfo/BufferInfoGetter.h"
 
 #include <errno.h>
 #include <log/log.h>
@@ -141,6 +142,17 @@ int DrmPlane::Init() {
   if (ret)
     ALOGI("Could not get IN_FENCE_FD property");
 
+  if (HasNonRgbFormat()) {
+    ret = drm_->GetPlaneProperty(*this, "COLOR_ENCODING",
+                                 &color_encoding_propery_);
+    if (ret)
+      ALOGI("Could not get COLOR_ENCODING property");
+
+    ret = drm_->GetPlaneProperty(*this, "COLOR_RANGE", &color_range_property_);
+    if (ret)
+      ALOGI("Could not get COLOR_RANGE property");
+  }
+
   return 0;
 }
 
@@ -161,6 +173,13 @@ bool DrmPlane::IsFormatSupported(uint32_t format) const {
          std::end(formats_);
 }
 
+bool DrmPlane::HasNonRgbFormat() const {
+  return std::find_if_not(std::begin(formats_), std::end(formats_),
+                          [](uint32_t format) {
+                            return BufferInfoGetter::IsDrmFormatRgb(format);
+                          }) != std::end(formats_);
+}
+
 const DrmProperty &DrmPlane::crtc_property() const {
   return crtc_property_;
 }
@@ -220,4 +239,12 @@ const DrmProperty &DrmPlane::blend_property() const {
 const DrmProperty &DrmPlane::in_fence_fd_property() const {
   return in_fence_fd_property_;
 }
+
+const DrmProperty &DrmPlane::color_encoding_propery() const {
+  return color_encoding_propery_;
+}
+
+const DrmProperty &DrmPlane::color_range_property() const {
+  return color_range_property_;
+}
 }  // namespace android
index 16731a8..7a915cc 100644 (file)
@@ -44,6 +44,7 @@ class DrmPlane {
   uint32_t type() const;
 
   bool IsFormatSupported(uint32_t format) const;
+  bool HasNonRgbFormat() const;
 
   const DrmProperty &crtc_property() const;
   const DrmProperty &fb_property() const;
@@ -60,6 +61,8 @@ class DrmPlane {
   const DrmProperty &alpha_property() const;
   const DrmProperty &blend_property() const;
   const DrmProperty &in_fence_fd_property() const;
+  const DrmProperty &color_encoding_propery() const;
+  const DrmProperty &color_range_property() const;
 
  private:
   DrmDevice *drm_;
@@ -86,6 +89,8 @@ class DrmPlane {
   DrmProperty alpha_property_;
   DrmProperty blend_property_;
   DrmProperty in_fence_fd_property_;
+  DrmProperty color_encoding_propery_;
+  DrmProperty color_range_property_;
 };
 }  // namespace android
 
index 0706ae5..1007144 100644 (file)
@@ -136,6 +136,7 @@ struct DrmHwcLayer {
   uint16_t alpha = 0xffff;
   hwc_frect_t source_crop;
   hwc_rect_t display_frame;
+  android_dataspace_t dataspace;
 
   UniqueFd acquire_fence;
   OutputFd release_fence;