keyrouter: Fix wrong validity check
[platform/core/uifw/libds-tizen.git] / src / libds / allocator / shm.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <sys/mman.h>
4 #include <unistd.h>
5
6 #include <drm_fourcc.h>
7 #include <wayland-server.h>
8
9 #include "libds/allocator/shm.h"
10 #include "libds/interfaces/allocator.h"
11 #include "libds/interfaces/buffer.h"
12 #include "libds/log.h"
13 #include "util.h"
14
15 struct ds_shm_allocator
16 {
17     struct ds_allocator base;
18 };
19
20 struct ds_shm_buffer
21 {
22     struct ds_buffer base;
23     struct ds_shm_attributes shm;
24     void *data;
25     size_t size;
26 };
27
28 static const struct ds_allocator_interface shm_allocator_iface;
29
30 WL_EXPORT struct ds_allocator *
31 ds_shm_allocator_create(void)
32 {
33     struct ds_shm_allocator *alloc;
34
35     alloc = calloc(1, sizeof *alloc);
36     if (!alloc)
37         return NULL;
38
39     ds_allocator_init(&alloc->base, &shm_allocator_iface,
40             DS_BUFFER_CAP_DATA_PTR | DS_BUFFER_CAP_SHM);
41
42     ds_dbg("Shm allocator(%p) created", alloc);
43
44     return &alloc->base;
45 }
46
47 static struct ds_shm_allocator *
48 shm_allocator_from_allocator(struct ds_allocator *ds_allocator)
49 {
50     assert(ds_allocator->iface == &shm_allocator_iface);
51     return (struct ds_shm_allocator *)ds_allocator;
52 }
53
54 static void
55 shm_allocator_destroy(struct ds_allocator *ds_allocator)
56 {
57     struct ds_shm_allocator *alloc;
58
59     alloc = shm_allocator_from_allocator(ds_allocator);
60     ds_dbg("Destroy Shm allocator(%p)", alloc);
61     free(alloc);
62 }
63
64 static const struct ds_buffer_interface shm_buffer_interface;
65
66 static struct ds_shm_buffer *
67 shm_buffer_from_buffer(struct ds_buffer *buffer)
68 {
69     assert(buffer->iface == &shm_buffer_interface);
70     return (struct ds_shm_buffer *)buffer;
71 }
72
73 static void
74 shm_buffer_destroy(struct ds_buffer *ds_buffer)
75 {
76     struct ds_shm_buffer *buffer;
77
78     buffer = shm_buffer_from_buffer(ds_buffer);
79
80     ds_dbg("Destroy shm buffer(%p)", buffer);
81
82     munmap(buffer->data, buffer->size);
83     close(buffer->shm.fd);
84     free(buffer);
85 }
86
87 static bool
88 shm_buffer_get_shm(struct ds_buffer *ds_buffer, struct ds_shm_attributes *shm)
89 {
90     struct ds_shm_buffer *buffer;
91
92     buffer = shm_buffer_from_buffer(ds_buffer);
93     memcpy(shm, &buffer->shm, sizeof *shm);
94     return true;
95 }
96
97 static bool
98 shm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags,
99         void **data, uint32_t *format, size_t *stride)
100 {
101     struct ds_shm_buffer *buffer;
102
103     buffer = shm_buffer_from_buffer(ds_buffer);
104     *data = buffer->data;
105     *format = buffer->shm.format;
106     *stride = buffer->shm.stride;
107     return true;
108 }
109
110 static void
111 shm_buffer_end_data_ptr_access(struct ds_buffer *buffer)
112 {
113     (void) buffer;
114
115     // This space is intentionally left blank
116 }
117
118 static const struct ds_buffer_interface shm_buffer_interface =
119 {
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,
124 };
125
126 static struct ds_buffer *
127 shm_allocator_create_buffer(struct ds_allocator *ds_allocator,
128         int width, int height, uint32_t format)
129 {
130     struct ds_shm_buffer *buffer;
131     int bytes_per_pixel, stride;
132
133     buffer = calloc(1, sizeof *buffer);
134     if (!buffer)
135         return NULL;
136
137     ds_buffer_init(&buffer->base, &shm_buffer_interface, width, height);
138
139     // FIXME
140     bytes_per_pixel = 4;
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) {
145         free(buffer);
146         return NULL;
147     }
148
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;
154
155     buffer->data = mmap(NULL, buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED,
156             buffer->shm.fd, 0);
157     if (buffer->data == MAP_FAILED) {
158         ds_log_errno(DS_ERR, "mmap failed");
159         close(buffer->shm.fd);
160         free(buffer);
161         return NULL;
162     }
163
164     ds_dbg("Shm buffer(%p) created: size(%dx%d)", buffer, width, height);
165
166     return &buffer->base;
167 }
168
169 static const struct ds_allocator_interface shm_allocator_iface =
170 {
171     .destroy = shm_allocator_destroy,
172     .create_buffer = shm_allocator_create_buffer,
173 };