OSDN Git Service

gralloc0_register_buffer: initialize gralloc0 when needed
[android-x86/external-minigbm.git] / cros_gralloc / gralloc0 / gralloc0.cc
1 /*
2  * Copyright 2016 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 #include "../cros_gralloc_driver.h"
8
9 #include <cassert>
10 #include <hardware/gralloc.h>
11 #include <memory.h>
12 #include <xf86drm.h>
13 #include "drm_framebuffer.h"
14 #include "gralloc_drm.h"
15
16 struct gralloc0_module {
17         gralloc_module_t base;
18         std::unique_ptr<alloc_device_t> alloc;
19         std::unique_ptr<cros_gralloc_driver> driver;
20         struct drm_framebuffer *fb;
21         bool initialized;
22         std::mutex initialization_mutex;
23 };
24
25 /* This enumeration must match the one in <gralloc_drm.h>.
26  * The functions supported by this gralloc's temporary private API are listed
27  * below. Use of these functions is highly discouraged and should only be
28  * reserved for cases where no alternative to get same information (such as
29  * querying ANativeWindow) exists.
30  */
31 // clang-format off
32 enum {
33         GRALLOC_DRM_GET_STRIDE,
34         GRALLOC_DRM_GET_FORMAT,
35         GRALLOC_DRM_GET_DIMENSIONS,
36         GRALLOC_DRM_GET_BACKING_STORE,
37 };
38 // clang-format on
39
40 static uint64_t gralloc0_convert_usage(int usage)
41 {
42         uint64_t use_flags = BO_USE_NONE;
43
44         if (usage & GRALLOC_USAGE_CURSOR)
45                 use_flags |= BO_USE_NONE;
46         if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY)
47                 use_flags |= BO_USE_SW_READ_RARELY;
48         if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
49                 use_flags |= BO_USE_SW_READ_OFTEN;
50         if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY)
51                 use_flags |= BO_USE_SW_WRITE_RARELY;
52         if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN)
53                 use_flags |= BO_USE_SW_WRITE_OFTEN;
54         if (usage & GRALLOC_USAGE_HW_TEXTURE)
55                 use_flags |= BO_USE_TEXTURE;
56         if (usage & GRALLOC_USAGE_HW_RENDER)
57                 use_flags |= BO_USE_RENDERING;
58         if (usage & GRALLOC_USAGE_HW_2D)
59                 use_flags |= BO_USE_RENDERING;
60         if (usage & GRALLOC_USAGE_HW_COMPOSER)
61                 /* HWC wants to use display hardware, but can defer to OpenGL. */
62                 use_flags |= BO_USE_SCANOUT | BO_USE_TEXTURE;
63         if (usage & GRALLOC_USAGE_HW_FB)
64                 use_flags |= BO_USE_FRAMEBUFFER;
65         if (usage & GRALLOC_USAGE_EXTERNAL_DISP)
66                 /*
67                  * This flag potentially covers external display for the normal drivers (i915,
68                  * rockchip) and usb monitors (evdi/udl). It's complicated so ignore it.
69                  * */
70                 use_flags |= BO_USE_NONE;
71         if (usage & GRALLOC_USAGE_PROTECTED)
72                 use_flags |= BO_USE_PROTECTED;
73         if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
74                 /*HACK: See b/30054495 */
75                 use_flags |= BO_USE_SW_READ_OFTEN;
76         if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
77                 use_flags |= BO_USE_CAMERA_WRITE;
78         if (usage & GRALLOC_USAGE_HW_CAMERA_READ)
79                 use_flags |= BO_USE_CAMERA_READ;
80         if (usage & GRALLOC_USAGE_RENDERSCRIPT)
81                 use_flags |= BO_USE_RENDERSCRIPT;
82
83         return use_flags;
84 }
85
86 static uint32_t gralloc0_convert_map_usage(int map_usage)
87 {
88         uint32_t map_flags = BO_MAP_NONE;
89
90         if (map_usage & GRALLOC_USAGE_SW_READ_MASK)
91                 map_flags |= BO_MAP_READ;
92         if (map_usage & GRALLOC_USAGE_SW_WRITE_MASK)
93                 map_flags |= BO_MAP_WRITE;
94
95         return map_flags;
96 }
97
98 static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usage,
99                           buffer_handle_t *handle, int *stride)
100 {
101         int32_t ret;
102         bool supported;
103         struct cros_gralloc_buffer_descriptor descriptor;
104         auto mod = (struct gralloc0_module const *)dev->common.module;
105
106         descriptor.width = w;
107         descriptor.height = h;
108         descriptor.droid_format = format;
109         descriptor.producer_usage = descriptor.consumer_usage = usage;
110         descriptor.drm_format = cros_gralloc_convert_format(format);
111         descriptor.use_flags = gralloc0_convert_usage(usage);
112
113         supported = mod->driver->is_supported(&descriptor);
114         if (!supported && (usage & GRALLOC_USAGE_HW_COMPOSER)) {
115                 descriptor.use_flags &= ~BO_USE_SCANOUT;
116                 supported = mod->driver->is_supported(&descriptor);
117         }
118
119         if (!supported) {
120                 drv_log("Unsupported combination -- HAL format: %u, HAL usage: %u, "
121                         "drv_format: %4.4s, use_flags: %llu\n",
122                         format, usage, reinterpret_cast<char *>(&descriptor.drm_format),
123                         static_cast<unsigned long long>(descriptor.use_flags));
124                 return -EINVAL;
125         }
126
127         ret = mod->driver->allocate(&descriptor, handle);
128         if (ret)
129                 return ret;
130
131         auto hnd = cros_gralloc_convert_handle(*handle);
132         *stride = hnd->pixel_stride;
133
134         return 0;
135 }
136
137 static int gralloc0_free(alloc_device_t *dev, buffer_handle_t handle)
138 {
139         auto mod = (struct gralloc0_module const *)dev->common.module;
140         return mod->driver->release(handle);
141 }
142
143 static int gralloc0_close(struct hw_device_t *dev)
144 {
145         /* Memory is freed by managed pointers on process close. */
146         return 0;
147 }
148
149 static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc,
150                           bool framebuffer = false)
151 {
152         std::lock_guard<std::mutex> lock(mod->initialization_mutex);
153
154         if (mod->initialized)
155                 return 0;
156
157         mod->driver = std::make_unique<cros_gralloc_driver>();
158         if (framebuffer ? mod->driver->init_master() : mod->driver->init()) {
159                 drv_log("Failed to initialize driver.\n");
160                 return -ENODEV;
161         }
162
163         if (initialize_alloc) {
164                 mod->alloc = std::make_unique<alloc_device_t>();
165                 mod->alloc->alloc = gralloc0_alloc;
166                 mod->alloc->free = gralloc0_free;
167                 mod->alloc->common.tag = HARDWARE_DEVICE_TAG;
168                 mod->alloc->common.version = 0;
169                 mod->alloc->common.module = (hw_module_t *)mod;
170                 mod->alloc->common.close = gralloc0_close;
171         }
172
173         if (framebuffer) {
174                 int ret = drm_framebuffer_init(mod->driver->get_fd(), &mod->fb);
175                 if (ret)
176                         return ret;
177         }
178
179         mod->initialized = true;
180         return 0;
181 }
182
183 static int gralloc0_open_fb0(struct gralloc0_module *mod, struct hw_device_t **dev)
184 {
185         int ret;
186
187         if (!mod->initialized) {
188                 ret = gralloc0_init(mod, true, true);
189                 if (ret)
190                         return ret;
191         }
192
193         if (!mod->fb) {
194                 /*
195                  * On Pie and above the FB HAL is opened before the Gralloc HAL.
196                  * This has the advantage that we can open the DRM card node in this case,
197                  * and open the render node in all other cases.
198                  *
199                  * On earlier Android versions this is not the case, so we need to make
200                  * sure the FB HAL was actually initialized.
201                  *
202                  * TODO: Currently it does not attempt to set master on the opened render
203                  * node. That means it will only work with DRM authentication disabled.
204                  */
205                 std::lock_guard<std::mutex> lock(mod->initialization_mutex);
206                 drv_log("FB HAL opened after Gralloc HAL, we might not be DRM master!\n");
207
208                 ret = drm_framebuffer_init(mod->driver->get_fd(), &mod->fb);
209                 if (ret)
210                         return ret;
211         }
212
213         *dev = (struct hw_device_t *) mod->fb;
214         return 0;
215 }
216
217 static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev)
218 {
219         auto const_module = reinterpret_cast<const struct gralloc0_module *>(mod);
220         auto module = const_cast<struct gralloc0_module *>(const_module);
221
222         if (!strcmp(name, GRALLOC_HARDWARE_FB0))
223                 return gralloc0_open_fb0(module, dev);
224
225         if (module->initialized) {
226                 *dev = &module->alloc->common;
227                 return 0;
228         }
229
230         if (strcmp(name, GRALLOC_HARDWARE_GPU0)) {
231                 drv_log("Incorrect device name - %s.\n", name);
232                 return -EINVAL;
233         }
234
235         if (gralloc0_init(module, true))
236                 return -ENODEV;
237
238         *dev = &module->alloc->common;
239         return 0;
240 }
241
242 static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffer_handle_t handle)
243 {
244         auto const_module = reinterpret_cast<const struct gralloc0_module *>(module);
245         auto mod = const_cast<struct gralloc0_module *>(const_module);
246
247         if (!mod->initialized)
248                 if (gralloc0_init(mod, true))
249                         return -ENODEV;
250
251         int ret = mod->driver->retain(handle);
252         if (ret == 0 && mod->fb)
253                 drm_framebuffer_import(mod->fb, handle);
254         return ret;
255 }
256
257 static int gralloc0_unregister_buffer(struct gralloc_module_t const *module, buffer_handle_t handle)
258 {
259         auto mod = (struct gralloc0_module const *)module;
260         return mod->driver->release(handle);
261 }
262
263 static int gralloc0_lock(struct gralloc_module_t const *module, buffer_handle_t handle, int usage,
264                          int l, int t, int w, int h, void **vaddr)
265 {
266         return module->lockAsync(module, handle, usage, l, t, w, h, vaddr, -1);
267 }
268
269 static int gralloc0_unlock(struct gralloc_module_t const *module, buffer_handle_t handle)
270 {
271         int32_t fence_fd, ret;
272         auto mod = (struct gralloc0_module const *)module;
273         ret = mod->driver->unlock(handle, &fence_fd);
274         if (ret)
275                 return ret;
276
277         ret = cros_gralloc_sync_wait(fence_fd);
278         if (ret)
279                 return ret;
280
281         return 0;
282 }
283
284 static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
285 {
286         va_list args;
287         int32_t *out_format, ret;
288         uint64_t *out_store;
289         buffer_handle_t handle;
290         uint32_t *out_width, *out_height, *out_stride;
291         auto mod = (struct gralloc0_module const *)module;
292
293         switch (op) {
294         case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
295         case GRALLOC_MODULE_PERFORM_ENTER_VT:
296         case GRALLOC_MODULE_PERFORM_LEAVE_VT:
297         case GRALLOC_DRM_GET_STRIDE:
298         case GRALLOC_DRM_GET_FORMAT:
299         case GRALLOC_DRM_GET_DIMENSIONS:
300         case GRALLOC_DRM_GET_BACKING_STORE:
301                 break;
302         default:
303                 return -EINVAL;
304         }
305
306         va_start(args, op);
307         ret = 0;
308
309         switch (op) {
310         case GRALLOC_MODULE_PERFORM_GET_DRM_FD: {
311                 int *fd = va_arg(args, int*);
312                 *fd = mod->driver->get_fd();
313                 break;
314         }
315         case GRALLOC_MODULE_PERFORM_ENTER_VT:
316                 ret = drmSetMaster(mod->driver->get_fd());
317                 break;
318         case GRALLOC_MODULE_PERFORM_LEAVE_VT:
319                 ret = drmDropMaster(mod->driver->get_fd());
320                 break;
321         default:
322                 goto other;
323         }
324
325         va_end(args);
326         return ret;
327
328 other:
329         handle = va_arg(args, buffer_handle_t);
330         auto hnd = cros_gralloc_convert_handle(handle);
331         if (!hnd) {
332                 drv_log("Invalid handle.\n");
333                 return -EINVAL;
334         }
335
336         switch (op) {
337         case GRALLOC_DRM_GET_STRIDE:
338                 out_stride = va_arg(args, uint32_t *);
339                 *out_stride = hnd->pixel_stride;
340                 break;
341         case GRALLOC_DRM_GET_FORMAT:
342                 out_format = va_arg(args, int32_t *);
343                 *out_format = hnd->droid_format;
344                 break;
345         case GRALLOC_DRM_GET_DIMENSIONS:
346                 out_width = va_arg(args, uint32_t *);
347                 out_height = va_arg(args, uint32_t *);
348                 *out_width = hnd->width;
349                 *out_height = hnd->height;
350                 break;
351         case GRALLOC_DRM_GET_BACKING_STORE:
352                 out_store = va_arg(args, uint64_t *);
353                 ret = mod->driver->get_backing_store(handle, out_store);
354                 break;
355         default:
356                 ret = -EINVAL;
357         }
358
359         va_end(args);
360
361         return ret;
362 }
363
364 static int gralloc0_lock_ycbcr(struct gralloc_module_t const *module, buffer_handle_t handle,
365                                int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr)
366 {
367         return module->lockAsync_ycbcr(module, handle, usage, l, t, w, h, ycbcr, -1);
368 }
369
370 static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_handle_t handle,
371                                int usage, int l, int t, int w, int h, void **vaddr, int fence_fd)
372 {
373         int32_t ret;
374         uint32_t map_flags;
375         uint8_t *addr[DRV_MAX_PLANES];
376         auto mod = (struct gralloc0_module const *)module;
377         struct rectangle rect = { .x = static_cast<uint32_t>(l),
378                                   .y = static_cast<uint32_t>(t),
379                                   .width = static_cast<uint32_t>(w),
380                                   .height = static_cast<uint32_t>(h) };
381
382         auto hnd = cros_gralloc_convert_handle(handle);
383         if (!hnd) {
384                 drv_log("Invalid handle.\n");
385                 return -EINVAL;
386         }
387
388         if (hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
389                 drv_log("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.\n");
390                 return -EINVAL;
391         }
392
393         assert(l >= 0);
394         assert(t >= 0);
395         assert(w >= 0);
396         assert(h >= 0);
397
398         map_flags = gralloc0_convert_map_usage(usage);
399         ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr);
400         *vaddr = addr[0];
401         return ret;
402 }
403
404 static int gralloc0_unlock_async(struct gralloc_module_t const *module, buffer_handle_t handle,
405                                  int *fence_fd)
406 {
407         auto mod = (struct gralloc0_module const *)module;
408         return mod->driver->unlock(handle, fence_fd);
409 }
410
411 static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buffer_handle_t handle,
412                                      int usage, int l, int t, int w, int h,
413                                      struct android_ycbcr *ycbcr, int fence_fd)
414 {
415         int32_t ret;
416         uint32_t map_flags;
417         uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr };
418         auto mod = (struct gralloc0_module const *)module;
419         struct rectangle rect = { .x = static_cast<uint32_t>(l),
420                                   .y = static_cast<uint32_t>(t),
421                                   .width = static_cast<uint32_t>(w),
422                                   .height = static_cast<uint32_t>(h) };
423
424         auto hnd = cros_gralloc_convert_handle(handle);
425         if (!hnd) {
426                 drv_log("Invalid handle.\n");
427                 return -EINVAL;
428         }
429
430         if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) &&
431             (hnd->droid_format != HAL_PIXEL_FORMAT_YV12) &&
432             (hnd->droid_format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) {
433                 drv_log("Non-YUV format not compatible.\n");
434                 return -EINVAL;
435         }
436
437         assert(l >= 0);
438         assert(t >= 0);
439         assert(w >= 0);
440         assert(h >= 0);
441
442         map_flags = gralloc0_convert_map_usage(usage);
443         ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr);
444         if (ret)
445                 return ret;
446
447         switch (hnd->format) {
448         case DRM_FORMAT_NV12:
449                 ycbcr->y = addr[0];
450                 ycbcr->cb = addr[1];
451                 ycbcr->cr = addr[1] + 1;
452                 ycbcr->ystride = hnd->strides[0];
453                 ycbcr->cstride = hnd->strides[1];
454                 ycbcr->chroma_step = 2;
455                 break;
456         case DRM_FORMAT_YVU420:
457         case DRM_FORMAT_YVU420_ANDROID:
458                 ycbcr->y = addr[0];
459                 ycbcr->cb = addr[2];
460                 ycbcr->cr = addr[1];
461                 ycbcr->ystride = hnd->strides[0];
462                 ycbcr->cstride = hnd->strides[1];
463                 ycbcr->chroma_step = 1;
464                 break;
465         default:
466                 module->unlock(module, handle);
467                 return -EINVAL;
468         }
469
470         return 0;
471 }
472
473 // clang-format off
474 static struct hw_module_methods_t gralloc0_module_methods = { .open = gralloc0_open };
475 // clang-format on
476
477 struct gralloc0_module HAL_MODULE_INFO_SYM = {
478         .base =
479             {
480                 .common =
481                     {
482                         .tag = HARDWARE_MODULE_TAG,
483                         .module_api_version = GRALLOC_MODULE_API_VERSION_0_3,
484                         .hal_api_version = 0,
485                         .id = GRALLOC_HARDWARE_MODULE_ID,
486                         .name = "CrOS Gralloc",
487                         .author = "Chrome OS",
488                         .methods = &gralloc0_module_methods,
489                     },
490
491                 .registerBuffer = gralloc0_register_buffer,
492                 .unregisterBuffer = gralloc0_unregister_buffer,
493                 .lock = gralloc0_lock,
494                 .unlock = gralloc0_unlock,
495                 .perform = gralloc0_perform,
496                 .lock_ycbcr = gralloc0_lock_ycbcr,
497                 .lockAsync = gralloc0_lock_async,
498                 .unlockAsync = gralloc0_unlock_async,
499                 .lockAsync_ycbcr = gralloc0_lock_async_ycbcr,
500             },
501
502         .alloc = nullptr,
503         .driver = nullptr,
504         .initialized = false,
505 };