OSDN Git Service

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