hc
2023-02-14 0cc9b7c44253c93447ddf73e206fbdbb3d9f16b1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
From 2153ebe11725de26614aff3b5512a185ba87a19c 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 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 <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 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