From 980116360b0f393e16064ec3b7a4ef9efb14372e Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Sun, 1 Oct 2017 21:07:05 +0100 Subject: vo_wayland: remove This VO was buggy and never worked correctly. Like with wayland_common, it needs to be rewritten from scratch. --- video/out/vo.c | 4 - video/out/vo_wayland.c | 682 -------------------------------------------- video/out/wayland/buffer.c | 140 --------- video/out/wayland/buffer.h | 102 ------- video/out/wayland/memfile.c | 105 ------- video/out/wayland/memfile.h | 26 -- wscript_build.py | 3 - 7 files changed, 1062 deletions(-) delete mode 100644 video/out/vo_wayland.c delete mode 100644 video/out/wayland/buffer.c delete mode 100644 video/out/wayland/buffer.h delete mode 100644 video/out/wayland/memfile.c delete mode 100644 video/out/wayland/memfile.h diff --git a/video/out/vo.c b/video/out/vo.c index 4eb0558147..d761300a47 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -61,7 +61,6 @@ extern const struct vo_driver video_out_drm; extern const struct vo_driver video_out_direct3d; extern const struct vo_driver video_out_sdl; extern const struct vo_driver video_out_vaapi; -extern const struct vo_driver video_out_wayland; extern const struct vo_driver video_out_rpi; extern const struct vo_driver video_out_tct; @@ -77,9 +76,6 @@ const struct vo_driver *const video_out_drivers[] = #if HAVE_DIRECT3D &video_out_direct3d, #endif -#if HAVE_WAYLAND - &video_out_wayland, -#endif #if HAVE_XV &video_out_xv, #endif diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c deleted file mode 100644 index 37ab4c7858..0000000000 --- a/video/out/vo_wayland.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * This file is part of mpv video player. - * Copyright © 2013 Alexander Preisinger - * - * 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 -#include -#include - -#include - -#include "config.h" - -#include "vo.h" -#include "video/mp_image.h" -#include "video/sws_utils.h" -#include "sub/osd.h" -#include "sub/img_convert.h" -#include "common/msg.h" -#include "input/input.h" -#include "osdep/endian.h" -#include "osdep/timer.h" - -#include "wayland_common.h" - -#include "video/out/wayland/buffer.h" - -static void draw_image(struct vo *vo, mp_image_t *mpi); -static void draw_osd(struct vo *vo); - -static const struct wl_buffer_listener buffer_listener; - -// TODO: pay attention to the reported subpixel order -static const format_t format_table[] = { - {WL_SHM_FORMAT_ARGB8888, IMGFMT_BGRA}, // 8b 8g 8r 8a - {WL_SHM_FORMAT_XRGB8888, IMGFMT_BGR0}, -#if BYTE_ORDER == LITTLE_ENDIAN - {WL_SHM_FORMAT_RGB565, IMGFMT_RGB565}, // 5b 6g 5r -#endif - {WL_SHM_FORMAT_RGB888, IMGFMT_BGR24}, // 8b 8g 8r - {WL_SHM_FORMAT_BGR888, IMGFMT_RGB24}, // 8r 8g 8b - {WL_SHM_FORMAT_XBGR8888, IMGFMT_RGB0}, - {WL_SHM_FORMAT_RGBX8888, IMGFMT_0BGR}, - {WL_SHM_FORMAT_BGRX8888, IMGFMT_0RGB}, - {WL_SHM_FORMAT_ABGR8888, IMGFMT_RGBA}, - {WL_SHM_FORMAT_RGBA8888, IMGFMT_ABGR}, - {WL_SHM_FORMAT_BGRA8888, IMGFMT_ARGB}, -}; - -#define MAX_FORMAT_ENTRIES (sizeof(format_table) / sizeof(format_table[0])) -#define DEFAULT_FORMAT_ENTRY 1 -#define DEFAULT_ALPHA_FORMAT_ENTRY 0 - -struct priv; - -// We only use double buffering but the creation and usage is still open to -// triple buffering. Triple buffering is now removed, because double buffering -// is now pixel-perfect. -struct buffer_pool { - shm_buffer_t **buffers; - shm_buffer_t *front_buffer; // just pointers to any of the buffers - shm_buffer_t *back_buffer; - uint32_t buffer_no; -}; - -struct supported_format { - format_t format; - bool is_alpha; - struct wl_list link; -}; - -struct priv { - struct vo *vo; - struct vo_wayland_state *wl; - - struct wl_list format_list; - const format_t *video_format; // pointer to element in supported_format list - - struct mp_rect src; - struct mp_rect dst; - int src_w, src_h; - int dst_w, dst_h; - struct mp_osd_res osd; - - struct mp_sws_context *sws; - struct mp_image_params in_format; - - struct buffer_pool video_bufpool; - - struct mp_image *original_image; - int width; // width of the original image - int height; - - int x, y; // coords for resizing - - struct wl_surface *osd_surfaces[MAX_OSD_PARTS]; - struct wl_subsurface *osd_subsurfaces[MAX_OSD_PARTS]; - shm_buffer_t *osd_buffers[MAX_OSD_PARTS]; - // this id tells us if the subtitle part has changed or not - int change_id[MAX_OSD_PARTS]; - - // options - int enable_alpha; - int use_rgb565; -}; - -static bool is_alpha_format(const format_t *fmt) -{ - return !!(mp_imgfmt_get_desc(fmt->mp_format).flags & MP_IMGFLAG_ALPHA); -} - -static const format_t* is_wayland_format_supported(struct priv *p, - enum wl_shm_format fmt) -{ - struct supported_format *sf; - - // find the matching format first - wl_list_for_each(sf, &p->format_list, link) { - if (sf->format.wl_format == fmt) { - return &sf->format; - } - } - - return NULL; -} - -// additional buffer functions - -static void buffer_finalise_front(shm_buffer_t *buf) -{ - SHM_BUFFER_SET_BUSY(buf); - SHM_BUFFER_CLEAR_DIRTY(buf); -} - -static void buffer_finalise_back(shm_buffer_t *buf) -{ - SHM_BUFFER_SET_DIRTY(buf); -} - -static struct mp_image buffer_get_mp_image(struct priv *p, - shm_buffer_t *buf) -{ - struct mp_image img = {0}; - mp_image_set_params(&img, &p->sws->dst); - - img.w = buf->stride / buf->bytes; - img.h = buf->height; - img.planes[0] = buf->data; - img.stride[0] = buf->stride; - - return img; -} - -// buffer pool functions - -static void buffer_pool_reinit(struct priv *p, - struct buffer_pool *pool, - uint32_t buffer_no, - uint32_t width, uint32_t height, - format_t fmt, - struct wl_shm *shm) -{ - if (!pool->buffers) - pool->buffers = calloc(buffer_no, sizeof(shm_buffer_t*)); - - pool->buffer_no = buffer_no; - - for (uint32_t i = 0; i < buffer_no; ++i) { - if (pool->buffers[i] == NULL) - pool->buffers[i] = shm_buffer_create(width, height, fmt, - shm, &buffer_listener); - else - shm_buffer_resize(pool->buffers[i], width, height); - } - - pool->back_buffer = pool->buffers[0]; - pool->front_buffer = pool->buffers[1]; -} - -static bool buffer_pool_resize(struct buffer_pool *pool, - int width, - int height) -{ - bool ret = true; - - for (uint32_t i = 0; ret && i < pool->buffer_no; ++i) - shm_buffer_resize(pool->buffers[i], width, height); - - return ret; -} - -static void buffer_pool_destroy(struct buffer_pool *pool) -{ - for (uint32_t i = 0; i < pool->buffer_no; ++i) - shm_buffer_destroy(pool->buffers[i]); - - free(pool->buffers); - pool->front_buffer = NULL; - pool->back_buffer = NULL; - pool->buffers = NULL; -} - -static void buffer_pool_swap(struct buffer_pool *pool) -{ - if (SHM_BUFFER_IS_DIRTY(pool->back_buffer)) { - shm_buffer_t *tmp = pool->back_buffer; - pool->back_buffer = pool->front_buffer; - pool->front_buffer = tmp; - } -} - -// returns NULL if the back buffer is busy -static shm_buffer_t * buffer_pool_get_back(struct buffer_pool *pool) -{ - if (!pool->back_buffer || SHM_BUFFER_IS_BUSY(pool->back_buffer)) - return NULL; - - return pool->back_buffer; -} - -static shm_buffer_t * buffer_pool_get_front(struct buffer_pool *pool) -{ - return pool->front_buffer; -} - -static bool redraw_frame(struct priv *p) -{ - draw_image(p->vo, NULL); - return true; -} - -static bool resize(struct priv *p) -{ - struct vo_wayland_state *wl = p->wl; - - if (!p->video_bufpool.back_buffer || SHM_BUFFER_IS_BUSY(p->video_bufpool.back_buffer)) - return false; // skip resizing if we can't guarantee pixel perfectness! - - int32_t scale = 1; - int32_t x = wl->window.sh_x; - int32_t y = wl->window.sh_y; - - if (wl->display.current_output) - scale = wl->display.current_output->scale; - - wl->vo->dwidth = scale*wl->window.sh_width; - wl->vo->dheight = scale*wl->window.sh_height; - - vo_get_src_dst_rects(p->vo, &p->src, &p->dst, &p->osd); - p->src_w = p->src.x1 - p->src.x0; - p->src_h = p->src.y1 - p->src.y0; - p->dst_w = p->dst.x1 - p->dst.x0; - p->dst_h = p->dst.y1 - p->dst.y0; - - mp_input_set_mouse_transform(p->vo->input_ctx, &p->dst, NULL); - - MP_DBG(wl, "resizing %dx%d -> %dx%d\n", wl->window.width, - wl->window.height, - p->dst_w, - p->dst_h); - - if (x != 0) - x = wl->window.width - p->dst_w; - - if (y != 0) - y = wl->window.height - p->dst_h; - - wl_surface_set_buffer_scale(wl->window.video_surface, scale); - mp_sws_set_from_cmdline(p->sws, p->vo->opts->sws_opts); - p->sws->src = p->in_format; - p->sws->dst = (struct mp_image_params) { - .imgfmt = p->video_format->mp_format, - .w = p->dst_w, - .h = p->dst_h, - .p_w = 1, - .p_h = 1, - }; - - mp_image_params_guess_csp(&p->sws->dst); - - if (mp_sws_reinit(p->sws) < 0) - return false; - - if (!buffer_pool_resize(&p->video_bufpool, p->dst_w, p->dst_h)) { - MP_ERR(wl, "failed to resize video buffers\n"); - return false; - } - - wl->window.width = p->dst_w; - wl->window.height = p->dst_h; - - // if no alpha enabled format is used then create an opaque region to allow - // the compositor to optimize the drawing of the window - if (!p->enable_alpha) { - struct wl_region *opaque = - wl_compositor_create_region(wl->display.compositor); - wl_region_add(opaque, 0, 0, p->dst_w/scale, p->dst_h/scale); - wl_surface_set_opaque_region(wl->window.video_surface, opaque); - wl_region_destroy(opaque); - } - - p->x = x; - p->y = y; - p->vo->want_redraw = true; - return true; -} - - -/* wayland listeners */ - -static void buffer_handle_release(void *data, struct wl_buffer *buffer) -{ - shm_buffer_t *buf = data; - - if (SHM_BUFFER_IS_ONESHOT(buf)) { - shm_buffer_destroy(buf); - return; - } - - SHM_BUFFER_CLEAR_BUSY(buf); - // does nothing and returns 0 if no pending resize flag was set - shm_buffer_pending_resize(buf); -} - -static const struct wl_buffer_listener buffer_listener = { - buffer_handle_release -}; - -static void shm_handle_format(void *data, - struct wl_shm *wl_shm, - uint32_t format) -{ - struct priv *p = data; - for (uint32_t i = 0; i < MAX_FORMAT_ENTRIES; ++i) { - if (format_table[i].wl_format == format) { - MP_INFO(p->wl, "format %s supported by hw\n", - mp_imgfmt_to_name(format_table[i].mp_format)); - struct supported_format *sf = talloc(p, struct supported_format); - sf->format = format_table[i]; - sf->is_alpha = is_alpha_format(&sf->format); - wl_list_insert(&p->format_list, &sf->link); - } - } -} - -static const struct wl_shm_listener shm_listener = { - shm_handle_format -}; - - -/* mpv interface */ - -static void draw_image(struct vo *vo, mp_image_t *mpi) -{ - struct priv *p = vo->priv; - - if (mpi) { - talloc_free(p->original_image); - p->original_image = mpi; - } - - vo_wayland_wait_events(vo, 0); - - shm_buffer_t *buf = buffer_pool_get_back(&p->video_bufpool); - - if (!buf) { - MP_VERBOSE(p->wl, "can't draw, back buffer is busy\n"); - return; - } - - struct mp_image img = buffer_get_mp_image(p, buf); - - if (p->original_image) { - struct mp_image src = *p->original_image; - struct mp_rect src_rc = p->src; - src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, src.fmt.align_x); - src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, src.fmt.align_y); - mp_image_crop_rc(&src, src_rc); - - mp_sws_scale(p->sws, &img, &src); - } else { - mp_image_clear(&img, 0, 0, img.w, img.h); - } - - buffer_finalise_back(buf); - - draw_osd(vo); -} - -static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs) -{ - struct priv *p = ctx; - int id = imgs->render_index; - - struct wl_surface *s = p->osd_surfaces[id]; - - if (imgs->change_id != p->change_id[id]) { - p->change_id[id] = imgs->change_id; - - struct mp_rect bb; - if (!mp_sub_bitmaps_bb(imgs, &bb)) - return; - - int width = mp_rect_w(bb); - int height = mp_rect_h(bb); - - if (!p->osd_buffers[id]) { - p->osd_buffers[id] = shm_buffer_create(width, - height, - format_table[DEFAULT_ALPHA_FORMAT_ENTRY], - p->wl->display.shm, - &buffer_listener); - } - else if (SHM_BUFFER_IS_BUSY(p->osd_buffers[id])) { - // freed on release in buffer_listener - // guarantees pixel perfect resizing of subtitles and osd - SHM_BUFFER_SET_ONESHOT(p->osd_buffers[id]); - p->osd_buffers[id] = shm_buffer_create(width, - height, - format_table[DEFAULT_ALPHA_FORMAT_ENTRY], - p->wl->display.shm, - &buffer_listener); - } - else { - shm_buffer_resize(p->osd_buffers[id], width, height); - } - - shm_buffer_t *buf = p->osd_buffers[id]; - SHM_BUFFER_SET_BUSY(buf); - - struct mp_image wlimg = buffer_get_mp_image(p, buf); - - for (int n = 0; n < imgs->num_parts; n++) { - struct sub_bitmap *sub = &imgs->parts[n]; - memcpy_pic(wlimg.planes[0], sub->bitmap, sub->w * 4, sub->h, - wlimg.stride[0], sub->stride); - } - - wl_subsurface_set_position(p->osd_subsurfaces[id], 0, 0); - wl_surface_attach(s, buf->buffer, bb.x0, bb.y0); - wl_surface_damage(s, 0, 0, width, height); - wl_surface_commit(s); - } - else { - // p->osd_buffer, guaranteed to exist here - assert(p->osd_buffers[id]); - wl_surface_attach(s, p->osd_buffers[id]->buffer, 0, 0); - wl_surface_commit(s); - } -} - -static const bool osd_formats[SUBBITMAP_COUNT] = { - [SUBBITMAP_RGBA] = true, -}; - -static void draw_osd(struct vo *vo) -{ - int32_t scale = 1; - struct priv *p = vo->priv; - - if (p->wl && p->wl->display.current_output) - scale = p->wl->display.current_output->scale; - - // detach all buffers and attach all needed buffers in osd_draw - // only the most recent attach & commit is applied once the parent surface - // is committed - for (int i = 0; i < MAX_OSD_PARTS; ++i) { - struct wl_surface *s = p->osd_surfaces[i]; - wl_surface_attach(s, NULL, 0, 0); - wl_surface_set_buffer_scale(s, scale); - wl_surface_damage(s, 0, 0, p->dst_w, p->dst_h); - wl_surface_commit(s); - } - - double pts = p->original_image ? p->original_image->pts : 0; - osd_draw(vo->osd, p->osd, pts, 0, osd_formats, draw_osd_cb, p); -} - -static void redraw(void *data, uint32_t time) -{ - struct priv *p = data; - - shm_buffer_t *buf = buffer_pool_get_front(&p->video_bufpool); - wl_surface_attach(p->wl->window.video_surface, buf->buffer, p->x, p->y); - wl_surface_damage(p->wl->window.video_surface, 0, 0, p->dst_w, p->dst_h); - buffer_finalise_front(buf); - - p->x = 0; - p->y = 0; -} - -static void flip_page(struct vo *vo) -{ - struct priv *p = vo->priv; - - buffer_pool_swap(&p->video_bufpool); - - if (!p->wl->frame.callback) - vo_wayland_request_frame(vo, p, redraw); - - vo_wayland_wait_events(vo, 0); -} - -static int query_format(struct vo *vo, int format) -{ - struct priv *p = vo->priv; - struct supported_format *sf; - wl_list_for_each_reverse(sf, &p->format_list, link) { - if (sf->format.mp_format == format) - return 1; - } - - if (mp_sws_supported_format(format)) - return 1; - - return 0; -} - -static int reconfig(struct vo *vo, struct mp_image_params *fmt) -{ - struct priv *p = vo->priv; - mp_image_unrefp(&p->original_image); - - p->width = fmt->w; - p->height = fmt->h; - p->in_format = *fmt; - - struct supported_format *sf; - - // find the matching format first - wl_list_for_each(sf, &p->format_list, link) { - if (sf->format.mp_format == fmt->imgfmt && - (p->enable_alpha == sf->is_alpha)) - { - p->video_format = &sf->format; - break; - } - } - - if (!p->video_format) { - // if use default is enable overwrite the auto selected one - if (p->enable_alpha) - p->video_format = &format_table[DEFAULT_ALPHA_FORMAT_ENTRY]; - else - p->video_format = &format_table[DEFAULT_FORMAT_ENTRY]; - } - - // overrides alpha - // use rgb565 if performance is your main concern - if (p->use_rgb565) { - MP_INFO(p->wl, "using rgb565\n"); - const format_t *entry = - is_wayland_format_supported(p, WL_SHM_FORMAT_RGB565); - if (entry) - p->video_format = entry; - } - - buffer_pool_reinit(p, &p->video_bufpool, 2, p->width, p->height, - *p->video_format, p->wl->display.shm); - - vo_wayland_config(vo); - - resize(p); - - return 0; -} - -static void uninit(struct vo *vo) -{ - struct priv *p = vo->priv; - buffer_pool_destroy(&p->video_bufpool); - - talloc_free(p->original_image); - - for (int i = 0; i < MAX_OSD_PARTS; ++i) { - shm_buffer_destroy(p->osd_buffers[i]); - wl_subsurface_destroy(p->osd_subsurfaces[i]); - wl_surface_destroy(p->osd_surfaces[i]); - } - - vo_wayland_uninit(vo); -} - -static int preinit(struct vo *vo) -{ - struct priv *p = vo->priv; - struct vo_wayland_state *wl = NULL; - - if (!vo_wayland_init(vo)) - return -1; - - wl = vo->wayland; - - p->vo = vo; - p->wl = wl; - p->sws = mp_sws_alloc(vo); - - wl_list_init(&p->format_list); - - wl_shm_add_listener(wl->display.shm, &shm_listener, p); - wl_display_dispatch(wl->display.display); - - // Commits on surfaces bound to a subsurface are cached until the parent - // surface is committed, in this case the video surface. - // Which means we can call commit anywhere. - struct wl_region *input = - wl_compositor_create_region(wl->display.compositor); - for (int i = 0; i < MAX_OSD_PARTS; ++i) { - p->osd_surfaces[i] = - wl_compositor_create_surface(wl->display.compositor); - wl_surface_attach(p->osd_surfaces[i], NULL, 0, 0); - wl_surface_set_input_region(p->osd_surfaces[i], input); - p->osd_subsurfaces[i] = - wl_subcompositor_get_subsurface(wl->display.subcomp, - p->osd_surfaces[i], - wl->window.video_surface); // parent - wl_surface_commit(p->osd_surfaces[i]); - wl_subsurface_set_sync(p->osd_subsurfaces[i]); - } - wl_region_destroy(input); - - return 0; -} - -static int control(struct vo *vo, uint32_t request, void *data) -{ - struct priv *p = vo->priv; - switch (request) { - case VOCTRL_SET_PANSCAN: { - resize(p); - return VO_TRUE; - } - case VOCTRL_REDRAW_FRAME: - return redraw_frame(p); - } - int events = 0; - int r = vo_wayland_control(vo, &events, request, data); - - // NOTE: VO_EVENT_EXPOSE is never returned by the wayland backend - if (events & VO_EVENT_RESIZE) - resize(p); - - vo_event(vo, events); - - return r; -} - -#define OPT_BASE_STRUCT struct priv -const struct vo_driver video_out_wayland = { - .description = "Wayland SHM video output", - .name = "wayland", - .priv_size = sizeof(struct priv), - .preinit = preinit, - .query_format = query_format, - .reconfig = reconfig, - .control = control, - .draw_image = draw_image, - .flip_page = flip_page, - .wakeup = vo_wayland_wakeup, - .wait_events = vo_wayland_wait_events, - .uninit = uninit, - .options = (const struct m_option[]) { - OPT_FLAG("alpha", enable_alpha, 0), - OPT_FLAG("rgb565", use_rgb565, 0), - {0} - }, - .options_prefix = "vo-wayland", -}; - diff --git a/video/out/wayland/buffer.c b/video/out/wayland/buffer.c deleted file mode 100644 index dce3ca4333..0000000000 --- a/video/out/wayland/buffer.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of mpv video player. - * Copyright © 2014 Alexander Preisinger - * - * 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 "buffer.h" -#include "memfile.h" - -#include -#include - -int8_t format_get_bytes(const format_t *fmt) -{ - return mp_imgfmt_get_desc(fmt->mp_format).bytes[0]; -} - -shm_buffer_t* shm_buffer_create(uint32_t width, - uint32_t height, - format_t fmt, - struct wl_shm *shm, - const struct wl_buffer_listener *listener) -{ - int8_t bytes = format_get_bytes(&fmt); - uint32_t stride = SHM_BUFFER_STRIDE(width, bytes); - uint32_t size = stride * height; - - shm_buffer_t *buffer = calloc(1, sizeof(shm_buffer_t)); - int fd = memfile_create(size); - - if (fd < 0) { - free(buffer); - return NULL; - } - - buffer->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - - if (buffer->data == MAP_FAILED) { - close(fd); - free(buffer); - return NULL; - } - - buffer->shm_pool = wl_shm_create_pool(shm, fd, size); - buffer->buffer = wl_shm_pool_create_buffer(buffer->shm_pool, - 0, width, height, stride, - fmt.wl_format); - - wl_buffer_add_listener(buffer->buffer, listener, buffer); - - buffer->fd = fd; - buffer->height = height; - buffer->stride = stride; - buffer->format = fmt; - buffer->bytes = bytes; - buffer->pool_size = size; - buffer->pending_height = 0; - buffer->pending_width = 0; - - return buffer; -} - -int shm_buffer_resize(shm_buffer_t *buffer, uint32_t width, uint32_t height) -{ - uint32_t new_stride = SHM_BUFFER_STRIDE(width, buffer->bytes); - uint32_t new_size = new_stride * height; - - if (SHM_BUFFER_IS_BUSY(buffer)) { - SHM_BUFFER_SET_PNDNG_RSZ(buffer); - buffer->pending_width = width; - buffer->pending_height = height; - return SHM_BUFFER_BUSY; - } - - SHM_BUFFER_CLEAR_PNDNG_RSZ(buffer); - - if (new_size > buffer->pool_size) { - munmap(buffer->data, buffer->pool_size); - ftruncate(buffer->fd, new_size); - - buffer->data = mmap(NULL, new_size, PROT_READ | PROT_WRITE, - MAP_SHARED, buffer->fd, 0); - - // TODO: the buffer should be destroyed when -1 is return - if (buffer->data == MAP_FAILED) - return -1; - - wl_shm_pool_resize(buffer->shm_pool, new_size); - buffer->pool_size = new_size; - } - - const void *listener = wl_proxy_get_listener((struct wl_proxy*)buffer->buffer); - - wl_buffer_destroy(buffer->buffer); - buffer->buffer = wl_shm_pool_create_buffer(buffer->shm_pool, - 0, width, height, new_stride, - buffer->format.wl_format); - - wl_buffer_add_listener(buffer->buffer, listener, buffer); - - buffer->height = height; - buffer->stride = new_stride; - - return 0; -} - -int shm_buffer_pending_resize(shm_buffer_t *buffer) -{ - if (SHM_BUFFER_PENDING_RESIZE(buffer)) { - SHM_BUFFER_CLEAR_PNDNG_RSZ(buffer); - return shm_buffer_resize(buffer, buffer->pending_width, buffer->pending_height); - } - else { - return 0; - } -} - -void shm_buffer_destroy(shm_buffer_t *buffer) -{ - if (!buffer) - return; - - wl_buffer_destroy(buffer->buffer); - wl_shm_pool_destroy(buffer->shm_pool); - munmap(buffer->data, buffer->pool_size); - close(buffer->fd); - free(buffer); -} diff --git a/video/out/wayland/buffer.h b/video/out/wayland/buffer.h deleted file mode 100644 index 783cd10713..0000000000 --- a/video/out/wayland/buffer.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of mpv video player. - * Copyright © 2014 Alexander Preisinger - * - * 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_WAYLAND_BUFFER_H -#define MPLAYER_WAYLAND_BUFFER_H - -#include -#include "video/sws_utils.h" -#include "video/img_format.h" -#include "video/out/wayland_common.h" - -#define SHM_BUFFER_STRIDE(width, bytes) \ - FFALIGN((width) * (bytes), SWS_MIN_BYTE_ALIGN) - -typedef struct format { - enum wl_shm_format wl_format; - enum mp_imgfmt mp_format; -} format_t; - -int8_t format_get_bytes(const format_t *fmt); - -typedef enum shm_buffer_flags { - SHM_BUFFER_BUSY = 1 << 0, // in use by the compositor - SHM_BUFFER_DIRTY = 1 << 1, // buffer contains new content - SHM_BUFFER_ONESHOT = 1 << 2, // free after release - SHM_BUFFER_RESIZE_LATER = 1 << 3, // free after release -} shm_buffer_flags_t; - -#define SHM_BUFFER_IS_BUSY(b) (!!((b)->flags & SHM_BUFFER_BUSY)) -#define SHM_BUFFER_IS_DIRTY(b) (!!((b)->flags & SHM_BUFFER_DIRTY)) -#define SHM_BUFFER_IS_ONESHOT(b) (!!((b)->flags & SHM_BUFFER_ONESHOT)) -#define SHM_BUFFER_PENDING_RESIZE(b) (!!((b)->flags & SHM_BUFFER_RESIZE_LATER)) - -#define SHM_BUFFER_SET_BUSY(b) (b)->flags |= SHM_BUFFER_BUSY -#define SHM_BUFFER_SET_DIRTY(b) (b)->flags |= SHM_BUFFER_DIRTY -#define SHM_BUFFER_SET_ONESHOT(b) (b)->flags |= SHM_BUFFER_ONESHOT -#define SHM_BUFFER_SET_PNDNG_RSZ(b) (b)->flags |= SHM_BUFFER_RESIZE_LATER - -#define SHM_BUFFER_CLEAR_BUSY(b) (b)->flags &= ~SHM_BUFFER_BUSY -#define SHM_BUFFER_CLEAR_DIRTY(b) (b)->flags &= ~SHM_BUFFER_DIRTY -#define SHM_BUFFER_CLEAR_ONESHOT(b) (b)->flags &= ~SHM_BUFFER_ONESHOT -#define SHM_BUFFER_CLEAR_PNDNG_RSZ(b) (b)->flags &= ~SHM_BUFFER_RESIZE_LATER - -typedef struct buffer { - struct wl_buffer *buffer; - - int flags; - - uint32_t height; - uint32_t stride; - uint32_t bytes; // bytes per pixel - // width = stride / bytes per pixel - // size = stride * height - - struct wl_shm_pool *shm_pool; // for growing buffers; - - int fd; - void *data; - uint32_t pool_size; // size of pool and data XXX - // pool_size can be far bigger than the buffer size - - format_t format; - - uint32_t pending_height; - uint32_t pending_width; -} shm_buffer_t; - -shm_buffer_t* shm_buffer_create(uint32_t width, - uint32_t height, - format_t fmt, - struct wl_shm *shm, - const struct wl_buffer_listener *listener); - -// shm pool is only able to grow and won't shrink -// returns 0 on success or buffer flags indicating the buffer status which -// prevent it from resizing -int shm_buffer_resize(shm_buffer_t *buffer, uint32_t width, uint32_t height); - -// if shm_buffer_resize returns SHM_BUFFER_BUSY this function can be called -// after the buffer is released to resize it afterwards -// returns 0 if no pending resize flag was set and -1 on errors -int shm_buffer_pending_resize(shm_buffer_t *buffer); - -// buffer is freed, don't use the buffer after calling this function on it -void shm_buffer_destroy(shm_buffer_t *buffer); - -#endif /* MPLAYER_WAYLAND_BUFFER_H */ diff --git a/video/out/wayland/memfile.c b/video/out/wayland/memfile.c deleted file mode 100644 index f28216d083..0000000000 --- a/video/out/wayland/memfile.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of mpv video player. - * Copyright © 2014 Alexander Preisinger - * - * 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 -#include -#include -#include -#include - -#include "video/out/wayland/memfile.h" - -/* copied from weston clients */ -static int set_cloexec_or_close(int fd) -{ - long flags; - - if (fd == -1) - return -1; - - if ((flags = fcntl(fd, F_GETFD)) == -1) - goto err; - - if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) - goto err; - - return fd; - -err: - close(fd); - return -1; -} - -static int create_tmpfile_cloexec(char *tmpname) -{ - int fd; - -#ifdef HAVE_MKOSTEMP - fd = mkostemp(tmpname, O_CLOEXEC); - if (fd >= 0) - unlink(tmpname); -#else - fd = mkstemp(tmpname); - if (fd >= 0) { - fd = set_cloexec_or_close(fd); - unlink(tmpname); - } -#endif - - return fd; -} - -static int os_create_anonymous_file(off_t size) -{ - static const char template[] = "/mpv-temp-XXXXXX"; - const char *path; - char *name; - int fd; - - path = getenv("XDG_RUNTIME_DIR"); - if (!path) { - errno = ENOENT; - return -1; - } - - name = malloc(strlen(path) + sizeof(template)); - if (!name) - return -1; - - strcpy(name, path); - strcat(name, template); - - fd = create_tmpfile_cloexec(name); - - free(name); - - if (fd < 0) - return -1; - - if (ftruncate(fd, size) < 0) { - close(fd); - return -1; - } - - return fd; -} - -int memfile_create(off_t size) -{ - return os_create_anonymous_file(size); -} diff --git a/video/out/wayland/memfile.h b/video/out/wayland/memfile.h deleted file mode 100644 index 67cdb1b923..0000000000 --- a/video/out/wayland/memfile.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of mpv video player. - * Copyright © 2014 Alexander Preisinger - * - * 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_WAYLAND_MEMFILE_H -#define MPLAYER_WAYLAND_MEMFILE_H - -// create file decsriptor to memory space without filesystem representation -// truncates to size immediately -int memfile_create(off_t size); - -#endif /* MPLAYER_WAYLAND_MEMFILE_H */ diff --git a/wscript_build.py b/wscript_build.py index 3f64058a43..5d8ee616fe 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -438,7 +438,6 @@ def build(ctx): ( "video/out/vo_tct.c" ), ( "video/out/vo_vaapi.c", "vaapi-x11 && gpl" ), ( "video/out/vo_vdpau.c", "vdpau" ), - ( "video/out/vo_wayland.c", "wayland" ), ( "video/out/vo_x11.c" , "x11" ), ( "video/out/vo_xv.c", "xv" ), ( "video/out/w32_common.c", "win32-desktop" ), @@ -455,8 +454,6 @@ def build(ctx): ( "video/out/vulkan/spirv_nvidia.c", "vulkan" ), ( "video/out/win32/exclusive_hack.c", "gl-win32" ), ( "video/out/wayland_common.c", "wayland" ), - ( "video/out/wayland/buffer.c", "wayland" ), - ( "video/out/wayland/memfile.c", "wayland" ), ( "video/out/win_state.c"), ( "video/out/x11_common.c", "x11" ), ( "video/out/drm_common.c", "drm" ), -- cgit v1.2.3