From 3da1a3c47568a3b35c194f1ff5045162264a7a77 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 24 Feb 2022 14:58:44 +0900 Subject: [PATCH] Add tbm allocator Change-Id: Iab7cb52148134b46ff2c12c945c3746c38146da0 --- include/libds/allocator/tbm.h | 12 +++ packaging/libds.spec | 1 + src/libds/allocator/tbm.c | 177 ++++++++++++++++++++++++++++++++++++++++++ src/libds/meson.build | 2 + 4 files changed, 192 insertions(+) create mode 100644 include/libds/allocator/tbm.h create mode 100644 src/libds/allocator/tbm.c diff --git a/include/libds/allocator/tbm.h b/include/libds/allocator/tbm.h new file mode 100644 index 0000000..1457e3f --- /dev/null +++ b/include/libds/allocator/tbm.h @@ -0,0 +1,12 @@ +#ifndef LIBDS_ALLOCATOR_TBM_H +#define LIBDS_ALLOCATOR_TBM_H + +#include + +struct ds_allocator * +ds_tbm_allocator_create(void); + +WL_EXPORT void * +ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer); + +#endif diff --git a/packaging/libds.spec b/packaging/libds.spec index f68b266..aaf79b3 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -15,6 +15,7 @@ BuildRequires: pkgconfig(pixman-1) BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libtdm) +BuildRequires: pkgconfig(libtbm) %description Wayland Compositor Library diff --git a/src/libds/allocator/tbm.c b/src/libds/allocator/tbm.c new file mode 100644 index 0000000..f4d0702 --- /dev/null +++ b/src/libds/allocator/tbm.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include + +#include +#include + +#include "libds/interfaces/allocator.h" +#include "libds/interfaces/buffer.h" +#include "libds/log.h" + +struct ds_tbm_allocator +{ + struct ds_allocator base; + tbm_bufmgr bufmgr; +}; + +struct ds_tbm_buffer +{ + struct ds_buffer base; + tbm_surface_h surface; +}; + +static const struct ds_allocator_interface tbm_allocator_iface; +static struct ds_tbm_buffer *tbm_buffer_from_buffer(struct ds_buffer *buffer); + +WL_EXPORT struct ds_allocator * +ds_tbm_allocator_create(void) +{ + struct ds_tbm_allocator *alloc; + + alloc = calloc(1, sizeof *alloc); + if (!alloc) + return NULL; + + alloc->bufmgr = tbm_bufmgr_init(-1); + if (!alloc->bufmgr) { + ds_err("Could not initialize tbm_bufmgr"); + free(alloc); + return NULL; + } + + ds_allocator_init(&alloc->base, &tbm_allocator_iface, + DS_BUFFER_CAP_DATA_PTR); + + ds_inf("TBM allocator(%p) created", alloc); + + return &alloc->base; +} + +WL_EXPORT void * +ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer) +{ + struct ds_tbm_buffer *buffer; + + buffer = tbm_buffer_from_buffer(ds_buffer); + if (!buffer) + return NULL; + + return buffer->surface; +} + +static struct ds_tbm_allocator * +tbm_allocator_from_allocator(struct ds_allocator *ds_allocator) +{ + assert(ds_allocator->iface == &tbm_allocator_iface); + return (struct ds_tbm_allocator *)ds_allocator; +} + +static const struct ds_buffer_interface tbm_buffer_iface; + +static struct ds_tbm_buffer * +tbm_buffer_from_buffer(struct ds_buffer *buffer) +{ + assert(buffer->iface == &tbm_buffer_iface); + return (struct ds_tbm_buffer *)buffer; +} + +static void +tbm_buffer_destroy(struct ds_buffer *ds_buffer) +{ + struct ds_tbm_buffer *buffer; + + buffer = tbm_buffer_from_buffer(ds_buffer); + + ds_dbg("Destroy tbm buffer(%p)", buffer); + + tbm_surface_destroy(buffer->surface); + free(buffer); +} + +static bool +tbm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags, + void **data, uint32_t *format, size_t *stride) +{ + struct ds_tbm_buffer *buffer; + tbm_surface_info_s info; + int tbm_access_flags = 0; + int ret; + + buffer = tbm_buffer_from_buffer(ds_buffer); + + if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ) + tbm_access_flags |= TBM_OPTION_READ; + else if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE) + tbm_access_flags |= TBM_OPTION_WRITE; + + ret = tbm_surface_map(buffer->surface, tbm_access_flags, &info); + if (ret != TBM_SURFACE_ERROR_NONE) { + ds_err("Could not map tbm_surface of buffer(%p)", buffer); + return false; + } + + *data = info.planes[0].ptr; + *format = info.format; + *stride = info.planes[0].stride; + + return true; +} + +static void +tbm_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer) +{ + struct ds_tbm_buffer *buffer; + + buffer = tbm_buffer_from_buffer(ds_buffer); + + tbm_surface_unmap(buffer->surface); +} + +static const struct ds_buffer_interface tbm_buffer_iface = +{ + .destroy = tbm_buffer_destroy, + .begin_data_ptr_access = tbm_buffer_begin_data_ptr_access, + .end_data_ptr_access = tbm_buffer_end_data_ptr_access, +}; + + +static void +tbm_allocator_destroy(struct ds_allocator *ds_allocator) +{ + struct ds_tbm_allocator *alloc; + + alloc = tbm_allocator_from_allocator(ds_allocator); + + ds_inf("Destroy TBM allocator(%p)", alloc); + + tbm_bufmgr_deinit(alloc->bufmgr); + free(alloc); +} + +static struct ds_buffer * +tbm_allocator_create_buffer(struct ds_allocator *ds_allocator, + int width, int height, uint32_t format) +{ + static int num_buffers = 0; + struct ds_tbm_buffer *buffer; + + buffer = calloc(1, sizeof *buffer); + if (!buffer) + return NULL; + + ds_buffer_init(&buffer->base, &tbm_buffer_iface, width, height); + + buffer->surface = tbm_surface_create(width, height, TBM_FORMAT_XRGB8888); + + ds_dbg("tbm buffer(%p) created: size(%dx%d) number of buffers: %d", + buffer, width, height, ++num_buffers); + + return &buffer->base; +} + +static const struct ds_allocator_interface tbm_allocator_iface = { + .destroy = tbm_allocator_destroy, + .create_buffer = tbm_allocator_create_buffer, +}; diff --git a/src/libds/meson.build b/src/libds/meson.build index 2d09a91..8a88b62 100644 --- a/src/libds/meson.build +++ b/src/libds/meson.build @@ -4,6 +4,7 @@ libds_files = [ 'buffer.c', 'allocator/allocator.c', 'allocator/shm.c', + 'allocator/tbm.c', 'swapchain.c', 'output.c', 'compositor.c', @@ -50,6 +51,7 @@ math = meson.get_compiler('c').find_library('m') wayland_server = dependency('wayland-server', required: true) pixman = dependency('pixman-1', required: true) libdrm = dependency('libdrm', required: true) +libtbm = dependency('libtbm', required: true) libds_deps = [ math, -- 2.7.4