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