Remove frame-capture abstraction
parent
b0ec79acf8
commit
2b522ee596
|
@ -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 <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "wlr-screencopy-unstable-v1.h"
|
#include "wlr-screencopy-unstable-v1.h"
|
||||||
#include "frame-capture.h"
|
|
||||||
#include "smooth.h"
|
#include "smooth.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
|
@ -32,14 +31,15 @@ struct aml_timer;
|
||||||
struct renderer;
|
struct renderer;
|
||||||
|
|
||||||
enum screencopy_status {
|
enum screencopy_status {
|
||||||
SCREENCOPY_STATUS_CAPTURING = 0,
|
SCREENCOPY_STOPPED = 0,
|
||||||
SCREENCOPY_STATUS_FATAL,
|
SCREENCOPY_IN_PROGRESS,
|
||||||
SCREENCOPY_STATUS_FAILED,
|
SCREENCOPY_FAILED,
|
||||||
SCREENCOPY_STATUS_DONE,
|
SCREENCOPY_FATAL,
|
||||||
|
SCREENCOPY_DONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct screencopy {
|
struct screencopy {
|
||||||
struct frame_capture frame_capture;
|
enum screencopy_status status;
|
||||||
|
|
||||||
struct wv_buffer_pool* pool;
|
struct wv_buffer_pool* pool;
|
||||||
struct wv_buffer* front;
|
struct wv_buffer* front;
|
||||||
|
@ -49,6 +49,9 @@ struct screencopy {
|
||||||
struct zwlr_screencopy_frame_v1* frame;
|
struct zwlr_screencopy_frame_v1* frame;
|
||||||
int version;
|
int version;
|
||||||
|
|
||||||
|
void* userdata;
|
||||||
|
void (*on_done)(struct screencopy*);
|
||||||
|
|
||||||
uint64_t last_time;
|
uint64_t last_time;
|
||||||
uint64_t start_time;
|
uint64_t start_time;
|
||||||
struct aml_timer* timer;
|
struct aml_timer* timer;
|
||||||
|
@ -56,6 +59,8 @@ struct screencopy {
|
||||||
struct smooth delay_smoother;
|
struct smooth delay_smoother;
|
||||||
double delay;
|
double delay;
|
||||||
bool is_immediate_copy;
|
bool is_immediate_copy;
|
||||||
|
bool overlay_cursor;
|
||||||
|
struct wl_output* wl_output;
|
||||||
|
|
||||||
uint32_t wl_shm_width, wl_shm_height, wl_shm_stride;
|
uint32_t wl_shm_width, wl_shm_height, wl_shm_stride;
|
||||||
enum wl_shm_format wl_shm_format;
|
enum wl_shm_format wl_shm_format;
|
||||||
|
@ -67,3 +72,8 @@ struct screencopy {
|
||||||
|
|
||||||
void screencopy_init(struct screencopy* self);
|
void screencopy_init(struct screencopy* self);
|
||||||
void screencopy_destroy(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);
|
||||||
|
|
81
src/main.c
81
src/main.c
|
@ -37,7 +37,6 @@
|
||||||
#include <gbm.h>
|
#include <gbm.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
|
||||||
#include "frame-capture.h"
|
|
||||||
#include "wlr-screencopy-unstable-v1.h"
|
#include "wlr-screencopy-unstable-v1.h"
|
||||||
#include "wlr-virtual-pointer-unstable-v1.h"
|
#include "wlr-virtual-pointer-unstable-v1.h"
|
||||||
#include "virtual-keyboard-unstable-v1.h"
|
#include "virtual-keyboard-unstable-v1.h"
|
||||||
|
@ -76,8 +75,7 @@ struct wayvnc {
|
||||||
const struct output* selected_output;
|
const struct output* selected_output;
|
||||||
const struct seat* selected_seat;
|
const struct seat* selected_seat;
|
||||||
|
|
||||||
struct screencopy screencopy_backend;
|
struct screencopy screencopy;
|
||||||
struct frame_capture* capture_backend;
|
|
||||||
struct pointer pointer_backend;
|
struct pointer pointer_backend;
|
||||||
struct keyboard keyboard_backend;
|
struct keyboard keyboard_backend;
|
||||||
|
|
||||||
|
@ -95,7 +93,7 @@ struct wayvnc {
|
||||||
};
|
};
|
||||||
|
|
||||||
void wayvnc_exit(struct wayvnc* self);
|
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);
|
static void on_render(struct nvnc_display* display, struct nvnc_fb* fb);
|
||||||
|
|
||||||
struct wl_shm* wl_shm = NULL;
|
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) {
|
if (strcmp(interface, zwlr_screencopy_manager_v1_interface.name) == 0) {
|
||||||
self->screencopy_backend.manager =
|
self->screencopy.manager =
|
||||||
wl_registry_bind(registry, id,
|
wl_registry_bind(registry, id,
|
||||||
&zwlr_screencopy_manager_v1_interface,
|
&zwlr_screencopy_manager_v1_interface,
|
||||||
version);
|
version);
|
||||||
self->screencopy_backend.version = version;
|
self->screencopy.version = version;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,8 +249,8 @@ void wayvnc_destroy(struct wayvnc* self)
|
||||||
zwlr_virtual_pointer_manager_v1_destroy(self->pointer_manager);
|
zwlr_virtual_pointer_manager_v1_destroy(self->pointer_manager);
|
||||||
pointer_destroy(&self->pointer_backend);
|
pointer_destroy(&self->pointer_backend);
|
||||||
|
|
||||||
if (self->screencopy_backend.manager)
|
if (self->screencopy.manager)
|
||||||
zwlr_screencopy_manager_v1_destroy(self->screencopy_backend.manager);
|
zwlr_screencopy_manager_v1_destroy(self->screencopy.manager);
|
||||||
|
|
||||||
wl_display_disconnect(self->display);
|
wl_display_disconnect(self->display);
|
||||||
}
|
}
|
||||||
|
@ -307,13 +305,13 @@ static int init_wayland(struct wayvnc* self)
|
||||||
wl_display_dispatch(self->display);
|
wl_display_dispatch(self->display);
|
||||||
wl_display_roundtrip(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");
|
log_error("Compositor doesn't support screencopy! Exiting.\n");
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->screencopy_backend.frame_capture.on_done = on_capture_done;
|
self->screencopy.on_done = on_capture_done;
|
||||||
self->screencopy_backend.frame_capture.userdata = self;
|
self->screencopy.userdata = self;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -454,9 +452,14 @@ failure:
|
||||||
return -1;
|
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)
|
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 nvnc* nvnc = nvnc_display_get_server(display);
|
||||||
struct wayvnc* self = nvnc_get_userdata(nvnc);
|
struct wayvnc* self = nvnc_get_userdata(nvnc);
|
||||||
|
|
||||||
if (!self->screencopy_backend.back)
|
if (!self->screencopy.back)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
enum wl_output_transform transform = self->selected_output->transform;
|
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);
|
&self->current_damage);
|
||||||
pixman_region_clear(&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);
|
nvnc_display_set_buffer(self->nvnc_display, self->buffer);
|
||||||
|
|
||||||
damage_refinery_init(&self->damage_refinery,
|
damage_refinery_init(&self->damage_refinery,
|
||||||
self->screencopy_backend.back->width,
|
self->screencopy.back->width,
|
||||||
self->screencopy_backend.back->height);
|
self->screencopy.back->height);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Reallocate
|
// TODO: Reallocate
|
||||||
assert(width == nvnc_fb_get_width(self->buffer));
|
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(&txdamage);
|
||||||
pixman_region_init(&refined);
|
pixman_region_init(&refined);
|
||||||
damage_refine(&self->damage_refinery, &refined,
|
damage_refine(&self->damage_refinery, &refined,
|
||||||
&self->screencopy_backend.back->damage,
|
&self->screencopy.back->damage,
|
||||||
self->screencopy_backend.back);
|
self->screencopy.back);
|
||||||
wv_region_transform(&txdamage, &refined,
|
wv_region_transform(&txdamage, &refined,
|
||||||
self->selected_output->transform,
|
self->selected_output->transform,
|
||||||
self->selected_output->width,
|
self->selected_output->width,
|
||||||
|
@ -513,32 +516,32 @@ void wayvnc_process_frame(struct wayvnc* self)
|
||||||
pixman_region_fini(&refined);
|
pixman_region_fini(&refined);
|
||||||
pixman_region_fini(&txdamage);
|
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");
|
log_error("Failed to start capture. Exiting...\n");
|
||||||
wayvnc_exit(self);
|
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) {
|
switch (sc->status) {
|
||||||
case CAPTURE_STOPPED:
|
case SCREENCOPY_STOPPED:
|
||||||
break;
|
break;
|
||||||
case CAPTURE_IN_PROGRESS:
|
case SCREENCOPY_IN_PROGRESS:
|
||||||
break;
|
break;
|
||||||
case CAPTURE_FATAL:
|
case SCREENCOPY_FATAL:
|
||||||
log_error("Fatal error while capturing. Exiting...\n");
|
log_error("Fatal error while capturing. Exiting...\n");
|
||||||
wayvnc_exit(self);
|
wayvnc_exit(self);
|
||||||
break;
|
break;
|
||||||
case CAPTURE_FAILED:
|
case SCREENCOPY_FAILED:
|
||||||
if (wayvnc_start_capture(self, CAPTURE_NOW) < 0) {
|
if (wayvnc_start_capture_immediate(self) < 0) {
|
||||||
log_error("Failed to start capture. Exiting...\n");
|
log_error("Failed to start capture. Exiting...\n");
|
||||||
wayvnc_exit(self);
|
wayvnc_exit(self);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CAPTURE_DONE:
|
case SCREENCOPY_DONE:
|
||||||
wayvnc_process_frame(self);
|
wayvnc_process_frame(self);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -722,7 +725,7 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
self.selected_output = out;
|
self.selected_output = out;
|
||||||
self.selected_seat = seat;
|
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 =
|
self.keyboard_backend.virtual_keyboard =
|
||||||
zwp_virtual_keyboard_manager_v1_create_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)
|
if (init_nvnc(&self, address, port) < 0)
|
||||||
goto nvnc_failure;
|
goto nvnc_failure;
|
||||||
|
|
||||||
if (self.screencopy_backend.manager)
|
if (self.screencopy.manager)
|
||||||
screencopy_init(&self.screencopy_backend);
|
screencopy_init(&self.screencopy);
|
||||||
|
|
||||||
if (!self.screencopy_backend.manager) {
|
if (!self.screencopy.manager) {
|
||||||
log_error("screencopy is not supported by compositor\n");
|
log_error("screencopy is not supported by compositor\n");
|
||||||
goto capture_failure;
|
goto capture_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.capture_backend = &self.screencopy_backend.frame_capture;
|
|
||||||
|
|
||||||
pixman_region_init(&self.current_damage);
|
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;
|
goto capture_failure;
|
||||||
|
|
||||||
wl_display_dispatch(self.display);
|
wl_display_dispatch(self.display);
|
||||||
|
@ -791,7 +792,7 @@ int main(int argc, char* argv[])
|
||||||
aml_dispatch(aml);
|
aml_dispatch(aml);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_capture_stop(self.capture_backend);
|
screencopy_stop(&self.screencopy);
|
||||||
|
|
||||||
if (self.buffer) nvnc_fb_unref(self.buffer);
|
if (self.buffer) nvnc_fb_unref(self.buffer);
|
||||||
|
|
||||||
|
@ -801,8 +802,8 @@ int main(int argc, char* argv[])
|
||||||
nvnc_close(self.nvnc);
|
nvnc_close(self.nvnc);
|
||||||
if (zwp_linux_dmabuf)
|
if (zwp_linux_dmabuf)
|
||||||
zwp_linux_dmabuf_v1_destroy(zwp_linux_dmabuf);
|
zwp_linux_dmabuf_v1_destroy(zwp_linux_dmabuf);
|
||||||
if (self.screencopy_backend.manager)
|
if (self.screencopy.manager)
|
||||||
screencopy_destroy(&self.screencopy_backend);
|
screencopy_destroy(&self.screencopy);
|
||||||
wayvnc_destroy(&self);
|
wayvnc_destroy(&self);
|
||||||
aml_unref(aml);
|
aml_unref(aml);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
#include "wlr-screencopy-unstable-v1.h"
|
#include "wlr-screencopy-unstable-v1.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "frame-capture.h"
|
|
||||||
#include "shm.h"
|
#include "shm.h"
|
||||||
#include "screencopy.h"
|
#include "screencopy.h"
|
||||||
#include "smooth.h"
|
#include "smooth.h"
|
||||||
|
@ -36,13 +35,12 @@
|
||||||
#define RATE_LIMIT 20.0 // Hz
|
#define RATE_LIMIT 20.0 // Hz
|
||||||
#define DELAY_SMOOTHER_TIME_CONSTANT 0.5 // s
|
#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);
|
aml_stop(aml_get_default(), self->timer);
|
||||||
|
|
||||||
self->frame_capture.status = CAPTURE_STOPPED;
|
self->status = SCREENCOPY_STOPPED;
|
||||||
|
|
||||||
if (self->frame) {
|
if (self->frame) {
|
||||||
zwlr_screencopy_frame_v1_destroy(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);
|
struct wv_buffer* buffer = wv_buffer_pool_acquire(self->pool);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
self->frame_capture.status = CAPTURE_FATAL;
|
screencopy_stop(self);
|
||||||
screencopy_stop(&self->frame_capture);
|
self->status = SCREENCOPY_FATAL;
|
||||||
self->frame_capture.on_done(&self->frame_capture);
|
self->on_done(self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,11 +95,6 @@ static void screencopy_buffer_done(void* data,
|
||||||
assert(!self->front);
|
assert(!self->front);
|
||||||
self->front = buffer;
|
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)
|
if (self->is_immediate_copy)
|
||||||
zwlr_screencopy_frame_v1_copy(self->frame, buffer->wl_buffer);
|
zwlr_screencopy_frame_v1_copy(self->frame, buffer->wl_buffer);
|
||||||
else
|
else
|
||||||
|
@ -150,7 +143,7 @@ static void screencopy_ready(void* data,
|
||||||
|
|
||||||
DTRACE_PROBE1(wayvnc, screencopy_ready, self);
|
DTRACE_PROBE1(wayvnc, screencopy_ready, self);
|
||||||
|
|
||||||
screencopy_stop(&self->frame_capture);
|
screencopy_stop(self);
|
||||||
|
|
||||||
self->last_time = gettime_us();
|
self->last_time = gettime_us();
|
||||||
|
|
||||||
|
@ -167,8 +160,8 @@ static void screencopy_ready(void* data,
|
||||||
|
|
||||||
wv_buffer_map(self->back);
|
wv_buffer_map(self->back);
|
||||||
|
|
||||||
self->frame_capture.status = CAPTURE_DONE;
|
self->status = SCREENCOPY_DONE;
|
||||||
self->frame_capture.on_done(&self->frame_capture);
|
self->on_done(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void screencopy_failed(void* data,
|
static void screencopy_failed(void* data,
|
||||||
|
@ -178,9 +171,9 @@ static void screencopy_failed(void* data,
|
||||||
|
|
||||||
DTRACE_PROBE1(wayvnc, screencopy_failed, self);
|
DTRACE_PROBE1(wayvnc, screencopy_failed, self);
|
||||||
|
|
||||||
screencopy_stop(&self->frame_capture);
|
screencopy_stop(self);
|
||||||
self->frame_capture.status = CAPTURE_FAILED;
|
self->status = SCREENCOPY_FAILED;
|
||||||
self->frame_capture.on_done(&self->frame_capture);
|
self->on_done(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void screencopy_damage(void* data,
|
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);
|
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);
|
DTRACE_PROBE1(wayvnc, screencopy_start, self);
|
||||||
|
|
||||||
static const struct zwlr_screencopy_frame_v1_listener frame_listener = {
|
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->start_time = gettime_us();
|
||||||
|
|
||||||
self->frame =
|
self->frame = zwlr_screencopy_manager_v1_capture_output(self->manager,
|
||||||
zwlr_screencopy_manager_v1_capture_output(self->manager,
|
self->overlay_cursor, self->wl_output);
|
||||||
fc->overlay_cursor,
|
|
||||||
fc->wl_output);
|
|
||||||
if (!self->frame)
|
if (!self->frame)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -229,38 +218,40 @@ static int screencopy__start_capture(struct frame_capture* fc)
|
||||||
static void screencopy__poll(void* obj)
|
static void screencopy__poll(void* obj)
|
||||||
{
|
{
|
||||||
struct screencopy* self = aml_get_userdata(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,
|
static int screencopy__start(struct screencopy* self, bool is_immediate_copy)
|
||||||
enum frame_capture_options options)
|
|
||||||
{
|
{
|
||||||
struct screencopy* self = (void*)fc;
|
|
||||||
|
|
||||||
if (fc->status == CAPTURE_IN_PROGRESS)
|
if (self->status == SCREENCOPY_IN_PROGRESS)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
self->is_immediate_copy = !!(options & CAPTURE_NOW);
|
self->is_immediate_copy = is_immediate_copy;
|
||||||
|
|
||||||
uint64_t now = gettime_us();
|
uint64_t now = gettime_us();
|
||||||
double dt = (now - self->last_time) * 1.0e-6;
|
double dt = (now - self->last_time) * 1.0e-6;
|
||||||
double time_left = (1.0 / RATE_LIMIT - dt - self->delay) * 1.0e3;
|
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) {
|
if (time_left > 0) {
|
||||||
aml_set_duration(self->timer, time_left);
|
aml_set_duration(self->timer, time_left);
|
||||||
return aml_start(aml_get_default(), self->timer);
|
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,
|
int screencopy_start(struct screencopy* self)
|
||||||
struct renderer* renderer, struct nvnc_fb* fb)
|
|
||||||
{
|
{
|
||||||
|
return screencopy__start(self, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int screencopy_start_immediate(struct screencopy* self)
|
||||||
|
{
|
||||||
|
return screencopy__start(self, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void screencopy_init(struct screencopy* self)
|
void screencopy_init(struct screencopy* self)
|
||||||
|
@ -272,10 +263,6 @@ void screencopy_init(struct screencopy* self)
|
||||||
assert(self->timer);
|
assert(self->timer);
|
||||||
|
|
||||||
self->delay_smoother.time_constant = DELAY_SMOOTHER_TIME_CONSTANT;
|
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)
|
void screencopy_destroy(struct screencopy* self)
|
||||||
|
|
Loading…
Reference in New Issue