Skip to content

Commit 55d0db5

Browse files
committed
kms window: fix implicit modifier support
- don't attempt to iterate over modified pixel formats if not supported by the plane - add some documentation to the way we choose the allowed modifiers - fix `supported_modified_formats_blob` documentation in modesetting.h - fix logging for `gbm_surface_create` errors
1 parent be323fc commit 55d0db5

File tree

3 files changed

+82
-54
lines changed

3 files changed

+82
-54
lines changed

src/egl_gbm_render_surface.c

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ static int egl_gbm_render_surface_init(
168168
);
169169
if (gbm_surface == NULL) {
170170
ok = errno;
171-
LOG_ERROR("Couldn't create GBM surface for rendering. gbm_surface_create_with_modifiers: %s\n", strerror(ok));
171+
LOG_ERROR("Couldn't create GBM surface for rendering. gbm_surface_create: %s\n", strerror(ok));
172172
return ok;
173173
}
174174
}
@@ -187,10 +187,10 @@ static int egl_gbm_render_surface_init(
187187
}
188188
}
189189

190-
// EGLAttribKHR is defined by EGL_KHR_cl_event2.
191-
#ifndef EGL_KHR_cl_event2
192-
#error "EGL header definitions for extension EGL_KHR_cl_event2 are required."
193-
#endif
190+
// EGLAttribKHR is defined by EGL_KHR_cl_event2.
191+
#ifndef EGL_KHR_cl_event2
192+
#error "EGL header definitions for extension EGL_KHR_cl_event2 are required."
193+
#endif
194194

195195
static const EGLAttribKHR surface_attribs[] = {
196196
/* EGL_GL_COLORSPACE, GL_LINEAR / GL_SRGB */
@@ -454,26 +454,28 @@ static int egl_gbm_render_surface_present_kms(struct surface *s, const struct fl
454454
TRACER_BEGIN(egl_surface->surface.tracer, "kms_req_builder_push_fb_layer");
455455
ok = kms_req_builder_push_fb_layer(
456456
builder,
457-
&(const struct kms_fb_layer){ .drm_fb_id = fb_id,
458-
.format = pixel_format,
459-
.has_modifier = gbm_bo_get_modifier(bo) != DRM_FORMAT_MOD_INVALID,
460-
.modifier = gbm_bo_get_modifier(bo),
461-
462-
.dst_x = (int32_t) props->aa_rect.offset.x,
463-
.dst_y = (int32_t) props->aa_rect.offset.y,
464-
.dst_w = (uint32_t) props->aa_rect.size.x,
465-
.dst_h = (uint32_t) props->aa_rect.size.y,
466-
467-
.src_x = 0,
468-
.src_y = 0,
469-
.src_w = DOUBLE_TO_FP1616_ROUNDED(egl_surface->render_surface.size.x),
470-
.src_h = DOUBLE_TO_FP1616_ROUNDED(egl_surface->render_surface.size.y),
471-
472-
.has_rotation = false,
473-
.rotation = PLANE_TRANSFORM_ROTATE_0,
474-
475-
.has_in_fence_fd = false,
476-
.in_fence_fd = 0, },
457+
&(const struct kms_fb_layer){
458+
.drm_fb_id = fb_id,
459+
.format = pixel_format,
460+
.has_modifier = gbm_bo_get_modifier(bo) != DRM_FORMAT_MOD_INVALID,
461+
.modifier = gbm_bo_get_modifier(bo),
462+
463+
.dst_x = (int32_t) props->aa_rect.offset.x,
464+
.dst_y = (int32_t) props->aa_rect.offset.y,
465+
.dst_w = (uint32_t) props->aa_rect.size.x,
466+
.dst_h = (uint32_t) props->aa_rect.size.y,
467+
468+
.src_x = 0,
469+
.src_y = 0,
470+
.src_w = DOUBLE_TO_FP1616_ROUNDED(egl_surface->render_surface.size.x),
471+
.src_h = DOUBLE_TO_FP1616_ROUNDED(egl_surface->render_surface.size.y),
472+
473+
.has_rotation = false,
474+
.rotation = PLANE_TRANSFORM_ROTATE_0,
475+
476+
.has_in_fence_fd = false,
477+
.in_fence_fd = 0,
478+
},
477479
on_release_layer,
478480
NULL,
479481
locked_fb_ref(egl_surface->locked_front_fb)

src/modesetting.h

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ struct drm_plane {
410410
uint32_t id;
411411

412412
/// @brief Bitmap of the indexes of the CRTCs that this plane can be scanned out on.
413-
///
413+
///
414414
/// I.e. if bit 0 is set, this plane can be scanned out on the CRTC with index 0.
415415
/// if bit 0 is not set, this plane can not be scanned out on that CRTC.
416416
uint32_t possible_crtcs;
@@ -438,7 +438,7 @@ struct drm_plane {
438438
/// @brief The minimum and maximum possible zpos
439439
///
440440
/// Only valid if @ref has_zpos is true.
441-
///
441+
///
442442
/// If @ref has_hardcoded_zpos is true, min_zpos should equal max_zpos.
443443
int64_t min_zpos, max_zpos;
444444

@@ -494,9 +494,8 @@ struct drm_plane {
494494
///
495495
/// DRM_FORMAT_MOD_LINEAR is supported for most (but not all pixel formats).
496496
/// There are some format & modifier pairs that may be faster to scanout by the GPU.
497-
/// Might be NULL if the plane didn't specify an IN_FORMATS property.
498-
//struct modified_format *supported_modified_formats;
499-
497+
///
498+
/// Is NULL if the plane didn't specify an IN_FORMATS property.
500499
struct drm_format_modifier_blob *supported_modified_formats_blob;
501500

502501
/// @brief Whether this plane has a mutable alpha property we can set.
@@ -527,7 +526,7 @@ struct drm_plane {
527526
uint32_t src_x, src_y, src_w, src_h;
528527

529528
/// @brief The committed destination rect, on the CRTC.
530-
///
529+
///
531530
/// Only valid when using atomic modesetting.
532531
uint32_t crtc_x, crtc_y, crtc_w, crtc_h;
533532

@@ -537,22 +536,22 @@ struct drm_plane {
537536
int64_t zpos;
538537

539538
/// @brief The committed plane rotation.
540-
///
539+
///
541540
/// Only valid if @ref drm_plane.has_rotation is true.
542541
drm_plane_transform_t rotation;
543-
542+
544543
/// @brief The committed alpha property.
545544
///
546545
/// Only valid if @ref drm_plane.has_alpha is true.
547546
uint16_t alpha;
548-
547+
549548
/// @brief The committed blend mode.
550549
///
551550
/// Only valid if @ref drm_plane.has_blend_mode is true.
552551
enum drm_blend_mode blend_mode;
553-
552+
554553
/// @brief If false, we don't know about the committed format.
555-
///
554+
///
556555
/// This can be false on debian buster for example, because we don't
557556
/// have drmModeGetFB2 here, which is required for querying the pixel
558557
/// format of a framebuffer. When a plane is associated with our own
@@ -578,28 +577,30 @@ struct drm_plane {
578577
/**
579578
* @brief Callback that will be called on each iteration of
580579
* @ref drm_plane_foreach_modified_format.
581-
*
580+
*
582581
* Should return true if looping should continue. False if iterating should be
583582
* stopped.
584-
*
583+
*
585584
* @param plane The plane that was passed to @ref drm_plane_foreach_modified_format.
586585
* @param index The index of the pixel format. Is incremented for each call of the callback.
587586
* @param pixel_format The pixel format.
588587
* @param modifier The modifier of this pixel format.
589588
* @param userdata Userdata that was passed to @ref drm_plane_foreach_modified_format.
590589
*/
591-
typedef bool (*drm_plane_modified_format_callback_t)(struct drm_plane *plane, int index, enum pixfmt pixel_format, uint64_t modifier, void *userdata);
590+
typedef bool (*drm_plane_modified_format_callback_t)(
591+
struct drm_plane *plane,
592+
int index,
593+
enum pixfmt pixel_format,
594+
uint64_t modifier,
595+
void *userdata
596+
);
592597

593598
/**
594599
* @brief Iterates over every supported pixel-format & modifier pair.
595-
*
600+
*
596601
* See @ref drm_plane_modified_format_callback_t for documentation on the callback.
597602
*/
598-
void drm_plane_foreach_modified_format(
599-
struct drm_plane *plane,
600-
drm_plane_modified_format_callback_t callback,
601-
void *userdata
602-
);
603+
void drm_plane_foreach_modified_format(struct drm_plane *plane, drm_plane_modified_format_callback_t callback, void *userdata);
603604

604605
struct drmdev;
605606
struct _drmModeModeInfo;

src/window.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
#include "util/collection.h"
2828

2929
#ifdef HAVE_EGL_GLES2
30-
#include "gl_renderer.h"
3130
#include "egl_gbm_render_surface.h"
31+
#include "gl_renderer.h"
3232
#endif
3333

3434
#ifdef HAVE_VULKAN
35-
#include "vk_renderer.h"
3635
#include "vk_gbm_render_surface.h"
36+
#include "vk_renderer.h"
3737
#endif
3838

3939
FILE_DESCR("native windows")
@@ -1273,7 +1273,13 @@ static int kms_window_push_composition(struct window *window, struct fl_layer_co
12731273
return ok;
12741274
}
12751275

1276-
static bool count_modifiers_for_pixel_format(UNUSED struct drm_plane *plane, UNUSED int index, enum pixfmt pixel_format, UNUSED uint64_t modifier, void *userdata) {
1276+
static bool count_modifiers_for_pixel_format(
1277+
UNUSED struct drm_plane *plane,
1278+
UNUSED int index,
1279+
enum pixfmt pixel_format,
1280+
UNUSED uint64_t modifier,
1281+
void *userdata
1282+
) {
12771283
struct {
12781284
enum pixfmt format;
12791285
uint64_t *modifiers;
@@ -1288,7 +1294,13 @@ static bool count_modifiers_for_pixel_format(UNUSED struct drm_plane *plane, UNU
12881294
return true;
12891295
}
12901296

1291-
static bool extract_modifiers_for_pixel_format(UNUSED struct drm_plane *plane, UNUSED int index, enum pixfmt pixel_format, uint64_t modifier, void *userdata) {
1297+
static bool extract_modifiers_for_pixel_format(
1298+
UNUSED struct drm_plane *plane,
1299+
UNUSED int index,
1300+
enum pixfmt pixel_format,
1301+
uint64_t modifier,
1302+
void *userdata
1303+
) {
12921304
struct {
12931305
enum pixfmt format;
12941306
uint64_t *modifiers;
@@ -1330,14 +1342,25 @@ static struct render_surface *kms_window_get_render_surface_internal(struct wind
13301342

13311343
// For now just set the supported modifiers for the first plane that supports this pixel format
13321344
// as the allowed modifiers.
1345+
/// TODO: Find a way to rank pixel formats, maybe by number of planes that support them for scanout.
13331346
{
13341347
struct drm_plane *plane;
13351348
for_each_plane_in_drmdev(window->kms.drmdev, plane) {
13361349
if (!(plane->possible_crtcs & window->kms.crtc->bitmask)) {
1350+
// Only query planes that are possible to connect to the CRTC we're using.
13371351
continue;
13381352
}
13391353

13401354
if (plane->type != kPrimary_DrmPlaneType && plane->type != kOverlay_DrmPlaneType) {
1355+
// We explicitly only look for primary and overlay planes.
1356+
continue;
1357+
}
1358+
1359+
if (plane->supports_modifiers == NULL) {
1360+
// The plane does not have an IN_FORMATS property and does not support
1361+
// explicit modifiers.
1362+
//
1363+
// Calling drm_plane_foreach_modified_format below will segfault.
13411364
continue;
13421365
}
13431366

@@ -1353,12 +1376,14 @@ static struct render_surface *kms_window_get_render_surface_internal(struct wind
13531376
.index = 0,
13541377
};
13551378

1379+
// First, count the allowed modifiers for this pixel format.
13561380
drm_plane_foreach_modified_format(plane, count_modifiers_for_pixel_format, &context);
13571381

13581382
n_allowed_modifiers = context.n_modifiers;
13591383
allowed_modifiers = calloc(n_allowed_modifiers, sizeof(*context.modifiers));
13601384
context.modifiers = allowed_modifiers;
13611385

1386+
// Next, fill context.modifiers with the allowed modifiers.
13621387
drm_plane_foreach_modified_format(plane, extract_modifiers_for_pixel_format, &context);
13631388
break;
13641389
}
@@ -1367,10 +1392,10 @@ static struct render_surface *kms_window_get_render_surface_internal(struct wind
13671392
if (window->renderer_type == kOpenGL_RendererType) {
13681393
// opengl
13691394
#ifdef HAVE_EGL_GLES2
1370-
// EGL_NO_CONFIG_KHR is defined by EGL_KHR_no_config_context.
1371-
#ifndef EGL_KHR_no_config_context
1372-
#error "EGL header definitions for extension EGL_KHR_no_config_context are required."
1373-
#endif
1395+
// EGL_NO_CONFIG_KHR is defined by EGL_KHR_no_config_context.
1396+
#ifndef EGL_KHR_no_config_context
1397+
#error "EGL header definitions for extension EGL_KHR_no_config_context are required."
1398+
#endif
13741399

13751400
struct egl_gbm_render_surface *egl_surface = egl_gbm_render_surface_new_with_egl_config(
13761401
window->tracer,
@@ -1388,7 +1413,7 @@ static struct render_surface *kms_window_get_render_surface_internal(struct wind
13881413
} else {
13891414
render_surface = CAST_RENDER_SURFACE(egl_surface);
13901415
}
1391-
1416+
13921417
#else
13931418
UNREACHABLE();
13941419
#endif

0 commit comments

Comments
 (0)