From 30030c3779a3f6a54c79abe1392862a2e82d1c1d Mon Sep 17 00:00:00 2001
From: hmz007 <hmz007@gmail.com>
Date: Thu, 5 May 2022 15:21:48 +0800
Subject: [PATCH] rockchip: drmhwc: Fix issue of set HDMI overscan [tbc]

- Add DrmConnector::unique_name()
- Porting CheckOverscan() of drmhwc2
- Get overscan value from persist.vendor.overscan.<unique_name()>
- introduce DrmConnector::update_overscan()
- Set overscan only when display changed

Signed-off-by: hmz007 <hmz007@gmail.com>
---
 .../rockchip/hwcomposer/drmhwc/Android.mk     |   7 ++
 .../hwcomposer/drmhwc/drmconnector.cpp        |  52 ++++++++-
 .../rockchip/hwcomposer/drmhwc/drmconnector.h |   5 +
 .../drmhwc/drmdisplaycompositor.cpp           | 110 +++++++++---------
 .../hwcomposer/drmhwc/drmdisplaycompositor.h  |   4 +
 .../hwcomposer/drmhwc/drmresources.cpp        |   4 +
 6 files changed, 125 insertions(+), 57 deletions(-)

diff --git a/hardware/rockchip/hwcomposer/drmhwc/Android.mk b/hardware/rockchip/hwcomposer/drmhwc/Android.mk
index 72f342694ac..857aac919c5 100755
--- a/hardware/rockchip/hwcomposer/drmhwc/Android.mk
+++ b/hardware/rockchip/hwcomposer/drmhwc/Android.mk
@@ -520,7 +520,14 @@ LOCAL_CPPFLAGS += -DUSE_DRM_GENERIC_IMPORTER \
 	       -DRK_RGA_SCALE_AND_ROTATE=$(RK_RGA_SCALE_AND_ROTATE) \
                -DRGA_VER=$(RGA_VER) -DRK_PER_MODE=$(RK_PER_MODE) -DRK_ROTATE_VIDEO_MODE=$(RK_ROTATE_VIDEO_MODE) \
                -DRK_CTS_WORKROUND=$(RK_CTS_WORKROUND)
+
+LOCAL_HAVE_GIT = $(shell test -d $(LOCAL_PATH)/.git && echo true)
+ifeq ($(LOCAL_HAVE_GIT),true)
 MAJOR_VERSION := "RK_GRAPHICS_VER=commit-id:$(shell cd $(LOCAL_PATH) && git log  -1 --oneline | awk '{print $$1}')"
+else
+MAJOR_VERSION := "RK_GRAPHICS_VER=commit-id:63fcb48"
+endif
+
 LOCAL_CPPFLAGS += -DRK_GRAPHICS_VER=\"$(MAJOR_VERSION)\"
 endif
 
diff --git a/hardware/rockchip/hwcomposer/drmhwc/drmconnector.cpp b/hardware/rockchip/hwcomposer/drmhwc/drmconnector.cpp
index a7f1bc113fa..9ee1d62fba5 100755
--- a/hardware/rockchip/hwcomposer/drmhwc/drmconnector.cpp
+++ b/hardware/rockchip/hwcomposer/drmhwc/drmconnector.cpp
@@ -127,6 +127,13 @@ int DrmConnector::Init() {
    ALOGW("Could not get hdmi_output_depth property\n");
   }
 
+  ret = drm_->GetConnectorProperty(*this, "CONNECTOR_ID", &connector_id_property_);
+  if (ret) {
+    ALOGW("Could not get CONNECTOR_ID property\n");
+  }
+
+  snprintf(unique_name_, 30, "%s-%d", drm_->connector_type_str(type_), connector_id());
+
   bSupportSt2084_ = drm_->is_hdr_panel_support_st2084(this);
   bSupportHLG_    = drm_->is_hdr_panel_support_HLG(this);
 
@@ -146,6 +153,12 @@ uint32_t DrmConnector::type_id() const {
   return type_id_;
 }
 
+uint32_t DrmConnector::connector_id() const {
+  uint64_t id = 0;
+  connector_id_property_.value(&id);
+  return (uint32_t) id;
+}
+
 int DrmConnector::priority() const{
   return priority_;
 }
@@ -170,7 +183,7 @@ bool DrmConnector::built_in() const {
          type_ == DRM_MODE_CONNECTOR_DSI ||
          type_ == DRM_MODE_CONNECTOR_VIRTUAL ||
          type_ == DRM_MODE_CONNECTOR_TV ||
-	 type_ == DRM_MODE_CONNECTOR_DPI;
+         type_ == DRM_MODE_CONNECTOR_DPI;
 }
 
 const DrmMode &DrmConnector::best_mode() const {
@@ -291,6 +304,43 @@ void DrmConnector::set_current_mode(const DrmMode &mode) {
   current_mode_ = mode;
 }
 
+static inline void check_margin(int &margin) {
+  if (margin < 80)
+    margin = 80;
+  else if (margin > 100)
+    margin = 100;
+}
+
+void DrmConnector::update_overscan(drmModeAtomicReqPtr pset, DrmCrtc *crtc) {
+  std::string prop = "persist.vendor.overscan.";
+  prop += unique_name();
+
+  char overscan[PROPERTY_VALUE_MAX] = {0};
+  int ret = property_get(prop.c_str(), overscan, "");
+  if (!ret)
+    return;
+
+  int left, right, top, bottom;
+  ret = sscanf(overscan, "overscan %d,%d,%d,%d", &left, &top, &right, &bottom);
+  if (ret != 4)
+    return;
+
+  check_margin(left);
+  check_margin(right);
+  check_margin(top);
+  check_margin(bottom);
+
+  uint32_t obj_id = crtc->id();
+  ALOGD_IF(log_level(DBG_DEBUG), "crtc-%d: set %s", obj_id, overscan);
+  ret = drmModeAtomicAddProperty(pset, obj_id, crtc->left_margin_property().id(), left) < 0 ||
+        drmModeAtomicAddProperty(pset, obj_id, crtc->right_margin_property().id(), right) < 0 ||
+        drmModeAtomicAddProperty(pset, obj_id, crtc->top_margin_property().id(), top) < 0 ||
+        drmModeAtomicAddProperty(pset, obj_id, crtc->bottom_margin_property().id(), bottom) < 0;
+  if (ret) {
+    ALOGE("Failed to add tv.margins %d,%d,%d,%d, ret = %d", left, right, top, bottom, ret);
+  }
+}
+
 const DrmProperty &DrmConnector::dpms_property() const {
   return dpms_property_;
 }
diff --git a/hardware/rockchip/hwcomposer/drmhwc/drmconnector.h b/hardware/rockchip/hwcomposer/drmhwc/drmconnector.h
index 2e900d45fdb..5521af5d107 100755
--- a/hardware/rockchip/hwcomposer/drmhwc/drmconnector.h
+++ b/hardware/rockchip/hwcomposer/drmhwc/drmconnector.h
@@ -61,6 +61,8 @@ class DrmConnector {
 
   uint32_t id() const;
   uint32_t type_id() const;
+  uint32_t connector_id() const;
+  const char* unique_name() const { return unique_name_; }
 
   int display() const;
   void set_display(int display);
@@ -84,6 +86,7 @@ class DrmConnector {
   void set_best_mode(const DrmMode &mode);
   void set_active_mode(const DrmMode &mode);
   void set_current_mode(const DrmMode &mode);
+  void update_overscan(drmModeAtomicReqPtr pset, DrmCrtc *crtc);
   void SetDpmsMode(uint32_t dpms_mode);
 
   const DrmProperty &dpms_property() const;
@@ -128,6 +131,7 @@ class DrmConnector {
 
   uint32_t id_;
   uint32_t type_id_;
+  char unique_name_[30] = {0};
   DrmEncoder *encoder_;
   int display_;
 
@@ -156,6 +160,7 @@ class DrmConnector {
   DrmProperty hdmi_output_colorimetry_;
   DrmProperty hdmi_output_format_;
   DrmProperty hdmi_output_depth_;
+  DrmProperty connector_id_property_;
 
   std::vector<DrmEncoder *> possible_encoders_;
   uint32_t possible_displays_;
diff --git a/hardware/rockchip/hwcomposer/drmhwc/drmdisplaycompositor.cpp b/hardware/rockchip/hwcomposer/drmhwc/drmdisplaycompositor.cpp
index b09377bfbc0..dc306df3b4d 100755
--- a/hardware/rockchip/hwcomposer/drmhwc/drmdisplaycompositor.cpp
+++ b/hardware/rockchip/hwcomposer/drmhwc/drmdisplaycompositor.cpp
@@ -410,6 +410,7 @@ int DrmDisplayCompositor::Init(DrmResources *drm, int display) {
 
   pthread_cond_init(&composite_queue_cond_, NULL);
 
+  forceOverscan_ = property_get_bool("vendor.hwc.force_overscan", false);
 
   vop_bw_fd_ = open(VOP_BW_PATH, O_WRONLY);
   if(vop_bw_fd_ < 0)
@@ -1069,6 +1070,48 @@ static const char *RotatingToString(uint64_t rotating) {
   }
 }
 
+int DrmDisplayCompositor::CheckOverscan(drmModeAtomicReqPtr pset, DrmCrtc *crtc, int display,
+    bool reset, const char *UniqueName)
+{
+  int ret = 0;
+  int left_margin = 100, right_margin= 100, top_margin = 100, bottom_margin = 100;
+
+  if (!reset) {
+    char overscan_value[PROPERTY_VALUE_MAX] = {0};
+    char overscan_pro[PROPERTY_VALUE_MAX] = {0};
+    snprintf(overscan_pro, PROPERTY_VALUE_MAX, "persist.vendor.overscan.%s", UniqueName);
+    ret = property_get(overscan_pro, overscan_value, "");
+    if (!ret) {
+      return 0;
+    }
+
+    sscanf(overscan_value, "overscan %d,%d,%d,%d", &left_margin, &top_margin,
+          &right_margin, &bottom_margin);
+    ALOGD_IF(log_level(DBG_VERBOSE), "display=%d, %s", display, overscan_value);
+
+    if (left_margin   < OVERSCAN_MIN_VALUE) left_margin   = OVERSCAN_MIN_VALUE;
+    if (top_margin    < OVERSCAN_MIN_VALUE) top_margin    = OVERSCAN_MIN_VALUE;
+    if (right_margin  < OVERSCAN_MIN_VALUE) right_margin  = OVERSCAN_MIN_VALUE;
+    if (bottom_margin < OVERSCAN_MIN_VALUE) bottom_margin = OVERSCAN_MIN_VALUE;
+
+    if (left_margin   > OVERSCAN_MAX_VALUE) left_margin   = OVERSCAN_MAX_VALUE;
+    if (top_margin    > OVERSCAN_MAX_VALUE) top_margin    = OVERSCAN_MAX_VALUE;
+    if (right_margin  > OVERSCAN_MAX_VALUE) right_margin  = OVERSCAN_MAX_VALUE;
+    if (bottom_margin > OVERSCAN_MAX_VALUE) bottom_margin = OVERSCAN_MAX_VALUE;
+  }
+
+  uint32_t crtc_id = crtc->id();
+  ret = drmModeAtomicAddProperty(pset, crtc_id, crtc->left_margin_property().id(), left_margin) < 0 ||
+        drmModeAtomicAddProperty(pset, crtc_id, crtc->right_margin_property().id(), right_margin) < 0 ||
+        drmModeAtomicAddProperty(pset, crtc_id, crtc->top_margin_property().id(), top_margin) < 0 ||
+        drmModeAtomicAddProperty(pset, crtc_id, crtc->bottom_margin_property().id(), bottom_margin) < 0;
+  if (ret) {
+    ALOGE("Failed to add overscan to pset");
+  }
+
+  return ret;
+}
+
 int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
                                       bool test_only) {
   ATRACE_CALL();
@@ -1094,67 +1137,22 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
     return -ENOMEM;
   }
 
-  if (crtc->can_overscan()) {
-    char overscan[PROPERTY_VALUE_MAX];
-    int left_margin = 100, right_margin= 100, top_margin = 100, bottom_margin = 100;
-
+  if (forceOverscan_ && crtc->can_overscan()) {
     DrmConnector *conn = drm_->GetConnectorFromType(display_);
-    if(conn == NULL)
-    {
+    if (!conn) {
       ALOGE("%s: line=%d display %d connector is NULL", __FUNCTION__, __LINE__, display_);
+      drmModeAtomicFree(pset);
       return -ENODEV;
     }
-    DrmMode mode = conn->current_mode();
-    if(display_comp->mode_3d() != NON_3D || (mode.interlaced() > 0))
-    {
-        left_margin = 100;
-        top_margin = 100;
-        right_margin = 100;
-        bottom_margin = 100;
-    }
-    else
-    {
-      if (display_ == HWC_DISPLAY_PRIMARY){
-        if(hwc_have_baseparameter()){
-          property_get("persist." PROPERTY_TYPE ".overscan.main", overscan, "use_baseparameter");
-          if(!strcmp(overscan,"use_baseparameter"))
-            hwc_get_baseparameter_config(overscan,display_,BP_OVERSCAN,0);
-        }else{
-          property_get("persist." PROPERTY_TYPE ".overscan.main", overscan, "overscan 100,100,100,100");
-        }
-      }else{
-        if(hwc_have_baseparameter()){
-          property_get("persist." PROPERTY_TYPE ".overscan.aux", overscan, "use_baseparameter");
-          if(!strcmp(overscan,"use_baseparameter"))
-            hwc_get_baseparameter_config(overscan,display_,BP_OVERSCAN,0);
-        }else{
-          property_get("persist." PROPERTY_TYPE ".overscan.aux", overscan, "overscan 100,100,100,100");
-        }
-      }
-      sscanf(overscan, "overscan %d,%d,%d,%d", &left_margin, &top_margin,
-               &right_margin, &bottom_margin);
-      ALOGD_IF(log_level(DBG_VERBOSE),"vop post scale overscan(%d,%d,%d,%d)",
-                left_margin,top_margin,right_margin,bottom_margin);
-    }
 
-    if (left_margin   < OVERSCAN_MIN_VALUE) left_margin   = OVERSCAN_MIN_VALUE;
-    if (top_margin    < OVERSCAN_MIN_VALUE) top_margin    = OVERSCAN_MIN_VALUE;
-    if (right_margin  < OVERSCAN_MIN_VALUE) right_margin  = OVERSCAN_MIN_VALUE;
-    if (bottom_margin < OVERSCAN_MIN_VALUE) bottom_margin = OVERSCAN_MIN_VALUE;
-
-    if (left_margin   > OVERSCAN_MAX_VALUE) left_margin   = OVERSCAN_MAX_VALUE;
-    if (top_margin    > OVERSCAN_MAX_VALUE) top_margin    = OVERSCAN_MAX_VALUE;
-    if (right_margin  > OVERSCAN_MAX_VALUE) right_margin  = OVERSCAN_MAX_VALUE;
-    if (bottom_margin > OVERSCAN_MAX_VALUE) bottom_margin = OVERSCAN_MAX_VALUE;
-
-    ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->left_margin_property().id(), left_margin) < 0 ||
-          drmModeAtomicAddProperty(pset, crtc->id(), crtc->right_margin_property().id(), right_margin) < 0 ||
-          drmModeAtomicAddProperty(pset, crtc->id(), crtc->top_margin_property().id(), top_margin) < 0 ||
-          drmModeAtomicAddProperty(pset, crtc->id(), crtc->bottom_margin_property().id(), bottom_margin) < 0;
-    if (ret) {
-      ALOGE("Failed to add overscan to pset");
-      drmModeAtomicFree(pset);
-      return ret;
+    if (!conn->built_in()) {
+      DrmMode mode = conn->current_mode();
+      bool reset = display_comp->mode_3d() != NON_3D || (mode.interlaced() > 0);
+      int ret = CheckOverscan(pset, crtc, display_, reset, conn->unique_name());
+      if (ret) {
+        drmModeAtomicFree(pset);
+        return ret;
+      }
     }
   }
 
diff --git a/hardware/rockchip/hwcomposer/drmhwc/drmdisplaycompositor.h b/hardware/rockchip/hwcomposer/drmhwc/drmdisplaycompositor.h
index 70373284aa2..cea7f99bc83 100755
--- a/hardware/rockchip/hwcomposer/drmhwc/drmdisplaycompositor.h
+++ b/hardware/rockchip/hwcomposer/drmhwc/drmdisplaycompositor.h
@@ -185,6 +185,8 @@ class DrmDisplayCompositor {
   void freeRgaBuffers();
 #endif
   int PrepareFrame(DrmDisplayComposition *display_comp);
+  int CheckOverscan(drmModeAtomicReqPtr pset, DrmCrtc *crtc, int display,
+                    bool reset, const char *UniqueName);
   int CommitFrame(DrmDisplayComposition *display_comp, bool test_only);
   int SquashFrame(DrmDisplayComposition *src, DrmDisplayComposition *dst);
   int ApplyDpms(DrmDisplayComposition *display_comp);
@@ -196,6 +198,7 @@ class DrmDisplayCompositor {
 
   std::tuple<int, uint32_t> CreateModeBlob(const DrmMode &mode);
 
+  std::map<uint32_t, std::string> overscan_;
   DrmResources *drm_;
   int display_;
 
@@ -216,6 +219,7 @@ class DrmDisplayCompositor {
    *  clearDisplay_ to notify FrameWorker to clear compositions.
    */
   bool clearDisplay_;
+  bool forceOverscan_;
 
   mutable pthread_mutex_t mode_lock_;
   ModeState mode_;
diff --git a/hardware/rockchip/hwcomposer/drmhwc/drmresources.cpp b/hardware/rockchip/hwcomposer/drmhwc/drmresources.cpp
index b9db2af3ee7..90ceb323e32 100755
--- a/hardware/rockchip/hwcomposer/drmhwc/drmresources.cpp
+++ b/hardware/rockchip/hwcomposer/drmhwc/drmresources.cpp
@@ -1003,7 +1003,11 @@ int DrmResources::UpdateDisplayRoute(void)
     DRM_ATOMIC_ADD_PROP(conn->id(), conn->crtc_id_property().id(), crtc->id());
     DRM_ATOMIC_ADD_PROP(crtc->id(), crtc->mode_property().id(), blob_id[i]);
     DRM_ATOMIC_ADD_PROP(crtc->id(), crtc->active_property().id(), 1);
+
+    if (!conn->built_in() && crtc->can_overscan())
+      conn->update_overscan(pset, crtc);
   }
+
   /*
    * Disable unused connector
    */