From 2153ebe11725de26614aff3b5512a185ba87a19c Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Thu, 15 Sep 2022 17:56:40 +0800 Subject: [PATCH 37/39] kmssink: Improve monitor and plane selection Major changes: 1/ Filter out disconnected monitors. 2/ Filter out inused planes. 3/ Prefer Nth primary plane for Nth CRTC. 4/ Fallback to the first usable overlay plane. Signed-off-by: Jeffy Chen --- sys/kms/gstkmssink.c | 74 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c index bfca332..78f58e3 100644 --- a/sys/kms/gstkmssink.c +++ b/sys/kms/gstkmssink.c @@ -210,13 +210,38 @@ kms_open (gchar ** driver) return fd; } +static int +drm_plane_get_type (int fd, drmModePlane * plane) +{ + drmModeObjectPropertiesPtr props; + drmModePropertyPtr prop; + int i, type = -1; + + props = drmModeObjectGetProperties (fd, plane->plane_id, + DRM_MODE_OBJECT_PLANE); + if (!props) + return -1; + + for (i = 0; i < props->count_props; i++) { + prop = drmModeGetProperty (fd, props->props[i]); + if (prop && !strcmp (prop->name, "type")) + type = props->prop_values[i]; + drmModeFreeProperty (prop); + } + + drmModeFreeObjectProperties (props); + return type; +} + static drmModePlane * find_plane_for_crtc (int fd, drmModeRes * res, drmModePlaneRes * pres, int crtc_id) { drmModePlane *plane; - int i, pipe; + int i, pipe, plane_type, num_primary, fallback; + num_primary = 0; + fallback = 0; plane = NULL; pipe = -1; for (i = 0; i < res->count_crtcs; i++) { @@ -231,11 +256,26 @@ find_plane_for_crtc (int fd, drmModeRes * res, drmModePlaneRes * pres, for (i = 0; i < pres->count_planes; i++) { plane = drmModeGetPlane (fd, pres->planes[i]); - if (plane->possible_crtcs & (1 << pipe)) - return plane; + plane_type = drm_plane_get_type (fd, plane); + num_primary += plane_type == DRM_PLANE_TYPE_PRIMARY; + + /* Check unused possible planes */ + if (plane->possible_crtcs & (1 << pipe) && !plane->fb_id) { + if (pipe == num_primary - 1 && plane_type == DRM_PLANE_TYPE_PRIMARY) { + /* Prefer the Nth primary plane */ + return plane; + } else if (!fallback && plane_type == DRM_PLANE_TYPE_OVERLAY) { + /* Use first overlay plane as fallback */ + fallback = plane->plane_id; + } + } drmModeFreePlane (plane); } + /* Fallback to the first overlay plane */ + if (fallback) + return drmModeGetPlane (fd, fallback); + return NULL; } @@ -346,6 +386,25 @@ find_first_used_connector (int fd, drmModeRes * res) return NULL; } +static drmModeConnector * +find_first_available_connector (int fd, drmModeRes * res) +{ + int i; + drmModeConnector *conn; + + conn = NULL; + for (i = 0; i < res->count_connectors; i++) { + conn = drmModeGetConnector (fd, res->connectors[i]); + if (conn) { + if (conn->connection == DRM_MODE_CONNECTED) + return conn; + drmModeFreeConnector (conn); + } + } + + return NULL; +} + static drmModeConnector * find_main_monitor (int fd, drmModeRes * res) { @@ -364,6 +423,10 @@ find_main_monitor (int fd, drmModeRes * res) if (!conn) conn = find_first_used_connector (fd, res); + /* if no connector is used, grab the first available one */ + if (!conn) + conn = find_first_available_connector (fd, res); + /* if no connector is used, grab the first one */ if (!conn) conn = drmModeGetConnector (fd, res->connectors[0]); @@ -910,7 +973,12 @@ gst_kms_sink_start (GstBaseSink * bsink) gboolean ret; self = GST_KMS_SINK (bsink); +#if 0 universal_planes = FALSE; +#else + /* Force checking every planes */ + universal_planes = TRUE; +#endif ret = FALSE; res = NULL; conn = NULL; -- 2.20.1