Add a buffer pool

fb-api-v3
Andri Yngvason 2021-08-29 16:30:00 +00:00
parent d63feadeab
commit 981256d8d5
3 changed files with 173 additions and 1 deletions

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
* purpose with or without fee is hereby granted, provided that the above
@ -23,6 +23,7 @@ struct nvnc;
struct nvnc_client;
struct nvnc_display;
struct nvnc_fb;
struct nvnc_fb_pool;
struct pixman_region16;
enum nvnc_button_mask {
@ -96,6 +97,17 @@ uint16_t nvnc_fb_get_width(const struct nvnc_fb* fb);
uint16_t nvnc_fb_get_height(const struct nvnc_fb* fb);
uint32_t nvnc_fb_get_fourcc_format(const struct nvnc_fb* fb);
struct nvnc_fb_pool* nvnc_fb_pool_new(uint16_t width, uint16_t height,
uint32_t fourcc_format);
void nvnc_fb_pool_resize(struct nvnc_fb_pool*, uint16_t width, uint16_t height,
uint32_t fourcc_format);
void nvnc_fb_pool_ref(struct nvnc_fb_pool*);
void nvnc_fb_pool_unref(struct nvnc_fb_pool*);
struct nvnc_fb* nvnc_fb_pool_acquire(struct nvnc_fb_pool*);
void nvnc_fb_pool_release(struct nvnc_fb_pool*, struct nvnc_fb*);
struct nvnc_display* nvnc_display_new(uint16_t x_pos, uint16_t y_pos);
void nvnc_display_ref(struct nvnc_display*);
void nvnc_display_unref(struct nvnc_display*);

View File

@ -66,6 +66,7 @@ sources = [
'src/pixels.c',
'src/damage.c',
'src/fb.c',
'src/fb_pool.c',
'src/rcbuf.c',
'src/stream.c',
'src/display.c',

159
src/fb_pool.c 100644
View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2021 Andri Yngvason
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "fb.h"
#include "neatvnc.h"
#include "sys/queue.h"
#include <stdlib.h>
#include <assert.h>
#define EXPORT __attribute__((visibility("default")))
struct fbq_item {
struct nvnc_fb* fb;
TAILQ_ENTRY(fbq_item) link;
};
TAILQ_HEAD(fbq, fbq_item);
struct nvnc_fb_pool {
int ref;
struct fbq fbs;
uint16_t width;
uint16_t height;
uint32_t fourcc_format;
};
EXPORT
struct nvnc_fb_pool* nvnc_fb_pool_new(uint16_t width, uint16_t height,
uint32_t fourcc_format)
{
struct nvnc_fb_pool* self = calloc(1, sizeof(*self));
if (!self)
return NULL;
self->ref = 1;
TAILQ_INIT(&self->fbs);
self->width = width;
self->height = height;
self->fourcc_format = fourcc_format;
return self;
}
static void nvnc_fb_pool__destroy_fbs(struct nvnc_fb_pool* self)
{
while (!TAILQ_EMPTY(&self->fbs)) {
struct fbq_item* item = TAILQ_FIRST(&self->fbs);
TAILQ_REMOVE(&self->fbs, item, link);
nvnc_fb_unref(item->fb);
}
}
static void nvnc_fb_pool__destroy(struct nvnc_fb_pool* self)
{
nvnc_fb_pool__destroy_fbs(self);
free(self);
}
EXPORT
void nvnc_fb_pool_resize(struct nvnc_fb_pool* self, uint16_t width,
uint16_t height, uint32_t fourcc_format)
{
if (width == self->width && height == self->height &&
fourcc_format == self->fourcc_format)
return;
nvnc_fb_pool__destroy_fbs(self);
self->width = width;
self->height = height;
self->fourcc_format = fourcc_format;
}
EXPORT
void nvnc_fb_pool_ref(struct nvnc_fb_pool* self)
{
self->ref++;
}
EXPORT
void nvnc_fb_pool_unref(struct nvnc_fb_pool* self)
{
if (--self->ref == 0)
nvnc_fb_pool__destroy(self);
}
static void nvnc_fb_pool__on_fb_release(struct nvnc_fb* fb, void* userdata)
{
struct nvnc_fb_pool* pool = userdata;
nvnc_fb_pool_release(pool, fb);
nvnc_fb_pool_unref(pool);
}
static struct nvnc_fb* nvnc_fb_pool__acquire_new(struct nvnc_fb_pool* self)
{
struct nvnc_fb* fb = nvnc_fb_new(self->width, self->height,
self->fourcc_format);
if (!fb)
return NULL;
nvnc_fb_set_release_fn(fb, nvnc_fb_pool__on_fb_release, self);
nvnc_fb_pool_ref(self);
return fb;
}
static struct nvnc_fb* nvnc_fb_pool__acquire_from_list(struct nvnc_fb_pool* self)
{
struct fbq_item* item = TAILQ_FIRST(&self->fbs);
struct nvnc_fb* fb = item->fb;
assert(item && fb);
TAILQ_REMOVE(&self->fbs, item, link);
free(item);
return fb;
}
EXPORT
struct nvnc_fb* nvnc_fb_pool_acquire(struct nvnc_fb_pool* self)
{
return TAILQ_EMPTY(&self->fbs) ?
nvnc_fb_pool__acquire_new(self) :
nvnc_fb_pool__acquire_from_list(self);
}
EXPORT
void nvnc_fb_pool_release(struct nvnc_fb_pool* self, struct nvnc_fb* fb)
{
if (fb->width != self->width || fb->height != self->height ||
fb->fourcc_format != self->fourcc_format) {
nvnc_fb_unref(fb);
return;
}
struct fbq_item* item = calloc(1, sizeof(*item));
assert(item);
item->fb = fb;
TAILQ_INSERT_TAIL(&self->fbs, item, link);
}