output: lift up output format fallback logic

This makes it possible for the two functions using output_pick_format
(output_pick_cursor_format and output_create_swapchain) to select
different buffer formats.
This commit is contained in:
Manuel Stoeckl 2021-11-10 22:54:04 -05:00 committed by Simon Ser
parent ee210758fc
commit 7508f87fcb
3 changed files with 39 additions and 37 deletions

View File

@ -8,7 +8,7 @@ void output_pending_resolution(struct wlr_output *output, int *width,
int *height);
struct wlr_drm_format *output_pick_format(struct wlr_output *output,
const struct wlr_drm_format_set *display_formats);
const struct wlr_drm_format_set *display_formats, uint32_t format);
void output_clear_back_buffer(struct wlr_output *output);
bool output_ensure_buffer(struct wlr_output *output);

View File

@ -206,7 +206,13 @@ static struct wlr_drm_format *output_pick_cursor_format(struct wlr_output *outpu
}
}
return output_pick_format(output, display_formats);
struct wlr_drm_format *format = output_pick_format(output, display_formats,
DRM_FORMAT_ARGB8888);
if (format == NULL) {
format = output_pick_format(output, display_formats,
DRM_FORMAT_XRGB8888);
}
return format;
}
static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor) {

View File

@ -66,7 +66,12 @@ static bool output_create_swapchain(struct wlr_output *output,
}
}
struct wlr_drm_format *format = output_pick_format(output, display_formats);
struct wlr_drm_format *format = output_pick_format(output, display_formats,
DRM_FORMAT_ARGB8888);
if (format == NULL) {
format = output_pick_format(output, display_formats,
DRM_FORMAT_XRGB8888);
}
if (format == NULL) {
wlr_log(WLR_ERROR, "Failed to pick primary buffer format for output '%s'",
output->name);
@ -231,7 +236,8 @@ void wlr_output_lock_attach_render(struct wlr_output *output, bool lock) {
}
struct wlr_drm_format *output_pick_format(struct wlr_output *output,
const struct wlr_drm_format_set *display_formats) {
const struct wlr_drm_format_set *display_formats,
uint32_t fmt) {
struct wlr_renderer *renderer = output->renderer;
struct wlr_allocator *allocator = output->allocator;
assert(renderer != NULL && allocator != NULL);
@ -243,41 +249,31 @@ struct wlr_drm_format *output_pick_format(struct wlr_output *output,
return NULL;
}
struct wlr_drm_format *format = NULL;
const uint32_t candidates[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 };
for (size_t i = 0; i < sizeof(candidates) / sizeof(candidates[0]); i++) {
uint32_t fmt = candidates[i];
const struct wlr_drm_format *render_format =
wlr_drm_format_set_get(render_formats, fmt);
if (render_format == NULL) {
wlr_log(WLR_DEBUG, "Renderer doesn't support format 0x%"PRIX32, fmt);
continue;
}
if (display_formats != NULL) {
const struct wlr_drm_format *display_format =
wlr_drm_format_set_get(display_formats, fmt);
if (display_format == NULL) {
wlr_log(WLR_DEBUG, "Output doesn't support format 0x%"PRIX32, fmt);
continue;
}
format = wlr_drm_format_intersect(display_format, render_format);
} else {
// The output can display any format
format = wlr_drm_format_dup(render_format);
}
if (format == NULL) {
wlr_log(WLR_DEBUG, "Failed to intersect display and render "
"modifiers for format 0x%"PRIX32, fmt);
} else {
break;
}
const struct wlr_drm_format *render_format =
wlr_drm_format_set_get(render_formats, fmt);
if (render_format == NULL) {
wlr_log(WLR_DEBUG, "Renderer doesn't support format 0x%"PRIX32, fmt);
return NULL;
}
struct wlr_drm_format *format = NULL;
if (display_formats != NULL) {
const struct wlr_drm_format *display_format =
wlr_drm_format_set_get(display_formats, fmt);
if (display_format == NULL) {
wlr_log(WLR_DEBUG, "Output doesn't support format 0x%"PRIX32, fmt);
return NULL;
}
format = wlr_drm_format_intersect(display_format, render_format);
} else {
// The output can display any format
format = wlr_drm_format_dup(render_format);
}
if (format == NULL) {
wlr_log(WLR_ERROR, "Failed to choose a format for output '%s'",
output->name);
wlr_log(WLR_DEBUG, "Failed to intersect display and render "
"modifiers for format 0x%"PRIX32 " on output '%s",
fmt, output->name);
return NULL;
}