weston: add hdr priority function [1/1]

PD#SWPL-189220

Problem:
add hdr priority function

Solution:
add hdr priority function

Verify:
s7d

Change-Id: I5ba04228bb6994a6c62e90aa4111d4d6c23974ce
Signed-off-by: leng.fang <leng.fang@amlogic.com>
diff --git a/aml-weston/aml-backend.c b/aml-weston/aml-backend.c
index f0444dc..617d2b3 100644
--- a/aml-weston/aml-backend.c
+++ b/aml-weston/aml-backend.c
@@ -1149,6 +1149,40 @@
 	}
 }
 
+static void drm_get_priority(drm_cmd *info, char **ctx)
+{
+	int priority = 0;
+
+	(void *)ctx;
+#ifdef ENABLE_MODE_POLICY
+	priority = mode_policy_get_priority();
+#endif
+
+	sprintf(info->response, "%d: priority %d", 0, priority);
+}
+
+static int drm_set_priority(drm_cmd *info, char **ctx)
+{
+	int ret = 0;
+	struct drm_head *head = NULL;
+	char *tok;
+
+	tok = strtok_r(0, " ", ctx);
+	if (tok) {
+		int value = atoi(tok);
+
+		head = info->head;
+#ifdef ENABLE_MODE_POLICY
+		mode_policy_set_head(head);
+		ret = mode_policy_set_priority(value);
+#endif
+		if (head && head->base.output)
+			weston_output_damage(head->base.output);
+	}
+
+	return ret;
+}
+
 static char *drm_execute_command(char *cmd)
 {
 	char *tok, *ctx = NULL;
@@ -1180,6 +1214,8 @@
 							bool auto_frm_mode =
 								(info->b && info->b->compositor) ? info->b->compositor->auto_frm_mode : false;
 							sprintf(info->response, "%d: auto-frm-mode %d", 0, auto_frm_mode);
+						} else if (compare_string(tok, "hdr_priority")) {
+							drm_get_priority(info, &ctx);
 						}
 					}
 				} else if (compare_string(tok, "set")) {
@@ -1252,6 +1288,9 @@
 								}
 								free(modestring);
 							}
+						} else if (compare_string(tok, "hdr_priority")) {
+							weston_log("hdr_priority: %s\n", ctx);
+							drm_set_priority(info, &ctx);
 						}
 					}
 				} else {
diff --git a/libweston/modepolicy/ModePolicy.cpp b/libweston/modepolicy/ModePolicy.cpp
index 430ecf6..397f661 100644
--- a/libweston/modepolicy/ModePolicy.cpp
+++ b/libweston/modepolicy/ModePolicy.cpp
@@ -352,12 +352,14 @@
 int32_t ModePolicy::setHdrPriority(int32_t type) {
     MESON_LOGI("setHdrPriority is [%s]\n", meson_hdrPriorityToString(type));
 
+    getConnectorData(&mConData, &mDvInfo);
     meson_mode_set_policy_input(mModeConType, &mConData);
     getDisplayMode(mCurrentMode);
 
     if (!meson_mode_support_mode(mModeConType, type, mCurrentMode)) {
         std::string value = std::to_string(type);
 
+        setBootEnv(UBOOTENV_HDR_PRIORITY, value.c_str());
         setSourceOutputMode(mCurrentMode);
     } else {
         MESON_LOGD("%s mode check failed", __func__);
@@ -370,11 +372,50 @@
 int32_t ModePolicy::getHdrPriority() {
     char hdr_priority[MESON_MODE_LEN] = {0};
     meson_hdr_priority_e value = MESON_DOLBY_VISION_PRIORITY;
+    bool dv_support = isMboxSupportDV();
+    bool hdr_support = isTvSupportHDR();
+    meson_hdr_priority_e act_hdr_priority = dv_support ?
+        MESON_DOLBY_VISION_PRIORITY :
+        (hdr_support ? MESON_HDR10_PRIORITY : MESON_SDR_PRIORITY);
 
     memset(hdr_priority, 0, MESON_MODE_LEN);
     getBootEnv(UBOOTENV_HDR_PRIORITY, hdr_priority);
 
+    if (strlen(hdr_priority) == 0) {
+        return act_hdr_priority;
+    }
+
     value = (meson_hdr_priority_e)atoi(hdr_priority);
+
+    if (value <= MESON_SDR_PRIORITY) {
+        if (!dv_support && value == MESON_DOLBY_VISION_PRIORITY)
+            value = MESON_HDR10_PRIORITY;
+        if (!hdr_support && value == MESON_HDR10_PRIORITY)
+            value = MESON_SDR_PRIORITY;
+        value = (act_hdr_priority > value ? act_hdr_priority : value);
+    } else if (value >= MESON_G_DV_HDR10_HLG) {
+        switch (value) {
+            case MESON_G_DV_HDR10_HLG:
+                value = dv_support ? value : (hdr_support ? MESON_G_HDR10_HLG : MESON_G_SDR);
+                break;
+            case MESON_G_DV_HDR10:
+                value = dv_support ? value : (hdr_support ? MESON_G_HDR10 : MESON_G_SDR);
+                break;
+            case MESON_G_DV_HLG:
+                value = dv_support ? value : (hdr_support ? MESON_G_HLG : MESON_G_SDR);
+                break;
+            case MESON_G_DV:
+                value = dv_support ? value : MESON_G_SDR;
+                break;
+            case MESON_G_HDR10_HLG:
+            case MESON_G_HDR10:
+            case MESON_G_HLG:
+                value = hdr_support ? value : MESON_G_SDR;
+                break;
+            default:
+                break;
+        }
+    }
     if ((value >= MESON_DOLBY_VISION_PRIORITY && value <= MESON_SDR_PRIORITY)
         || (value >= MESON_G_DV_HDR10_HLG && value <= MESON_G_SDR)) {
         MESON_LOGI("%s is [%s]", __FUNCTION__, meson_hdrPriorityToString(value));
@@ -3334,3 +3375,16 @@
        g_Policy->seamlessSwitchEnabled(enable);
 }
 
+int setPriority(int priority)
+{
+    if (g_Policy.get())
+        return g_Policy->setHdrPriority(priority);
+    return -1;
+}
+
+int getPriority()
+{
+    if (g_Policy.get())
+        return g_Policy->getHdrPriority();
+    return 0;
+}
diff --git a/libweston/modepolicy/ModePolicy.h b/libweston/modepolicy/ModePolicy.h
index 8cc64e5..1df354f 100644
--- a/libweston/modepolicy/ModePolicy.h
+++ b/libweston/modepolicy/ModePolicy.h
@@ -354,6 +354,8 @@
         int32_t width, int32_t height, uint32_t refresh, uint32_t flags);
     void updateDrmfd(int drmFd);
     void seamlessSwitchEnabled(bool enable);
+    int32_t setHdrPriority(int32_t type);
+    int32_t getHdrPriority();
 
     // void dump(String8 &dumpstr) override;
 
@@ -372,8 +374,6 @@
     // HDR functions
     int32_t setHdrStrategy(int32_t policy, const char *type);
     void getHdrStrategy(char* value);
-    int32_t setHdrPriority(int32_t type);
-    int32_t getHdrPriority();
     int32_t getCurrentHdrPriority(void);
     void gethdrforcemode(char* value);
     bool isDVEnable();
diff --git a/libweston/modepolicy/modepolicy_aml.cpp b/libweston/modepolicy/modepolicy_aml.cpp
index fb098b6..357ffdf 100644
--- a/libweston/modepolicy/modepolicy_aml.cpp
+++ b/libweston/modepolicy/modepolicy_aml.cpp
@@ -991,6 +991,82 @@
 	weston_set_state_for_ctx(ctx, flag, true);
 }
 
+static int get_priority_strategy(int prio)
+{
+	return (prio >> 28) & 0xf;
+}
+
+static int switch_strategy1_to_strategy2(int prio)
+{
+	int ret = prio;
+
+	if (get_priority_strategy(prio) == 0) {
+		switch (prio) {
+			case MESON_DOLBY_VISION_PRIORITY:
+				ret = MESON_G_DV_HDR10_HLG;
+				break;
+			case MESON_HDR10_PRIORITY:
+				ret = MESON_G_HDR10_HLG;
+				break;
+			case MESON_SDR_PRIORITY:
+				ret = MESON_G_SDR;
+				break;
+			default:
+				ret = prio;
+				break;
+		}
+	}
+	return ret;
+}
+
+static int switch_strategy2_to_strategy1(int prio)
+{
+	int ret = prio;
+
+	if (get_priority_strategy(prio) == 1) {
+		switch (prio) {
+			case MESON_G_DV_HDR10_HLG:
+			case MESON_G_DV_HDR10:
+			case MESON_G_DV_HLG:
+			case MESON_G_DV:
+				ret = MESON_DOLBY_VISION_PRIORITY;
+				break;
+			case MESON_G_HDR10_HLG:
+			case MESON_G_HDR10:
+			case MESON_G_HLG:
+				ret = MESON_HDR10_PRIORITY;
+				break;
+			case MESON_G_SDR:
+				ret = MESON_SDR_PRIORITY;
+				break;
+			default:
+				ret = prio;
+				break;
+		}
+	}
+	return ret;
+}
+
+int mode_policy_set_priority(int priority)
+{
+	weston_ctx_list * ctx_list = weston_get_ctx_list();
+	weston_ctx *ctx = weston_get_ctx();
+
+	if (!ctx)
+		return NULL;
+
+	initModePolicyFun(ctx->crtc, ctx->conn, callback);
+	updateDrmfd(ctx->drm_fd);
+	seamlessSwitchEnabled(ctx->enableVrr);
+	return setPriority(switch_strategy2_to_strategy1(priority));
+}
+
+int mode_policy_get_priority()
+{
+	int priority = getPriority();
+	return switch_strategy2_to_strategy1(priority);
+}
+
 static void * wstUpdatenvThread(void *arg )
 {
 	long long delay = 16667LL;
diff --git a/libweston/modepolicy/modepolicy_aml.h b/libweston/modepolicy/modepolicy_aml.h
index ee3c792..509e4a2 100644
--- a/libweston/modepolicy/modepolicy_aml.h
+++ b/libweston/modepolicy/modepolicy_aml.h
@@ -83,6 +83,8 @@
 drmModeCrtc *weston_get_crtc_for_conn(int drm_fd, drmModeConnector *conn);
 bool set_policy_by_appName(const char *name, int state);
 bool get_next_mode(struct weston_mode* mode);
+int mode_policy_set_priority(int priority);
+int mode_policy_get_priority();
 
 #ifdef __cplusplus
 }
diff --git a/libweston/modepolicy/modepolicyfunc.h b/libweston/modepolicy/modepolicyfunc.h
index d4749d7..f76a007 100644
--- a/libweston/modepolicy/modepolicyfunc.h
+++ b/libweston/modepolicy/modepolicyfunc.h
@@ -44,6 +44,8 @@
     int32_t width, int32_t height, uint32_t refresh, uint32_t flags);
 void seamlessSwitchEnabled(bool enable);
 void updateDrmfd(int fd);
+int setPriority(int priority);
+int getPriority();
 
 #ifdef __cplusplus
 }