Add build option for enabling screencopy-dmabuf
parent
ca069ea738
commit
3742dc7144
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "sys/queue.h"
|
#include "sys/queue.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -29,7 +30,9 @@ struct gbm_bo;
|
||||||
enum wv_buffer_type {
|
enum wv_buffer_type {
|
||||||
WV_BUFFER_UNSPEC = 0,
|
WV_BUFFER_UNSPEC = 0,
|
||||||
WV_BUFFER_SHM,
|
WV_BUFFER_SHM,
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
WV_BUFFER_DMABUF,
|
WV_BUFFER_DMABUF,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wv_buffer {
|
struct wv_buffer {
|
||||||
|
|
|
@ -41,7 +41,7 @@ libm = cc.find_library('m', required: false)
|
||||||
librt = cc.find_library('rt', required: false)
|
librt = cc.find_library('rt', required: false)
|
||||||
|
|
||||||
pixman = dependency('pixman-1')
|
pixman = dependency('pixman-1')
|
||||||
gbm = dependency('gbm')
|
gbm = dependency('gbm', required: get_option('screencopy-dmabuf'))
|
||||||
drm = dependency('libdrm')
|
drm = dependency('libdrm')
|
||||||
xkbcommon = dependency('xkbcommon')
|
xkbcommon = dependency('xkbcommon')
|
||||||
wayland_client = dependency('wayland-client')
|
wayland_client = dependency('wayland-client')
|
||||||
|
@ -116,6 +116,10 @@ elif cc.has_function('SYS_memfd_create', prefix : '#include <sys/syscall.h>')
|
||||||
config.set('HAVE_MEMFD', true)
|
config.set('HAVE_MEMFD', true)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if gbm.found() and not get_option('screencopy-dmabuf').disabled()
|
||||||
|
config.set('ENABLE_SCREENCOPY_DMABUF', true)
|
||||||
|
endif
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
output: 'config.h',
|
output: 'config.h',
|
||||||
configuration: config,
|
configuration: config,
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
option('screencopy-dmabuf', type: 'feature', value: 'disabled',
|
||||||
|
description: 'Enable GPU-side screencopy (experimental)')
|
22
src/buffer.c
22
src/buffer.c
|
@ -30,6 +30,7 @@
|
||||||
#include "sys/queue.h"
|
#include "sys/queue.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "pixels.h"
|
#include "pixels.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
extern struct wl_shm* wl_shm;
|
extern struct wl_shm* wl_shm;
|
||||||
extern struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf;
|
extern struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf;
|
||||||
|
@ -42,8 +43,10 @@ enum wv_buffer_type wv_buffer_get_available_types(void)
|
||||||
if (wl_shm)
|
if (wl_shm)
|
||||||
type |= WV_BUFFER_SHM;
|
type |= WV_BUFFER_SHM;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
if (zwp_linux_dmabuf && gbm_device)
|
if (zwp_linux_dmabuf && gbm_device)
|
||||||
type |= WV_BUFFER_DMABUF;
|
type |= WV_BUFFER_DMABUF;
|
||||||
|
#endif
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -99,6 +102,7 @@ failure:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
static struct wv_buffer* wv_buffer_create_dmabuf(int width, int height,
|
static struct wv_buffer* wv_buffer_create_dmabuf(int width, int height,
|
||||||
uint32_t fourcc)
|
uint32_t fourcc)
|
||||||
{
|
{
|
||||||
|
@ -152,6 +156,7 @@ bo_failure:
|
||||||
free(self);
|
free(self);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct wv_buffer* wv_buffer_create(enum wv_buffer_type type, int width,
|
struct wv_buffer* wv_buffer_create(enum wv_buffer_type type, int width,
|
||||||
int height, int stride, uint32_t fourcc)
|
int height, int stride, uint32_t fourcc)
|
||||||
|
@ -159,8 +164,10 @@ struct wv_buffer* wv_buffer_create(enum wv_buffer_type type, int width,
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case WV_BUFFER_SHM:
|
case WV_BUFFER_SHM:
|
||||||
return wv_buffer_create_shm(width, height, stride, fourcc);
|
return wv_buffer_create_shm(width, height, stride, fourcc);
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
case WV_BUFFER_DMABUF:
|
case WV_BUFFER_DMABUF:
|
||||||
return wv_buffer_create_dmabuf(width, height, fourcc);
|
return wv_buffer_create_dmabuf(width, height, fourcc);
|
||||||
|
#endif
|
||||||
case WV_BUFFER_UNSPEC:;
|
case WV_BUFFER_UNSPEC:;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,12 +182,14 @@ static void wv_buffer_destroy_shm(struct wv_buffer* self)
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
static void wv_buffer_destroy_dmabuf(struct wv_buffer* self)
|
static void wv_buffer_destroy_dmabuf(struct wv_buffer* self)
|
||||||
{
|
{
|
||||||
wl_buffer_destroy(self->wl_buffer);
|
wl_buffer_destroy(self->wl_buffer);
|
||||||
gbm_bo_destroy(self->bo);
|
gbm_bo_destroy(self->bo);
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void wv_buffer_destroy(struct wv_buffer* self)
|
void wv_buffer_destroy(struct wv_buffer* self)
|
||||||
{
|
{
|
||||||
|
@ -191,15 +200,18 @@ void wv_buffer_destroy(struct wv_buffer* self)
|
||||||
case WV_BUFFER_SHM:
|
case WV_BUFFER_SHM:
|
||||||
wv_buffer_destroy_shm(self);
|
wv_buffer_destroy_shm(self);
|
||||||
return;
|
return;
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
case WV_BUFFER_DMABUF:
|
case WV_BUFFER_DMABUF:
|
||||||
wv_buffer_destroy_dmabuf(self);
|
wv_buffer_destroy_dmabuf(self);
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
case WV_BUFFER_UNSPEC:;
|
case WV_BUFFER_UNSPEC:;
|
||||||
}
|
}
|
||||||
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
static int wv_buffer_map_dmabuf(struct wv_buffer* self)
|
static int wv_buffer_map_dmabuf(struct wv_buffer* self)
|
||||||
{
|
{
|
||||||
if (self->bo_map_handle)
|
if (self->bo_map_handle)
|
||||||
|
@ -215,34 +227,41 @@ static int wv_buffer_map_dmabuf(struct wv_buffer* self)
|
||||||
self->bo_map_handle = NULL;
|
self->bo_map_handle = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int wv_buffer_map(struct wv_buffer* self)
|
int wv_buffer_map(struct wv_buffer* self)
|
||||||
{
|
{
|
||||||
switch (self->type) {
|
switch (self->type) {
|
||||||
case WV_BUFFER_SHM:
|
case WV_BUFFER_SHM:
|
||||||
return 0;
|
return 0;
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
case WV_BUFFER_DMABUF:
|
case WV_BUFFER_DMABUF:
|
||||||
return wv_buffer_map_dmabuf(self);
|
return wv_buffer_map_dmabuf(self);
|
||||||
|
#endif
|
||||||
case WV_BUFFER_UNSPEC:;
|
case WV_BUFFER_UNSPEC:;
|
||||||
}
|
}
|
||||||
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
static void wv_buffer_unmap_dmabuf(struct wv_buffer* self)
|
static void wv_buffer_unmap_dmabuf(struct wv_buffer* self)
|
||||||
{
|
{
|
||||||
if (self->bo_map_handle)
|
if (self->bo_map_handle)
|
||||||
gbm_bo_unmap(self->bo, self->bo_map_handle);
|
gbm_bo_unmap(self->bo, self->bo_map_handle);
|
||||||
self->bo_map_handle = NULL;
|
self->bo_map_handle = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void wv_buffer_unmap(struct wv_buffer* self)
|
void wv_buffer_unmap(struct wv_buffer* self)
|
||||||
{
|
{
|
||||||
switch (self->type) {
|
switch (self->type) {
|
||||||
case WV_BUFFER_SHM:
|
case WV_BUFFER_SHM:
|
||||||
return;
|
return;
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
case WV_BUFFER_DMABUF:
|
case WV_BUFFER_DMABUF:
|
||||||
return wv_buffer_unmap_dmabuf(self);
|
return wv_buffer_unmap_dmabuf(self);
|
||||||
|
#endif
|
||||||
case WV_BUFFER_UNSPEC:;
|
case WV_BUFFER_UNSPEC:;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -327,12 +346,13 @@ static bool wv_buffer_pool_match_buffer(struct wv_buffer_pool* pool,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
case WV_BUFFER_DMABUF:
|
case WV_BUFFER_DMABUF:
|
||||||
if (pool->width != buffer->width
|
if (pool->width != buffer->width
|
||||||
|| pool->height != buffer->height
|
|| pool->height != buffer->height
|
||||||
|| pool->format != buffer->format)
|
|| pool->format != buffer->format)
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
case WV_BUFFER_UNSPEC:
|
case WV_BUFFER_UNSPEC:
|
||||||
abort();
|
abort();
|
||||||
|
|
54
src/main.c
54
src/main.c
|
@ -34,8 +34,6 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <gbm.h>
|
|
||||||
#include <xf86drm.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"
|
||||||
|
@ -55,6 +53,11 @@
|
||||||
#include "damage-refinery.h"
|
#include "damage-refinery.h"
|
||||||
#include "usdt.h"
|
#include "usdt.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
|
#include <gbm.h>
|
||||||
|
#include <xf86drm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_ADDRESS "127.0.0.1"
|
#define DEFAULT_ADDRESS "127.0.0.1"
|
||||||
#define DEFAULT_PORT 5900
|
#define DEFAULT_PORT 5900
|
||||||
|
|
||||||
|
@ -229,6 +232,7 @@ static void registry_remove(void* data, struct wl_registry* registry,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
static int find_render_node(char *node, size_t maxlen) {
|
static int find_render_node(char *node, size_t maxlen) {
|
||||||
bool r = -1;
|
bool r = -1;
|
||||||
drmDevice *devices[64];
|
drmDevice *devices[64];
|
||||||
|
@ -248,6 +252,26 @@ static int find_render_node(char *node, size_t maxlen) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int init_render_node(int* fd)
|
||||||
|
{
|
||||||
|
char render_node[256];
|
||||||
|
if (find_render_node(render_node, sizeof(render_node)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*fd = open(render_node, O_RDWR);
|
||||||
|
if (*fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
gbm_device = gbm_create_device(*fd);
|
||||||
|
if (!gbm_device) {
|
||||||
|
close(*fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void wayvnc_destroy(struct wayvnc* self)
|
void wayvnc_destroy(struct wayvnc* self)
|
||||||
{
|
{
|
||||||
output_list_destroy(&self->outputs);
|
output_list_destroy(&self->outputs);
|
||||||
|
@ -739,7 +763,7 @@ int main(int argc, char* argv[])
|
||||||
int max_rate = 30;
|
int max_rate = 30;
|
||||||
|
|
||||||
static const char* shortopts = "C:o:k:s:rf:hpV";
|
static const char* shortopts = "C:o:k:s:rf:hpV";
|
||||||
int drm_fd = -1;
|
int drm_fd MAYBE_UNUSED = -1;
|
||||||
|
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
{ "config", required_argument, NULL, 'C' },
|
{ "config", required_argument, NULL, 'C' },
|
||||||
|
@ -883,17 +907,11 @@ int main(int argc, char* argv[])
|
||||||
out->on_dimension_change = on_output_dimension_change;
|
out->on_dimension_change = on_output_dimension_change;
|
||||||
out->userdata = &self;
|
out->userdata = &self;
|
||||||
|
|
||||||
char render_node[256];
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
if (find_render_node(render_node, sizeof(render_node)) < 0)
|
if (init_render_node(&drm_fd) < 0) {
|
||||||
goto failure;
|
log_error("Failed to initialise DRM render node. No GPU acceleration will be available.\n");
|
||||||
|
}
|
||||||
drm_fd = open(render_node, O_RDWR);
|
#endif
|
||||||
if (drm_fd < 0)
|
|
||||||
goto failure;
|
|
||||||
|
|
||||||
gbm_device = gbm_create_device(drm_fd);
|
|
||||||
if (!gbm_device)
|
|
||||||
goto failure;
|
|
||||||
|
|
||||||
struct aml* aml = aml_new();
|
struct aml* aml = aml_new();
|
||||||
if (!aml)
|
if (!aml)
|
||||||
|
@ -948,7 +966,12 @@ int main(int argc, char* argv[])
|
||||||
zwp_linux_dmabuf_v1_destroy(zwp_linux_dmabuf);
|
zwp_linux_dmabuf_v1_destroy(zwp_linux_dmabuf);
|
||||||
if (self.screencopy.manager)
|
if (self.screencopy.manager)
|
||||||
screencopy_destroy(&self.screencopy);
|
screencopy_destroy(&self.screencopy);
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
|
if (gbm_device) {
|
||||||
gbm_device_destroy(gbm_device);
|
gbm_device_destroy(gbm_device);
|
||||||
|
close(drm_fd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
wayvnc_destroy(&self);
|
wayvnc_destroy(&self);
|
||||||
aml_unref(aml);
|
aml_unref(aml);
|
||||||
|
|
||||||
|
@ -960,9 +983,12 @@ capture_failure:
|
||||||
nvnc_failure:
|
nvnc_failure:
|
||||||
main_loop_failure:
|
main_loop_failure:
|
||||||
failure:
|
failure:
|
||||||
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
|
if (gbm_device)
|
||||||
gbm_device_destroy(gbm_device);
|
gbm_device_destroy(gbm_device);
|
||||||
if (drm_fd >= 0)
|
if (drm_fd >= 0)
|
||||||
close(drm_fd);
|
close(drm_fd);
|
||||||
|
#endif
|
||||||
wayvnc_destroy(&self);
|
wayvnc_destroy(&self);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
#include "usdt.h"
|
#include "usdt.h"
|
||||||
#include "pixels.h"
|
#include "pixels.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#define DELAY_SMOOTHER_TIME_CONSTANT 0.5 // s
|
#define DELAY_SMOOTHER_TIME_CONSTANT 0.5 // s
|
||||||
|
|
||||||
|
@ -63,6 +64,9 @@ static void screencopy_linux_dmabuf(void* data,
|
||||||
#ifdef ENABLE_SCREENCOPY_DMABUF
|
#ifdef ENABLE_SCREENCOPY_DMABUF
|
||||||
struct screencopy* self = data;
|
struct screencopy* self = data;
|
||||||
|
|
||||||
|
if (!(wv_buffer_get_available_types() & WV_BUFFER_DMABUF))
|
||||||
|
return;
|
||||||
|
|
||||||
self->have_linux_dmabuf = true;
|
self->have_linux_dmabuf = true;
|
||||||
self->dmabuf_width = width;
|
self->dmabuf_width = width;
|
||||||
self->dmabuf_height = height;
|
self->dmabuf_height = height;
|
||||||
|
@ -77,13 +81,16 @@ static void screencopy_buffer_done(void* 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
|
||||||
if (self->have_linux_dmabuf) {
|
if (self->have_linux_dmabuf) {
|
||||||
width = self->dmabuf_width;
|
width = self->dmabuf_width;
|
||||||
height = self->dmabuf_height;
|
height = self->dmabuf_height;
|
||||||
stride = 0;
|
stride = 0;
|
||||||
fourcc = self->fourcc;
|
fourcc = self->fourcc;
|
||||||
type = WV_BUFFER_DMABUF;
|
type = WV_BUFFER_DMABUF;
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
width = self->wl_shm_width;
|
width = self->wl_shm_width;
|
||||||
height = self->wl_shm_height;
|
height = self->wl_shm_height;
|
||||||
stride = self->wl_shm_stride;
|
stride = self->wl_shm_stride;
|
||||||
|
|
Loading…
Reference in New Issue