1*4882a593SmuzhiyunFrom 851f652c8600b53d17da699080d315d10be053ec 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 39/41] 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 3bb55e6..4538459 100644 13*4882a593Smuzhiyun--- a/sys/kms/gstkmssink.c 14*4882a593Smuzhiyun+++ b/sys/kms/gstkmssink.c 15*4882a593Smuzhiyun@@ -539,11 +539,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@@ -565,7 +566,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@@ -830,12 +832,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@@ -847,9 +843,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@@ -1025,7 +1037,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@@ -1344,7 +1356,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@@ -1900,7 +1912,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@@ -2227,15 +2239,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