From 06a1119512b8747d825038f6ac77843e8fef5410 Mon Sep 17 00:00:00 2001 From: Loki Date: Sun, 29 Aug 2021 09:34:00 +0200 Subject: [PATCH] Fix segfault for wlroots based capturing --- sunshine/platform/linux/wayland.cpp | 11 +++++------ sunshine/platform/linux/wayland.h | 2 -- sunshine/platform/linux/wlgrab.cpp | 23 +++++++++++++++++++++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/sunshine/platform/linux/wayland.cpp b/sunshine/platform/linux/wayland.cpp index 338a2115..9ca20f2a 100644 --- a/sunshine/platform/linux/wayland.cpp +++ b/sunshine/platform/linux/wayland.cpp @@ -168,7 +168,6 @@ void dmabuf_t::frame( next_frame->width = width; next_frame->height = height; next_frame->obj_count = obj_count; - next_frame->frame = frame; } void dmabuf_t::object( @@ -192,6 +191,8 @@ void dmabuf_t::ready( zwlr_export_dmabuf_frame_v1 *frame, std::uint32_t tv_sec_hi, std::uint32_t tv_sec_lo, std::uint32_t tv_nsec) { + zwlr_export_dmabuf_frame_v1_destroy(frame); + current_frame->destroy(); current_frame = get_next_frame(); @@ -201,6 +202,9 @@ void dmabuf_t::ready( void dmabuf_t::cancel( zwlr_export_dmabuf_frame_v1 *frame, zwlr_export_dmabuf_frame_v1_cancel_reason reason) { + + zwlr_export_dmabuf_frame_v1_destroy(frame); + auto next_frame = get_next_frame(); next_frame->destroy(); @@ -208,15 +212,10 @@ void dmabuf_t::cancel( } void frame_t::destroy() { - if(frame) { - zwlr_export_dmabuf_frame_v1_destroy(frame); - } - for(auto x = 0; x < obj_count; ++x) { close(fds[x]); } - frame = nullptr; obj_count = 0; } diff --git a/sunshine/platform/linux/wayland.h b/sunshine/platform/linux/wayland.h index 31905f60..ca876922 100644 --- a/sunshine/platform/linux/wayland.h +++ b/sunshine/platform/linux/wayland.h @@ -22,8 +22,6 @@ public: std::uint32_t offsets[4]; std::uint32_t plane_indices[4]; - zwlr_export_dmabuf_frame_v1 *frame; - void destroy(); }; diff --git a/sunshine/platform/linux/wlgrab.cpp b/sunshine/platform/linux/wlgrab.cpp index 1fee24a2..6b7ba492 100644 --- a/sunshine/platform/linux/wlgrab.cpp +++ b/sunshine/platform/linux/wlgrab.cpp @@ -16,6 +16,21 @@ struct img_t : public platf::img_t { } }; +class frame_descriptor_t : public egl::img_descriptor_t { +public: + ~frame_descriptor_t() { + reset(); + } + + void reset() { + std::for_each_n(fds, obj_count, [](int fd) { + close(fd); + }); + + obj_count = 0; + } +}; + class wlr_t : public platf::display_t { public: int init(platf::mem_type_e hwdevice_type, const std::string &display_name, int framerate) { @@ -259,7 +274,8 @@ public: return status; } - auto img = (egl::img_descriptor_t *)img_out_base; + auto img = (frame_descriptor_t *)img_out_base; + img->reset(); auto current_frame = dmabuf.current_frame; @@ -275,11 +291,14 @@ public: std::copy_n(std::begin(current_frame->offsets), current_frame->obj_count, img->offsets); std::copy_n(std::begin(current_frame->strides), current_frame->obj_count, img->strides); + // Prevent dmabuf from closing the file descriptors. + current_frame->obj_count = 0; + return platf::capture_e::ok; } std::shared_ptr alloc_img() override { - auto img = std::make_shared(); + auto img = std::make_shared(); img->img_width = width; img->img_height = height;