4 #include <drm_fourcc.h>
5 #include <wayland-server.h>
6 #include <tbm_bufmgr.h>
7 #include <tbm_surface.h>
9 #include <libds/interfaces/allocator.h>
10 #include <libds/interfaces/buffer.h>
11 #include <libds/log.h>
13 struct ds_tbm_allocator
15 struct ds_allocator base;
21 struct ds_buffer base;
22 tbm_surface_h surface;
25 static const struct ds_allocator_interface tbm_allocator_iface;
26 static struct ds_tbm_buffer *tbm_buffer_from_buffer(struct ds_buffer *buffer);
28 WL_EXPORT struct ds_allocator *
29 ds_tbm_allocator_create(void)
31 struct ds_tbm_allocator *alloc;
33 alloc = calloc(1, sizeof *alloc);
37 alloc->bufmgr = tbm_bufmgr_init(-1);
39 ds_err("Could not initialize tbm_bufmgr");
44 ds_allocator_init(&alloc->base, &tbm_allocator_iface,
45 DS_BUFFER_CAP_DATA_PTR);
47 ds_inf("TBM allocator(%p) created", alloc);
53 ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer)
55 struct ds_tbm_buffer *buffer;
57 buffer = tbm_buffer_from_buffer(ds_buffer);
61 return buffer->surface;
64 static struct ds_tbm_allocator *
65 tbm_allocator_from_allocator(struct ds_allocator *ds_allocator)
67 assert(ds_allocator->iface == &tbm_allocator_iface);
68 return (struct ds_tbm_allocator *)ds_allocator;
71 static const struct ds_buffer_interface tbm_buffer_iface;
73 static struct ds_tbm_buffer *
74 tbm_buffer_from_buffer(struct ds_buffer *buffer)
76 assert(buffer->iface == &tbm_buffer_iface);
77 return (struct ds_tbm_buffer *)buffer;
81 tbm_buffer_destroy(struct ds_buffer *ds_buffer)
83 struct ds_tbm_buffer *buffer;
85 buffer = tbm_buffer_from_buffer(ds_buffer);
87 ds_dbg("Destroy tbm buffer(%p)", buffer);
89 tbm_surface_destroy(buffer->surface);
94 tbm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags,
95 void **data, uint32_t *format, size_t *stride)
97 struct ds_tbm_buffer *buffer;
98 tbm_surface_info_s info;
99 int tbm_access_flags = 0;
102 buffer = tbm_buffer_from_buffer(ds_buffer);
104 if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ)
105 tbm_access_flags |= TBM_OPTION_READ;
106 else if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE)
107 tbm_access_flags |= TBM_OPTION_WRITE;
109 ret = tbm_surface_map(buffer->surface, tbm_access_flags, &info);
110 if (ret != TBM_SURFACE_ERROR_NONE) {
111 ds_err("Could not map tbm_surface of buffer(%p)", buffer);
115 *data = info.planes[0].ptr;
116 *format = info.format;
117 *stride = info.planes[0].stride;
123 tbm_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer)
125 struct ds_tbm_buffer *buffer;
127 buffer = tbm_buffer_from_buffer(ds_buffer);
129 tbm_surface_unmap(buffer->surface);
132 static const struct ds_buffer_interface tbm_buffer_iface =
134 .destroy = tbm_buffer_destroy,
135 .begin_data_ptr_access = tbm_buffer_begin_data_ptr_access,
136 .end_data_ptr_access = tbm_buffer_end_data_ptr_access,
140 tbm_allocator_destroy(struct ds_allocator *ds_allocator)
142 struct ds_tbm_allocator *alloc;
144 alloc = tbm_allocator_from_allocator(ds_allocator);
146 ds_inf("Destroy TBM allocator(%p)", alloc);
148 tbm_bufmgr_deinit(alloc->bufmgr);
152 static struct ds_buffer *
153 tbm_allocator_create_buffer(struct ds_allocator *ds_allocator,
154 int width, int height, uint32_t format)
156 static int num_buffers = 0;
157 struct ds_tbm_buffer *buffer;
159 buffer = calloc(1, sizeof *buffer);
163 ds_buffer_init(&buffer->base, &tbm_buffer_iface, width, height);
165 buffer->surface = tbm_surface_create(width, height, TBM_FORMAT_XRGB8888);
167 ds_dbg("tbm buffer(%p) created: size(%dx%d) number of buffers: %d",
168 buffer, width, height, ++num_buffers);
170 return &buffer->base;
173 static const struct ds_allocator_interface tbm_allocator_iface =
175 .destroy = tbm_allocator_destroy,
176 .create_buffer = tbm_allocator_create_buffer,