1From f0fb72e564a241e07150cb17ac57bbe7e82b783d Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Thu, 15 Sep 2022 17:56:40 +0800 4Subject: [PATCH 38/41] kmssink: Improve monitor and plane selection 5 6Major changes: 71/ Filter out disconnected monitors. 82/ Filter out inused planes. 93/ Prefer Nth primary plane for Nth CRTC. 104/ Fallback to the first usable overlay plane. 11 12Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 13--- 14 sys/kms/gstkmssink.c | 74 ++++++++++++++++++++++++++++++++++++++++++-- 15 1 file changed, 71 insertions(+), 3 deletions(-) 16 17diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c 18index 0db743c..3bb55e6 100644 19--- a/sys/kms/gstkmssink.c 20+++ b/sys/kms/gstkmssink.c 21@@ -515,13 +515,38 @@ kms_open (gchar ** driver) 22 return fd; 23 } 24 25+static int 26+drm_plane_get_type (int fd, drmModePlane * plane) 27+{ 28+ drmModeObjectPropertiesPtr props; 29+ drmModePropertyPtr prop; 30+ int i, type = -1; 31+ 32+ props = drmModeObjectGetProperties (fd, plane->plane_id, 33+ DRM_MODE_OBJECT_PLANE); 34+ if (!props) 35+ return -1; 36+ 37+ for (i = 0; i < props->count_props; i++) { 38+ prop = drmModeGetProperty (fd, props->props[i]); 39+ if (prop && !strcmp (prop->name, "type")) 40+ type = props->prop_values[i]; 41+ drmModeFreeProperty (prop); 42+ } 43+ 44+ drmModeFreeObjectProperties (props); 45+ return type; 46+} 47+ 48 static drmModePlane * 49 find_plane_for_crtc (int fd, drmModeRes * res, drmModePlaneRes * pres, 50 int crtc_id) 51 { 52 drmModePlane *plane; 53- int i, pipe; 54+ int i, pipe, plane_type, num_primary, fallback; 55 56+ num_primary = 0; 57+ fallback = 0; 58 plane = NULL; 59 pipe = -1; 60 for (i = 0; i < res->count_crtcs; i++) { 61@@ -536,11 +561,26 @@ find_plane_for_crtc (int fd, drmModeRes * res, drmModePlaneRes * pres, 62 63 for (i = 0; i < pres->count_planes; i++) { 64 plane = drmModeGetPlane (fd, pres->planes[i]); 65- if (plane->possible_crtcs & (1 << pipe)) 66- return plane; 67+ plane_type = drm_plane_get_type (fd, plane); 68+ num_primary += plane_type == DRM_PLANE_TYPE_PRIMARY; 69+ 70+ /* Check unused possible planes */ 71+ if (plane->possible_crtcs & (1 << pipe) && !plane->fb_id) { 72+ if (pipe == num_primary - 1 && plane_type == DRM_PLANE_TYPE_PRIMARY) { 73+ /* Prefer the Nth primary plane */ 74+ return plane; 75+ } else if (!fallback && plane_type == DRM_PLANE_TYPE_OVERLAY) { 76+ /* Use first overlay plane as fallback */ 77+ fallback = plane->plane_id; 78+ } 79+ } 80 drmModeFreePlane (plane); 81 } 82 83+ /* Fallback to the first overlay plane */ 84+ if (fallback) 85+ return drmModeGetPlane (fd, fallback); 86+ 87 return NULL; 88 } 89 90@@ -651,6 +691,25 @@ find_first_used_connector (int fd, drmModeRes * res) 91 return NULL; 92 } 93 94+static drmModeConnector * 95+find_first_available_connector (int fd, drmModeRes * res) 96+{ 97+ int i; 98+ drmModeConnector *conn; 99+ 100+ conn = NULL; 101+ for (i = 0; i < res->count_connectors; i++) { 102+ conn = drmModeGetConnector (fd, res->connectors[i]); 103+ if (conn) { 104+ if (conn->connection == DRM_MODE_CONNECTED) 105+ return conn; 106+ drmModeFreeConnector (conn); 107+ } 108+ } 109+ 110+ return NULL; 111+} 112+ 113 static drmModeConnector * 114 find_main_monitor (int fd, drmModeRes * res) 115 { 116@@ -669,6 +728,10 @@ find_main_monitor (int fd, drmModeRes * res) 117 if (!conn) 118 conn = find_first_used_connector (fd, res); 119 120+ /* if no connector is used, grab the first available one */ 121+ if (!conn) 122+ conn = find_first_available_connector (fd, res); 123+ 124 /* if no connector is used, grab the first one */ 125 if (!conn) 126 conn = drmModeGetConnector (fd, res->connectors[0]); 127@@ -1215,7 +1278,12 @@ gst_kms_sink_start (GstBaseSink * bsink) 128 gboolean ret; 129 130 self = GST_KMS_SINK (bsink); 131+#if 0 132 universal_planes = FALSE; 133+#else 134+ /* Force checking every planes */ 135+ universal_planes = TRUE; 136+#endif 137 ret = FALSE; 138 res = NULL; 139 conn = NULL; 140-- 1412.20.1 142 143