backend/drm: introduce drm_plane_pick_render_format

This is a new helper function to pick a render format suitable for
a plane.

The next commit will use it to initialize the cursor multi-GPU
surface.
master
Simon Ser 4 years ago
parent e06ea4e84a
commit 01e0f51fad

@ -191,88 +191,95 @@ static struct wlr_drm_format *create_linear_format(uint32_t format) {
return fmt; return fmt;
} }
bool drm_plane_init_surface(struct wlr_drm_plane *plane, static struct wlr_drm_format *drm_plane_pick_render_format(
struct wlr_drm_backend *drm, int32_t width, uint32_t height, struct wlr_drm_plane *plane, struct wlr_drm_renderer *renderer) {
bool with_modifiers) { const struct wlr_drm_format_set *render_formats =
uint32_t format = DRM_FORMAT_ARGB8888; wlr_renderer_get_render_formats(renderer->wlr_rend);
if (render_formats == NULL) {
wlr_log(WLR_ERROR, "Failed to get render formats");
return NULL;
}
if (!wlr_drm_format_set_has(&plane->formats, format, DRM_FORMAT_MOD_INVALID)) { const struct wlr_drm_format_set *plane_formats = &plane->formats;
const struct wlr_pixel_format_info *info =
drm_get_pixel_format_info(format); uint32_t fmt = DRM_FORMAT_ARGB8888;
if (!info) { if (!wlr_drm_format_set_has(&plane->formats, fmt, DRM_FORMAT_MOD_INVALID)) {
wlr_log(WLR_ERROR, const struct wlr_pixel_format_info *format_info =
"Failed to fallback on DRM opaque substitute for format " drm_get_pixel_format_info(fmt);
"0x%"PRIX32, format); assert(format_info != NULL &&
return false; format_info->opaque_substitute != DRM_FORMAT_INVALID);
fmt = format_info->opaque_substitute;
} }
format = info->opaque_substitute;
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;
} }
const struct wlr_drm_format *plane_format = const struct wlr_drm_format *plane_format =
wlr_drm_format_set_get(&plane->formats, format); wlr_drm_format_set_get(plane_formats, fmt);
if (plane_format == NULL) { if (plane_format == NULL) {
wlr_log(WLR_ERROR, "Plane %"PRIu32" doesn't support format 0x%"PRIX32, wlr_log(WLR_DEBUG, "Plane %"PRIu32" doesn't support format 0x%"PRIX32,
plane->id, format); plane->id, fmt);
return false; return NULL;
} }
const struct wlr_drm_format_set *render_formats = struct wlr_drm_format *format =
wlr_renderer_get_render_formats(drm->renderer.wlr_rend); wlr_drm_format_intersect(plane_format, render_format);
if (render_formats == NULL) { if (format == NULL) {
wlr_log(WLR_ERROR, "Failed to get render formats"); wlr_log(WLR_DEBUG, "Failed to intersect plane and render "
return false; "modifiers for format 0x%"PRIX32, fmt);
} return NULL;
const struct wlr_drm_format *render_format =
wlr_drm_format_set_get(render_formats, format);
if (render_format == NULL) {
wlr_log(WLR_ERROR, "Renderer doesn't support format 0x%"PRIX32,
format);
return false;
} }
struct wlr_drm_format *format_implicit_modifier = NULL; return format;
if (!with_modifiers) {
format_implicit_modifier = wlr_drm_format_create(format);
render_format = format_implicit_modifier;
} }
struct wlr_drm_format *drm_format = bool drm_plane_init_surface(struct wlr_drm_plane *plane,
wlr_drm_format_intersect(plane_format, render_format); struct wlr_drm_backend *drm, int32_t width, uint32_t height,
if (drm_format == NULL) { bool with_modifiers) {
wlr_log(WLR_ERROR, struct wlr_drm_format *format =
"Failed to intersect plane and render formats 0x%"PRIX32, drm_plane_pick_render_format(plane, &drm->renderer);
format); if (format == NULL) {
free(format_implicit_modifier); wlr_log(WLR_ERROR, "Failed to pick render format for plane %"PRIu32,
plane->id);
return false; return false;
} }
if (!with_modifiers) {
struct wlr_drm_format *format_implicit_modifier =
wlr_drm_format_create(format->format);
free(format);
format = format_implicit_modifier;
}
drm_plane_finish_surface(plane); drm_plane_finish_surface(plane);
bool ok = true; bool ok = true;
if (!drm->parent) { if (!drm->parent) {
ok = init_drm_surface(&plane->surf, &drm->renderer, ok = init_drm_surface(&plane->surf, &drm->renderer,
width, height, drm_format); width, height, format);
} else { } else {
struct wlr_drm_format *drm_format_linear = create_linear_format(format); struct wlr_drm_format *format_linear = create_linear_format(format->format);
if (drm_format_linear == NULL) { if (format_linear == NULL) {
free(drm_format); free(format);
free(format_implicit_modifier);
return false; return false;
} }
ok = init_drm_surface(&plane->surf, &drm->parent->renderer, ok = init_drm_surface(&plane->surf, &drm->parent->renderer,
width, height, drm_format_linear); width, height, format_linear);
free(drm_format_linear); free(format_linear);
if (ok && !init_drm_surface(&plane->mgpu_surf, &drm->renderer, if (ok && !init_drm_surface(&plane->mgpu_surf, &drm->renderer,
width, height, drm_format)) { width, height, format)) {
finish_drm_surface(&plane->surf); finish_drm_surface(&plane->surf);
ok = false; ok = false;
} }
} }
free(drm_format); free(format);
free(format_implicit_modifier);
return ok; return ok;
} }

Loading…
Cancel
Save