summaryrefslogtreecommitdiffstats
path: root/video/out/vo_wlshm.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/vo_wlshm.c')
-rw-r--r--video/out/vo_wlshm.c119
1 files changed, 61 insertions, 58 deletions
diff --git a/video/out/vo_wlshm.c b/video/out/vo_wlshm.c
index a71f9507fc..0b63426a23 100644
--- a/video/out/vo_wlshm.c
+++ b/video/out/vo_wlshm.c
@@ -21,9 +21,8 @@
#include <time.h>
#include <unistd.h>
-#include <libswscale/swscale.h>
-
#include "osdep/endian.h"
+#include "present_sync.h"
#include "sub/osd.h"
#include "video/fmt-conversion.h"
#include "video/mp_image.h"
@@ -31,6 +30,8 @@
#include "vo.h"
#include "wayland_common.h"
+#define IMGFMT_WL_RGB MP_SELECT_LE_BE(IMGFMT_BGR0, IMGFMT_0RGB)
+
struct buffer {
struct vo *vo;
size_t size;
@@ -74,21 +75,6 @@ static void buffer_destroy(void *p)
munmap(buf->mpi.planes[0], buf->size);
}
-static int allocate_memfd(size_t size)
-{
- int fd = memfd_create("mpv", MFD_CLOEXEC | MFD_ALLOW_SEALING);
- if (fd < 0)
- return -1;
-
- fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
-
- if (posix_fallocate(fd, 0, size) == 0)
- return fd;
-
- close(fd);
- return -1;
-}
-
static struct buffer *buffer_create(struct vo *vo, int width, int height)
{
struct priv *p = vo->priv;
@@ -101,7 +87,7 @@ static struct buffer *buffer_create(struct vo *vo, int width, int height)
stride = MP_ALIGN_UP(width * 4, 16);
size = height * stride;
- fd = allocate_memfd(size);
+ fd = vo_wayland_allocate_memfd(vo, size);
if (fd < 0)
goto error0;
data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
@@ -142,22 +128,44 @@ error0:
return NULL;
}
+static void uninit(struct vo *vo)
+{
+ struct priv *p = vo->priv;
+ struct buffer *buf;
+
+ while (p->free_buffers) {
+ buf = p->free_buffers;
+ p->free_buffers = buf->next;
+ talloc_free(buf);
+ }
+ vo_wayland_uninit(vo);
+}
+
static int preinit(struct vo *vo)
{
struct priv *p = vo->priv;
if (!vo_wayland_init(vo))
- return -1;
+ goto err;
+ if (!vo->wl->shm) {
+ MP_FATAL(vo->wl, "Compositor doesn't support the %s protocol!\n",
+ wl_shm_interface.name);
+ goto err;
+ }
p->sws = mp_sws_alloc(vo);
p->sws->log = vo->log;
mp_sws_enable_cmdline_opts(p->sws, vo->global);
return 0;
+err:
+ uninit(vo);
+ return -1;
}
static int query_format(struct vo *vo, int format)
{
- return sws_isSupportedInput(imgfmt2pixfmt(format));
+ struct priv *p = vo->priv;
+ return mp_sws_supports_formats(p->sws, IMGFMT_WL_RGB, format) ? 1 : 0;
}
static int reconfig(struct vo *vo, struct mp_image_params *params)
@@ -175,33 +183,51 @@ static int resize(struct vo *vo)
{
struct priv *p = vo->priv;
struct vo_wayland_state *wl = vo->wl;
- const int32_t width = wl->scaling * mp_rect_w(wl->geometry);
- const int32_t height = wl->scaling * mp_rect_h(wl->geometry);
+ const int32_t width = mp_rect_w(wl->geometry);
+ const int32_t height = mp_rect_h(wl->geometry);
+
+ if (width == 0 || height == 0)
+ return 1;
+
struct buffer *buf;
- vo_wayland_set_opaque_region(wl, 0);
+ vo_wayland_set_opaque_region(wl, false);
vo->want_redraw = true;
vo->dwidth = width;
vo->dheight = height;
vo_get_src_dst_rects(vo, &p->src, &p->dst, &p->osd);
+
p->sws->dst = (struct mp_image_params) {
- .imgfmt = MP_SELECT_LE_BE(IMGFMT_BGR0, IMGFMT_0RGB),
+ .imgfmt = IMGFMT_WL_RGB,
.w = width,
.h = height,
.p_w = 1,
.p_h = 1,
};
mp_image_params_guess_csp(&p->sws->dst);
+ mp_mutex_lock(&vo->params_mutex);
+ vo->target_params = &p->sws->dst;
+ mp_mutex_unlock(&vo->params_mutex);
+
while (p->free_buffers) {
buf = p->free_buffers;
p->free_buffers = buf->next;
talloc_free(buf);
}
+
+ vo_wayland_handle_scale(wl);
+
return mp_sws_reinit(p->sws);
}
static int control(struct vo *vo, uint32_t request, void *data)
{
+ switch (request) {
+ case VOCTRL_SET_PANSCAN:
+ resize(vo);
+ return VO_TRUE;
+ }
+
int events = 0;
int ret = vo_wayland_control(vo, &events, request, data);
@@ -213,17 +239,17 @@ static int control(struct vo *vo, uint32_t request, void *data)
return ret;
}
-static void draw_image(struct vo *vo, struct mp_image *src)
+static void draw_frame(struct vo *vo, struct vo_frame *frame)
{
struct priv *p = vo->priv;
struct vo_wayland_state *wl = vo->wl;
+ struct mp_image *src = frame->current;
struct buffer *buf;
- if (wl->hidden)
+ bool render = vo_wayland_check_visible(vo);
+ if (!render)
return;
- wl->frame_wait = true;
-
buf = p->free_buffers;
if (buf) {
p->free_buffers = buf->next;
@@ -262,7 +288,6 @@ static void draw_image(struct vo *vo, struct mp_image *src)
mp_image_clear(&buf->mpi, 0, 0, buf->mpi.w, buf->mpi.h);
osd_draw_on_image(vo->osd, p->osd, 0, 0, &buf->mpi);
}
- talloc_free(src);
wl_surface_attach(wl->surface, buf->buffer, 0, 0);
}
@@ -270,45 +295,24 @@ static void flip_page(struct vo *vo)
{
struct vo_wayland_state *wl = vo->wl;
- wl_surface_damage(wl->surface, 0, 0, mp_rect_w(wl->geometry),
- mp_rect_h(wl->geometry));
+ wl_surface_damage_buffer(wl->surface, 0, 0, vo->dwidth,
+ vo->dheight);
wl_surface_commit(wl->surface);
if (!wl->opts->disable_vsync)
vo_wayland_wait_frame(wl);
- if (wl->presentation)
- wayland_sync_swap(wl);
+ if (wl->use_present)
+ present_sync_swap(wl->present);
}
static void get_vsync(struct vo *vo, struct vo_vsync_info *info)
{
struct vo_wayland_state *wl = vo->wl;
- if (wl->presentation) {
- info->vsync_duration = wl->vsync_duration;
- info->skipped_vsyncs = wl->last_skipped_vsyncs;
- info->last_queue_display_time = wl->last_queue_display_time;
- }
+ if (wl->use_present)
+ present_sync_get_info(wl->present, info);
}
-static void uninit(struct vo *vo)
-{
- struct priv *p = vo->priv;
- struct buffer *buf;
-
- while (p->free_buffers) {
- buf = p->free_buffers;
- p->free_buffers = buf->next;
- talloc_free(buf);
- }
- vo_wayland_uninit(vo);
-}
-
-#define OPT_BASE_STRUCT struct priv
-static const m_option_t options[] = {
- {0}
-};
-
const struct vo_driver video_out_wlshm = {
.description = "Wayland SHM video output (software scaling)",
.name = "wlshm",
@@ -316,12 +320,11 @@ const struct vo_driver video_out_wlshm = {
.query_format = query_format,
.reconfig = reconfig,
.control = control,
- .draw_image = draw_image,
+ .draw_frame = draw_frame,
.flip_page = flip_page,
.get_vsync = get_vsync,
.wakeup = vo_wayland_wakeup,
.wait_events = vo_wayland_wait_events,
.uninit = uninit,
.priv_size = sizeof(struct priv),
- .options = options,
};