Add build option for enabling screencopy-dmabuf

pull/58/head
Andri Yngvason 2020-07-26 14:52:00 +00:00
parent ca069ea738
commit 3742dc7144
6 changed files with 81 additions and 19 deletions

View File

@ -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 {

View File

@ -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,

View File

@ -0,0 +1,2 @@
option('screencopy-dmabuf', type: 'feature', value: 'disabled',
description: 'Enable GPU-side screencopy (experimental)')

View File

@ -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();

View File

@ -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;
}

View File

@ -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;