diff options
Diffstat (limited to 'video/out/vo_wlshm.c')
-rw-r--r-- | video/out/vo_wlshm.c | 119 |
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, }; |