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.
7 #include "cros_gralloc.h"
9 static struct cros_gralloc_bo *cros_gralloc_bo_create(struct driver *drv,
10 int width, int height,
11 int format, int usage)
15 struct cros_gralloc_bo *bo;
17 drv_format = cros_gralloc_convert_format(format);
18 drv_format = drv_resolve_format(drv, drv_format);
19 drv_usage = cros_gralloc_convert_flags(usage);
21 if (!drv_is_combination_supported(drv, drv_format, drv_usage,
22 DRM_FORMAT_MOD_NONE)) {
23 cros_gralloc_error("Unsupported combination -- HAL format: %u, "
24 "HAL flags: %u, drv_format: %u, "
25 "drv_flags: %llu", format, usage,
26 drv_format, drv_usage);
30 bo = new cros_gralloc_bo();
31 memset(bo, 0, sizeof(*bo));
33 bo->bo = drv_bo_create(drv, width, height, drv_format, drv_usage);
36 cros_gralloc_error("Failed to create bo.");
40 if (drv_num_buffers_per_bo(bo->bo) != 1) {
41 drv_bo_destroy(bo->bo);
43 cros_gralloc_error("Can only support one buffer per bo.");
52 static struct cros_gralloc_handle *cros_gralloc_handle_from_bo(struct bo *bo)
54 struct cros_gralloc_handle *hnd;
56 hnd = new cros_gralloc_handle();
57 memset(hnd, 0, sizeof(*hnd));
59 hnd->base.version = sizeof(hnd->base);
61 hnd->base.numInts = num_ints();
63 for (size_t p = 0; p < drv_bo_get_num_planes(bo); p++) {
64 hnd->data.strides[p] = drv_bo_get_plane_stride(bo, p);
65 hnd->data.offsets[p] = drv_bo_get_plane_offset(bo, p);
66 hnd->data.sizes[p] = drv_bo_get_plane_size(bo, p);
69 hnd->data.fds[0] = drv_bo_get_plane_fd(bo, 0);
70 hnd->data.width = drv_bo_get_width(bo);
71 hnd->data.height = drv_bo_get_height(bo);
72 hnd->data.format = drv_bo_get_format(bo);
74 hnd->magic = cros_gralloc_magic();
75 hnd->registrations = 0;
77 hnd->pixel_stride = hnd->data.strides[0];
78 hnd->pixel_stride /= drv_stride_from_format(hnd->data.format, 1, 0);
83 static int cros_gralloc_alloc(alloc_device_t *dev, int w, int h, int format,
84 int usage, buffer_handle_t *handle, int *stride)
86 auto mod = (struct cros_gralloc_module *) dev->common.module;
87 std::lock_guard<std::mutex> lock(mod->mutex);
89 auto bo = cros_gralloc_bo_create(mod->drv, w, h, format, usage);
91 return CROS_GRALLOC_ERROR_NO_RESOURCES;
93 auto hnd = cros_gralloc_handle_from_bo(bo->bo);
94 hnd->format = static_cast<int32_t>(format);
95 hnd->usage = static_cast<int32_t>(usage);
97 hnd->bo = reinterpret_cast<uint64_t>(bo);
100 mod->handles.insert(reinterpret_cast<uint64_t>(&hnd->base));
101 mod->buffers[drv_bo_get_plane_handle(bo->bo, 0).u32] = bo;
103 *stride = static_cast<int>(hnd->pixel_stride);
104 *handle = &hnd->base;
106 return CROS_GRALLOC_ERROR_NONE;
109 static int cros_gralloc_free(alloc_device_t *dev, buffer_handle_t handle)
111 struct cros_gralloc_bo *bo;
112 auto hnd = (struct cros_gralloc_handle *) handle;
113 auto mod = (struct cros_gralloc_module *) dev->common.module;
114 std::lock_guard<std::mutex> lock(mod->mutex);
116 if (cros_gralloc_validate_handle(hnd)) {
117 cros_gralloc_error("Invalid handle.");
118 return CROS_GRALLOC_ERROR_BAD_HANDLE;
121 if (cros_gralloc_validate_reference(mod, hnd, &bo)) {
122 cros_gralloc_error("Invalid Reference.");
123 return CROS_GRALLOC_ERROR_BAD_HANDLE;
126 if (hnd->registrations > 0) {
127 cros_gralloc_error("Deallocating before unregistering.");
128 return CROS_GRALLOC_ERROR_BAD_HANDLE;
131 return cros_gralloc_decrement_reference_count(mod, bo);
134 static int cros_gralloc_close(struct hw_device_t *dev)
136 auto mod = (struct cros_gralloc_module *) dev->module;
137 auto alloc = (struct alloc_device_t *) dev;
138 std::lock_guard<std::mutex> lock(mod->mutex);
141 drv_destroy(mod->drv);
145 mod->buffers.clear();
146 mod->handles.clear();
150 return CROS_GRALLOC_ERROR_NONE;
153 int cros_gralloc_open(const struct hw_module_t *mod, const char *name,
154 struct hw_device_t **dev)
156 auto module = (struct cros_gralloc_module *) mod;
157 std::lock_guard<std::mutex> lock(module->mutex);
160 return CROS_GRALLOC_ERROR_NONE;
162 if (strcmp(name, GRALLOC_HARDWARE_GPU0)) {
163 cros_gralloc_error("Incorrect device name - %s.", name);
164 return CROS_GRALLOC_ERROR_UNSUPPORTED;
167 if (cros_gralloc_rendernode_open(&module->drv)) {
168 cros_gralloc_error("Failed to open render node.");
169 return CROS_GRALLOC_ERROR_NO_RESOURCES;
172 auto alloc = new alloc_device_t();
173 memset(alloc, 0, sizeof(*alloc));
175 alloc->alloc = cros_gralloc_alloc;
176 alloc->free = cros_gralloc_free;
177 alloc->common.tag = HARDWARE_DEVICE_TAG;
178 alloc->common.version = 0;
179 alloc->common.module = (hw_module_t*) mod;
180 alloc->common.close = cros_gralloc_close;
182 *dev = &alloc->common;
184 return CROS_GRALLOC_ERROR_NONE;