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