backend-drm: add support for blend mode plane property

This is used in the next commits.

Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This commit is contained in:
Leandro Ribeiro 2026-04-15 12:27:50 -03:00 committed by Marius Vlad
parent 21126325a8
commit 339c8eef1f
4 changed files with 88 additions and 0 deletions

View file

@ -461,6 +461,8 @@ struct drm_plane_state {
uint64_t zpos;
uint16_t alpha;
enum wdrm_plane_blend blend_mode;
enum wdrm_plane_color_encoding color_encoding;
enum wdrm_plane_color_range color_range;
@ -1041,6 +1043,10 @@ bool
drm_plane_supports_color_range(struct drm_plane *plane,
enum wdrm_plane_color_range range);
bool
drm_plane_supports_blend_mode(struct drm_plane *plane,
enum wdrm_plane_blend blend_mode);
void
drm_output_render(struct drm_output_state *state);

View file

@ -56,6 +56,7 @@ enum wdrm_plane_property {
WDRM_PLANE_ZPOS,
WDRM_PLANE_ROTATION,
WDRM_PLANE_ALPHA,
WDRM_PLANE_BLEND,
WDRM_PLANE_COLOR_ENCODING,
WDRM_PLANE_COLOR_PIPELINE,
WDRM_PLANE_COLOR_RANGE,
@ -179,6 +180,17 @@ enum wdrm_colorop_lut3d_interpolation {
WDRM_COLOROP_LUT3D_INTERPOLATION__COUNT,
};
/**
* Possible values for the WDRM_PLANE_BLEND property.
*/
enum wdrm_plane_blend {
WDRM_PLANE_BLEND_NONE = 0,
WDRM_PLANE_BLEND_PREMULT,
WDRM_PLANE_BLEND_COVERAGE,
WDRM_PLANE_BLEND__COUNT
};
#define WDRM_PLANE_BLEND_DEFAULT WDRM_PLANE_BLEND_PREMULT
/**
* List of properties attached to a DRM connector
*/

View file

@ -109,6 +109,18 @@ struct drm_property_enum_info plane_color_range_enums[] = {
},
};
struct drm_property_enum_info plane_blend_enums[] = {
[WDRM_PLANE_BLEND_NONE] = {
.name = "None",
},
[WDRM_PLANE_BLEND_PREMULT] = {
.name = "Pre-multiplied",
},
[WDRM_PLANE_BLEND_COVERAGE] = {
.name = "Coverage",
},
};
const struct drm_property_info plane_props[] = {
[WDRM_PLANE_TYPE] = {
.name = "type",
@ -135,6 +147,11 @@ const struct drm_property_info plane_props[] = {
.num_enum_values = WDRM_PLANE_ROTATION__COUNT,
},
[WDRM_PLANE_ALPHA] = { .name = "alpha" },
[WDRM_PLANE_BLEND] = {
.name = "pixel blend mode",
.enum_values = plane_blend_enums,
.num_enum_values = WDRM_PLANE_BLEND__COUNT,
},
[WDRM_PLANE_COLOR_ENCODING] = {
.name = "COLOR_ENCODING",
.enum_values = plane_color_encoding_enums,
@ -815,6 +832,31 @@ drm_plane_supports_color_range(struct drm_plane *plane,
return enum_info->valid;
}
/**
* Check if a blend mode is supported by a KMS plane
*
* If the blend mode property is not supported by the plane, this assumes that
* the blend mode is unsupported if different from WDRM_PLANE_BLEND_DEFAULT.
*
* @param plane The KMS plane
* @param blend_mode The blend mode to check
* @return True if supported, false otherwise
*/
bool
drm_plane_supports_blend_mode(struct drm_plane *plane,
enum wdrm_plane_blend blend_mode)
{
const struct drm_property_info *info = &plane->props[WDRM_PLANE_BLEND];
const struct drm_property_enum_info *enum_info;
if (info->prop_id == 0)
return blend_mode == WDRM_PLANE_BLEND_DEFAULT;
enum_info = &info->enum_values[blend_mode];
return enum_info->valid;
}
/**
* Mark an output state as current on the output, i.e. it has been
* submitted to the kernel. The mode argument determines whether this
@ -1603,6 +1645,28 @@ drm_plane_set_color_range(struct drm_plane *plane,
color_range);
}
static int
drm_plane_set_blend_mode(struct drm_plane *plane,
enum wdrm_plane_blend blend_mode,
drmModeAtomicReq *req)
{
struct weston_compositor *wc = plane->base.compositor;
weston_assert_s32_ge(wc, blend_mode, 0);
weston_assert_s32_lt(wc, blend_mode, WDRM_PLANE_BLEND__COUNT);
if (plane->props[WDRM_PLANE_BLEND].prop_id == 0) {
if (blend_mode == WDRM_PLANE_BLEND_DEFAULT)
return 0;
return -1;
}
weston_assert_true(wc, drm_plane_supports_blend_mode(plane, blend_mode));
return plane_add_prop_enum(req, plane, WDRM_PLANE_BLEND, blend_mode);
}
static bool
colorop_enforce(drmModeAtomicReq *req, const struct drm_colorop *colorop,
char **err_msg)
@ -1952,6 +2016,10 @@ drm_output_apply_state_atomic(struct drm_output_state *state,
WDRM_PLANE_ALPHA,
plane_state->alpha);
ret |= drm_plane_set_blend_mode(plane,
plane_state->blend_mode,
req);
ret |= drm_plane_set_color_encoding(plane,
plane_state->color_encoding,
req);

View file

@ -59,6 +59,8 @@ drm_plane_state_alloc(struct drm_output_state *state_output,
state->alpha = (plane->alpha_max < DRM_PLANE_ALPHA_OPAQUE) ?
plane->alpha_max : DRM_PLANE_ALPHA_OPAQUE;
state->blend_mode = WDRM_PLANE_BLEND_DEFAULT;
state->color_encoding = WDRM_PLANE_COLOR_ENCODING_DEFAULT;
state->color_range = WDRM_PLANE_COLOR_RANGE_DEFAULT;