rearrange the directories of git repository
[platform/core/uifw/libds-tizen.git] / src / allocator / tbm.c
1 #include <assert.h>
2 #include <stdlib.h>
3
4 #include <drm_fourcc.h>
5 #include <wayland-server.h>
6 #include <tbm_bufmgr.h>
7 #include <tbm_surface.h>
8
9 #include <libds/interfaces/allocator.h>
10 #include <libds/interfaces/buffer.h>
11 #include <libds/log.h>
12
13 struct ds_tbm_allocator
14 {
15     struct ds_allocator base;
16     tbm_bufmgr bufmgr;
17 };
18
19 struct ds_tbm_buffer
20 {
21     struct ds_buffer base;
22     tbm_surface_h surface;
23 };
24
25 static const struct ds_allocator_interface tbm_allocator_iface;
26 static struct ds_tbm_buffer *tbm_buffer_from_buffer(struct ds_buffer *buffer);
27
28 WL_EXPORT struct ds_allocator *
29 ds_tbm_allocator_create(void)
30 {
31     struct ds_tbm_allocator *alloc;
32
33     alloc = calloc(1, sizeof *alloc);
34     if (!alloc)
35         return NULL;
36
37     alloc->bufmgr = tbm_bufmgr_init(-1);
38     if (!alloc->bufmgr) {
39         ds_err("Could not initialize tbm_bufmgr");
40         free(alloc);
41         return NULL;
42     }
43
44     ds_allocator_init(&alloc->base, &tbm_allocator_iface,
45             DS_BUFFER_CAP_DATA_PTR);
46
47     ds_inf("TBM allocator(%p) created", alloc);
48
49     return &alloc->base;
50 }
51
52 WL_EXPORT void *
53 ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer)
54 {
55     struct ds_tbm_buffer *buffer;
56
57     buffer = tbm_buffer_from_buffer(ds_buffer);
58     if (!buffer)
59         return NULL;
60
61     return buffer->surface;
62 }
63
64 static struct ds_tbm_allocator *
65 tbm_allocator_from_allocator(struct ds_allocator *ds_allocator)
66 {
67     assert(ds_allocator->iface == &tbm_allocator_iface);
68     return (struct ds_tbm_allocator *)ds_allocator;
69 }
70
71 static const struct ds_buffer_interface tbm_buffer_iface;
72
73 static struct ds_tbm_buffer *
74 tbm_buffer_from_buffer(struct ds_buffer *buffer)
75 {
76     assert(buffer->iface == &tbm_buffer_iface);
77     return (struct ds_tbm_buffer *)buffer;
78 }
79
80 static void
81 tbm_buffer_destroy(struct ds_buffer *ds_buffer)
82 {
83     struct ds_tbm_buffer *buffer;
84
85     buffer = tbm_buffer_from_buffer(ds_buffer);
86
87     ds_dbg("Destroy tbm buffer(%p)", buffer);
88
89     tbm_surface_destroy(buffer->surface);
90     free(buffer);
91 }
92
93 static bool
94 tbm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags,
95         void **data, uint32_t *format, size_t *stride)
96 {
97     struct ds_tbm_buffer *buffer;
98     tbm_surface_info_s info;
99     int tbm_access_flags = 0;
100     int ret;
101
102     buffer = tbm_buffer_from_buffer(ds_buffer);
103
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;
108
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);
112         return false;
113     }
114     
115     *data = info.planes[0].ptr;
116     *format = info.format;
117     *stride = info.planes[0].stride;
118
119     return true;
120 }
121
122 static void
123 tbm_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer)
124 {
125     struct ds_tbm_buffer *buffer;
126
127     buffer = tbm_buffer_from_buffer(ds_buffer);
128
129     tbm_surface_unmap(buffer->surface);
130 }
131
132 static const struct ds_buffer_interface tbm_buffer_iface =
133 {
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,
137 };
138
139 static void
140 tbm_allocator_destroy(struct ds_allocator *ds_allocator)
141 {
142     struct ds_tbm_allocator *alloc;
143
144     alloc = tbm_allocator_from_allocator(ds_allocator);
145
146     ds_inf("Destroy TBM allocator(%p)", alloc);
147
148     tbm_bufmgr_deinit(alloc->bufmgr);
149     free(alloc);
150 }
151
152 static struct ds_buffer *
153 tbm_allocator_create_buffer(struct ds_allocator *ds_allocator,
154         int width, int height, uint32_t format)
155 {
156     static int num_buffers = 0;
157     struct ds_tbm_buffer *buffer;
158
159     buffer = calloc(1, sizeof *buffer);
160     if (!buffer)
161         return NULL;
162
163     ds_buffer_init(&buffer->base, &tbm_buffer_iface, width, height);
164
165     buffer->surface = tbm_surface_create(width, height, TBM_FORMAT_XRGB8888);
166
167     ds_dbg("tbm buffer(%p) created: size(%dx%d) number of buffers: %d",
168             buffer, width, height, ++num_buffers);
169
170     return &buffer->base;
171 }
172
173 static const struct ds_allocator_interface tbm_allocator_iface =
174 {
175     .destroy = tbm_allocator_destroy,
176     .create_buffer = tbm_allocator_create_buffer,
177 };