diff --git a/meson.build b/meson.build
index bc7361af2f..959710bb83 100644
--- a/meson.build
+++ b/meson.build
@@ -1420,7 +1420,6 @@ if features['dmabuf-wayland']
sources += files('video/out/hwdec/dmabuf_interop_wl.c')
sources += files('video/out/wldmabuf/context_wldmabuf.c')
sources += files('video/out/wldmabuf/ra_wldmabuf.c')
- sources += files('video/out/wlbuf_pool.c')
endif
vdpau_opt = get_option('vdpau').require(
diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c
index 9606d1b0db..d18aea2a5b 100644
--- a/video/out/vo_dmabuf_wayland.c
+++ b/video/out/vo_dmabuf_wayland.c
@@ -14,8 +14,8 @@
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see .
*/
-#include
+#include
#include "config.h"
#if HAVE_VAAPI
@@ -25,21 +25,19 @@
#include
#endif
-#include "mpv_talloc.h"
#include "common/global.h"
-#include "vo.h"
-#include "video/mp_image.h"
-
#include "gpu/hwdec.h"
#include "gpu/video.h"
+#include "mpv_talloc.h"
+#include "present_sync.h"
+#include "video/mp_image.h"
+#include "vo.h"
+#include "wayland_common.h"
+#include "wldmabuf/ra_wldmabuf.h"
#if HAVE_VAAPI
#include "video/vaapi.h"
#endif
-#include "present_sync.h"
-#include "wayland_common.h"
-#include "wlbuf_pool.h"
-#include "wldmabuf/ra_wldmabuf.h"
// Generated from wayland-protocols
#include "generated/wayland/linux-dmabuf-unstable-v1.h"
@@ -49,138 +47,272 @@
#include "generated/wayland/single-pixel-buffer-v1.h"
#endif
+// We need at least enough buffers to avoid a
+// flickering artifact in certain formats.
+#define WL_BUFFERS_WANTED 8
+
+enum hwdec_type {
+ HWDEC_NONE,
+ HWDEC_VAAPI,
+ HWDEC_DRMPRIME,
+};
+
+struct buffer {
+ struct vo *vo;
+ struct wl_buffer *buffer;
+ struct wl_list link;
+ struct mp_image *image;
+
+ uint32_t drm_format;
+ uintptr_t id;
+};
+
struct priv {
struct mp_log *log;
- struct ra_ctx *ctx;
+ struct mp_rect src;
struct mpv_global *global;
+
+ struct ra_ctx *ctx;
struct ra_hwdec_ctx hwdec_ctx;
- int events;
struct wl_shm_pool *solid_buffer_pool;
struct wl_buffer *solid_buffer;
- struct wlbuf_pool *wlbuf_pool;
- bool want_reset;
- bool want_resize;
- struct mp_rect src;
- bool resized;
+ struct wl_list buffer_list;
-#if HAVE_VAAPI
- VADisplay display;
-#endif
+ bool destroy_buffers;
+ enum hwdec_type hwdec_type;
+};
+
+static void buffer_handle_release(void *data, struct wl_buffer *wl_buffer)
+{
+ struct buffer *buf = data;
+ if (buf->image) {
+ mp_image_unrefp(&buf->image);
+ buf->image = NULL;
+ }
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+ buffer_handle_release,
};
#if HAVE_VAAPI
-static uintptr_t vaapi_key_provider(struct mp_image *src)
-{
- return va_surface_id(src);
-}
-
static void close_file_descriptors(VADRMPRIMESurfaceDescriptor desc)
{
for (int i = 0; i < desc.num_objects; i++)
close(desc.objects[i].fd);
}
+#endif
-/* va-api dmabuf importer */
-static bool vaapi_dmabuf_importer(struct mp_image *src, struct wlbuf_pool_entry* entry,
+static uintptr_t vaapi_surface_id(struct mp_image *src)
+{
+ uintptr_t id = 0;
+#if HAVE_VAAPI
+ id = (uintptr_t)va_surface_id(src);
+#endif
+ return id;
+}
+
+static void vaapi_dmabuf_importer(struct buffer *buf, struct mp_image *src,
struct zwp_linux_buffer_params_v1 *params)
{
- struct priv *p = entry->vo->priv;
- VADRMPRIMESurfaceDescriptor desc = { 0 };
+#if HAVE_VAAPI
+ struct vo *vo = buf->vo;
+ struct priv *p = vo->priv;
+ VADRMPRIMESurfaceDescriptor desc = {0};
+ VADisplay display = ra_get_native_resource(p->ctx->ra, "VADisplay");
+
/* composed has single layer */
int layer_no = 0;
- VAStatus status = vaExportSurfaceHandle(p->display, entry->key, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
+ buf->id = vaapi_surface_id(src);
+ VAStatus status = vaExportSurfaceHandle(display, buf->id, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
VA_EXPORT_SURFACE_COMPOSED_LAYERS | VA_EXPORT_SURFACE_READ_ONLY, &desc);
- if (!CHECK_VA_STATUS(entry->vo, "vaExportSurfaceHandle()")) {
+ if (!CHECK_VA_STATUS(vo, "vaExportSurfaceHandle()")) {
/* invalid surface warning => composed layers not supported */
if (status == VA_STATUS_ERROR_INVALID_SURFACE)
- MP_VERBOSE(entry->vo, "vaExportSurfaceHandle: composed layers not supported.\n");
- close_file_descriptors(desc);
-
- return false;
+ MP_VERBOSE(vo, "vaExportSurfaceHandle: composed layers not supported.\n");
+ goto done;
}
- bool success = false;
- uint32_t drm_format = desc.layers[layer_no].drm_format;
- if (!ra_compatible_format(p->ctx->ra, drm_format, desc.objects[0].drm_format_modifier)) {
- MP_VERBOSE(entry->vo, "Surface with format %s; drm format '%s(%016lx)' is "
- "not supported by compositor.\n",
- mp_imgfmt_to_name(src->params.hw_subfmt),
- mp_tag_str(drm_format),
- desc.objects[0].drm_format_modifier);
- goto done;
+ buf->drm_format = desc.layers[layer_no].drm_format;
+ if (!ra_compatible_format(p->ctx->ra, buf->drm_format, desc.objects[0].drm_format_modifier)) {
+ MP_VERBOSE(vo, "%s(%016lx) is not supported.\n",
+ mp_tag_str(buf->drm_format), desc.objects[0].drm_format_modifier);
+ buf->drm_format = 0;
+ goto done;
}
- entry->drm_format = drm_format;
for (int plane_no = 0; plane_no < desc.layers[layer_no].num_planes; ++plane_no) {
int object = desc.layers[layer_no].object_index[plane_no];
uint64_t modifier = desc.objects[object].drm_format_modifier;
zwp_linux_buffer_params_v1_add(params, desc.objects[object].fd, plane_no, desc.layers[layer_no].offset[plane_no],
desc.layers[layer_no].pitch[plane_no], modifier >> 32, modifier & 0xffffffff);
}
- success = true;
done:
close_file_descriptors(desc);
-
- return success;
-}
#endif
+}
-#if HAVE_DRM
-
-static uintptr_t drmprime_key_provider(struct mp_image *src)
+static uintptr_t drmprime_surface_id(struct mp_image *src)
{
+ uintptr_t id = 0;
+#if HAVE_DRM
struct AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->planes[0];
AVDRMObjectDescriptor object = desc->objects[0];
- return (uintptr_t)object.fd;
+ id = (uintptr_t)object.fd;
+#endif
+ return id;
}
-static bool drmprime_dmabuf_importer(struct mp_image *src, struct wlbuf_pool_entry *entry,
+static void drmprime_dmabuf_importer(struct buffer *buf, struct mp_image *src,
struct zwp_linux_buffer_params_v1 *params)
{
+#if HAVE_DRM
int layer_no, plane_no;
- const AVDRMFrameDescriptor *avdesc = (AVDRMFrameDescriptor *)src->planes[0];
+ int max_planes = 0;
+ const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->planes[0];
+ if (!desc)
+ return;
- for (layer_no = 0; layer_no < avdesc->nb_layers; layer_no++) {
- AVDRMLayerDescriptor layer = avdesc->layers[layer_no];
+ buf->id = drmprime_surface_id(src);
+ for (layer_no = 0; layer_no < desc->nb_layers; layer_no++) {
+ AVDRMLayerDescriptor layer = desc->layers[layer_no];
- entry->drm_format = layer.format;
+ buf->drm_format = layer.format;
+ max_planes = MPMAX(max_planes, layer.nb_planes);
for (plane_no = 0; plane_no < layer.nb_planes; ++plane_no) {
AVDRMPlaneDescriptor plane = layer.planes[plane_no];
int object_index = plane.object_index;
- AVDRMObjectDescriptor object = avdesc->objects[object_index];
+ AVDRMObjectDescriptor object = desc->objects[object_index];
uint64_t modifier = object.format_modifier;
zwp_linux_buffer_params_v1_add(params, object.fd, plane_no, plane.offset,
plane.pitch, modifier >> 32, modifier & 0xffffffff);
}
}
-
- return true;
-}
#endif
+}
+
+static intptr_t surface_id(struct vo *vo, struct mp_image *src)
+{
+ struct priv *p = vo->priv;
+ switch(p->hwdec_type) {
+ case HWDEC_VAAPI:
+ return vaapi_surface_id(src);
+ case HWDEC_DRMPRIME:
+ return drmprime_surface_id(src);
+ default:
+ return 0;
+ }
+}
+
+static struct buffer *buffer_check(struct vo *vo, struct mp_image *src)
+{
+ struct priv *p = vo->priv;
+
+ /* Make more buffers if we're not at the desired amount yet. */
+ if (wl_list_length(&p->buffer_list) < WL_BUFFERS_WANTED)
+ goto done;
+
+ uintptr_t id = surface_id(vo, src);
+ struct buffer *buf;
+ wl_list_for_each(buf, &p->buffer_list, link) {
+ if (buf->id == id) {
+ if (buf->image) {
+ mp_image_unrefp(&buf->image);
+ buf->image = NULL;
+ goto done;
+ } else {
+ buf->image = src;
+ return buf;
+ }
+ }
+ }
+
+done:
+ return NULL;
+}
+
+static struct buffer *buffer_create(struct vo *vo, struct mp_image *src)
+{
+ struct vo_wayland_state *wl = vo->wl;
+ struct priv *p = vo->priv;
+
+ struct buffer *buf = talloc_zero(vo, struct buffer);
+ buf->vo = vo;
+ buf->image = src;
+
+ struct zwp_linux_buffer_params_v1 *params = zwp_linux_dmabuf_v1_create_params(wl->dmabuf);
+
+ switch(p->hwdec_type) {
+ case HWDEC_VAAPI:
+ vaapi_dmabuf_importer(buf, src, params);
+ break;
+ case HWDEC_DRMPRIME:
+ drmprime_dmabuf_importer(buf, src, params);
+ break;
+ }
+
+ if (!buf->drm_format) {
+ mp_image_unrefp(&buf->image);
+ talloc_free(buf);
+ zwp_linux_buffer_params_v1_destroy(params);
+ return NULL;
+ }
+
+ buf->buffer = zwp_linux_buffer_params_v1_create_immed(params, src->params.w, src->params.h,
+ buf->drm_format, 0);
+ zwp_linux_buffer_params_v1_destroy(params);
+ wl_buffer_add_listener(buf->buffer, &buffer_listener, buf);
+ wl_list_insert(&p->buffer_list, &buf->link);
+ return buf;
+}
+
+static struct buffer *buffer_get(struct vo *vo, struct mp_image *src)
+{
+ /* Reuse existing buffer if possible. */
+ struct buffer *buf = buffer_check(vo, src);
+ if (buf) {
+ return buf;
+ } else {
+ return buffer_create(vo, src);
+ }
+}
+
+static void destroy_buffers(struct vo *vo)
+{
+ struct priv *p = vo->priv;
+ struct buffer *buf, *tmp;
+ p->destroy_buffers = false;
+ wl_list_for_each_safe(buf, tmp, &p->buffer_list, link) {
+ wl_list_remove(&buf->link);
+ if (buf->image) {
+ mp_image_unrefp(&buf->image);
+ buf->image = NULL;
+ }
+ if (buf->buffer) {
+ wl_buffer_destroy(buf->buffer);
+ buf->buffer = NULL;
+ }
+ talloc_free(buf);
+ }
+}
static void set_viewport_source(struct vo *vo, struct mp_rect src) {
struct priv *p = vo->priv;
struct vo_wayland_state *wl = vo->wl;
if (wl->video_viewport && !mp_rect_equals(&p->src, &src)) {
- // 1. update viewport source
wp_viewport_set_source(wl->video_viewport, src.x0 << 8,
src.y0 << 8, mp_rect_w(src) << 8,
mp_rect_h(src) << 8);
- // 2. reset buffer pool
- p->want_reset = true;
-
- // 3. update to new src dimensions
p->src = src;
}
}
static void resize(struct vo *vo)
{
- struct priv *p = vo->priv;
struct vo_wayland_state *wl = vo->wl;
struct mp_rect src;
struct mp_rect dst;
@@ -188,6 +320,9 @@ static void resize(struct vo *vo)
struct mp_vo_opts *vo_opts = wl->vo_opts;
const int width = mp_rect_w(wl->geometry);
const int height = mp_rect_h(wl->geometry);
+
+ if (width == 0 || height == 0)
+ return;
vo_wayland_set_opaque_region(wl, false);
vo->dwidth = width;
@@ -208,83 +343,59 @@ static void resize(struct vo *vo)
wp_viewport_set_destination(wl->video_viewport, mp_rect_w(dst), mp_rect_h(dst));
wl_subsurface_set_position(wl->video_subsurface, dst.x0, dst.y0);
set_viewport_source(vo, src);
-
- vo->want_redraw = true;
- p->resized = true;
- p->want_reset = true;
- p->want_resize = false;
}
static void draw_frame(struct vo *vo, struct vo_frame *frame)
{
struct priv *p = vo->priv;
struct vo_wayland_state *wl = vo->wl;
- struct wlbuf_pool_entry *entry;
-
- if (!vo_wayland_check_visible(vo))
+ struct buffer *buf;
+
+ if (!vo_wayland_check_visible(vo) || !frame->current)
return;
- /* lazy initialization of buffer pool */
- if (!p->wlbuf_pool) {
-#if HAVE_VAAPI
- p->display = (VADisplay)ra_get_native_resource(p->ctx->ra, "VADisplay");
- if (p->display)
- p->wlbuf_pool = wlbuf_pool_alloc(vo, wl, vaapi_key_provider, vaapi_dmabuf_importer);
-#endif
-#if HAVE_DRM
- if (!p->wlbuf_pool)
- p->wlbuf_pool = wlbuf_pool_alloc(vo, wl, drmprime_key_provider, drmprime_dmabuf_importer);
-#endif
+ if (p->destroy_buffers)
+ destroy_buffers(vo);
+
+ struct mp_image *src = mp_image_new_ref(frame->current);
+ buf = buffer_get(vo, src);
+
+ if (buf && buf->image) {
+ wl_surface_attach(wl->video_surface, buf->buffer, 0, 0);
+ wl_surface_damage_buffer(wl->video_surface, 0, 0, buf->image->params.w,
+ buf->image->params.h);
}
- entry = wlbuf_pool_get_entry(p->wlbuf_pool, frame->current);
- if (!entry)
- return;
-
- // ensure the pool is reset after hwdec seek,
- // to avoid stutter artifact
- if (p->want_reset)
- wlbuf_pool_clean(p->wlbuf_pool,false);
- if (p->want_resize)
- resize(vo);
-
- MP_TRACE(entry->vo, "Schedule buffer pool entry : %lu\n",entry->key );
- wl_surface_attach(wl->video_surface, entry->buffer, 0, 0);
- wl_surface_damage_buffer(wl->video_surface, 0, 0, INT32_MAX, INT32_MAX);
}
static void flip_page(struct vo *vo)
{
struct vo_wayland_state *wl = vo->wl;
- struct priv *p = vo->priv;
wl_surface_commit(wl->video_surface);
wl_surface_commit(wl->surface);
+
if (!wl->opts->disable_vsync)
vo_wayland_wait_frame(wl);
+
if (wl->use_present)
present_sync_swap(wl->present);
- if (p->want_reset) {
- wlbuf_pool_clean(p->wlbuf_pool,false);
- p->want_reset = false;
- }
}
static void get_vsync(struct vo *vo, struct vo_vsync_info *info)
{
struct vo_wayland_state *wl = vo->wl;
-
if (wl->use_present)
present_sync_get_info(wl->present, info);
}
static bool is_supported_fmt(int fmt)
{
- return (fmt == IMGFMT_DRMPRIME || fmt == IMGFMT_VAAPI);
+ return (fmt == IMGFMT_DRMPRIME || fmt == IMGFMT_VAAPI);
}
static int query_format(struct vo *vo, int format)
{
- return is_supported_fmt(format);
+ return is_supported_fmt(format);
}
static int reconfig(struct vo *vo, struct mp_image_params *params)
@@ -292,6 +403,8 @@ static int reconfig(struct vo *vo, struct mp_image_params *params)
if (!vo_wayland_reconfig(vo))
return VO_ERROR;
+ // Immediately destroy all buffers if params change.
+ destroy_buffers(vo);
return 0;
}
@@ -309,9 +422,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
int ret;
switch (request) {
- case VOCTRL_SET_PANSCAN:
- p->want_resize = true;
- return VO_TRUE;
case VOCTRL_LOAD_HWDEC_API:
assert(p->hwdec_ctx.ra);
struct hwdec_imgfmt_request* req = (struct hwdec_imgfmt_request*)data;
@@ -319,19 +429,17 @@ static int control(struct vo *vo, uint32_t request, void *data)
return 0;
ra_hwdec_ctx_load_fmt(&p->hwdec_ctx, vo->hwdec_devs, req);
return (p->hwdec_ctx.num_hwdecs > 0);
- break;
- case VOCTRL_RESET:
- p->want_reset = true;
- return VO_TRUE;
- break;
+ case VOCTRL_RESET:
+ p->destroy_buffers = true;
+ return VO_TRUE;
+ case VOCTRL_SET_PANSCAN:
+ resize(vo);
+ return VO_TRUE;
}
ret = vo_wayland_control(vo, &events, request, data);
- if (events & VO_EVENT_RESIZE){
- p->want_resize = true;
- if (!p->resized)
- resize(vo);
- }
+ if (events & VO_EVENT_RESIZE)
+ resize(vo);
if (events & VO_EVENT_EXPOSE)
vo->want_redraw = true;
vo_event(vo, events);
@@ -343,7 +451,7 @@ static void uninit(struct vo *vo)
{
struct priv *p = vo->priv;
- wlbuf_pool_free(p->wlbuf_pool);
+ destroy_buffers(vo);
if (p->solid_buffer_pool)
wl_shm_pool_destroy(p->solid_buffer_pool);
if (p->solid_buffer)
@@ -353,6 +461,7 @@ static void uninit(struct vo *vo)
hwdec_devices_set_loader(vo->hwdec_devs, NULL, NULL);
hwdec_devices_destroy(vo->hwdec_devs);
}
+
vo_wayland_uninit(vo);
ra_ctx_destroy(&p->ctx);
}
@@ -368,6 +477,8 @@ static int preinit(struct vo *vo)
goto err;
assert(p->ctx->ra);
+ wl_list_init(&p->buffer_list);
+
if (!vo->wl->dmabuf) {
MP_FATAL(vo->wl, "Compositor doesn't support the %s protocol!\n",
zwp_linux_dmabuf_v1_interface.name);
@@ -424,9 +535,24 @@ static int preinit(struct vo *vo)
.global = p->global,
.ra = p->ctx->ra,
};
- ra_hwdec_ctx_init(&p->hwdec_ctx, vo->hwdec_devs, NULL, true);
- p->src = (struct mp_rect){0, 0, 0, 0};
+ ra_hwdec_ctx_init(&p->hwdec_ctx, vo->hwdec_devs, NULL, true);
+
+ for (int i = 0; i < p->hwdec_ctx.num_hwdecs; i++) {
+ struct ra_hwdec *hw = p->hwdec_ctx.hwdecs[i];
+ if (ra_get_native_resource(p->ctx->ra, "VADisplay")) {
+ p->hwdec_type = HWDEC_VAAPI;
+ } else if (strcmp(hw->driver->name, "drmprime") == 0) {
+ p->hwdec_type = HWDEC_DRMPRIME;
+ }
+ }
+
+ if (p->hwdec_type == HWDEC_NONE) {
+ MP_ERR(vo, "No valid hardware decoding driver could be loaded!");
+ goto err;
+ }
+
+ p->src = (struct mp_rect){0, 0, 0, 0};
return 0;
err:
diff --git a/video/out/wlbuf_pool.c b/video/out/wlbuf_pool.c
deleted file mode 100644
index 8c05adb5fb..0000000000
--- a/video/out/wlbuf_pool.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * mpv is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with mpv. If not, see .
- */
-
-#include "mpv_talloc.h"
-#include "common/global.h"
-#include "vo.h"
-#include "video/mp_image.h"
-
-#include "wayland_common.h"
-#include "generated/wayland/linux-dmabuf-unstable-v1.h"
-#include "pthread.h"
-#include "wlbuf_pool.h"
-
-#define WLBUF_POOL_NUM_ALLOCATED_INIT 30
-
-static void wlbuf_pool_entry_free(struct wlbuf_pool_entry *entry, bool force);
-
-/**
- * When trying to free pool entries that are being held by Wayland,
- * these entries are set to pending free state. They will be freed
- * when either the frame listener gets called, or the vo is uninitialized
-*/
-static bool set_pending_free(struct wlbuf_pool_entry *entry) {
- if (entry->image) {
- MP_TRACE(entry->vo, "Pending free for buffer pool entry : %lu\n",
- entry->key);
- entry->pending_free = true;
- // add to purgatory
- struct wlbuf_pool *pool = entry->pool;
- for (int i = 0; i < WLBUF_NUM_PURG_ENTRIES; ++i) {
- if (pool->purg.entries[i] == NULL) {
- pool->purg.entries[i] = entry;
- break;
- }
- }
- }
-
- return entry->image;
-}
-
-/**
- * Complete pending free of entry.
- *
- */
-static void complete_pending_free(struct wlbuf_pool_entry *entry) {
- if (entry->pending_free) {
- // 1. remove from purgatory
- struct wlbuf_pool *pool = entry->pool;
- for (int i = 0; i < WLBUF_NUM_PURG_ENTRIES; ++i) {
- if (pool->purg.entries[i] == entry) {
- pool->purg.entries[i] = NULL;
- break;
- }
- }
- // 2. free entry
- wlbuf_pool_entry_free(entry, false);
- }
-}
-
-/**
- * Free all purgatory entries
- */
-static void free_purgatory(struct wlbuf_pool *pool){
- for (int i = 0; i < WLBUF_NUM_PURG_ENTRIES; ++i)
- wlbuf_pool_entry_free(pool->purg.entries[i], true);
-}
-
-struct wlbuf_pool *wlbuf_pool_alloc(struct vo *vo, struct vo_wayland_state *wl, wlbuf_pool_key_provider key_provider,
- wlbuf_pool_dmabuf_importer dmabuf_importer)
-{
- struct wlbuf_pool *pool = talloc(NULL, struct wlbuf_pool);
- memset(pool, 0, sizeof(struct wlbuf_pool));
- pool->num_allocated = WLBUF_POOL_NUM_ALLOCATED_INIT;
- pool->entries = talloc_array(pool, struct wlbuf_pool_entry *, pool->num_allocated);
- memset(pool->entries, 0, pool->num_allocated * sizeof(struct wlbuf_pool_entry *));
- pool->vo = vo;
- pool->key_provider = key_provider;
- pool->dmabuf_importer = dmabuf_importer;
- pool->wl = wl;
- for (int i = 0; i < WLBUF_NUM_PURG_ENTRIES; ++i)
- pool->purg.entries[i] = NULL;
-
- return pool;
-}
-
-void wlbuf_pool_clean(struct wlbuf_pool *pool, bool final_clean)
-{
- int i;
- if (!pool)
- return;
- MP_TRACE(pool->vo, "Begin clean pool\n");
- if (final_clean)
- free_purgatory(pool);
- for (i = 0; i < pool->num_allocated; ++i) {
- struct wlbuf_pool_entry *entry = pool->entries[i];
- if (!entry)
- continue;
- wlbuf_pool_entry_free(entry, final_clean);
- pool->entries[i] = NULL;
- }
- pool->num_entries = 0;
- MP_TRACE(pool->vo, "End clean pool\n");
-}
-
-void wlbuf_pool_free(struct wlbuf_pool *pool)
-{
- if (!pool)
- return;
-
- wlbuf_pool_clean(pool, true);
- talloc_free(pool);
-}
-
-static void wlbuf_pool_entry_free(struct wlbuf_pool_entry *entry, bool force)
-{
- if (!entry)
- return;
- if (force && entry->image) {
- mp_image_unrefp(&entry->image);
- entry->image = NULL;
- }
- if (!set_pending_free(entry)) {
- MP_TRACE(entry->vo, "Free buffer pool entry : %lu\n", entry->key);
- if (entry->buffer)
- wl_buffer_destroy(entry->buffer);
- talloc_free(entry);
- }
-}
-
-/**
- * Unref pool entry's image, and also free entry itself if it's set to pending_free
- */
-static void wlbuf_pool_entry_release(void *data, struct wl_buffer *wl_buffer)
-{
- struct wlbuf_pool_entry *entry = (struct wlbuf_pool_entry*) data;
-
- MP_TRACE(entry->vo, "Release buffer pool entry : %lu\n", entry->key);
-
- // 1. always unref image
- if (entry->image)
- mp_image_unrefp(&entry->image);
- entry->image = NULL;
-
- // 2. complete pending free if needed
- complete_pending_free(entry);
-}
-
-static const struct wl_buffer_listener wlbuf_pool_listener = {
- wlbuf_pool_entry_release,
-};
-
-struct wlbuf_pool_entry *wlbuf_pool_get_entry(struct wlbuf_pool *pool, struct mp_image *src)
-{
- uintptr_t key;
- struct wlbuf_pool_entry *entry;
- struct vo_wayland_state *wl = pool->wl;
- bool import_successful;
- struct zwp_linux_buffer_params_v1 *params;
-
- if (!pool || !src)
- return NULL;
-
- /* 1. try to find existing entry in pool */
- src = mp_image_new_ref(src);
- key = pool->key_provider(src);
- for (int i = 0; i < pool->num_entries; ++i) {
- struct wlbuf_pool_entry *item = pool->entries[i];
- if (!item)
- continue;
- if (item->key == key) {
- if (item->image) {
- mp_image_unrefp(&src);
- MP_DBG(item->vo, "Buffer already scheduled - returning NULL.\n");
- return NULL;
- } else {
- item->image = src;
- return item;
- }
- }
- }
- /* 2. otherwise allocate new entry and buffer */
- entry = talloc(pool, struct wlbuf_pool_entry);
- memset(entry, 0, sizeof(struct wlbuf_pool_entry));
- entry->vo = pool->vo;
- entry->key = pool->key_provider(src);
- entry->pool = pool;
- MP_TRACE(entry->vo, "Allocate buffer pool entry : %lu\n", entry->key);
- params = zwp_linux_dmabuf_v1_create_params(wl->dmabuf);
- import_successful = pool->dmabuf_importer(src, entry, params);
- if (!import_successful) {
- MP_DBG(entry->vo, "Failed to import\n");
- wlbuf_pool_entry_free(entry, false);
- } else {
- entry->buffer = zwp_linux_buffer_params_v1_create_immed(params, src->params.w, src->params.h,
- entry->drm_format, 0);
- }
- zwp_linux_buffer_params_v1_destroy(params);
- if (!import_successful) {
- mp_image_unrefp(&src);
- return NULL;
- }
- /* 3. add new entry to pool */
- if (pool->num_entries == pool->num_allocated) {
- int current_num_allocated = pool->num_allocated;
- pool->num_allocated *= 2;
- pool->entries = talloc_realloc(pool, pool->entries, struct wlbuf_pool_entry *, pool->num_allocated);
- for (int i = current_num_allocated; i < pool->num_allocated; ++i)
- pool->entries[i] = NULL;
- }
- wl_buffer_add_listener(entry->buffer, &wlbuf_pool_listener, entry);
- entry->image = src;
- pool->entries[pool->num_entries++] = entry;
-
- return entry;
-}
diff --git a/video/out/wlbuf_pool.h b/video/out/wlbuf_pool.h
deleted file mode 100644
index df1f6f6065..0000000000
--- a/video/out/wlbuf_pool.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * mpv is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with mpv. If not, see .
- */
-
-#ifndef MPLAYER_VIDEO_OUT_WLBUF_POOL_H
-#define MPLAYER_VIDEO_OUT_WLBUF_POOL_H
-
-#include "wayland_common.h"
-#include "generated/wayland/linux-dmabuf-unstable-v1.h"
-
-struct wlbuf_pool_entry;
-
-typedef uintptr_t (*wlbuf_pool_key_provider)(struct mp_image *src);
-typedef bool (*wlbuf_pool_dmabuf_importer)(struct mp_image *src, struct wlbuf_pool_entry* entry,
- struct zwp_linux_buffer_params_v1 *params);
-
-#define WLBUF_NUM_PURG_ENTRIES 60
-
-struct wlbuf_purgatory {
- struct wlbuf_pool_entry *entries[WLBUF_NUM_PURG_ENTRIES];
-};
-
-struct wlbuf_pool {
- struct vo *vo;
- struct vo_wayland_state *wl;
- struct wlbuf_pool_entry **entries;
- int num_entries;
- int num_allocated;
- wlbuf_pool_key_provider key_provider;
- wlbuf_pool_dmabuf_importer dmabuf_importer;
- struct wlbuf_purgatory purg;
-};
-
-struct wlbuf_pool_entry {
- uintptr_t key;
- struct vo *vo;
- struct wl_buffer *buffer;
- uint32_t drm_format;
- struct mp_image *image;
- bool pending_free;
- struct wlbuf_pool *pool;
-};
-
-/**
- * Allocate pool
- */
-struct wlbuf_pool *wlbuf_pool_alloc(struct vo *vo, struct vo_wayland_state *wl, wlbuf_pool_key_provider key_provider,
- wlbuf_pool_dmabuf_importer dmabuf_importer);
-
-/**
- * Free pool entries but leave pool itself intact
- */
-void wlbuf_pool_clean(struct wlbuf_pool *pool, bool final_clean);
-
-/**
- * Free pool
- */
-void wlbuf_pool_free(struct wlbuf_pool *pool);
-
-/**
- * Get pool entry - will allocate entry if not present in pool.
- */
-struct wlbuf_pool_entry *wlbuf_pool_get_entry(struct wlbuf_pool *pool, struct mp_image *src);
-
-#endif
diff --git a/wscript_build.py b/wscript_build.py
index 51f6351960..823f875c91 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -520,7 +520,6 @@ def build(ctx):
( "video/out/present_sync.c", "wayland || x11" ),
( "video/out/wldmabuf/context_wldmabuf.c", "dmabuf-wayland" ),
( "video/out/wldmabuf/ra_wldmabuf.c", "dmabuf-wayland" ),
- ( "video/out/wlbuf_pool.c", "dmabuf-wayland" ),
( "video/out/vo.c" ),
( "video/out/vo_caca.c", "caca" ),
( "video/out/vo_direct3d.c", "direct3d" ),