Create abstract screencopy interface
parent
3652f1e6cf
commit
d7e256942f
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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 <stdbool.h>
|
||||||
|
|
||||||
|
// TODO: Add a way to set the rate limit
|
||||||
|
|
||||||
|
struct zext_screencopy_manager_v1;
|
||||||
|
struct wl_output;
|
||||||
|
struct wv_buffer;
|
||||||
|
|
||||||
|
enum screencopy_result {
|
||||||
|
SCREENCOPY_DONE,
|
||||||
|
SCREENCOPY_FATAL,
|
||||||
|
SCREENCOPY_FAILED,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*screencopy_done_fn)(enum screencopy_result,
|
||||||
|
struct wv_buffer* buffer, void* userdata);
|
||||||
|
|
||||||
|
struct screencopy_impl {
|
||||||
|
struct screencopy* (*create)(struct wl_output*, bool render_cursor);
|
||||||
|
struct screencopy* (*create_cursor)(struct wl_output*);
|
||||||
|
void (*destroy)(struct screencopy*);
|
||||||
|
int (*start)(struct screencopy*, bool immediate);
|
||||||
|
void (*stop)(struct screencopy*);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct screencopy {
|
||||||
|
struct screencopy_impl* impl;
|
||||||
|
|
||||||
|
double rate_limit;
|
||||||
|
bool enable_linux_dmabuf;
|
||||||
|
|
||||||
|
screencopy_done_fn on_done;
|
||||||
|
void (*cursor_enter)(void* userdata);
|
||||||
|
void (*cursor_leave)(void* userdata);
|
||||||
|
void (*cursor_hotspot)(int x, int y, void* userdata);
|
||||||
|
|
||||||
|
void* userdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct screencopy* screencopy_create(struct screencopy_impl* impl,
|
||||||
|
struct wl_output* output, bool render_cursor);
|
||||||
|
struct screencopy* screencopy_create_cursor(struct screencopy_impl* impl,
|
||||||
|
struct wl_output* output);
|
||||||
|
void screencopy_destroy(struct screencopy* self);
|
||||||
|
|
||||||
|
int screencopy_start(struct screencopy* self, bool immediate);
|
||||||
|
void screencopy_stop(struct screencopy* self);
|
|
@ -1,81 +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 <stdbool.h>
|
|
||||||
|
|
||||||
#include "wlr-screencopy-unstable-v1.h"
|
|
||||||
#include "smooth.h"
|
|
||||||
#include "buffer.h"
|
|
||||||
|
|
||||||
struct zwlr_screencopy_manager_v1;
|
|
||||||
struct zwlr_screencopy_frame_v1;
|
|
||||||
struct wl_output;
|
|
||||||
struct wl_buffer;
|
|
||||||
struct wl_shm;
|
|
||||||
struct aml_timer;
|
|
||||||
struct renderer;
|
|
||||||
|
|
||||||
enum screencopy_status {
|
|
||||||
SCREENCOPY_STOPPED = 0,
|
|
||||||
SCREENCOPY_IN_PROGRESS,
|
|
||||||
SCREENCOPY_FAILED,
|
|
||||||
SCREENCOPY_FATAL,
|
|
||||||
SCREENCOPY_DONE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct screencopy {
|
|
||||||
enum screencopy_status status;
|
|
||||||
|
|
||||||
struct wv_buffer_pool* pool;
|
|
||||||
struct wv_buffer* front;
|
|
||||||
struct wv_buffer* back;
|
|
||||||
|
|
||||||
struct zwlr_screencopy_manager_v1* manager;
|
|
||||||
struct zwlr_screencopy_frame_v1* frame;
|
|
||||||
|
|
||||||
void* userdata;
|
|
||||||
void (*on_done)(struct screencopy*);
|
|
||||||
|
|
||||||
uint64_t last_time;
|
|
||||||
uint64_t start_time;
|
|
||||||
struct aml_timer* timer;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
bool have_linux_dmabuf;
|
|
||||||
bool enable_linux_dmabuf;
|
|
||||||
uint32_t dmabuf_width, dmabuf_height;
|
|
||||||
uint32_t fourcc;
|
|
||||||
|
|
||||||
double rate_limit;
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
|
|
@ -87,6 +87,7 @@ sources = [
|
||||||
'src/strlcpy.c',
|
'src/strlcpy.c',
|
||||||
'src/shm.c',
|
'src/shm.c',
|
||||||
'src/screencopy.c',
|
'src/screencopy.c',
|
||||||
|
'src/screencopy-interface.c',
|
||||||
'src/data-control.c',
|
'src/data-control.c',
|
||||||
'src/output.c',
|
'src/output.c',
|
||||||
'src/output-management.c',
|
'src/output-management.c',
|
||||||
|
|
100
src/main.c
100
src/main.c
|
@ -42,7 +42,7 @@
|
||||||
#include "wlr-output-management-unstable-v1.h"
|
#include "wlr-output-management-unstable-v1.h"
|
||||||
#include "linux-dmabuf-unstable-v1.h"
|
#include "linux-dmabuf-unstable-v1.h"
|
||||||
#include "ext-transient-seat-v1.h"
|
#include "ext-transient-seat-v1.h"
|
||||||
#include "screencopy.h"
|
#include "screencopy-interface.h"
|
||||||
#include "data-control.h"
|
#include "data-control.h"
|
||||||
#include "strlcpy.h"
|
#include "strlcpy.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
@ -56,6 +56,7 @@
|
||||||
#include "ctl-server.h"
|
#include "ctl-server.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "option-parser.h"
|
#include "option-parser.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
#ifdef ENABLE_PAM
|
#ifdef ENABLE_PAM
|
||||||
#include "pam_auth.h"
|
#include "pam_auth.h"
|
||||||
|
@ -100,7 +101,7 @@ struct wayvnc {
|
||||||
struct output* selected_output;
|
struct output* selected_output;
|
||||||
struct seat* selected_seat;
|
struct seat* selected_seat;
|
||||||
|
|
||||||
struct screencopy screencopy;
|
struct screencopy* screencopy;
|
||||||
|
|
||||||
struct aml_handler* wayland_handler;
|
struct aml_handler* wayland_handler;
|
||||||
struct aml_signal* signal_handler;
|
struct aml_signal* signal_handler;
|
||||||
|
@ -126,6 +127,7 @@ struct wayvnc {
|
||||||
bool is_initializing;
|
bool is_initializing;
|
||||||
|
|
||||||
bool start_detached;
|
bool start_detached;
|
||||||
|
bool overlay_cursor;
|
||||||
|
|
||||||
struct wayvnc_client* master_layout_client;
|
struct wayvnc_client* master_layout_client;
|
||||||
};
|
};
|
||||||
|
@ -144,7 +146,8 @@ struct wayvnc_client {
|
||||||
};
|
};
|
||||||
|
|
||||||
void wayvnc_exit(struct wayvnc* self);
|
void wayvnc_exit(struct wayvnc* self);
|
||||||
void on_capture_done(struct screencopy* sc);
|
void on_capture_done(enum screencopy_result result, struct wv_buffer* buffer,
|
||||||
|
void* userdata);
|
||||||
static void on_nvnc_client_new(struct nvnc_client* client);
|
static void on_nvnc_client_new(struct nvnc_client* client);
|
||||||
void switch_to_output(struct wayvnc*, struct output*);
|
void switch_to_output(struct wayvnc*, struct output*);
|
||||||
void switch_to_next_output(struct wayvnc*);
|
void switch_to_next_output(struct wayvnc*);
|
||||||
|
@ -164,6 +167,9 @@ struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf = NULL;
|
||||||
struct gbm_device* gbm_device = NULL;
|
struct gbm_device* gbm_device = NULL;
|
||||||
struct zxdg_output_manager_v1* xdg_output_manager = NULL;
|
struct zxdg_output_manager_v1* xdg_output_manager = NULL;
|
||||||
struct zwlr_output_power_manager_v1* wlr_output_power_manager = NULL;
|
struct zwlr_output_power_manager_v1* wlr_output_power_manager = NULL;
|
||||||
|
struct zwlr_screencopy_manager_v1* screencopy_manager = NULL;
|
||||||
|
|
||||||
|
extern struct screencopy_impl wlr_screencopy_impl;
|
||||||
|
|
||||||
static bool registry_add_input(void* data, struct wl_registry* registry,
|
static bool registry_add_input(void* data, struct wl_registry* registry,
|
||||||
uint32_t id, const char* interface,
|
uint32_t id, const char* interface,
|
||||||
|
@ -275,7 +281,7 @@ 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.manager =
|
screencopy_manager =
|
||||||
wl_registry_bind(registry, id,
|
wl_registry_bind(registry, id,
|
||||||
&zwlr_screencopy_manager_v1_interface,
|
&zwlr_screencopy_manager_v1_interface,
|
||||||
MIN(3, version));
|
MIN(3, version));
|
||||||
|
@ -417,7 +423,8 @@ static void wayland_detach(struct wayvnc* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
self->selected_output = NULL;
|
self->selected_output = NULL;
|
||||||
self->screencopy.wl_output = NULL;
|
//TODO: Make output inert:
|
||||||
|
//self->screencopy->wl_output = NULL;
|
||||||
|
|
||||||
output_list_destroy(&self->outputs);
|
output_list_destroy(&self->outputs);
|
||||||
seat_list_destroy(&self->seats);
|
seat_list_destroy(&self->seats);
|
||||||
|
@ -426,12 +433,12 @@ static void wayland_detach(struct wayvnc* self)
|
||||||
zwp_linux_dmabuf_v1_destroy(zwp_linux_dmabuf);
|
zwp_linux_dmabuf_v1_destroy(zwp_linux_dmabuf);
|
||||||
zwp_linux_dmabuf = NULL;
|
zwp_linux_dmabuf = NULL;
|
||||||
|
|
||||||
if (self->screencopy.manager) {
|
if (screencopy_manager) {
|
||||||
screencopy_stop(&self->screencopy);
|
screencopy_stop(self->screencopy);
|
||||||
screencopy_destroy(&self->screencopy);
|
screencopy_destroy(self->screencopy);
|
||||||
zwlr_screencopy_manager_v1_destroy(self->screencopy.manager);
|
zwlr_screencopy_manager_v1_destroy(screencopy_manager);
|
||||||
}
|
}
|
||||||
self->screencopy.manager = NULL;
|
screencopy_manager = NULL;
|
||||||
|
|
||||||
if (xdg_output_manager)
|
if (xdg_output_manager)
|
||||||
zxdg_output_manager_v1_destroy(xdg_output_manager);
|
zxdg_output_manager_v1_destroy(xdg_output_manager);
|
||||||
|
@ -458,6 +465,9 @@ static void wayland_detach(struct wayvnc* self)
|
||||||
zwlr_data_control_manager_v1_destroy(self->data_control_manager);
|
zwlr_data_control_manager_v1_destroy(self->data_control_manager);
|
||||||
self->data_control_manager = NULL;
|
self->data_control_manager = NULL;
|
||||||
|
|
||||||
|
if (screencopy_manager)
|
||||||
|
zwlr_screencopy_manager_v1_destroy(screencopy_manager);
|
||||||
|
|
||||||
if (self->performance_ticker) {
|
if (self->performance_ticker) {
|
||||||
aml_stop(aml_get_default(), self->performance_ticker);
|
aml_stop(aml_get_default(), self->performance_ticker);
|
||||||
aml_unref(self->performance_ticker);
|
aml_unref(self->performance_ticker);
|
||||||
|
@ -559,7 +569,7 @@ static int init_wayland(struct wayvnc* self, const char* display)
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self->screencopy.manager) {
|
if (!screencopy_manager) {
|
||||||
nvnc_log(NVNC_LOG_ERROR, "Screencopy protocol not supported by compositor. Exiting. Refer to FAQ section in man page.");
|
nvnc_log(NVNC_LOG_ERROR, "Screencopy protocol not supported by compositor. Exiting. Refer to FAQ section in man page.");
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
@ -569,8 +579,8 @@ static int init_wayland(struct wayvnc* self, const char* display)
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->screencopy.on_done = on_capture_done;
|
self->screencopy->on_done = on_capture_done;
|
||||||
self->screencopy.userdata = self;
|
self->screencopy->userdata = self;
|
||||||
|
|
||||||
self->wl_handler = aml_handler_new(wl_display_get_fd(self->display),
|
self->wl_handler = aml_handler_new(wl_display_get_fd(self->display),
|
||||||
on_wayland_event, self, NULL);
|
on_wayland_event, self, NULL);
|
||||||
|
@ -976,7 +986,7 @@ failure:
|
||||||
|
|
||||||
int wayvnc_start_capture(struct wayvnc* self)
|
int wayvnc_start_capture(struct wayvnc* self)
|
||||||
{
|
{
|
||||||
int rc = screencopy_start(&self->screencopy);
|
int rc = screencopy_start(self->screencopy, false);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
nvnc_log(NVNC_LOG_ERROR, "Failed to start capture. Exiting...");
|
nvnc_log(NVNC_LOG_ERROR, "Failed to start capture. Exiting...");
|
||||||
wayvnc_exit(self);
|
wayvnc_exit(self);
|
||||||
|
@ -997,7 +1007,7 @@ int wayvnc_start_capture_immediate(struct wayvnc* self)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = screencopy_start_immediate(&self->screencopy);
|
int rc = screencopy_start(self->screencopy, true);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
nvnc_log(NVNC_LOG_ERROR, "Failed to start capture. Exiting...");
|
nvnc_log(NVNC_LOG_ERROR, "Failed to start capture. Exiting...");
|
||||||
wayvnc_exit(self);
|
wayvnc_exit(self);
|
||||||
|
@ -1035,7 +1045,7 @@ void on_output_dimension_change(struct output* output)
|
||||||
|
|
||||||
nvnc_log(NVNC_LOG_DEBUG, "Output dimensions changed. Restarting frame capturer...");
|
nvnc_log(NVNC_LOG_DEBUG, "Output dimensions changed. Restarting frame capturer...");
|
||||||
|
|
||||||
screencopy_stop(&self->screencopy);
|
screencopy_stop(self->screencopy);
|
||||||
wayvnc_start_capture_immediate(self);
|
wayvnc_start_capture_immediate(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1054,7 +1064,7 @@ static void on_output_power_change(struct output* output)
|
||||||
break;
|
break;
|
||||||
case OUTPUT_POWER_OFF:
|
case OUTPUT_POWER_OFF:
|
||||||
nvnc_log(NVNC_LOG_WARNING, "Output is now off. Pausing frame capture");
|
nvnc_log(NVNC_LOG_WARNING, "Output is now off. Pausing frame capture");
|
||||||
screencopy_stop(&self->screencopy);
|
screencopy_stop(self->screencopy);
|
||||||
blank_screen(self);
|
blank_screen(self);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1079,10 +1089,9 @@ static uint32_t calculate_region_area(struct pixman_region16* region)
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wayvnc_process_frame(struct wayvnc* self)
|
void wayvnc_process_frame(struct wayvnc* self, struct wv_buffer* buffer)
|
||||||
{
|
{
|
||||||
struct wv_buffer* buffer = self->screencopy.back;
|
// TODO: Back buffer used to be set to NULL here, what's that about?
|
||||||
self->screencopy.back = NULL;
|
|
||||||
|
|
||||||
self->n_frames_captured++;
|
self->n_frames_captured++;
|
||||||
self->damage_area_sum +=
|
self->damage_area_sum +=
|
||||||
|
@ -1120,15 +1129,12 @@ void wayvnc_process_frame(struct wayvnc* self)
|
||||||
wayvnc_start_capture(self);
|
wayvnc_start_capture(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_capture_done(struct screencopy* sc)
|
void on_capture_done(enum screencopy_result result, struct wv_buffer* buffer,
|
||||||
|
void* userdata)
|
||||||
{
|
{
|
||||||
struct wayvnc* self = sc->userdata;
|
struct wayvnc* self = userdata;
|
||||||
|
|
||||||
switch (sc->status) {
|
switch (result) {
|
||||||
case SCREENCOPY_STOPPED:
|
|
||||||
break;
|
|
||||||
case SCREENCOPY_IN_PROGRESS:
|
|
||||||
break;
|
|
||||||
case SCREENCOPY_FATAL:
|
case SCREENCOPY_FATAL:
|
||||||
nvnc_log(NVNC_LOG_ERROR, "Fatal error while capturing. Exiting...");
|
nvnc_log(NVNC_LOG_ERROR, "Fatal error while capturing. Exiting...");
|
||||||
wayvnc_exit(self);
|
wayvnc_exit(self);
|
||||||
|
@ -1137,7 +1143,7 @@ void on_capture_done(struct screencopy* sc)
|
||||||
wayvnc_restart_capture(self);
|
wayvnc_restart_capture(self);
|
||||||
break;
|
break;
|
||||||
case SCREENCOPY_DONE:
|
case SCREENCOPY_DONE:
|
||||||
wayvnc_process_frame(self);
|
wayvnc_process_frame(self, buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1300,7 +1306,7 @@ static void client_destroy(void* obj)
|
||||||
|
|
||||||
if (wayvnc->nr_clients == 0 && wayvnc->display) {
|
if (wayvnc->nr_clients == 0 && wayvnc->display) {
|
||||||
nvnc_log(NVNC_LOG_INFO, "Stopping screen capture");
|
nvnc_log(NVNC_LOG_INFO, "Stopping screen capture");
|
||||||
screencopy_stop(&wayvnc->screencopy);
|
screencopy_stop(wayvnc->screencopy);
|
||||||
stop_performance_ticker(wayvnc);
|
stop_performance_ticker(wayvnc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1524,7 +1530,8 @@ void set_selected_output(struct wayvnc* self, struct output* output) {
|
||||||
self->selected_output->on_dimension_change = NULL;
|
self->selected_output->on_dimension_change = NULL;
|
||||||
}
|
}
|
||||||
self->selected_output = output;
|
self->selected_output = output;
|
||||||
self->screencopy.wl_output = output->wl_output;
|
// TODO: Change screencopy output:
|
||||||
|
// self->screencopy.wl_output = output->wl_output;
|
||||||
output->on_dimension_change = on_output_dimension_change;
|
output->on_dimension_change = on_output_dimension_change;
|
||||||
output->on_power_change = on_output_power_change;
|
output->on_power_change = on_output_power_change;
|
||||||
output->userdata = self;
|
output->userdata = self;
|
||||||
|
@ -1540,7 +1547,7 @@ void switch_to_output(struct wayvnc* self, struct output* output)
|
||||||
output->name);
|
output->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
screencopy_stop(&self->screencopy);
|
screencopy_stop(self->screencopy);
|
||||||
set_selected_output(self, output);
|
set_selected_output(self, output);
|
||||||
reinitialise_pointers(self);
|
reinitialise_pointers(self);
|
||||||
if (self->nr_clients > 0)
|
if (self->nr_clients > 0)
|
||||||
|
@ -1632,12 +1639,13 @@ static bool wayland_attach(struct wayvnc* self, const char* display,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screencopy_init(&self->screencopy);
|
if (!screencopy_manager) {
|
||||||
if (!self->screencopy.manager) {
|
|
||||||
nvnc_log(NVNC_LOG_ERROR, "Attached display does not implement wlr-screencopy-v1");
|
nvnc_log(NVNC_LOG_ERROR, "Attached display does not implement wlr-screencopy-v1");
|
||||||
wayland_detach(self);
|
wayland_detach(self);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
self->screencopy = screencopy_create(&wlr_screencopy_impl,
|
||||||
|
self->selected_output->wl_output, self->overlay_cursor);
|
||||||
|
|
||||||
set_selected_output(self, out);
|
set_selected_output(self, out);
|
||||||
|
|
||||||
|
@ -1801,6 +1809,7 @@ int main(int argc, char* argv[])
|
||||||
start_detached = !!option_parser_get_value(&option_parser, "detached");
|
start_detached = !!option_parser_get_value(&option_parser, "detached");
|
||||||
|
|
||||||
self.start_detached = start_detached;
|
self.start_detached = start_detached;
|
||||||
|
self.overlay_cursor = overlay_cursor;
|
||||||
|
|
||||||
keyboard_options = option_parser_get_value(&option_parser, "keyboard");
|
keyboard_options = option_parser_get_value(&option_parser, "keyboard");
|
||||||
if (keyboard_options)
|
if (keyboard_options)
|
||||||
|
@ -1905,9 +1914,6 @@ int main(int argc, char* argv[])
|
||||||
self.selected_seat = seat;
|
self.selected_seat = seat;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.screencopy.rate_limit = max_rate;
|
|
||||||
self.screencopy.enable_linux_dmabuf = enable_gpu_features;
|
|
||||||
|
|
||||||
#ifdef ENABLE_SCREENCOPY_DMABUF
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
if (enable_gpu_features && init_render_node(&drm_fd) < 0) {
|
if (enable_gpu_features && init_render_node(&drm_fd) < 0) {
|
||||||
nvnc_log(NVNC_LOG_ERROR, "Failed to initialise DRM render node. No GPU acceleration will be available.");
|
nvnc_log(NVNC_LOG_ERROR, "Failed to initialise DRM render node. No GPU acceleration will be available.");
|
||||||
|
@ -1927,16 +1933,23 @@ int main(int argc, char* argv[])
|
||||||
goto nvnc_failure;
|
goto nvnc_failure;
|
||||||
|
|
||||||
if (!start_detached) {
|
if (!start_detached) {
|
||||||
if (self.screencopy.manager)
|
if (screencopy_manager) {
|
||||||
screencopy_init(&self.screencopy);
|
self.screencopy = screencopy_create(&wlr_screencopy_impl,
|
||||||
|
self.selected_output->wl_output,
|
||||||
|
overlay_cursor);
|
||||||
|
if (!self.screencopy)
|
||||||
|
goto screencopy_failure;
|
||||||
|
|
||||||
if (!self.screencopy.manager) {
|
self.screencopy->rate_limit = max_rate;
|
||||||
|
self.screencopy->enable_linux_dmabuf = enable_gpu_features;
|
||||||
|
} else {
|
||||||
nvnc_log(NVNC_LOG_ERROR, "screencopy is not supported by compositor");
|
nvnc_log(NVNC_LOG_ERROR, "screencopy is not supported by compositor");
|
||||||
goto capture_failure;
|
goto capture_failure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.screencopy.overlay_cursor = overlay_cursor;
|
self.screencopy->on_done = on_capture_done;
|
||||||
|
self.screencopy->userdata = &self;
|
||||||
|
|
||||||
if (show_performance)
|
if (show_performance)
|
||||||
self.performance_ticker = aml_ticker_new(1000000, on_perf_tick,
|
self.performance_ticker = aml_ticker_new(1000000, on_perf_tick,
|
||||||
|
@ -1972,7 +1985,7 @@ int main(int argc, char* argv[])
|
||||||
nvnc_log(NVNC_LOG_INFO, "Exiting...");
|
nvnc_log(NVNC_LOG_INFO, "Exiting...");
|
||||||
|
|
||||||
if (self.display)
|
if (self.display)
|
||||||
screencopy_stop(&self.screencopy);
|
screencopy_stop(self.screencopy);
|
||||||
|
|
||||||
ctl_server_destroy(self.ctl);
|
ctl_server_destroy(self.ctl);
|
||||||
self.ctl = NULL;
|
self.ctl = NULL;
|
||||||
|
@ -1981,6 +1994,10 @@ int main(int argc, char* argv[])
|
||||||
nvnc_close(self.nvnc);
|
nvnc_close(self.nvnc);
|
||||||
self.nvnc = NULL;
|
self.nvnc = NULL;
|
||||||
wayvnc_destroy(&self);
|
wayvnc_destroy(&self);
|
||||||
|
if (zwp_linux_dmabuf)
|
||||||
|
zwp_linux_dmabuf_v1_destroy(zwp_linux_dmabuf);
|
||||||
|
if (self.screencopy)
|
||||||
|
screencopy_destroy(self.screencopy);
|
||||||
#ifdef ENABLE_SCREENCOPY_DMABUF
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
if (gbm_device) {
|
if (gbm_device) {
|
||||||
gbm_device_destroy(gbm_device);
|
gbm_device_destroy(gbm_device);
|
||||||
|
@ -1993,6 +2010,7 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
ctl_server_failure:
|
ctl_server_failure:
|
||||||
capture_failure:
|
capture_failure:
|
||||||
|
screencopy_failure:
|
||||||
nvnc_display_unref(self.nvnc_display);
|
nvnc_display_unref(self.nvnc_display);
|
||||||
nvnc_close(self.nvnc);
|
nvnc_close(self.nvnc);
|
||||||
nvnc_failure:
|
nvnc_failure:
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "screencopy-interface.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
struct screencopy* screencopy_create(struct screencopy_impl* impl,
|
||||||
|
struct wl_output* output, bool render_cursor)
|
||||||
|
{
|
||||||
|
return impl->create(output, render_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct screencopy* screencopy_create_cursor(struct screencopy_impl* impl,
|
||||||
|
struct wl_output* output)
|
||||||
|
{
|
||||||
|
return impl->create_cursor ? impl->create_cursor(output) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void screencopy_destroy(struct screencopy* self)
|
||||||
|
{
|
||||||
|
self->impl->destroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
int screencopy_start(struct screencopy* self, bool immediate)
|
||||||
|
{
|
||||||
|
return self->impl->start(self, immediate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void screencopy_stop(struct screencopy* self)
|
||||||
|
{
|
||||||
|
self->impl->stop(self);
|
||||||
|
}
|
140
src/screencopy.c
140
src/screencopy.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 - 2020 Andri Yngvason
|
* Copyright (c) 2019 - 2022 Andri Yngvason
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -19,7 +19,6 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <wayland-client-protocol.h>
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <libdrm/drm_fourcc.h>
|
#include <libdrm/drm_fourcc.h>
|
||||||
#include <aml.h>
|
#include <aml.h>
|
||||||
|
@ -28,7 +27,7 @@
|
||||||
#include "wlr-screencopy-unstable-v1.h"
|
#include "wlr-screencopy-unstable-v1.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "shm.h"
|
#include "shm.h"
|
||||||
#include "screencopy.h"
|
#include "screencopy-interface.h"
|
||||||
#include "smooth.h"
|
#include "smooth.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
#include "usdt.h"
|
#include "usdt.h"
|
||||||
|
@ -37,11 +36,52 @@
|
||||||
|
|
||||||
#define DELAY_SMOOTHER_TIME_CONSTANT 0.5 // s
|
#define DELAY_SMOOTHER_TIME_CONSTANT 0.5 // s
|
||||||
|
|
||||||
static void screencopy__stop(struct screencopy* self)
|
extern struct zwlr_screencopy_manager_v1* screencopy_manager;
|
||||||
|
|
||||||
|
enum wlr_screencopy_status {
|
||||||
|
WLR_SCREENCOPY_STOPPED = 0,
|
||||||
|
WLR_SCREENCOPY_IN_PROGRESS,
|
||||||
|
WLR_SCREENCOPY_FAILED,
|
||||||
|
WLR_SCREENCOPY_FATAL,
|
||||||
|
WLR_SCREENCOPY_DONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_screencopy {
|
||||||
|
struct screencopy parent;
|
||||||
|
|
||||||
|
enum wlr_screencopy_status status;
|
||||||
|
|
||||||
|
struct wv_buffer_pool* pool;
|
||||||
|
struct wv_buffer* front;
|
||||||
|
struct wv_buffer* back;
|
||||||
|
|
||||||
|
struct zwlr_screencopy_frame_v1* frame;
|
||||||
|
|
||||||
|
uint64_t last_time;
|
||||||
|
uint64_t start_time;
|
||||||
|
struct aml_timer* timer;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
bool have_linux_dmabuf;
|
||||||
|
uint32_t dmabuf_width, dmabuf_height;
|
||||||
|
uint32_t fourcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct screencopy_impl wlr_screencopy_impl;
|
||||||
|
|
||||||
|
static void screencopy__stop(struct wlr_screencopy* self)
|
||||||
{
|
{
|
||||||
aml_stop(aml_get_default(), self->timer);
|
aml_stop(aml_get_default(), self->timer);
|
||||||
|
|
||||||
self->status = SCREENCOPY_STOPPED;
|
self->status = WLR_SCREENCOPY_STOPPED;
|
||||||
|
|
||||||
if (self->frame) {
|
if (self->frame) {
|
||||||
zwlr_screencopy_frame_v1_destroy(self->frame);
|
zwlr_screencopy_frame_v1_destroy(self->frame);
|
||||||
|
@ -49,8 +89,10 @@ static void screencopy__stop(struct screencopy* self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void screencopy_stop(struct screencopy* self)
|
void wlr_screencopy_stop(struct screencopy* ptr)
|
||||||
{
|
{
|
||||||
|
struct wlr_screencopy* self = (struct wlr_screencopy*)ptr;
|
||||||
|
|
||||||
if (self->front)
|
if (self->front)
|
||||||
wv_buffer_pool_release(self->pool, self->front);
|
wv_buffer_pool_release(self->pool, self->front);
|
||||||
self->front = NULL;
|
self->front = NULL;
|
||||||
|
@ -63,7 +105,7 @@ static void screencopy_linux_dmabuf(void* data,
|
||||||
uint32_t format, uint32_t width, uint32_t height)
|
uint32_t format, uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_SCREENCOPY_DMABUF
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
struct screencopy* self = data;
|
struct wlr_screencopy* self = data;
|
||||||
|
|
||||||
if (!(wv_buffer_get_available_types() & WV_BUFFER_DMABUF))
|
if (!(wv_buffer_get_available_types() & WV_BUFFER_DMABUF))
|
||||||
return;
|
return;
|
||||||
|
@ -78,12 +120,12 @@ static void screencopy_linux_dmabuf(void* data,
|
||||||
static void screencopy_buffer_done(void* data,
|
static void screencopy_buffer_done(void* data,
|
||||||
struct zwlr_screencopy_frame_v1* frame)
|
struct zwlr_screencopy_frame_v1* frame)
|
||||||
{
|
{
|
||||||
struct screencopy* self = data;
|
struct wlr_screencopy* self = data;
|
||||||
uint32_t width, height, stride, fourcc;
|
uint32_t width, height, stride, fourcc;
|
||||||
enum wv_buffer_type type = WV_BUFFER_UNSPEC;
|
enum wv_buffer_type type = WV_BUFFER_UNSPEC;
|
||||||
|
|
||||||
#ifdef ENABLE_SCREENCOPY_DMABUF
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
if (self->have_linux_dmabuf && self->enable_linux_dmabuf) {
|
if (self->have_linux_dmabuf && self->parent.enable_linux_dmabuf) {
|
||||||
width = self->dmabuf_width;
|
width = self->dmabuf_width;
|
||||||
height = self->dmabuf_height;
|
height = self->dmabuf_height;
|
||||||
stride = 0;
|
stride = 0;
|
||||||
|
@ -104,8 +146,8 @@ 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) {
|
||||||
screencopy__stop(self);
|
screencopy__stop(self);
|
||||||
self->status = SCREENCOPY_FATAL;
|
self->status = WLR_SCREENCOPY_FATAL;
|
||||||
self->on_done(self);
|
self->parent.on_done(SCREENCOPY_FATAL, NULL, self->parent.userdata);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,14 +166,14 @@ static void screencopy_buffer(void* data,
|
||||||
enum wl_shm_format format, uint32_t width,
|
enum wl_shm_format format, uint32_t width,
|
||||||
uint32_t height, uint32_t stride)
|
uint32_t height, uint32_t stride)
|
||||||
{
|
{
|
||||||
struct screencopy* self = data;
|
struct wlr_screencopy* self = data;
|
||||||
|
|
||||||
self->wl_shm_format = format;
|
self->wl_shm_format = format;
|
||||||
self->wl_shm_width = width;
|
self->wl_shm_width = width;
|
||||||
self->wl_shm_height = height;
|
self->wl_shm_height = height;
|
||||||
self->wl_shm_stride = stride;
|
self->wl_shm_stride = stride;
|
||||||
|
|
||||||
int version = zwlr_screencopy_manager_v1_get_version(self->manager);
|
int version = zwlr_screencopy_manager_v1_get_version(screencopy_manager);
|
||||||
if (version < 3) {
|
if (version < 3) {
|
||||||
self->have_linux_dmabuf = false;
|
self->have_linux_dmabuf = false;
|
||||||
screencopy_buffer_done(data, frame);
|
screencopy_buffer_done(data, frame);
|
||||||
|
@ -145,7 +187,7 @@ static void screencopy_flags(void* data,
|
||||||
{
|
{
|
||||||
(void)frame;
|
(void)frame;
|
||||||
|
|
||||||
struct screencopy* self = data;
|
struct wlr_screencopy* self = data;
|
||||||
|
|
||||||
self->front->y_inverted =
|
self->front->y_inverted =
|
||||||
!!(flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT);
|
!!(flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT);
|
||||||
|
@ -155,7 +197,11 @@ static void screencopy_ready(void* data,
|
||||||
struct zwlr_screencopy_frame_v1* frame,
|
struct zwlr_screencopy_frame_v1* frame,
|
||||||
uint32_t sec_hi, uint32_t sec_lo, uint32_t nsec)
|
uint32_t sec_hi, uint32_t sec_lo, uint32_t nsec)
|
||||||
{
|
{
|
||||||
struct screencopy* self = data;
|
(void)sec_hi;
|
||||||
|
(void)sec_lo;
|
||||||
|
(void)nsec;
|
||||||
|
|
||||||
|
struct wlr_screencopy* self = data;
|
||||||
|
|
||||||
uint64_t sec = (uint64_t)sec_hi << 32 | (uint64_t)sec_lo;
|
uint64_t sec = (uint64_t)sec_hi << 32 | (uint64_t)sec_lo;
|
||||||
uint64_t pts = sec * UINT64_C(1000000) + (uint64_t)nsec / UINT64_C(1000);
|
uint64_t pts = sec * UINT64_C(1000000) + (uint64_t)nsec / UINT64_C(1000);
|
||||||
|
@ -179,14 +225,16 @@ static void screencopy_ready(void* data,
|
||||||
|
|
||||||
nvnc_fb_set_pts(self->back->nvnc_fb, pts);
|
nvnc_fb_set_pts(self->back->nvnc_fb, pts);
|
||||||
|
|
||||||
self->status = SCREENCOPY_DONE;
|
self->status = WLR_SCREENCOPY_DONE;
|
||||||
self->on_done(self);
|
self->parent.on_done(SCREENCOPY_DONE, self->back, self->parent.userdata);
|
||||||
|
|
||||||
|
self->back = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void screencopy_failed(void* data,
|
static void screencopy_failed(void* data,
|
||||||
struct zwlr_screencopy_frame_v1* frame)
|
struct zwlr_screencopy_frame_v1* frame)
|
||||||
{
|
{
|
||||||
struct screencopy* self = data;
|
struct wlr_screencopy* self = data;
|
||||||
|
|
||||||
DTRACE_PROBE1(wayvnc, screencopy_failed, self);
|
DTRACE_PROBE1(wayvnc, screencopy_failed, self);
|
||||||
|
|
||||||
|
@ -196,8 +244,8 @@ static void screencopy_failed(void* data,
|
||||||
wv_buffer_pool_release(self->pool, self->front);
|
wv_buffer_pool_release(self->pool, self->front);
|
||||||
self->front = NULL;
|
self->front = NULL;
|
||||||
|
|
||||||
self->status = SCREENCOPY_FAILED;
|
self->status = WLR_SCREENCOPY_FAILED;
|
||||||
self->on_done(self);
|
self->parent.on_done(SCREENCOPY_FAILED, NULL, self->parent.userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void screencopy_damage(void* data,
|
static void screencopy_damage(void* data,
|
||||||
|
@ -205,14 +253,14 @@ static void screencopy_damage(void* data,
|
||||||
uint32_t x, uint32_t y,
|
uint32_t x, uint32_t y,
|
||||||
uint32_t width, uint32_t height)
|
uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
struct screencopy* self = data;
|
struct wlr_screencopy* self = data;
|
||||||
|
|
||||||
DTRACE_PROBE1(wayvnc, screencopy_damage, self);
|
DTRACE_PROBE1(wayvnc, screencopy_damage, self);
|
||||||
|
|
||||||
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 screencopy* self)
|
static int screencopy__start_capture(struct wlr_screencopy* self)
|
||||||
{
|
{
|
||||||
DTRACE_PROBE1(wayvnc, screencopy_start, self);
|
DTRACE_PROBE1(wayvnc, screencopy_start, self);
|
||||||
|
|
||||||
|
@ -228,8 +276,9 @@ static int screencopy__start_capture(struct screencopy* self)
|
||||||
|
|
||||||
self->start_time = gettime_us();
|
self->start_time = gettime_us();
|
||||||
|
|
||||||
self->frame = zwlr_screencopy_manager_v1_capture_output(self->manager,
|
self->frame = zwlr_screencopy_manager_v1_capture_output(
|
||||||
self->overlay_cursor, self->wl_output);
|
screencopy_manager, self->overlay_cursor,
|
||||||
|
self->wl_output);
|
||||||
if (!self->frame)
|
if (!self->frame)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -241,23 +290,25 @@ static int screencopy__start_capture(struct screencopy* self)
|
||||||
|
|
||||||
static void screencopy__poll(void* obj)
|
static void screencopy__poll(void* obj)
|
||||||
{
|
{
|
||||||
struct screencopy* self = aml_get_userdata(obj);
|
struct wlr_screencopy* self = aml_get_userdata(obj);
|
||||||
|
|
||||||
screencopy__start_capture(self);
|
screencopy__start_capture(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int screencopy__start(struct screencopy* self, bool is_immediate_copy)
|
static int wlr_screencopy_start(struct screencopy* ptr, bool is_immediate_copy)
|
||||||
{
|
{
|
||||||
if (self->status == SCREENCOPY_IN_PROGRESS)
|
struct wlr_screencopy* self = (struct wlr_screencopy*)ptr;
|
||||||
|
|
||||||
|
if (self->status == WLR_SCREENCOPY_IN_PROGRESS)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
self->is_immediate_copy = is_immediate_copy;
|
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;
|
||||||
int32_t time_left = (1.0 / self->rate_limit - dt - self->delay) * 1.0e6;
|
int32_t time_left = (1.0 / ptr->rate_limit - dt - self->delay) * 1.0e3;
|
||||||
|
|
||||||
self->status = SCREENCOPY_IN_PROGRESS;
|
self->status = WLR_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);
|
||||||
|
@ -267,18 +318,19 @@ static int screencopy__start(struct screencopy* self, bool is_immediate_copy)
|
||||||
return screencopy__start_capture(self);
|
return screencopy__start_capture(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
int screencopy_start(struct screencopy* self)
|
static struct screencopy* wlr_screencopy_create(struct wl_output* output,
|
||||||
|
bool render_cursor)
|
||||||
{
|
{
|
||||||
return screencopy__start(self, false);
|
struct wlr_screencopy* self = calloc(1, sizeof(*self));
|
||||||
}
|
if (!self)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
int screencopy_start_immediate(struct screencopy* self)
|
self->parent.impl = &wlr_screencopy_impl;
|
||||||
{
|
self->parent.rate_limit = 30;
|
||||||
return screencopy__start(self, true);
|
|
||||||
}
|
self->wl_output = output;
|
||||||
|
self->overlay_cursor = render_cursor;
|
||||||
|
|
||||||
void screencopy_init(struct screencopy* self)
|
|
||||||
{
|
|
||||||
self->pool = wv_buffer_pool_create(0, 0, 0, 0, 0);
|
self->pool = wv_buffer_pool_create(0, 0, 0, 0, 0);
|
||||||
assert(self->pool);
|
assert(self->pool);
|
||||||
|
|
||||||
|
@ -286,10 +338,13 @@ 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;
|
||||||
|
|
||||||
|
return (struct screencopy*)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
void screencopy_destroy(struct screencopy* self)
|
static void wlr_screencopy_destroy(struct screencopy* ptr)
|
||||||
{
|
{
|
||||||
|
struct wlr_screencopy* self = (struct wlr_screencopy*)ptr;
|
||||||
aml_stop(aml_get_default(), self->timer);
|
aml_stop(aml_get_default(), self->timer);
|
||||||
aml_unref(self->timer);
|
aml_unref(self->timer);
|
||||||
|
|
||||||
|
@ -303,3 +358,10 @@ void screencopy_destroy(struct screencopy* self)
|
||||||
|
|
||||||
wv_buffer_pool_destroy(self->pool);
|
wv_buffer_pool_destroy(self->pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct screencopy_impl wlr_screencopy_impl = {
|
||||||
|
.create = wlr_screencopy_create,
|
||||||
|
.destroy = wlr_screencopy_destroy,
|
||||||
|
.start = wlr_screencopy_start,
|
||||||
|
.stop = wlr_screencopy_stop,
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue