1From 82a36b79c1219793525ee45c76f1a91fc3f6cc0e 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