From 815b6ad52f08de3dd9447b88946c869e65b7d72c Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Fri, 26 Jun 2020 21:44:58 +0000 Subject: [PATCH] Remove frame-capture abstraction --- include/frame-capture.h | 77 --------------------------------------- include/screencopy.h | 22 ++++++++--- src/main.c | 81 +++++++++++++++++++++-------------------- src/screencopy.c | 67 ++++++++++++++-------------------- 4 files changed, 84 insertions(+), 163 deletions(-) delete mode 100644 include/frame-capture.h diff --git a/include/frame-capture.h b/include/frame-capture.h deleted file mode 100644 index 871f01e..0000000 --- a/include/frame-capture.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2019 - 2020 Andri Yngvason - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#pragma once - -#include -#include - -struct wl_output; -struct nvnc_fb; -struct renderer; - -enum frame_capture_status { - CAPTURE_STOPPED = 0, - CAPTURE_IN_PROGRESS, - CAPTURE_FAILED, - CAPTURE_FATAL, - CAPTURE_DONE, -}; - -enum frame_capture_options { - CAPTURE_NOW = 1 << 0, -}; - -struct frame_capture { - enum frame_capture_status status; - - bool overlay_cursor; - struct wl_output* wl_output; - - void* userdata; - void (*on_done)(struct frame_capture*); - - struct { - uint32_t fourcc_format; - uint32_t width; - uint32_t height; - uint32_t stride; - } frame_info; - - struct { - void (*render)(struct frame_capture*, struct renderer*, - struct nvnc_fb* fb); - int (*start)(struct frame_capture*, enum frame_capture_options); - void (*stop)(struct frame_capture*); - } backend; -}; - -static inline int frame_capture_start(struct frame_capture* self, enum frame_capture_options options) -{ - return self->backend.start(self, options); -} - -static inline void frame_capture_stop(struct frame_capture* self) -{ - self->backend.stop(self); -} - -static inline void frame_capture_render(struct frame_capture* self, - struct renderer* renderer, - struct nvnc_fb* fb) -{ - return self->backend.render(self, renderer, fb); -} diff --git a/include/screencopy.h b/include/screencopy.h index 88a5349..5387ade 100644 --- a/include/screencopy.h +++ b/include/screencopy.h @@ -19,7 +19,6 @@ #include #include "wlr-screencopy-unstable-v1.h" -#include "frame-capture.h" #include "smooth.h" #include "buffer.h" @@ -32,14 +31,15 @@ struct aml_timer; struct renderer; enum screencopy_status { - SCREENCOPY_STATUS_CAPTURING = 0, - SCREENCOPY_STATUS_FATAL, - SCREENCOPY_STATUS_FAILED, - SCREENCOPY_STATUS_DONE, + SCREENCOPY_STOPPED = 0, + SCREENCOPY_IN_PROGRESS, + SCREENCOPY_FAILED, + SCREENCOPY_FATAL, + SCREENCOPY_DONE, }; struct screencopy { - struct frame_capture frame_capture; + enum screencopy_status status; struct wv_buffer_pool* pool; struct wv_buffer* front; @@ -49,6 +49,9 @@ struct screencopy { struct zwlr_screencopy_frame_v1* frame; int version; + void* userdata; + void (*on_done)(struct screencopy*); + uint64_t last_time; uint64_t start_time; struct aml_timer* timer; @@ -56,6 +59,8 @@ struct screencopy { struct smooth delay_smoother; double delay; bool is_immediate_copy; + bool overlay_cursor; + struct wl_output* wl_output; uint32_t wl_shm_width, wl_shm_height, wl_shm_stride; enum wl_shm_format wl_shm_format; @@ -67,3 +72,8 @@ struct screencopy { void screencopy_init(struct screencopy* self); void screencopy_destroy(struct screencopy* self); + +int screencopy_start(struct screencopy* self); +int screencopy_start_immediate(struct screencopy* self); + +void screencopy_stop(struct screencopy* self); diff --git a/src/main.c b/src/main.c index 68fd6a6..967eff9 100644 --- a/src/main.c +++ b/src/main.c @@ -37,7 +37,6 @@ #include #include -#include "frame-capture.h" #include "wlr-screencopy-unstable-v1.h" #include "wlr-virtual-pointer-unstable-v1.h" #include "virtual-keyboard-unstable-v1.h" @@ -76,8 +75,7 @@ struct wayvnc { const struct output* selected_output; const struct seat* selected_seat; - struct screencopy screencopy_backend; - struct frame_capture* capture_backend; + struct screencopy screencopy; struct pointer pointer_backend; struct keyboard keyboard_backend; @@ -95,7 +93,7 @@ struct wayvnc { }; void wayvnc_exit(struct wayvnc* self); -void on_capture_done(struct frame_capture* capture); +void on_capture_done(struct screencopy* sc); static void on_render(struct nvnc_display* display, struct nvnc_fb* fb); struct wl_shm* wl_shm = NULL; @@ -136,11 +134,11 @@ static void registry_add(void* data, struct wl_registry* registry, } if (strcmp(interface, zwlr_screencopy_manager_v1_interface.name) == 0) { - self->screencopy_backend.manager = + self->screencopy.manager = wl_registry_bind(registry, id, &zwlr_screencopy_manager_v1_interface, version); - self->screencopy_backend.version = version; + self->screencopy.version = version; return; } @@ -251,8 +249,8 @@ void wayvnc_destroy(struct wayvnc* self) zwlr_virtual_pointer_manager_v1_destroy(self->pointer_manager); pointer_destroy(&self->pointer_backend); - if (self->screencopy_backend.manager) - zwlr_screencopy_manager_v1_destroy(self->screencopy_backend.manager); + if (self->screencopy.manager) + zwlr_screencopy_manager_v1_destroy(self->screencopy.manager); wl_display_disconnect(self->display); } @@ -307,13 +305,13 @@ static int init_wayland(struct wayvnc* self) wl_display_dispatch(self->display); wl_display_roundtrip(self->display); - if (!self->screencopy_backend.manager) { + if (!self->screencopy.manager) { log_error("Compositor doesn't support screencopy! Exiting.\n"); goto failure; } - self->screencopy_backend.frame_capture.on_done = on_capture_done; - self->screencopy_backend.frame_capture.userdata = self; + self->screencopy.on_done = on_capture_done; + self->screencopy.userdata = self; return 0; @@ -454,9 +452,14 @@ failure: return -1; } -int wayvnc_start_capture(struct wayvnc* self, enum frame_capture_options opt) +int wayvnc_start_capture(struct wayvnc* self) { - return frame_capture_start(self->capture_backend, opt); + return screencopy_start(&self->screencopy); +} + +int wayvnc_start_capture_immediate(struct wayvnc* self) +{ + return screencopy_start_immediate(&self->screencopy); } static void on_render(struct nvnc_display* display, struct nvnc_fb* fb) @@ -464,11 +467,11 @@ static void on_render(struct nvnc_display* display, struct nvnc_fb* fb) struct nvnc* nvnc = nvnc_display_get_server(display); struct wayvnc* self = nvnc_get_userdata(nvnc); - if (!self->screencopy_backend.back) + if (!self->screencopy.back) return; enum wl_output_transform transform = self->selected_output->transform; - wv_pixman_render(fb, self->screencopy_backend.back, transform, + wv_pixman_render(fb, self->screencopy.back, transform, &self->current_damage); pixman_region_clear(&self->current_damage); } @@ -490,8 +493,8 @@ void wayvnc_process_frame(struct wayvnc* self) nvnc_display_set_buffer(self->nvnc_display, self->buffer); damage_refinery_init(&self->damage_refinery, - self->screencopy_backend.back->width, - self->screencopy_backend.back->height); + self->screencopy.back->width, + self->screencopy.back->height); } else { // TODO: Reallocate assert(width == nvnc_fb_get_width(self->buffer)); @@ -502,8 +505,8 @@ void wayvnc_process_frame(struct wayvnc* self) pixman_region_init(&txdamage); pixman_region_init(&refined); damage_refine(&self->damage_refinery, &refined, - &self->screencopy_backend.back->damage, - self->screencopy_backend.back); + &self->screencopy.back->damage, + self->screencopy.back); wv_region_transform(&txdamage, &refined, self->selected_output->transform, self->selected_output->width, @@ -513,32 +516,32 @@ void wayvnc_process_frame(struct wayvnc* self) pixman_region_fini(&refined); pixman_region_fini(&txdamage); - if (wayvnc_start_capture(self, 0) < 0) { + if (wayvnc_start_capture(self) < 0) { log_error("Failed to start capture. Exiting...\n"); wayvnc_exit(self); } } -void on_capture_done(struct frame_capture* capture) +void on_capture_done(struct screencopy* sc) { - struct wayvnc* self = capture->userdata; + struct wayvnc* self = sc->userdata; - switch (capture->status) { - case CAPTURE_STOPPED: + switch (sc->status) { + case SCREENCOPY_STOPPED: break; - case CAPTURE_IN_PROGRESS: + case SCREENCOPY_IN_PROGRESS: break; - case CAPTURE_FATAL: + case SCREENCOPY_FATAL: log_error("Fatal error while capturing. Exiting...\n"); wayvnc_exit(self); break; - case CAPTURE_FAILED: - if (wayvnc_start_capture(self, CAPTURE_NOW) < 0) { + case SCREENCOPY_FAILED: + if (wayvnc_start_capture_immediate(self) < 0) { log_error("Failed to start capture. Exiting...\n"); wayvnc_exit(self); } break; - case CAPTURE_DONE: + case SCREENCOPY_DONE: wayvnc_process_frame(self); break; } @@ -722,7 +725,7 @@ int main(int argc, char* argv[]) self.selected_output = out; self.selected_seat = seat; - self.screencopy_backend.frame_capture.wl_output = out->wl_output; + self.screencopy.wl_output = out->wl_output; self.keyboard_backend.virtual_keyboard = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard( @@ -766,21 +769,19 @@ int main(int argc, char* argv[]) if (init_nvnc(&self, address, port) < 0) goto nvnc_failure; - if (self.screencopy_backend.manager) - screencopy_init(&self.screencopy_backend); + if (self.screencopy.manager) + screencopy_init(&self.screencopy); - if (!self.screencopy_backend.manager) { + if (!self.screencopy.manager) { log_error("screencopy is not supported by compositor\n"); goto capture_failure; } - self.capture_backend = &self.screencopy_backend.frame_capture; - pixman_region_init(&self.current_damage); - self.capture_backend->overlay_cursor = overlay_cursor; + self.screencopy.overlay_cursor = overlay_cursor; - if (wayvnc_start_capture(&self, 0) < 0) + if (wayvnc_start_capture(&self) < 0) goto capture_failure; wl_display_dispatch(self.display); @@ -791,7 +792,7 @@ int main(int argc, char* argv[]) aml_dispatch(aml); } - frame_capture_stop(self.capture_backend); + screencopy_stop(&self.screencopy); if (self.buffer) nvnc_fb_unref(self.buffer); @@ -801,8 +802,8 @@ int main(int argc, char* argv[]) nvnc_close(self.nvnc); if (zwp_linux_dmabuf) zwp_linux_dmabuf_v1_destroy(zwp_linux_dmabuf); - if (self.screencopy_backend.manager) - screencopy_destroy(&self.screencopy_backend); + if (self.screencopy.manager) + screencopy_destroy(&self.screencopy); wayvnc_destroy(&self); aml_unref(aml); diff --git a/src/screencopy.c b/src/screencopy.c index 5952f99..a0efa00 100644 --- a/src/screencopy.c +++ b/src/screencopy.c @@ -26,7 +26,6 @@ #include "wlr-screencopy-unstable-v1.h" #include "buffer.h" -#include "frame-capture.h" #include "shm.h" #include "screencopy.h" #include "smooth.h" @@ -36,13 +35,12 @@ #define RATE_LIMIT 20.0 // Hz #define DELAY_SMOOTHER_TIME_CONSTANT 0.5 // s -static void screencopy_stop(struct frame_capture* fc) +void screencopy_stop(struct screencopy* self) { - struct screencopy* self = (void*)fc; aml_stop(aml_get_default(), self->timer); - self->frame_capture.status = CAPTURE_STOPPED; + self->status = SCREENCOPY_STOPPED; if (self->frame) { zwlr_screencopy_frame_v1_destroy(self->frame); @@ -86,9 +84,9 @@ static void screencopy_buffer_done(void* data, 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); + screencopy_stop(self); + self->status = SCREENCOPY_FATAL; + self->on_done(self); return; } @@ -97,11 +95,6 @@ static void screencopy_buffer_done(void* data, assert(!self->front); self->front = buffer; - self->frame_capture.frame_info.fourcc_format = fourcc; - self->frame_capture.frame_info.width = width; - self->frame_capture.frame_info.height = height; - self->frame_capture.frame_info.stride = stride; - if (self->is_immediate_copy) zwlr_screencopy_frame_v1_copy(self->frame, buffer->wl_buffer); else @@ -150,7 +143,7 @@ static void screencopy_ready(void* data, DTRACE_PROBE1(wayvnc, screencopy_ready, self); - screencopy_stop(&self->frame_capture); + screencopy_stop(self); self->last_time = gettime_us(); @@ -167,8 +160,8 @@ static void screencopy_ready(void* data, wv_buffer_map(self->back); - self->frame_capture.status = CAPTURE_DONE; - self->frame_capture.on_done(&self->frame_capture); + self->status = SCREENCOPY_DONE; + self->on_done(self); } static void screencopy_failed(void* data, @@ -178,9 +171,9 @@ static void screencopy_failed(void* data, DTRACE_PROBE1(wayvnc, screencopy_failed, self); - screencopy_stop(&self->frame_capture); - self->frame_capture.status = CAPTURE_FAILED; - self->frame_capture.on_done(&self->frame_capture); + screencopy_stop(self); + self->status = SCREENCOPY_FAILED; + self->on_done(self); } static void screencopy_damage(void* data, @@ -195,10 +188,8 @@ static void screencopy_damage(void* data, wv_buffer_damage_rect(self->front, x, y, width, height); } -static int screencopy__start_capture(struct frame_capture* fc) +static int screencopy__start_capture(struct screencopy* self) { - struct screencopy* self = (void*)fc; - DTRACE_PROBE1(wayvnc, screencopy_start, self); static const struct zwlr_screencopy_frame_v1_listener frame_listener = { @@ -213,10 +204,8 @@ static int screencopy__start_capture(struct frame_capture* fc) self->start_time = gettime_us(); - self->frame = - zwlr_screencopy_manager_v1_capture_output(self->manager, - fc->overlay_cursor, - fc->wl_output); + self->frame = zwlr_screencopy_manager_v1_capture_output(self->manager, + self->overlay_cursor, self->wl_output); if (!self->frame) return -1; @@ -229,38 +218,40 @@ static int screencopy__start_capture(struct frame_capture* fc) static void screencopy__poll(void* obj) { struct screencopy* self = aml_get_userdata(obj); - struct frame_capture* fc = (struct frame_capture*)self; - screencopy__start_capture(fc); + screencopy__start_capture(self); } -static int screencopy_start(struct frame_capture* fc, - enum frame_capture_options options) +static int screencopy__start(struct screencopy* self, bool is_immediate_copy) { - struct screencopy* self = (void*)fc; - if (fc->status == CAPTURE_IN_PROGRESS) + if (self->status == SCREENCOPY_IN_PROGRESS) return -1; - self->is_immediate_copy = !!(options & CAPTURE_NOW); + self->is_immediate_copy = is_immediate_copy; uint64_t now = gettime_us(); double dt = (now - self->last_time) * 1.0e-6; double time_left = (1.0 / RATE_LIMIT - dt - self->delay) * 1.0e3; - fc->status = CAPTURE_IN_PROGRESS; + self->status = SCREENCOPY_IN_PROGRESS; if (time_left > 0) { aml_set_duration(self->timer, time_left); return aml_start(aml_get_default(), self->timer); } - return screencopy__start_capture(fc); + return screencopy__start_capture(self); } -static void screencopy_render(struct frame_capture* fc, - struct renderer* renderer, struct nvnc_fb* fb) +int screencopy_start(struct screencopy* self) { + return screencopy__start(self, false); +} + +int screencopy_start_immediate(struct screencopy* self) +{ + return screencopy__start(self, true); } void screencopy_init(struct screencopy* self) @@ -272,10 +263,6 @@ void screencopy_init(struct screencopy* self) assert(self->timer); self->delay_smoother.time_constant = DELAY_SMOOTHER_TIME_CONSTANT; - - self->frame_capture.backend.start = screencopy_start; - self->frame_capture.backend.stop = screencopy_stop; - self->frame_capture.backend.render = screencopy_render; } void screencopy_destroy(struct screencopy* self)