1From 851f652c8600b53d17da699080d315d10be053ec Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Thu, 15 Sep 2022 18:01:12 +0800
4Subject: [PATCH 39/41] kmssink: Support scaling in modesetting
5
6Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
7---
8 sys/kms/gstkmssink.c | 52 +++++++++++++++++++++++++++++---------------
9 1 file changed, 34 insertions(+), 18 deletions(-)
10
11diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c
12index 3bb55e6..4538459 100644
13--- a/sys/kms/gstkmssink.c
14+++ b/sys/kms/gstkmssink.c
15@@ -539,11 +539,12 @@ drm_plane_get_type (int fd, drmModePlane * plane)
16 }
17
18 static drmModePlane *
19-find_plane_for_crtc (int fd, drmModeRes * res, drmModePlaneRes * pres,
20+find_plane_for_crtc (GstKMSSink * self, drmModeRes * res, drmModePlaneRes * pres,
21     int crtc_id)
22 {
23   drmModePlane *plane;
24   int i, pipe, plane_type, num_primary, fallback;
25+  int fd = self->fd;
26
27   num_primary = 0;
28   fallback = 0;
29@@ -565,7 +566,8 @@ find_plane_for_crtc (int fd, drmModeRes * res, drmModePlaneRes * pres,
30     num_primary += plane_type == DRM_PLANE_TYPE_PRIMARY;
31
32     /* Check unused possible planes */
33-    if (plane->possible_crtcs & (1 << pipe) && !plane->fb_id) {
34+    if (plane->possible_crtcs & (1 << pipe) &&
35+        (!plane->fb_id || self->modesetting_enabled)) {
36       if (pipe == num_primary - 1 && plane_type == DRM_PLANE_TYPE_PRIMARY) {
37         /* Prefer the Nth primary plane */
38         return plane;
39@@ -830,12 +832,6 @@ configure_mode_setting (GstKMSSink * self, GstVideoInfo * vinfo)
40
41   GST_INFO_OBJECT (self, "configuring mode setting");
42
43-  ensure_kms_allocator (self);
44-  kmsmem = (GstKMSMemory *) gst_kms_allocator_bo_alloc (self->allocator, vinfo);
45-  if (!kmsmem)
46-    goto bo_failed;
47-  fb_id = kmsmem->fb_id;
48-
49   conn = drmModeGetConnector (self->fd, self->conn_id);
50   if (!conn)
51     goto connector_failed;
52@@ -847,9 +843,25 @@ configure_mode_setting (GstKMSSink * self, GstVideoInfo * vinfo)
53       break;
54     }
55   }
56+
57+  /* Fallback to the last mode (using scale) */
58+  if (!mode && self->can_scale && conn->count_modes) {
59+    mode = &conn->modes[conn->count_modes - 1];
60+
61+    /* Hack this temp video info */
62+    gst_video_info_set_format (vinfo, GST_VIDEO_INFO_FORMAT (vinfo),
63+        mode->hdisplay, mode->vdisplay);
64+  }
65+
66   if (!mode)
67     goto mode_failed;
68
69+  ensure_kms_allocator (self);
70+  kmsmem = (GstKMSMemory *) gst_kms_allocator_bo_alloc (self->allocator, vinfo);
71+  if (!kmsmem)
72+    goto bo_failed;
73+  fb_id = kmsmem->fb_id;
74+
75   err = drmModeSetCrtc (self->fd, self->crtc_id, fb_id, 0, 0,
76       (uint32_t *) & self->conn_id, 1, mode);
77   if (err)
78@@ -1025,7 +1037,7 @@ ensure_allowed_caps (GstKMSSink * self, drmModeConnector * conn,
79
80       format = gst_video_format_to_string (fmt);
81
82-      if (mode) {
83+      if (mode && !self->can_scale) {
84         caps = gst_caps_new_simple ("video/x-raw",
85             "format", G_TYPE_STRING, format,
86             "width", G_TYPE_INT, mode->hdisplay,
87@@ -1344,7 +1356,7 @@ retry_find_plane:
88     goto plane_resources_failed;
89
90   if (self->plane_id == -1)
91-    plane = find_plane_for_crtc (self->fd, res, pres, crtc->crtc_id);
92+    plane = find_plane_for_crtc (self, res, pres, crtc->crtc_id);
93   else
94     plane = drmModeGetPlane (self->fd, self->plane_id);
95   if (!plane)
96@@ -1900,7 +1912,7 @@ gst_kms_sink_sync (GstKMSSink * self)
97   } else if (self->sync_mode == GST_KMS_SYNC_VBLANK) {
98     pageflip = FALSE;
99   } else if (self->sync_mode == GST_KMS_SYNC_AUTO) {
100-    pageflip = self->modesetting_enabled;
101+    pageflip = self->modesetting_enabled && self->buffer_id;
102   } else {
103     return TRUE;
104   }
105@@ -2227,15 +2239,19 @@ gst_kms_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
106
107   GST_OBJECT_LOCK (self);
108   if (self->modesetting_enabled) {
109-    self->buffer_id = fb_id;
110+    if (video_width == self->hdisplay && video_height == self->vdisplay) {
111+      self->buffer_id = fb_id;
112
113-    if (!self->render_rect.w || !self->render_rect.h)
114-      goto sync_frame;
115+      if (!self->render_rect.w || !self->render_rect.h)
116+        goto sync_frame;
117
118-    if (!self->render_rect.x && !self->render_rect.y &&
119-        self->render_rect.w == self->hdisplay &&
120-        self->render_rect.h == self->vdisplay)
121-      goto sync_frame;
122+      if (!self->render_rect.x && !self->render_rect.y &&
123+          self->render_rect.w == self->hdisplay &&
124+          self->render_rect.h == self->vdisplay)
125+        goto sync_frame;
126+    } else {
127+      self->buffer_id = 0;
128+    }
129   }
130
131   if ((crop = gst_buffer_get_video_crop_meta (buffer))) {
132--
1332.20.1
134
135