weston: add interface with meson display [1/1]
PD#SWPL-155659
Problem:
support interface for meson display to call
Solution:
support interface for meson display to call
Verify:
ah212
Change-Id: Ie86052dee3da6b6da509e99f08dbe361861ab14c
Signed-off-by: leng.fang <leng.fang@amlogic.com>
diff --git a/aml-weston/aml-backend.c b/aml-weston/aml-backend.c
index d7665d8..b07ce19 100644
--- a/aml-weston/aml-backend.c
+++ b/aml-weston/aml-backend.c
@@ -233,10 +233,20 @@
#endif
#ifdef MESON_DRM_FIX_UI_SIZE
- // for scale to full screen
- //// TODO: Need consider different aspect_ration
- scanout_state->dest_w = output->display_size.width;
- scanout_state->dest_h = output->display_size.height;
+ int scaling = mode_policy_get_scaling();
+ if (scaling > 40 && scaling < 100) {
+ int x_margin = output->display_size.width * (100 - scaling) / 100;
+ int y_margin = output->display_size.height * (100 - scaling) / 100;
+ scanout_state->dest_x = x_margin / 2;
+ scanout_state->dest_y = y_margin / 2;
+ scanout_state->dest_w = output->display_size.width - x_margin;
+ scanout_state->dest_h = output->display_size.height - y_margin;
+ } else {
+ // for scale to full screen
+ //// TODO: Need consider different aspect_ration
+ scanout_state->dest_w = output->display_size.width;
+ scanout_state->dest_h = output->display_size.height;
+ }
#endif
}
}
@@ -254,8 +264,8 @@
output->base.current_mode->height = output->display_size.height;
}
//Save the orgin size of next current_mode
- output->display_size.width = drm_mode->base.width;
- output->display_size.height = drm_mode->base.height;
+ output->display_size.width = drm_mode->mode_info.hdisplay;
+ output->display_size.height = drm_mode->mode_info.vdisplay;
//Set the fixed ui size to current_mode
drm_mode->base.width = b->fixed_ui_size.width;
drm_mode->base.height = b->fixed_ui_size.height;
@@ -318,6 +328,17 @@
}
}
+static int drm_set_property(const char *name, int value)
+{
+ int ret = 0;
+
+#ifdef ENABLE_MODE_POLICY
+ ret = mode_policy_set_property(name, value);
+#endif
+
+ return ret;
+}
+
void drm_enable_aml_output_config(struct drm_output* output,
struct weston_output *base, struct drm_backend *b)
{
@@ -348,6 +369,8 @@
if (head->connector.conn->connector_type == DRM_MODE_CONNECTOR_HDMIA)
{
help_set_switch_mode_function((output_ctx)base, drm_output_switch_mode_helper);
+ help_set_force_refresh_function(drm_output_force_refresh);
+ help_set_property_function(drm_set_property);
}
}
#endif
@@ -810,6 +833,12 @@
weston_compositor_damage_all(compositor);
}
+int drm_output_force_refresh(output_ctx ctx)
+{
+ drm_output_refresh_force(((struct weston_output *)ctx)->compositor);
+ return 0;
+}
+
int drm_output_switch_mode_helper(output_ctx ctx, drm_helper_mode* mode)
{
struct weston_mode m;
@@ -826,7 +855,12 @@
m.aspect_ratio = 0;
#ifdef ENABLE_MODE_POLICY
- wst_mode = mode_policy_choose_mode(&m);
+ mode_policy_update_bestmode(mode->auto_mode);
+ if (!mode->auto_mode)
+ wst_mode = &m;
+ else
+ mode_policy_set_hotplug(AML_WESTON_HOTPLUG_SET);
+ wst_mode = mode_policy_choose_mode(wst_mode);
#endif
if (!wst_mode)
wst_mode = &m;
diff --git a/aml-weston/aml-backend.h b/aml-weston/aml-backend.h
index a82c643..83dab6f 100644
--- a/aml-weston/aml-backend.h
+++ b/aml-weston/aml-backend.h
@@ -21,6 +21,7 @@
void weston_print_info(struct weston_compositor* ec, int count);
int drm_output_switch_mode_helper(output_ctx ctx, drm_helper_mode* mode);
+int drm_output_force_refresh(output_ctx ctx);
#endif
void drm_output_render_aml_config(struct drm_output *output, struct drm_plane_state *scanout_state);
diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c
index da739f5..3d777d4 100644
--- a/libweston/backend-drm/kms.c
+++ b/libweston/backend-drm/kms.c
@@ -976,10 +976,6 @@
WDRM_CONNECTOR_CRTC_ID, 0);
}
- wl_list_for_each(head, &output->base.head_list, base.output_link)
- drm_connector_set_hdcp_property(&head->connector,
- state->protection, req);
-
if (ret != 0) {
weston_log("couldn't set atomic CRTC/connector state\n");
return ret;
@@ -1183,7 +1179,10 @@
#endif
#ifdef ENABLE_MODE_POLICY
- ret |= mode_policy_add_prop(req);
+ if (mode != DRM_STATE_TEST_ONLY &&
+ mode_policy_add_prop(req) > 0) {
+ flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
+ }
#endif
ret = drmModeAtomicCommit(b->drm.fd, req, flags, b);
diff --git a/libweston/modepolicy/modepolicy_aml.cpp b/libweston/modepolicy/modepolicy_aml.cpp
index 8258ea3..de11399 100644
--- a/libweston/modepolicy/modepolicy_aml.cpp
+++ b/libweston/modepolicy/modepolicy_aml.cpp
@@ -12,6 +12,7 @@
if (!gCtx) {
gCtx = (weston_ctx *)calloc(1, sizeof(*gCtx));
gCtx->need_update_hdmi_param = false;
+ gCtx->scaling = -1;
wl_list_init(&gCtx->prop_list);
}
return gCtx;
@@ -400,10 +401,8 @@
if (value)
scaling = atoi(value);
- if (ctx && ctx->head && ctx->head->output) {
- if (ctx->head->output->current_scale != scaling)
- ctx->head->output->current_scale = scaling;
- }
+ if (ctx && ctx->scaling != scaling)
+ ctx->scaling = scaling;
}
CompositorFunctionCallBack callback = {
@@ -415,6 +414,118 @@
.set_scaling_position = weston_set_scaling_position,
};
+static char *get_color_space_by_value(int value)
+{
+ char *str;
+
+ switch ( value ) {
+ case 0:
+ str = "rgb";
+ break;
+ case 1:
+ str = "422";
+ break;
+ case 2:
+ str = "444";
+ break;
+ case 3:
+ default:
+ str = "420";
+ break;
+ }
+ return str;
+}
+
+static int get_property_value(char *name)
+{
+ prop_info *info;
+ weston_ctx *ctx = weston_get_ctx();
+
+ wl_list_for_each(info, &ctx->prop_list, link) {
+ if (!strcmp(name, info->name)) {
+ if (info->need_change == 1)
+ return info->value;
+ }
+ }
+ return -1;
+}
+
+static int get_id_by_name(const char *name)
+{
+ prop_info *info;
+ weston_ctx *ctx = weston_get_ctx();
+
+ wl_list_for_each(info, &ctx->prop_list, link) {
+ if (!strcmp(name, info->name))
+ return info->item_id;
+ }
+ return -1;
+}
+
+static int mode_policy_parse_other(const char *name, int value)
+{
+ weston_ctx *ctx = weston_get_ctx();
+ char attrvalue[32] = { 0 };
+
+ if (STRCMPS(name, "scaling") == 0) {
+ if (ctx && ctx->scaling != value)
+ ctx->scaling = value;
+
+ sprintf(attrvalue, "%d", value);
+ bootenv_update("scaling", attrvalue);
+ return 0;
+ }
+ return -1;
+}
+
+int mode_policy_set_property(const char *name, int value)
+{
+ char attrvalue[32] = { 0 };
+ int color_space = 0;
+ int color_depth = 0;
+ int id = get_id_by_name(name);
+ MESON_LOGI("id: %d, name: %s, value: %d", id, name, value);
+
+ if (value < 0 || id < 0)
+ return mode_policy_parse_other(name, value);
+
+ if (strncmp(name, "dv_mode", sizeof("dv_mode")) == 0) {
+ setDvMode(value == 0 ? 1 : (value == 1 ? 2 : 0));
+ return 0;
+ } else if (strncmp(name, "color_depth", sizeof("color_depth")) == 0) {
+ color_space = get_property_value("color_space");
+ if (color_space >= 0) {
+ sprintf(attrvalue, "%s,%dbit", get_color_space_by_value(color_space), value);
+ setColorSpace(attrvalue);
+ mode_policy_update_bestmode(false);
+ return 0;
+ }
+ } else if (strncmp(name, "color_space", sizeof("color_space")) == 0) {
+ color_depth = get_property_value("color_depth");
+ if (color_depth >= 0) {
+ sprintf(attrvalue, "%s,%dbit", get_color_space_by_value(value), color_depth);
+ setColorSpace(attrvalue);
+ mode_policy_update_bestmode(false);
+ return 0;
+ }
+ } else if (strncmp(name, "meson.crtc.hdr_policy", sizeof("meson.crtc.hdr_policy")) == 0) {
+ sprintf(attrvalue, "%d", value);
+ bootenv_update("hdr_policy", attrvalue);
+ }
+
+ return weston_set_property(id, name, value);
+}
+
+int mode_policy_get_scaling()
+{
+ weston_ctx *ctx = weston_get_ctx();
+
+ if (ctx->scaling < 0)
+ return 100;
+
+ return ctx->scaling;
+}
+
static drmModeCrtc *weston_get_crtc_for_conn(int drm_fd, drmModeConnector *conn)
{
drmModeEncoder *encoder;
@@ -470,6 +581,7 @@
weston_ctx *ctx = weston_get_ctx();
prop_info *info;
int err = 0, ret = 0;
+ int count = 0;
wl_list_for_each(info, &ctx->prop_list, link) {
if (info->need_change) {
@@ -479,10 +591,12 @@
info->name, err, errno);
info->need_change = 0;
ret |= (err <= 0) ? -1 : 0;
+ if (!ret)
+ count++;
ctx->need_update_hdmi_param = true;
}
}
- return ret;
+ return ret >= 0 ? count : ret;
}
void mode_policy_set_hotplug(int plug)
@@ -519,7 +633,7 @@
} else {
if (ctx->hotplug & (AML_WESTON_HOTPLUG_PLUG | AML_WESTON_HOTPLUG_UNPLUG))
onHotplug(ctx->hotplug & AML_WESTON_HOTPLUG_PLUG);
- else if (ctx->hotplug & AML_WESTON_HOTPLUG_BOOT)
+ else if (ctx->hotplug & (AML_WESTON_HOTPLUG_BOOT | AML_WESTON_HOTPLUG_SET))
initModePolicy(NULL, NULL, callback);
ctx->hotplug = AML_WESTON_HOTPLUG_INIT;
}
@@ -528,6 +642,11 @@
return NULL;
}
+void mode_policy_update_bestmode(bool bestmode)
+{
+ bootenv_update("is.bestmode", bestmode ? "true" : "false");
+}
+
static void * wstUpdatenvThread(void *arg )
{
long long delay = 16667LL;
diff --git a/libweston/modepolicy/modepolicy_aml.h b/libweston/modepolicy/modepolicy_aml.h
index ea64a64..f2999ff 100644
--- a/libweston/modepolicy/modepolicy_aml.h
+++ b/libweston/modepolicy/modepolicy_aml.h
@@ -29,6 +29,7 @@
struct weston_head *head;
struct weston_mode current_mode;
struct weston_mode next_mode;
+ int scaling;
bool mode_update;
int hotplug; // 0: init 2: hotplug 4: unplug
struct wl_list prop_list;
@@ -38,15 +39,21 @@
AML_WESTON_HOTPLUG_INIT = 0x0,
AML_WESTON_HOTPLUG_BOOT = 0x1,
AML_WESTON_HOTPLUG_PLUG = 0x2,
- AML_WESTON_HOTPLUG_UNPLUG = 0x4
+ AML_WESTON_HOTPLUG_UNPLUG = 0x4,
+ AML_WESTON_HOTPLUG_SET = 0x8
};
+#define STRCMPS(str1, str2) strncmp(str1, str2, sizeof(str2))
+
void init_mode_policy_without_mode(struct weston_head *head, int fd, drmModeConnector *conn);
void weston_start_update_env_thread();
int mode_policy_add_prop(drmModeAtomicReq *req);
void mode_policy_set_hotplug(int plug);
struct weston_mode *mode_policy_choose_mode(struct weston_mode *mode);
+void mode_policy_update_bestmode(bool bestmode);
void mode_policy_update_mode(struct weston_mode *mode);
+int mode_policy_set_property(const char *name, int value);
+int mode_policy_get_scaling();
#ifdef __cplusplus
}