1*4882a593SmuzhiyunFrom 4bee4b39fde94de80077778ad25fc744bdf0aa7a Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com> 3*4882a593SmuzhiyunDate: Wed, 6 Jan 2021 04:11:48 +0800 4*4882a593SmuzhiyunSubject: [PATCH 39/79] backend-drm: Support modifier 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunTested on rk356x with ARM AFBC modifier. 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 9*4882a593Smuzhiyun--- 10*4882a593Smuzhiyun libweston/backend-drm/drm-internal.h | 1 + 11*4882a593Smuzhiyun libweston/backend-drm/drm.c | 84 ++++++++++++++++++++++++---- 12*4882a593Smuzhiyun libweston/backend-drm/kms.c | 6 +- 13*4882a593Smuzhiyun libweston/pixel-formats.c | 2 + 14*4882a593Smuzhiyun 4 files changed, 80 insertions(+), 13 deletions(-) 15*4882a593Smuzhiyun 16*4882a593Smuzhiyundiff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h 17*4882a593Smuzhiyunindex 67e6dd2..161c1ee 100644 18*4882a593Smuzhiyun--- a/libweston/backend-drm/drm-internal.h 19*4882a593Smuzhiyun+++ b/libweston/backend-drm/drm-internal.h 20*4882a593Smuzhiyun@@ -528,6 +528,7 @@ struct drm_plane { 21*4882a593Smuzhiyun struct weston_drm_format_array formats; 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun bool can_scale; 24*4882a593Smuzhiyun+ bool has_modifiers; 25*4882a593Smuzhiyun }; 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun struct drm_connector { 28*4882a593Smuzhiyundiff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c 29*4882a593Smuzhiyunindex 2b887eb..149ac01 100644 30*4882a593Smuzhiyun--- a/libweston/backend-drm/drm.c 31*4882a593Smuzhiyun+++ b/libweston/backend-drm/drm.c 32*4882a593Smuzhiyun@@ -1221,6 +1221,42 @@ err: 33*4882a593Smuzhiyun return NULL; 34*4882a593Smuzhiyun } 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun+static inline bool 37*4882a593Smuzhiyun+drm_plane_has_modifier(struct drm_plane *plane, uint32_t format) 38*4882a593Smuzhiyun+{ 39*4882a593Smuzhiyun+ struct weston_drm_format *fmt; 40*4882a593Smuzhiyun+ const uint64_t *modifiers; 41*4882a593Smuzhiyun+ unsigned int num_modifiers, i; 42*4882a593Smuzhiyun+ 43*4882a593Smuzhiyun+ fmt = weston_drm_format_array_find_format(&plane->formats, format); 44*4882a593Smuzhiyun+ if (!fmt) 45*4882a593Smuzhiyun+ return false; 46*4882a593Smuzhiyun+ 47*4882a593Smuzhiyun+ modifiers = weston_drm_format_get_modifiers(fmt, &num_modifiers); 48*4882a593Smuzhiyun+ for (i = 0; i < num_modifiers; i++) { 49*4882a593Smuzhiyun+ if (DRM_MOD_VALID(modifiers[i])) 50*4882a593Smuzhiyun+ return true; 51*4882a593Smuzhiyun+ } 52*4882a593Smuzhiyun+ 53*4882a593Smuzhiyun+ return false; 54*4882a593Smuzhiyun+} 55*4882a593Smuzhiyun+ 56*4882a593Smuzhiyun+static inline bool 57*4882a593Smuzhiyun+drm_planes_have_modifier(struct drm_backend *b) 58*4882a593Smuzhiyun+{ 59*4882a593Smuzhiyun+ struct drm_plane *plane; 60*4882a593Smuzhiyun+ 61*4882a593Smuzhiyun+ if (!b->fb_modifiers) 62*4882a593Smuzhiyun+ return false; 63*4882a593Smuzhiyun+ 64*4882a593Smuzhiyun+ wl_list_for_each_reverse(plane, &b->plane_list, link) { 65*4882a593Smuzhiyun+ if (plane->has_modifiers) 66*4882a593Smuzhiyun+ return true; 67*4882a593Smuzhiyun+ } 68*4882a593Smuzhiyun+ 69*4882a593Smuzhiyun+ return false; 70*4882a593Smuzhiyun+} 71*4882a593Smuzhiyun+ 72*4882a593Smuzhiyun /** 73*4882a593Smuzhiyun * Find, or create, a special-purpose plane 74*4882a593Smuzhiyun * 75*4882a593Smuzhiyun@@ -1233,8 +1269,11 @@ drm_output_find_special_plane(struct drm_backend *b, struct drm_output *output, 76*4882a593Smuzhiyun enum wdrm_plane_type type) 77*4882a593Smuzhiyun { 78*4882a593Smuzhiyun struct drm_plane *plane; 79*4882a593Smuzhiyun+ bool prefer_modifier = 80*4882a593Smuzhiyun+ b->fb_modifiers && type == WDRM_PLANE_TYPE_PRIMARY; 81*4882a593Smuzhiyun int num_primary; 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun+retry: 84*4882a593Smuzhiyun num_primary = 0; 85*4882a593Smuzhiyun wl_list_for_each_reverse(plane, &b->plane_list, link) { 86*4882a593Smuzhiyun struct drm_output *tmp; 87*4882a593Smuzhiyun@@ -1254,7 +1293,7 @@ drm_output_find_special_plane(struct drm_backend *b, struct drm_output *output, 88*4882a593Smuzhiyun num_primary - 1 != output->crtc->pipe) 89*4882a593Smuzhiyun continue; 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun- if (!plane->plane_id || plane->type != type) 92*4882a593Smuzhiyun+ if (!plane->plane_id) 93*4882a593Smuzhiyun continue; 94*4882a593Smuzhiyun if (!drm_plane_is_available(plane, output)) 95*4882a593Smuzhiyun continue; 96*4882a593Smuzhiyun@@ -1273,10 +1312,22 @@ drm_output_find_special_plane(struct drm_backend *b, struct drm_output *output, 97*4882a593Smuzhiyun if (found_elsewhere) 98*4882a593Smuzhiyun continue; 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun+ if (prefer_modifier && 101*4882a593Smuzhiyun+ !drm_plane_has_modifier(plane, output->gbm_format)) 102*4882a593Smuzhiyun+ continue; 103*4882a593Smuzhiyun+ 104*4882a593Smuzhiyun+ if (plane->type != type) 105*4882a593Smuzhiyun+ continue; 106*4882a593Smuzhiyun+ 107*4882a593Smuzhiyun plane->possible_crtcs = (1 << output->crtc->pipe); 108*4882a593Smuzhiyun return plane; 109*4882a593Smuzhiyun } 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun+ if (prefer_modifier) { 112*4882a593Smuzhiyun+ prefer_modifier = false; 113*4882a593Smuzhiyun+ goto retry; 114*4882a593Smuzhiyun+ } 115*4882a593Smuzhiyun+ 116*4882a593Smuzhiyun return NULL; 117*4882a593Smuzhiyun } 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun@@ -4127,9 +4178,6 @@ drm_backend_create(struct weston_compositor *compositor, 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun compositor->backend = &b->base; 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun- if (parse_gbm_format(config->gbm_format, DRM_FORMAT_XRGB8888, &b->gbm_format) < 0) 124*4882a593Smuzhiyun- goto err_compositor; 125*4882a593Smuzhiyun- 126*4882a593Smuzhiyun /* Check if we run drm-backend using weston-launch */ 127*4882a593Smuzhiyun compositor->launcher = weston_launcher_connect(compositor, config->tty, 128*4882a593Smuzhiyun seat_id, true); 129*4882a593Smuzhiyun@@ -4163,15 +4211,30 @@ drm_backend_create(struct weston_compositor *compositor, 130*4882a593Smuzhiyun goto err_udev_dev; 131*4882a593Smuzhiyun } 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun+ wl_list_init(&b->plane_list); 134*4882a593Smuzhiyun+ create_sprites(b); 135*4882a593Smuzhiyun+ 136*4882a593Smuzhiyun+ if (!drm_planes_have_modifier(b)) 137*4882a593Smuzhiyun+ b->fb_modifiers = false; 138*4882a593Smuzhiyun+ 139*4882a593Smuzhiyun+ b->gbm_format = DRM_FORMAT_XRGB8888; 140*4882a593Smuzhiyun+ 141*4882a593Smuzhiyun+ /* HACK: The modifiers only work with xbgr8888 now */ 142*4882a593Smuzhiyun+ if (b->fb_modifiers) 143*4882a593Smuzhiyun+ b->gbm_format = DRM_FORMAT_XBGR8888; 144*4882a593Smuzhiyun+ 145*4882a593Smuzhiyun+ if (parse_gbm_format(config->gbm_format, b->gbm_format, &b->gbm_format) < 0) 146*4882a593Smuzhiyun+ goto err_sprite; 147*4882a593Smuzhiyun+ 148*4882a593Smuzhiyun if (b->use_pixman) { 149*4882a593Smuzhiyun if (init_pixman(b) < 0) { 150*4882a593Smuzhiyun weston_log("failed to initialize pixman renderer\n"); 151*4882a593Smuzhiyun- goto err_udev_dev; 152*4882a593Smuzhiyun+ goto err_sprite; 153*4882a593Smuzhiyun } 154*4882a593Smuzhiyun } else { 155*4882a593Smuzhiyun if (init_egl(b) < 0) { 156*4882a593Smuzhiyun weston_log("failed to initialize egl\n"); 157*4882a593Smuzhiyun- goto err_udev_dev; 158*4882a593Smuzhiyun+ goto err_sprite; 159*4882a593Smuzhiyun } 160*4882a593Smuzhiyun } 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun@@ -4188,7 +4251,7 @@ drm_backend_create(struct weston_compositor *compositor, 163*4882a593Smuzhiyun res = drmModeGetResources(b->drm.fd); 164*4882a593Smuzhiyun if (!res) { 165*4882a593Smuzhiyun weston_log("Failed to get drmModeRes\n"); 166*4882a593Smuzhiyun- goto err_udev_dev; 167*4882a593Smuzhiyun+ goto err_sprite; 168*4882a593Smuzhiyun } 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun wl_list_init(&b->crtc_list); 171*4882a593Smuzhiyun@@ -4197,9 +4260,6 @@ drm_backend_create(struct weston_compositor *compositor, 172*4882a593Smuzhiyun goto err_create_crtc_list; 173*4882a593Smuzhiyun } 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun- wl_list_init(&b->plane_list); 176*4882a593Smuzhiyun- create_sprites(b); 177*4882a593Smuzhiyun- 178*4882a593Smuzhiyun if (udev_input_init(&b->input, 179*4882a593Smuzhiyun compositor, b->udev, seat_id, 180*4882a593Smuzhiyun config->configure_device) < 0) { 181*4882a593Smuzhiyun@@ -4333,10 +4393,10 @@ err_drm_source: 182*4882a593Smuzhiyun wl_event_source_remove(b->drm_source); 183*4882a593Smuzhiyun err_udev_input: 184*4882a593Smuzhiyun udev_input_destroy(&b->input); 185*4882a593Smuzhiyun-err_sprite: 186*4882a593Smuzhiyun- destroy_sprites(b); 187*4882a593Smuzhiyun err_create_crtc_list: 188*4882a593Smuzhiyun drmModeFreeResources(res); 189*4882a593Smuzhiyun+err_sprite: 190*4882a593Smuzhiyun+ destroy_sprites(b); 191*4882a593Smuzhiyun err_udev_dev: 192*4882a593Smuzhiyun udev_device_unref(drm_device); 193*4882a593Smuzhiyun err_udev: 194*4882a593Smuzhiyundiff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c 195*4882a593Smuzhiyunindex 4443741..6596d9e 100644 196*4882a593Smuzhiyun--- a/libweston/backend-drm/kms.c 197*4882a593Smuzhiyun+++ b/libweston/backend-drm/kms.c 198*4882a593Smuzhiyun@@ -38,6 +38,7 @@ 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun #include <libweston/libweston.h> 201*4882a593Smuzhiyun #include <libweston/backend-drm.h> 202*4882a593Smuzhiyun+#include <libweston/linux-dmabuf.h> 203*4882a593Smuzhiyun #include "shared/helpers.h" 204*4882a593Smuzhiyun #include "shared/weston-drm-fourcc.h" 205*4882a593Smuzhiyun #include "drm-internal.h" 206*4882a593Smuzhiyun@@ -525,6 +526,9 @@ drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane, 207*4882a593Smuzhiyun ret = weston_drm_format_add_modifier(fmt, mod->modifier); 208*4882a593Smuzhiyun if (ret < 0) 209*4882a593Smuzhiyun goto out; 210*4882a593Smuzhiyun+ 211*4882a593Smuzhiyun+ if (DRM_MOD_VALID(mod->modifier)) 212*4882a593Smuzhiyun+ plane->has_modifiers = true; 213*4882a593Smuzhiyun } 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun if (fmt->modifiers.size == 0) 216*4882a593Smuzhiyun@@ -1583,7 +1587,7 @@ init_kms_caps(struct drm_backend *b) 217*4882a593Smuzhiyun weston_log("DRM: %s atomic modesetting\n", 218*4882a593Smuzhiyun b->atomic_modeset ? "supports" : "does not support"); 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun- if (!getenv("WESTON_DISABLE_GBM_MODIFIERS")) { 221*4882a593Smuzhiyun+ if (getenv("WESTON_ALLOW_GBM_MODIFIERS")) { 222*4882a593Smuzhiyun ret = drmGetCap(b->drm.fd, DRM_CAP_ADDFB2_MODIFIERS, &cap); 223*4882a593Smuzhiyun if (ret == 0) 224*4882a593Smuzhiyun b->fb_modifiers = cap; 225*4882a593Smuzhiyundiff --git a/libweston/pixel-formats.c b/libweston/pixel-formats.c 226*4882a593Smuzhiyunindex 172e6cc..85fae20 100644 227*4882a593Smuzhiyun--- a/libweston/pixel-formats.c 228*4882a593Smuzhiyun+++ b/libweston/pixel-formats.c 229*4882a593Smuzhiyun@@ -220,6 +220,8 @@ static const struct pixel_format_info pixel_format_table[] = { 230*4882a593Smuzhiyun { 231*4882a593Smuzhiyun DRM_FORMAT(XBGR8888), 232*4882a593Smuzhiyun BITS_RGBA_FIXED(8, 8, 8, 0), 233*4882a593Smuzhiyun+ .depth = 24, 234*4882a593Smuzhiyun+ .bpp = 32, 235*4882a593Smuzhiyun GL_FORMAT(GL_RGBA), 236*4882a593Smuzhiyun GL_TYPE(GL_UNSIGNED_BYTE), 237*4882a593Smuzhiyun #if __BYTE_ORDER == __LITTLE_ENDIAN 238*4882a593Smuzhiyun-- 239*4882a593Smuzhiyun2.20.1 240*4882a593Smuzhiyun 241