diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index daa8ba9bf..856c82380 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -474,6 +474,11 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_backend *drm, atomic_add(atom, id, props->crtc_y, dst_box->y); atomic_add(atom, id, props->crtc_w, dst_box->width); atomic_add(atom, id, props->crtc_h, dst_box->height); + if (props->pixel_blend_mode != 0) { + enum wlr_drm_pixel_blend_mode blend_mode = fb->has_alpha ? + WLR_DRM_BLEND_PREMULTI : WLR_DRM_BLEND_PIXEL_NONE; + atomic_add(atom, id, props->pixel_blend_mode, blend_mode); + } } static void set_color_encoding_and_range(struct atomic *atom, diff --git a/backend/drm/fb.c b/backend/drm/fb.c index 575f32d91..4549136d2 100644 --- a/backend/drm/fb.c +++ b/backend/drm/fb.c @@ -196,6 +196,7 @@ static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm, fb->backend = drm; fb->wlr_buf = buf; + fb->has_alpha = pixel_format_has_alpha(attribs.format); wlr_addon_init(&fb->addon, &buf->addons, drm, &fb_addon_impl); wl_list_insert(&drm->fbs, &fb->link); diff --git a/backend/drm/libliftoff.c b/backend/drm/libliftoff.c index 333beacad..b05299128 100644 --- a/backend/drm/libliftoff.c +++ b/backend/drm/libliftoff.c @@ -159,6 +159,10 @@ static bool set_plane_props(struct wlr_drm_plane *plane, } // The src_* properties are in 16.16 fixed point + enum wlr_drm_pixel_blend_mode blend_mode = fb->has_alpha ? + WLR_DRM_BLEND_PREMULTI : WLR_DRM_BLEND_PIXEL_NONE; + bool set_blend_mode = plane->props.pixel_blend_mode == 0 || + liftoff_layer_set_property(layer, "pixel blend mode", blend_mode) == 0; return liftoff_layer_set_property(layer, "zpos", zpos) == 0 && liftoff_layer_set_property(layer, "SRC_X", src_box->x * (1 << 16)) == 0 && liftoff_layer_set_property(layer, "SRC_Y", src_box->y * (1 << 16)) == 0 && @@ -168,7 +172,8 @@ static bool set_plane_props(struct wlr_drm_plane *plane, liftoff_layer_set_property(layer, "CRTC_Y", dst_box->y) == 0 && liftoff_layer_set_property(layer, "CRTC_W", dst_box->width) == 0 && liftoff_layer_set_property(layer, "CRTC_H", dst_box->height) == 0 && - liftoff_layer_set_property(layer, "FB_ID", fb->id) == 0; + liftoff_layer_set_property(layer, "FB_ID", fb->id) == 0 && + set_blend_mode; } static bool disable_plane(struct wlr_drm_plane *plane) { diff --git a/backend/drm/properties.c b/backend/drm/properties.c index 4c6bdcb36..976ed7ece 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -68,6 +68,7 @@ static const struct prop_info plane_info[] = { { "SRC_W", INDEX(src_w) }, { "SRC_X", INDEX(src_x) }, { "SRC_Y", INDEX(src_y) }, + { "pixel blend mode", INDEX(pixel_blend_mode) }, { "rotation", INDEX(rotation) }, { "type", INDEX(type) }, #undef INDEX diff --git a/include/backend/drm/fb.h b/include/backend/drm/fb.h index e8d328e97..82e44fb70 100644 --- a/include/backend/drm/fb.h +++ b/include/backend/drm/fb.h @@ -14,6 +14,7 @@ struct wlr_drm_fb { struct wl_list link; // wlr_drm_backend.fbs uint32_t id; + bool has_alpha; }; bool drm_fb_import(struct wlr_drm_fb **fb, struct wlr_drm_backend *drm, diff --git a/include/backend/drm/properties.h b/include/backend/drm/properties.h index 20e0a5bff..cd80a08a6 100644 --- a/include/backend/drm/properties.h +++ b/include/backend/drm/properties.h @@ -48,6 +48,7 @@ struct wlr_drm_plane_props { uint32_t rotation; // Not guaranteed to exist uint32_t in_formats; // Not guaranteed to exist uint32_t size_hints; // Not guaranteed to exist + uint32_t pixel_blend_mode; // Not guaranteed to exist // atomic-modesetting only @@ -83,6 +84,13 @@ enum wlr_drm_color_range { WLR_DRM_COLOR_YCBCR_LIMITED_RANGE, }; +// Equivalent to drm_mode_blend_mode defined in the kernel +enum wlr_drm_pixel_blend_mode { + WLR_DRM_BLEND_PREMULTI, + WLR_DRM_BLEND_COVERAGE, + WLR_DRM_BLEND_PIXEL_NONE, +}; + bool get_drm_connector_props(int fd, uint32_t id, struct wlr_drm_connector_props *out); bool get_drm_crtc_props(int fd, uint32_t id, struct wlr_drm_crtc_props *out);