OSDN Git Service

minigbm: Switch to <drm_fourcc.h>
[android-x86/external-minigbm.git] / cros_gralloc / cros_alloc_device.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.h"
8
9 static struct cros_gralloc_bo *cros_gralloc_bo_create(struct driver *drv,
10                                                       int width, int height,
11                                                       int format, int usage)
12 {
13         uint64_t drv_usage;
14         uint32_t drv_format;
15         struct cros_gralloc_bo *bo;
16
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);
20
21         if (!drv_is_format_supported(drv, drv_format, drv_usage)) {
22                 cros_gralloc_error("Unsupported combination -- HAL format: %u, "
23                                     "HAL flags: %u, drv_format: %u, "
24                                     "drv_flags: %llu", format, usage,
25                                     drv_format, drv_usage);
26                 return NULL;
27         }
28
29         bo = new cros_gralloc_bo();
30         memset(bo, 0, sizeof(*bo));
31
32         bo->bo = drv_bo_create(drv, width, height, drv_format, drv_usage);
33         if (!bo->bo) {
34                 delete bo;
35                 cros_gralloc_error("Failed to create bo.");
36                 return NULL;
37         }
38
39         if (drv_num_buffers_per_bo(bo->bo) != 1) {
40                 drv_bo_destroy(bo->bo);
41                 delete bo;
42                 cros_gralloc_error("Can only support one buffer per bo.");
43                 return NULL;
44         }
45
46         bo->refcount = 1;
47
48         return bo;
49 }
50
51 static struct cros_gralloc_handle *cros_gralloc_handle_from_bo(struct bo *bo)
52 {
53         struct cros_gralloc_handle *hnd;
54
55         hnd = new cros_gralloc_handle();
56         memset(hnd, 0, sizeof(*hnd));
57
58         hnd->base.version = sizeof(hnd->base);
59         hnd->base.numFds = 1;
60         hnd->base.numInts = num_ints();
61
62         for (size_t p = 0; p < drv_bo_get_num_planes(bo); p++) {
63                 hnd->data.strides[p] = drv_bo_get_plane_stride(bo, p);
64                 hnd->data.offsets[p] = drv_bo_get_plane_offset(bo, p);
65                 hnd->data.sizes[p] = drv_bo_get_plane_size(bo, p);
66         }
67
68         hnd->data.fds[0] = drv_bo_get_plane_fd(bo, 0);
69         hnd->data.width = drv_bo_get_width(bo);
70         hnd->data.height = drv_bo_get_height(bo);
71         hnd->data.format = drv_bo_get_format(bo);
72
73         hnd->magic = cros_gralloc_magic();
74         hnd->registrations = 0;
75
76         hnd->pixel_stride = hnd->data.strides[0];
77         hnd->pixel_stride /= drv_stride_from_format(hnd->data.format, 1, 0);
78
79         return hnd;
80 }
81
82 static int cros_gralloc_alloc(alloc_device_t *dev, int w, int h, int format,
83                               int usage, buffer_handle_t *handle, int *stride)
84 {
85         auto mod = (struct cros_gralloc_module *) dev->common.module;
86         std::lock_guard<std::mutex> lock(mod->mutex);
87
88         auto bo = cros_gralloc_bo_create(mod->drv, w, h, format, usage);
89         if (!bo)
90                 return CROS_GRALLOC_ERROR_NO_RESOURCES;
91
92         auto hnd = cros_gralloc_handle_from_bo(bo->bo);
93         hnd->format = static_cast<int32_t>(format);
94         hnd->usage = static_cast<int32_t>(usage);
95
96         hnd->bo = reinterpret_cast<uint64_t>(bo);
97         bo->hnd = hnd;
98
99         mod->handles.insert(reinterpret_cast<uint64_t>(&hnd->base));
100         mod->buffers[drv_bo_get_plane_handle(bo->bo, 0).u32] = bo;
101
102         *stride = static_cast<int>(hnd->pixel_stride);
103         *handle = &hnd->base;
104
105         return CROS_GRALLOC_ERROR_NONE;
106 }
107
108 static int cros_gralloc_free(alloc_device_t *dev, buffer_handle_t handle)
109 {
110         struct cros_gralloc_bo *bo;
111         auto hnd = (struct cros_gralloc_handle *) handle;
112         auto mod = (struct cros_gralloc_module *) dev->common.module;
113         std::lock_guard<std::mutex> lock(mod->mutex);
114
115         if (cros_gralloc_validate_handle(hnd)) {
116                 cros_gralloc_error("Invalid handle.");
117                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
118         }
119
120         if (cros_gralloc_validate_reference(mod, hnd, &bo)) {
121                 cros_gralloc_error("Invalid Reference.");
122                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
123         }
124
125         if (hnd->registrations > 0) {
126                 cros_gralloc_error("Deallocating before unregistering.");
127                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
128         }
129
130         return cros_gralloc_decrement_reference_count(mod, bo);
131 }
132
133 static int cros_gralloc_close(struct hw_device_t *dev)
134 {
135         auto mod = (struct cros_gralloc_module *) dev->module;
136         auto alloc = (struct alloc_device_t *) dev;
137         std::lock_guard<std::mutex> lock(mod->mutex);
138
139         if (mod->drv) {
140                 drv_destroy(mod->drv);
141                 mod->drv = NULL;
142         }
143
144         mod->buffers.clear();
145         mod->handles.clear();
146
147         delete alloc;
148
149         return CROS_GRALLOC_ERROR_NONE;
150 }
151
152 int cros_gralloc_open(const struct hw_module_t *mod, const char *name,
153                       struct hw_device_t **dev)
154 {
155         auto module = (struct cros_gralloc_module *) mod;
156         std::lock_guard<std::mutex> lock(module->mutex);
157
158         if (module->drv)
159                 return CROS_GRALLOC_ERROR_NONE;
160
161         if (strcmp(name, GRALLOC_HARDWARE_GPU0)) {
162                 cros_gralloc_error("Incorrect device name - %s.", name);
163                 return CROS_GRALLOC_ERROR_UNSUPPORTED;
164         }
165
166         if (cros_gralloc_rendernode_open(&module->drv)) {
167                 cros_gralloc_error("Failed to open render node.");
168                 return CROS_GRALLOC_ERROR_NO_RESOURCES;
169         }
170
171         auto alloc = new alloc_device_t();
172         memset(alloc, 0, sizeof(*alloc));
173
174         alloc->alloc = cros_gralloc_alloc;
175         alloc->free = cros_gralloc_free;
176         alloc->common.tag = HARDWARE_DEVICE_TAG;
177         alloc->common.version = 0;
178         alloc->common.module = (hw_module_t*) mod;
179         alloc->common.close = cros_gralloc_close;
180
181         *dev = &alloc->common;
182
183         return CROS_GRALLOC_ERROR_NONE;
184 }