Add gbm_bo nvnc_fb type
parent
a14b829743
commit
cf42f76f56
18
include/fb.h
18
include/fb.h
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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')
|
||||||
|
|
86
src/fb.c
86
src/fb.c
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue