From 3fc07f571da1eec9289f0560e972f19f545ccf7d Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Tue, 23 Jun 2020 23:04:57 +0000 Subject: [PATCH] screencopy: Use linux-dmabuf if available --- include/screencopy.h | 8 ++++++ src/screencopy.c | 59 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/include/screencopy.h b/include/screencopy.h index a5f4c11..88a5349 100644 --- a/include/screencopy.h +++ b/include/screencopy.h @@ -47,6 +47,7 @@ struct screencopy { struct zwlr_screencopy_manager_v1* manager; struct zwlr_screencopy_frame_v1* frame; + int version; uint64_t last_time; uint64_t start_time; @@ -55,6 +56,13 @@ struct screencopy { struct smooth delay_smoother; double delay; bool is_immediate_copy; + + uint32_t wl_shm_width, wl_shm_height, wl_shm_stride; + enum wl_shm_format wl_shm_format; + + bool have_linux_dmabuf; + uint32_t dmabuf_width, dmabuf_height; + uint32_t fourcc; }; void screencopy_init(struct screencopy* self); diff --git a/src/screencopy.c b/src/screencopy.c index 9882c32..c8c0680 100644 --- a/src/screencopy.c +++ b/src/screencopy.c @@ -60,25 +60,49 @@ static void screencopy_stop(struct frame_capture* fc) } } -static void screencopy_buffer(void* data, +static void screencopy_linux_dmabuf(void* data, struct zwlr_screencopy_frame_v1* frame, - enum wl_shm_format format, uint32_t width, - uint32_t height, uint32_t stride) + uint32_t format, uint32_t width, uint32_t height) { struct screencopy* self = data; - uint32_t fourcc = fourcc_from_wl_shm(format); - wv_buffer_pool_resize(self->pool, WV_BUFFER_SHM, width, height, stride, - fourcc); + self->have_linux_dmabuf = true; + self->dmabuf_width = width; + self->dmabuf_height = height; + self->fourcc = format; +} + +static void screencopy_buffer_done(void* data, + struct zwlr_screencopy_frame_v1* frame) +{ + struct screencopy* self = data; + uint32_t width, height, stride, fourcc; + + if (self->have_linux_dmabuf) { + width = self->dmabuf_width; + height = self->dmabuf_height; + stride = 0; + fourcc = self->fourcc; + wv_buffer_pool_resize(self->pool, WV_BUFFER_DMABUF, width, + height, stride, fourcc); + } else { + width = self->wl_shm_width; + height = self->wl_shm_height; + stride = self->wl_shm_stride; + fourcc = self->fourcc; + wv_buffer_pool_resize(self->pool, WV_BUFFER_SHM, width, + height, stride, self->wl_shm_format); + } struct wv_buffer* buffer = wv_buffer_pool_acquire(self->pool); if (!buffer) { self->frame_capture.status = CAPTURE_FATAL; screencopy_stop(&self->frame_capture); self->frame_capture.on_done(&self->frame_capture); + return; } - buffer->y_inverted = true; + buffer->y_inverted = !self->have_linux_dmabuf; assert(!self->front); self->front = buffer; @@ -95,6 +119,25 @@ static void screencopy_buffer(void* data, buffer->wl_buffer); } +static void screencopy_buffer(void* data, + struct zwlr_screencopy_frame_v1* frame, + enum wl_shm_format format, uint32_t width, + uint32_t height, uint32_t stride) +{ + struct screencopy* self = data; + + self->wl_shm_format = format; + self->wl_shm_width = width; + self->wl_shm_height = height; + self->wl_shm_stride = stride; + + if (self->version < 3) { + self->have_linux_dmabuf = false; + screencopy_buffer_done(data, frame); + return; + } +} + static void screencopy_flags(void* data, struct zwlr_screencopy_frame_v1* frame, uint32_t flags) @@ -177,6 +220,8 @@ static int screencopy__start_capture(struct frame_capture* fc) static const struct zwlr_screencopy_frame_v1_listener frame_listener = { .buffer = screencopy_buffer, + .linux_dmabuf = screencopy_linux_dmabuf, + .buffer_done = screencopy_buffer_done, .flags = screencopy_flags, .ready = screencopy_ready, .failed = screencopy_failed,