OSDN Git Service

Merge remote-tracking branch 'origin/master' into nougat-x86
[android-x86/external-gbm_gralloc.git] / gralloc.cpp
1 /*
2  * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
3  * Copyright (C) 2010-2011 LunarG Inc.
4  * Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 #define LOG_TAG "GRALLOC-GBM"
26
27 #include <log/log.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include <pthread.h>
32 #include <errno.h>
33
34 #include <hardware/gralloc.h>
35 #include <system/graphics.h>
36
37 #include <gbm.h>
38 #include <drm_framebuffer.h>
39
40 #include "gralloc_drm.h"
41 #include "gralloc_gbm_priv.h"
42
43 struct gbm_module_t {
44         gralloc_module_t base;
45
46         pthread_mutex_t mutex;
47         struct gbm_device *gbm;
48         struct drm_framebuffer *fb;
49 };
50
51 /*
52  * Initialize the DRM device object
53  */
54 static int gbm_init(struct gbm_module_t *dmod, bool master = false)
55 {
56         int err = 0;
57
58         pthread_mutex_lock(&dmod->mutex);
59         if (!dmod->gbm) {
60                 dmod->gbm = gbm_dev_create(master);
61                 if (!dmod->gbm)
62                         err = -EINVAL;
63         }
64         pthread_mutex_unlock(&dmod->mutex);
65
66         return err;
67 }
68
69 static int gbm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
70 {
71         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
72         va_list args;
73         int err;
74         uint32_t uop = static_cast<uint32_t>(op);
75
76         err = gbm_init(dmod);
77         if (err)
78                 return err;
79
80         va_start(args, op);
81         switch (uop) {
82         case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
83                 {
84                         int *fd = va_arg(args, int *);
85                         *fd = gbm_device_get_fd(dmod->gbm);
86                         err = 0;
87                 }
88                 break;
89         default:
90                 err = -EINVAL;
91                 break;
92         }
93         va_end(args);
94
95         return err;
96 }
97
98 static int gbm_mod_register_buffer(const gralloc_module_t *mod,
99                 buffer_handle_t handle)
100 {
101         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
102         int err;
103
104         err = gbm_init(dmod);
105         if (err)
106                 return err;
107
108         pthread_mutex_lock(&dmod->mutex);
109         err = gralloc_gbm_handle_register(handle, dmod->gbm);
110         if (err == 0 && dmod->fb)
111                 drm_framebuffer_import(dmod->fb, handle);
112         pthread_mutex_unlock(&dmod->mutex);
113
114         return err;
115 }
116
117 static int gbm_mod_unregister_buffer(const gralloc_module_t *mod,
118                 buffer_handle_t handle)
119 {
120         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
121         int err;
122
123         pthread_mutex_lock(&dmod->mutex);
124         err = gralloc_gbm_handle_unregister(handle);
125         pthread_mutex_unlock(&dmod->mutex);
126
127         return err;
128 }
129
130 static int gbm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle,
131                 int usage, int x, int y, int w, int h, void **ptr)
132 {
133         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
134         int err;
135
136         pthread_mutex_lock(&dmod->mutex);
137
138         err = gralloc_gbm_bo_lock(handle, usage, x, y, w, h, ptr);
139         ALOGV("buffer %p lock usage = %08x", handle, usage);
140
141         pthread_mutex_unlock(&dmod->mutex);
142         return err;
143 }
144
145 static int gbm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
146 {
147         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
148         int err;
149
150         pthread_mutex_lock(&dmod->mutex);
151         err = gralloc_gbm_bo_unlock(handle);
152         pthread_mutex_unlock(&dmod->mutex);
153
154         return err;
155 }
156
157 static int gbm_mod_lock_ycbcr(gralloc_module_t const *mod, buffer_handle_t handle,
158                 int usage, int x, int y, int w, int h, struct android_ycbcr *ycbcr)
159 {
160         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
161         int err;
162
163         pthread_mutex_lock(&dmod->mutex);
164         err = gralloc_gbm_bo_lock_ycbcr(handle, usage, x, y, w, h, ycbcr);
165         pthread_mutex_unlock(&dmod->mutex);
166
167         return err;
168 }
169
170 static int gbm_mod_close_gpu0(struct hw_device_t *dev)
171 {
172         struct gbm_module_t *dmod = (struct gbm_module_t *)dev->module;
173         struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
174
175         gbm_dev_destroy(dmod->gbm);
176         delete alloc;
177
178         return 0;
179 }
180
181 static int gbm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
182 {
183         struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
184
185         pthread_mutex_lock(&dmod->mutex);
186         gbm_free(handle);
187         native_handle_close(handle);
188         delete handle;
189
190         pthread_mutex_unlock(&dmod->mutex);
191         return 0;
192 }
193
194 static int gbm_mod_alloc_gpu0(alloc_device_t *dev,
195                 int w, int h, int format, int usage,
196                 buffer_handle_t *handle, int *stride)
197 {
198         struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
199         int err = 0;
200
201         pthread_mutex_lock(&dmod->mutex);
202
203         *handle = gralloc_gbm_bo_create(dmod->gbm, w, h, format, usage, stride);
204         if (!*handle)
205                 err = -errno;
206
207         ALOGV("buffer %p usage = %08x", *handle, usage);
208         pthread_mutex_unlock(&dmod->mutex);
209         return err;
210 }
211
212 static int gbm_mod_open_gpu0(struct gbm_module_t *dmod, hw_device_t **dev)
213 {
214         struct alloc_device_t *alloc;
215         int err;
216
217         err = gbm_init(dmod);
218         if (err)
219                 return err;
220
221         alloc = new alloc_device_t();
222         if (!alloc)
223                 return -EINVAL;
224
225         alloc->common.tag = HARDWARE_DEVICE_TAG;
226         alloc->common.version = 0;
227         alloc->common.module = &dmod->base.common;
228         alloc->common.close = gbm_mod_close_gpu0;
229
230         alloc->alloc = gbm_mod_alloc_gpu0;
231         alloc->free = gbm_mod_free_gpu0;
232
233         *dev = &alloc->common;
234
235         return 0;
236 }
237
238 static int gbm_mod_open_fb0(struct gbm_module_t *dmod, hw_device_t **dev)
239 {
240         int err = gbm_init(dmod, true);
241         if (err)
242                 return err;
243
244         pthread_mutex_lock(&dmod->mutex);
245         err = drm_framebuffer_open(gbm_device_get_fd(dmod->gbm), &dmod->fb, dev);
246         pthread_mutex_unlock(&dmod->mutex);
247
248         return err;
249 }
250
251 static int gbm_mod_open(const struct hw_module_t *mod,
252                 const char *name, struct hw_device_t **dev)
253 {
254         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
255         int err;
256
257         if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
258                 err = gbm_mod_open_gpu0(dmod, dev);
259         else if (strcmp(name, GRALLOC_HARDWARE_FB0) == 0)
260                 err = gbm_mod_open_fb0(dmod, dev);
261         else
262                 err = -EINVAL;
263
264         return err;
265 }
266
267 static struct hw_module_methods_t gbm_mod_methods = {
268         .open = gbm_mod_open
269 };
270
271 struct gbm_module_t HAL_MODULE_INFO_SYM = {
272         .base = {
273                 .common = {
274                         .tag = HARDWARE_MODULE_TAG,
275                         .version_major = 1,
276                         .version_minor = 0,
277                         .id = GRALLOC_HARDWARE_MODULE_ID,
278                         .name = "GBM Memory Allocator",
279                         .author = "Rob Herring - Linaro",
280                         .methods = &gbm_mod_methods
281                 },
282                 .registerBuffer = gbm_mod_register_buffer,
283                 .unregisterBuffer = gbm_mod_unregister_buffer,
284                 .lock = gbm_mod_lock,
285                 .unlock = gbm_mod_unlock,
286                 .lock_ycbcr = gbm_mod_lock_ycbcr,
287                 .perform = gbm_mod_perform
288         },
289
290         .mutex = PTHREAD_MUTEX_INITIALIZER,
291         .gbm = NULL,
292 };