Add gbm_bo nvnc_fb type

dmabuf-import
Andri Yngvason 2021-09-12 18:01:58 +00:00
parent a14b829743
commit cf42f76f56
11 changed files with 138 additions and 14 deletions

View File

@ -24,20 +24,30 @@
#include "neatvnc.h" #include "neatvnc.h"
#include "common.h" #include "common.h"
struct gbm_bo;
struct nvnc_fb { struct nvnc_fb {
struct nvnc_common common; struct nvnc_common common;
enum nvnc_fb_type type;
int ref; int ref;
int hold_count; int hold_count;
nvnc_fb_release_fn on_release; nvnc_fb_release_fn on_release;
void* release_context; void* release_context;
void* addr; bool is_external;
uint16_t width; uint16_t width;
uint16_t height; uint16_t height;
int32_t stride;
uint32_t fourcc_format; uint32_t fourcc_format;
uint64_t fourcc_modifier;
bool is_external; /* main memory buffer attributes */
void* addr;
int32_t stride;
/* dmabuf attributes */
struct gbm_bo* bo;
void* bo_map_handle;
}; };
void nvnc_fb_hold(struct nvnc_fb* fb); void nvnc_fb_hold(struct nvnc_fb* fb);
void nvnc_fb_release(struct nvnc_fb* fb); void nvnc_fb_release(struct nvnc_fb* fb);
int nvnc_fb_map(struct nvnc_fb* fb);
void nvnc_fb_unmap(struct nvnc_fb* fb);

View File

@ -25,6 +25,7 @@ struct nvnc_display;
struct nvnc_fb; struct nvnc_fb;
struct nvnc_fb_pool; struct nvnc_fb_pool;
struct pixman_region16; struct pixman_region16;
struct gbm_bo;
enum nvnc_button_mask { enum nvnc_button_mask {
NVNC_BUTTON_LEFT = 1 << 0, NVNC_BUTTON_LEFT = 1 << 0,
@ -34,6 +35,12 @@ enum nvnc_button_mask {
NVNC_SCROLL_DOWN = 1 << 4, NVNC_SCROLL_DOWN = 1 << 4,
}; };
enum nvnc_fb_type {
NVNC_FB_UNSPEC = 0,
NVNC_FB_SIMPLE,
NVNC_FB_GBM_BO,
};
typedef void (*nvnc_key_fn)(struct nvnc_client*, uint32_t key, typedef void (*nvnc_key_fn)(struct nvnc_client*, uint32_t key,
bool is_pressed); bool is_pressed);
typedef void (*nvnc_pointer_fn)(struct nvnc_client*, uint16_t x, uint16_t y, typedef void (*nvnc_pointer_fn)(struct nvnc_client*, uint16_t x, uint16_t y,
@ -80,7 +87,9 @@ int nvnc_enable_auth(struct nvnc* self, const char* privkey_path,
struct nvnc_fb* nvnc_fb_new(uint16_t width, uint16_t height, struct nvnc_fb* nvnc_fb_new(uint16_t width, uint16_t height,
uint32_t fourcc_format, uint16_t stride); uint32_t fourcc_format, uint16_t stride);
struct nvnc_fb* nvnc_fb_from_buffer(void* buffer, uint16_t width, struct nvnc_fb* nvnc_fb_from_buffer(void* buffer, uint16_t width,
uint16_t height, uint32_t fourcc_format, int32_t stride); uint16_t height, uint32_t fourcc_format,
int32_t stride);
struct nvnc_fb* nvnc_fb_from_gbm_bo(struct gbm_bo* bo);
void nvnc_fb_ref(struct nvnc_fb* fb); void nvnc_fb_ref(struct nvnc_fb* fb);
void nvnc_fb_unref(struct nvnc_fb* fb); void nvnc_fb_unref(struct nvnc_fb* fb);
@ -94,6 +103,7 @@ uint16_t nvnc_fb_get_height(const struct nvnc_fb* fb);
uint32_t nvnc_fb_get_fourcc_format(const struct nvnc_fb* fb); uint32_t nvnc_fb_get_fourcc_format(const struct nvnc_fb* fb);
int32_t nvnc_fb_get_stride(const struct nvnc_fb* fb); int32_t nvnc_fb_get_stride(const struct nvnc_fb* fb);
int nvnc_fb_get_pixel_size(const struct nvnc_fb* fb); int nvnc_fb_get_pixel_size(const struct nvnc_fb* fb);
struct gbm_bo* nvnc_fb_get_gbm_bo(const struct nvnc_fb* fb);
struct nvnc_fb_pool* nvnc_fb_pool_new(uint16_t width, uint16_t height, struct nvnc_fb_pool* nvnc_fb_pool_new(uint16_t width, uint16_t height,
uint32_t fourcc_format, uint16_t stride); uint32_t fourcc_format, uint16_t stride);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 - 2020 Andri Yngvason * Copyright (c) 2019 - 2021 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
@ -22,6 +22,6 @@ struct pixman_region16;
struct vec; struct vec;
int raw_encode_frame(struct vec* dst, const struct rfb_pixel_format* dst_fmt, int raw_encode_frame(struct vec* dst, const struct rfb_pixel_format* dst_fmt,
const struct nvnc_fb* src, struct nvnc_fb* src,
const struct rfb_pixel_format* src_fmt, const struct rfb_pixel_format* src_fmt,
struct pixman_region16* region); struct pixman_region16* region);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 - 2020 Andri Yngvason * Copyright (c) 2019 - 2021 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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 Andri Yngvason * Copyright (c) 2019 - 2021 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
@ -27,6 +27,6 @@ struct vec;
int zrle_encode_frame(z_stream* zs, struct vec* dst, int zrle_encode_frame(z_stream* zs, struct vec* dst,
const struct rfb_pixel_format* dst_fmt, const struct rfb_pixel_format* dst_fmt,
const struct nvnc_fb* src, struct nvnc_fb* src,
const struct rfb_pixel_format* src_fmt, const struct rfb_pixel_format* src_fmt,
struct pixman_region16* region); struct pixman_region16* region);

View File

@ -48,6 +48,7 @@ pixman = dependency('pixman-1')
libturbojpeg = dependency('libturbojpeg', required: get_option('jpeg')) libturbojpeg = dependency('libturbojpeg', required: get_option('jpeg'))
gnutls = dependency('gnutls', required: get_option('tls')) gnutls = dependency('gnutls', required: get_option('tls'))
zlib = dependency('zlib') zlib = dependency('zlib')
gbm = dependency('gbm', required: get_option('gbm'))
aml_project = subproject('aml', required: false) aml_project = subproject('aml', required: false)
if aml_project.found() if aml_project.found()
@ -97,6 +98,11 @@ if host_system == 'linux' and get_option('systemtap') and cc.has_header('sys/sdt
config.set('HAVE_USDT', true) config.set('HAVE_USDT', true)
endif endif
if gbm.found()
dependencies += gbm
config.set('HAVE_GBM', true)
endif
configure_file( configure_file(
output: 'config.h', output: 'config.h',
configuration: config, configuration: config,

View File

@ -3,3 +3,4 @@ option('examples', type: 'boolean', value: false, description: 'Build examples')
option('jpeg', type: 'feature', value: 'auto', description: 'Enable JPEG compression') option('jpeg', type: 'feature', value: 'auto', description: 'Enable JPEG compression')
option('tls', type: 'feature', value: 'auto', description: 'Enable encryption & authentication') option('tls', type: 'feature', value: 'auto', description: 'Enable encryption & authentication')
option('systemtap', type: 'boolean', value: false, description: 'Enable tracing using sdt') option('systemtap', type: 'boolean', value: false, description: 'Enable tracing using sdt')
option('gbm', type: 'feature', value: 'auto', description: 'Enable GBM integration')

View File

@ -17,12 +17,19 @@
#include "fb.h" #include "fb.h"
#include "pixels.h" #include "pixels.h"
#include "neatvnc.h" #include "neatvnc.h"
#include "logging.h"
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <sys/param.h> #include <sys/param.h>
#include <stdatomic.h> #include <stdatomic.h>
#include "config.h"
#ifdef HAVE_GBM
#include <gbm.h>
#endif
#define UDIV_UP(a, b) (((a) + (b) - 1) / (b)) #define UDIV_UP(a, b) (((a) + (b) - 1) / (b))
#define ALIGN_UP(n, a) (UDIV_UP(n, a) * a) #define ALIGN_UP(n, a) (UDIV_UP(n, a) * a)
#define EXPORT __attribute__((visibility("default"))) #define EXPORT __attribute__((visibility("default")))
@ -35,6 +42,7 @@ struct nvnc_fb* nvnc_fb_new(uint16_t width, uint16_t height,
if (!fb) if (!fb)
return NULL; return NULL;
fb->type = NVNC_FB_SIMPLE;
fb->ref = 1; fb->ref = 1;
fb->width = width; fb->width = width;
fb->height = height; fb->height = height;
@ -62,6 +70,7 @@ struct nvnc_fb* nvnc_fb_from_buffer(void* buffer, uint16_t width, uint16_t heigh
if (!fb) if (!fb)
return NULL; return NULL;
fb->type = NVNC_FB_SIMPLE;
fb->ref = 1; fb->ref = 1;
fb->addr = buffer; fb->addr = buffer;
fb->is_external = true; fb->is_external = true;
@ -73,6 +82,29 @@ struct nvnc_fb* nvnc_fb_from_buffer(void* buffer, uint16_t width, uint16_t heigh
return fb; return fb;
} }
EXPORT
struct nvnc_fb* nvnc_fb_from_gbm_bo(struct gbm_bo* bo)
{
#ifdef HAVE_GBM
struct nvnc_fb* fb = calloc(1, sizeof(*fb));
if (!fb)
return NULL;
fb->type = NVNC_FB_GBM_BO;
fb->ref = 1;
fb->is_external = true;
fb->width = gbm_bo_get_width(bo);
fb->height = gbm_bo_get_height(bo);
fb->fourcc_format = gbm_bo_get_format(bo);
fb->bo = bo;
return fb;
#else
log_error("nvnc_fb_from_gbm_bo was not enabled during build time\n");
return NULL;
#endif
}
EXPORT EXPORT
void* nvnc_fb_get_addr(const struct nvnc_fb* fb) void* nvnc_fb_get_addr(const struct nvnc_fb* fb)
{ {
@ -109,14 +141,31 @@ int nvnc_fb_get_pixel_size(const struct nvnc_fb* fb)
return pixel_size_from_fourcc(fb->fourcc_format); return pixel_size_from_fourcc(fb->fourcc_format);
} }
EXPORT
struct gbm_bo* nvnc_fb_get_gbm_bo(const struct nvnc_fb* fb)
{
return fb->bo;
}
static void nvnc__fb_free(struct nvnc_fb* fb) static void nvnc__fb_free(struct nvnc_fb* fb)
{ {
nvnc_cleanup_fn cleanup = fb->common.cleanup_fn; nvnc_cleanup_fn cleanup = fb->common.cleanup_fn;
if (cleanup) if (cleanup)
cleanup(fb->common.userdata); cleanup(fb->common.userdata);
nvnc_fb_unmap(fb);
if (!fb->is_external) if (!fb->is_external)
free(fb->addr); switch (fb->type) {
case NVNC_FB_UNSPEC:
abort();
case NVNC_FB_SIMPLE:
free(fb->addr);
break;
case NVNC_FB_GBM_BO:
gbm_bo_destroy(fb->bo);
break;
}
free(fb); free(fb);
} }
@ -151,3 +200,38 @@ void nvnc_fb_release(struct nvnc_fb* fb)
if (--fb->hold_count == 0 && fb->on_release) if (--fb->hold_count == 0 && fb->on_release)
fb->on_release(fb, fb->release_context); fb->on_release(fb, fb->release_context);
} }
int nvnc_fb_map(struct nvnc_fb* fb)
{
#ifdef HAVE_GBM
if (fb->type != NVNC_FB_GBM_BO || fb->bo_map_handle)
return 0;
uint32_t stride = 0;
fb->addr = gbm_bo_map(fb->bo, 0, 0, fb->width, fb->height,
GBM_BO_TRANSFER_READ, &stride, &fb->bo_map_handle);
fb->stride = stride;
if (fb->addr)
return 0;
fb->bo_map_handle = NULL;
return -1;
#else
return 0;
#endif
}
void nvnc_fb_unmap(struct nvnc_fb* fb)
{
#ifdef HAVE_GBM
if (fb->type != NVNC_FB_GBM_BO)
return;
if (fb->bo_map_handle)
gbm_bo_unmap(fb->bo, fb->bo_map_handle);
fb->bo_map_handle = NULL;
fb->addr = NULL;
fb->stride = 0;
#endif
}

View File

@ -58,7 +58,7 @@ static int raw_encode_box(struct vec* dst,
} }
int raw_encode_frame(struct vec* dst, const struct rfb_pixel_format* dst_fmt, int raw_encode_frame(struct vec* dst, const struct rfb_pixel_format* dst_fmt,
const struct nvnc_fb* src, struct nvnc_fb* src,
const struct rfb_pixel_format* src_fmt, const struct rfb_pixel_format* src_fmt,
struct pixman_region16* region) struct pixman_region16* region)
{ {
@ -71,6 +71,10 @@ int raw_encode_frame(struct vec* dst, const struct rfb_pixel_format* dst_fmt,
n_rects = 1; n_rects = 1;
} }
rc = nvnc_fb_map(src);
if (rc < 0)
return -1;
rc = vec_reserve(dst, src->width * src->height * 4); rc = vec_reserve(dst, src->width * src->height * 4);
if (rc < 0) if (rc < 0)
return -1; return -1;

View File

@ -23,6 +23,7 @@
#include "tight.h" #include "tight.h"
#include "config.h" #include "config.h"
#include "enc-util.h" #include "enc-util.h"
#include "fb.h"
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
@ -494,9 +495,13 @@ int tight_encode_frame(struct tight_encoder* self,
self->on_frame_done = on_done; self->on_frame_done = on_done;
self->userdata = userdata; self->userdata = userdata;
int rc = nvnc_fb_map(self->fb);
if (rc < 0)
return -1;
uint32_t width = nvnc_fb_get_width(src); uint32_t width = nvnc_fb_get_width(src);
uint32_t height = nvnc_fb_get_height(src); uint32_t height = nvnc_fb_get_height(src);
int rc = vec_init(&self->dst, width * height * 4); rc = vec_init(&self->dst, width * height * 4);
if (rc < 0) if (rc < 0)
return -1; return -1;

View File

@ -263,7 +263,7 @@ failure:
int zrle_encode_frame(z_stream* zs, struct vec* dst, int zrle_encode_frame(z_stream* zs, struct vec* dst,
const struct rfb_pixel_format* dst_fmt, const struct rfb_pixel_format* dst_fmt,
const struct nvnc_fb* src, struct nvnc_fb* src,
const struct rfb_pixel_format* src_fmt, const struct rfb_pixel_format* src_fmt,
struct pixman_region16* region) struct pixman_region16* region)
{ {
@ -276,6 +276,10 @@ int zrle_encode_frame(z_stream* zs, struct vec* dst,
n_rects = 1; n_rects = 1;
} }
rc = nvnc_fb_map(src);
if (rc < 0)
return -1;
rc = encode_rect_count(dst, n_rects); rc = encode_rect_count(dst, n_rects);
if (rc < 0) if (rc < 0)
return -1; return -1;