6 #include <drm_fourcc.h>
7 #include <wayland-server.h>
9 #include "libds/allocator/shm.h"
10 #include "libds/interfaces/allocator.h"
11 #include "libds/interfaces/buffer.h"
12 #include "libds/log.h"
15 struct ds_shm_allocator
17 struct ds_allocator base;
22 struct ds_buffer base;
23 struct ds_shm_attributes shm;
28 static const struct ds_allocator_interface shm_allocator_iface;
30 WL_EXPORT struct ds_allocator *
31 ds_shm_allocator_create(void)
33 struct ds_shm_allocator *alloc;
35 alloc = calloc(1, sizeof *alloc);
39 ds_allocator_init(&alloc->base, &shm_allocator_iface,
40 DS_BUFFER_CAP_DATA_PTR | DS_BUFFER_CAP_SHM);
42 ds_dbg("Shm allocator(%p) created", alloc);
47 static struct ds_shm_allocator *
48 shm_allocator_from_allocator(struct ds_allocator *ds_allocator)
50 assert(ds_allocator->iface == &shm_allocator_iface);
51 return (struct ds_shm_allocator *)ds_allocator;
55 shm_allocator_destroy(struct ds_allocator *ds_allocator)
57 struct ds_shm_allocator *alloc;
59 alloc = shm_allocator_from_allocator(ds_allocator);
60 ds_dbg("Destroy Shm allocator(%p)", alloc);
64 static const struct ds_buffer_interface shm_buffer_interface;
66 static struct ds_shm_buffer *
67 shm_buffer_from_buffer(struct ds_buffer *buffer)
69 assert(buffer->iface == &shm_buffer_interface);
70 return (struct ds_shm_buffer *)buffer;
74 shm_buffer_destroy(struct ds_buffer *ds_buffer)
76 struct ds_shm_buffer *buffer;
78 buffer = shm_buffer_from_buffer(ds_buffer);
80 ds_dbg("Destroy shm buffer(%p)", buffer);
82 munmap(buffer->data, buffer->size);
83 close(buffer->shm.fd);
88 shm_buffer_get_shm(struct ds_buffer *ds_buffer, struct ds_shm_attributes *shm)
90 struct ds_shm_buffer *buffer;
92 buffer = shm_buffer_from_buffer(ds_buffer);
93 memcpy(shm, &buffer->shm, sizeof *shm);
98 shm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags,
99 void **data, uint32_t *format, size_t *stride)
101 struct ds_shm_buffer *buffer;
103 buffer = shm_buffer_from_buffer(ds_buffer);
104 *data = buffer->data;
105 *format = buffer->shm.format;
106 *stride = buffer->shm.stride;
111 shm_buffer_end_data_ptr_access(struct ds_buffer *buffer)
115 // This space is intentionally left blank
118 static const struct ds_buffer_interface shm_buffer_interface =
120 .destroy = shm_buffer_destroy,
121 .get_shm = shm_buffer_get_shm,
122 .begin_data_ptr_access = shm_buffer_begin_data_ptr_access,
123 .end_data_ptr_access = shm_buffer_end_data_ptr_access,
126 static struct ds_buffer *
127 shm_allocator_create_buffer(struct ds_allocator *ds_allocator,
128 int width, int height, uint32_t format)
130 struct ds_shm_buffer *buffer;
131 int bytes_per_pixel, stride;
133 buffer = calloc(1, sizeof *buffer);
137 ds_buffer_init(&buffer->base, &shm_buffer_interface, width, height);
141 stride = width * bytes_per_pixel;
142 buffer->size = stride * height;
143 buffer->shm.fd = allocate_shm_file(buffer->size);
144 if (buffer->shm.fd < 0) {
149 buffer->shm.format = format;
150 buffer->shm.width = width;
151 buffer->shm.height = height;
152 buffer->shm.stride = stride;
153 buffer->shm.offset = 0;
155 buffer->data = mmap(NULL, buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED,
157 if (buffer->data == MAP_FAILED) {
158 ds_log_errno(DS_ERR, "mmap failed");
159 close(buffer->shm.fd);
164 ds_dbg("Shm buffer(%p) created: size(%dx%d)", buffer, width, height);
166 return &buffer->base;
169 static const struct ds_allocator_interface shm_allocator_iface =
171 .destroy = shm_allocator_destroy,
172 .create_buffer = shm_allocator_create_buffer,