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