HYL_OK3568_LINUX/buildroot/package/gstreamer1/gst1-plugins-bad/0038-kmssink-Improve-monitor-and-plane-selection.patch
2025-05-10 21:49:39 +08:00

143 lines
3.8 KiB
Diff

From f0fb72e564a241e07150cb17ac57bbe7e82b783d Mon Sep 17 00:00:00 2001
From: Jeffy Chen <jeffy.chen@rock-chips.com>
Date: Thu, 15 Sep 2022 17:56:40 +0800
Subject: [PATCH 38/41] 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 <jeffy.chen@rock-chips.com>
---
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 0db743c..3bb55e6 100644
--- a/sys/kms/gstkmssink.c
+++ b/sys/kms/gstkmssink.c
@@ -515,13 +515,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++) {
@@ -536,11 +561,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;
}
@@ -651,6 +691,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)
{
@@ -669,6 +728,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]);
@@ -1215,7 +1278,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