mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-26 06:35:58 +01:00
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.
This commit is contained in:
parent
e06ea4e84a
commit
01e0f51fad
1 changed files with 61 additions and 54 deletions
|
@ -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) {
|
||||||
if (!wlr_drm_format_set_has(&plane->formats, format, DRM_FORMAT_MOD_INVALID)) {
|
wlr_log(WLR_ERROR, "Failed to get render formats");
|
||||||
const struct wlr_pixel_format_info *info =
|
return NULL;
|
||||||
drm_get_pixel_format_info(format);
|
|
||||||
if (!info) {
|
|
||||||
wlr_log(WLR_ERROR,
|
|
||||||
"Failed to fallback on DRM opaque substitute for format "
|
|
||||||
"0x%"PRIX32, format);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
format = info->opaque_substitute;
|
|
||||||
|
const struct wlr_drm_format_set *plane_formats = &plane->formats;
|
||||||
|
|
||||||
|
uint32_t fmt = DRM_FORMAT_ARGB8888;
|
||||||
|
if (!wlr_drm_format_set_has(&plane->formats, fmt, DRM_FORMAT_MOD_INVALID)) {
|
||||||
|
const struct wlr_pixel_format_info *format_info =
|
||||||
|
drm_get_pixel_format_info(fmt);
|
||||||
|
assert(format_info != NULL &&
|
||||||
|
format_info->opaque_substitute != DRM_FORMAT_INVALID);
|
||||||
|
fmt = 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);
|
|
||||||
if (render_formats == NULL) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to get render formats");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
if (!with_modifiers) {
|
|
||||||
format_implicit_modifier = wlr_drm_format_create(format);
|
|
||||||
render_format = format_implicit_modifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_drm_format *drm_format =
|
|
||||||
wlr_drm_format_intersect(plane_format, render_format);
|
wlr_drm_format_intersect(plane_format, render_format);
|
||||||
if (drm_format == NULL) {
|
if (format == NULL) {
|
||||||
wlr_log(WLR_ERROR,
|
wlr_log(WLR_DEBUG, "Failed to intersect plane and render "
|
||||||
"Failed to intersect plane and render formats 0x%"PRIX32,
|
"modifiers for format 0x%"PRIX32, fmt);
|
||||||
format);
|
return NULL;
|
||||||
free(format_implicit_modifier);
|
}
|
||||||
|
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool drm_plane_init_surface(struct wlr_drm_plane *plane,
|
||||||
|
struct wlr_drm_backend *drm, int32_t width, uint32_t height,
|
||||||
|
bool with_modifiers) {
|
||||||
|
struct wlr_drm_format *format =
|
||||||
|
drm_plane_pick_render_format(plane, &drm->renderer);
|
||||||
|
if (format == NULL) {
|
||||||
|
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…
Reference in a new issue