vo_dmabuf_wayland: use single-pixel-buffer-v1

The new single-pixel-buffer protocol is designed to optimize the case
for using a solid color as an underlay wl_surface. It works the same as
the wl_shm 1x1 pixel trick currently used, but it allows the compositor
to make optimizations with more certainty than the wl_shm trick.
This commit is contained in:
LaserEyess 2022-11-15 20:52:56 -05:00 committed by Dudemanguy
parent 303178e645
commit a62f71bfbe
5 changed files with 58 additions and 19 deletions

View File

@ -12,7 +12,8 @@ features += {'wayland_protocols_1_24': wayland['deps'][2].version().version_comp
features += {'wayland_protocols_1_27': wayland['deps'][2].version().version_compare('>=1.27')}
if features['wayland_protocols_1_27']
protocols += [[wl_protocol_dir, 'staging/content-type/content-type-v1.xml']]
protocols += [[wl_protocol_dir, 'staging/content-type/content-type-v1.xml'],
[wl_protocol_dir, 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml']]
endif
foreach p: protocols

View File

@ -41,9 +41,15 @@
#include "present_sync.h"
#include "wayland_common.h"
#include "wlbuf_pool.h"
// Generated from wayland-protocols
#include "generated/wayland/linux-dmabuf-unstable-v1.h"
#include "generated/wayland/viewporter.h"
#if HAVE_WAYLAND_PROTOCOLS_1_27
#include "generated/wayland/single-pixel-buffer-v1.h"
#endif
struct priv {
struct mp_log *log;
struct ra_ctx *ctx;
@ -238,24 +244,6 @@ static int query_format(struct vo *vo, int format)
static int reconfig(struct vo *vo, struct mp_image_params *params)
{
struct priv *p = vo->priv;
struct vo_wayland_state *wl = vo->wl;
if (!p->solid_buffer_pool) {
int width = 1;
int height = 1;
int stride = MP_ALIGN_UP(width * 4, 16);
int fd = vo_wayland_allocate_memfd(vo, stride);
if (fd < 0)
return VO_ERROR;
p->solid_buffer_pool = wl_shm_create_pool(wl->shm, fd, height * stride);
if (!p->solid_buffer_pool)
return VO_ERROR;
p->solid_buffer = wl_shm_pool_create_buffer(p->solid_buffer_pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888);
if (!p->solid_buffer)
return VO_ERROR;
wl_surface_attach(wl->surface, p->solid_buffer, 0, 0);
}
if (!vo_wayland_reconfig(vo))
return VO_ERROR;
@ -354,6 +342,30 @@ static int preinit(struct vo *vo)
return VO_ERROR;
}
if (vo->wl->single_pixel_manager) {
#if HAVE_WAYLAND_PROTOCOLS_1_27
p->solid_buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer(
vo->wl->single_pixel_manager, 0, 0, 0, UINT32_MAX); /* R, G, B, A */
#endif
} else {
int width = 1;
int height = 1;
int stride = MP_ALIGN_UP(width * 4, 16);
int fd = vo_wayland_allocate_memfd(vo, stride);
if (fd < 0)
return VO_ERROR;
p->solid_buffer_pool = wl_shm_create_pool(vo->wl->shm, fd, height * stride);
if (!p->solid_buffer_pool)
return VO_ERROR;
p->solid_buffer = wl_shm_pool_create_buffer(
p->solid_buffer_pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888);
}
if (!p->solid_buffer)
return VO_ERROR;
wl_surface_attach(vo->wl->surface, p->solid_buffer, 0, 0);
vo->hwdec_devs = hwdec_devices_create();
hwdec_devices_set_loader(vo->hwdec_devs, call_request_hwdec_api, vo);
assert(!p->hwdec_ctx.ra);

View File

@ -44,6 +44,7 @@
#if HAVE_WAYLAND_PROTOCOLS_1_27
#include "generated/wayland/content-type-v1.h"
#include "generated/wayland/single-pixel-buffer-v1.h"
#endif
#if WAYLAND_VERSION_MAJOR > 1 || WAYLAND_VERSION_MINOR >= 20
@ -1240,6 +1241,10 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
if (!strcmp(interface, wp_content_type_manager_v1_interface.name) && found++) {
wl->content_type_manager = wl_registry_bind(reg, id, &wp_content_type_manager_v1_interface, 1);
}
if (!strcmp(interface, wp_single_pixel_buffer_manager_v1_interface.name) && found++) {
wl->single_pixel_manager = wl_registry_bind(reg, id, &wp_single_pixel_buffer_manager_v1_interface, 1);
}
#endif
if (!strcmp(interface, wp_presentation_interface.name) && found++) {
@ -2007,6 +2012,11 @@ int vo_wayland_init(struct vo *vo)
MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n",
wp_content_type_manager_v1_interface.name);
}
if (!wl->single_pixel_manager) {
MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n",
wp_single_pixel_buffer_manager_v1_interface.name);
}
#endif
if (wl->dnd_devman && wl->seat) {
@ -2225,6 +2235,11 @@ void vo_wayland_uninit(struct vo *vo)
if (wl->shm)
wl_shm_destroy(wl->shm);
#if HAVE_WAYLAND_PROTOCOLS_1_27
if (wl->single_pixel_manager)
wp_single_pixel_buffer_manager_v1_destroy(wl->single_pixel_manager);
#endif
if (wl->surface)
wl_surface_destroy(wl->surface);

View File

@ -106,6 +106,10 @@ struct vo_wayland_state {
int64_t refresh_interval;
bool use_present;
/* single-pixel-buffer */
/* TODO: unvoid this if required wayland-protocols is bumped to 1.27+ */
void *single_pixel_manager;
/* xdg-decoration */
struct zxdg_decoration_manager_v1 *xdg_decoration_manager;
struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration;

View File

@ -147,6 +147,12 @@ def build(ctx):
ctx.wayland_protocol_header(proto_dir = ctx.env.WL_PROTO_DIR,
protocol = "staging/content-type/content-type-v1",
target = "generated/wayland/content-type-v1.h")
ctx.wayland_protocol_code(proto_dir = ctx.env.WL_PROTO_DIR,
protocol = "staging/single-pixel-buffer/single-pixel-buffer-v1",
target = "generated/wayland/single-pixel-buffer-v1.c")
ctx.wayland_protocol_header(proto_dir = ctx.env.WL_PROTO_DIR,
protocol = "staging/single-pixel-buffer/single-pixel-buffer-v1",
target = "generated/wayland/single-pixel-buffer-v1.h")
ctx(features = "ebml_header", target = "generated/ebml_types.h")
ctx(features = "ebml_definitions", target = "generated/ebml_defs.inc")
@ -548,6 +554,7 @@ def build(ctx):
( "video/out/vulkan/context_xlib.c", "vulkan && x11" ),
( "video/out/vulkan/utils.c", "vulkan" ),
( "video/out/w32_common.c", "win32-desktop" ),
( "generated/wayland/single-pixel-buffer-v1.c", "wayland-protocols-1-27" ),
( "generated/wayland/content-type-v1.c", "wayland-protocols-1-27" ),
( "generated/wayland/idle-inhibit-unstable-v1.c", "wayland" ),
( "generated/wayland/presentation-time.c", "wayland" ),