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