1*d95af8dfSAndroid Build Coastguard Worker /*
2*d95af8dfSAndroid Build Coastguard Worker * Copyright 2017 The Chromium OS Authors. All rights reserved.
3*d95af8dfSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
4*d95af8dfSAndroid Build Coastguard Worker * found in the LICENSE file.
5*d95af8dfSAndroid Build Coastguard Worker */
6*d95af8dfSAndroid Build Coastguard Worker
7*d95af8dfSAndroid Build Coastguard Worker #include "cros_gralloc_driver.h"
8*d95af8dfSAndroid Build Coastguard Worker
9*d95af8dfSAndroid Build Coastguard Worker #include <cstdlib>
10*d95af8dfSAndroid Build Coastguard Worker #include <cutils/properties.h>
11*d95af8dfSAndroid Build Coastguard Worker #include <fcntl.h>
12*d95af8dfSAndroid Build Coastguard Worker #include <hardware/gralloc.h>
13*d95af8dfSAndroid Build Coastguard Worker #include <sys/mman.h>
14*d95af8dfSAndroid Build Coastguard Worker #include <syscall.h>
15*d95af8dfSAndroid Build Coastguard Worker #include <xf86drm.h>
16*d95af8dfSAndroid Build Coastguard Worker
17*d95af8dfSAndroid Build Coastguard Worker #include "../drv_helpers.h"
18*d95af8dfSAndroid Build Coastguard Worker #include "../drv_priv.h"
19*d95af8dfSAndroid Build Coastguard Worker #include "../util.h"
20*d95af8dfSAndroid Build Coastguard Worker #include "cros_gralloc_buffer_metadata.h"
21*d95af8dfSAndroid Build Coastguard Worker
22*d95af8dfSAndroid Build Coastguard Worker // Constants taken from pipe_loader_drm.c in Mesa
23*d95af8dfSAndroid Build Coastguard Worker
24*d95af8dfSAndroid Build Coastguard Worker #define DRM_NUM_NODES 63
25*d95af8dfSAndroid Build Coastguard Worker
26*d95af8dfSAndroid Build Coastguard Worker // DRM Render nodes start at 128
27*d95af8dfSAndroid Build Coastguard Worker #define DRM_RENDER_NODE_START 128
28*d95af8dfSAndroid Build Coastguard Worker
29*d95af8dfSAndroid Build Coastguard Worker // DRM Card nodes start at 0
30*d95af8dfSAndroid Build Coastguard Worker #define DRM_CARD_NODE_START 0
31*d95af8dfSAndroid Build Coastguard Worker
32*d95af8dfSAndroid Build Coastguard Worker class cros_gralloc_driver_preloader
33*d95af8dfSAndroid Build Coastguard Worker {
34*d95af8dfSAndroid Build Coastguard Worker public:
cros_gralloc_driver_preloader()35*d95af8dfSAndroid Build Coastguard Worker cros_gralloc_driver_preloader()
36*d95af8dfSAndroid Build Coastguard Worker {
37*d95af8dfSAndroid Build Coastguard Worker drv_preload(true);
38*d95af8dfSAndroid Build Coastguard Worker }
39*d95af8dfSAndroid Build Coastguard Worker
~cros_gralloc_driver_preloader()40*d95af8dfSAndroid Build Coastguard Worker ~cros_gralloc_driver_preloader()
41*d95af8dfSAndroid Build Coastguard Worker {
42*d95af8dfSAndroid Build Coastguard Worker drv_preload(false);
43*d95af8dfSAndroid Build Coastguard Worker }
44*d95af8dfSAndroid Build Coastguard Worker };
45*d95af8dfSAndroid Build Coastguard Worker
46*d95af8dfSAndroid Build Coastguard Worker static class cros_gralloc_driver_preloader cros_gralloc_driver_preloader;
47*d95af8dfSAndroid Build Coastguard Worker
memfd_create_wrapper(const char * name,unsigned int flags)48*d95af8dfSAndroid Build Coastguard Worker int memfd_create_wrapper(const char *name, unsigned int flags)
49*d95af8dfSAndroid Build Coastguard Worker {
50*d95af8dfSAndroid Build Coastguard Worker int fd;
51*d95af8dfSAndroid Build Coastguard Worker
52*d95af8dfSAndroid Build Coastguard Worker #if defined(HAVE_MEMFD_CREATE)
53*d95af8dfSAndroid Build Coastguard Worker fd = memfd_create(name, flags);
54*d95af8dfSAndroid Build Coastguard Worker #elif defined(__NR_memfd_create)
55*d95af8dfSAndroid Build Coastguard Worker fd = syscall(__NR_memfd_create, name, flags);
56*d95af8dfSAndroid Build Coastguard Worker #else
57*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to create memfd '%s': memfd_create not available.", name);
58*d95af8dfSAndroid Build Coastguard Worker return -1;
59*d95af8dfSAndroid Build Coastguard Worker #endif
60*d95af8dfSAndroid Build Coastguard Worker
61*d95af8dfSAndroid Build Coastguard Worker if (fd == -1)
62*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to create memfd '%s': %s.", name, strerror(errno));
63*d95af8dfSAndroid Build Coastguard Worker
64*d95af8dfSAndroid Build Coastguard Worker return fd;
65*d95af8dfSAndroid Build Coastguard Worker }
66*d95af8dfSAndroid Build Coastguard Worker
memfd_create_reserved_region(const std::string & buffer_name,uint64_t reserved_region_size)67*d95af8dfSAndroid Build Coastguard Worker int memfd_create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size)
68*d95af8dfSAndroid Build Coastguard Worker {
69*d95af8dfSAndroid Build Coastguard Worker const std::string reserved_region_name = buffer_name + " reserved region";
70*d95af8dfSAndroid Build Coastguard Worker
71*d95af8dfSAndroid Build Coastguard Worker int reserved_region_fd = memfd_create_wrapper(reserved_region_name.c_str(), FD_CLOEXEC);
72*d95af8dfSAndroid Build Coastguard Worker if (reserved_region_fd == -1)
73*d95af8dfSAndroid Build Coastguard Worker return -errno;
74*d95af8dfSAndroid Build Coastguard Worker
75*d95af8dfSAndroid Build Coastguard Worker if (ftruncate(reserved_region_fd, reserved_region_size)) {
76*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to set reserved region size: %s.", strerror(errno));
77*d95af8dfSAndroid Build Coastguard Worker return -errno;
78*d95af8dfSAndroid Build Coastguard Worker }
79*d95af8dfSAndroid Build Coastguard Worker
80*d95af8dfSAndroid Build Coastguard Worker return reserved_region_fd;
81*d95af8dfSAndroid Build Coastguard Worker }
82*d95af8dfSAndroid Build Coastguard Worker
get_instance()83*d95af8dfSAndroid Build Coastguard Worker std::shared_ptr<cros_gralloc_driver> cros_gralloc_driver::get_instance()
84*d95af8dfSAndroid Build Coastguard Worker {
85*d95af8dfSAndroid Build Coastguard Worker static std::shared_ptr<cros_gralloc_driver> s_instance = []() {
86*d95af8dfSAndroid Build Coastguard Worker return std::shared_ptr<cros_gralloc_driver>(new cros_gralloc_driver());
87*d95af8dfSAndroid Build Coastguard Worker }();
88*d95af8dfSAndroid Build Coastguard Worker
89*d95af8dfSAndroid Build Coastguard Worker if (!s_instance->is_initialized()) {
90*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to initialize driver.");
91*d95af8dfSAndroid Build Coastguard Worker return nullptr;
92*d95af8dfSAndroid Build Coastguard Worker }
93*d95af8dfSAndroid Build Coastguard Worker
94*d95af8dfSAndroid Build Coastguard Worker return s_instance;
95*d95af8dfSAndroid Build Coastguard Worker }
96*d95af8dfSAndroid Build Coastguard Worker
init_try_node(int idx,char const * str)97*d95af8dfSAndroid Build Coastguard Worker static struct driver *init_try_node(int idx, char const *str)
98*d95af8dfSAndroid Build Coastguard Worker {
99*d95af8dfSAndroid Build Coastguard Worker int fd;
100*d95af8dfSAndroid Build Coastguard Worker char *node;
101*d95af8dfSAndroid Build Coastguard Worker struct driver *drv;
102*d95af8dfSAndroid Build Coastguard Worker
103*d95af8dfSAndroid Build Coastguard Worker if (asprintf(&node, str, DRM_DIR_NAME, idx) < 0)
104*d95af8dfSAndroid Build Coastguard Worker return NULL;
105*d95af8dfSAndroid Build Coastguard Worker
106*d95af8dfSAndroid Build Coastguard Worker fd = open(node, O_RDWR, 0);
107*d95af8dfSAndroid Build Coastguard Worker free(node);
108*d95af8dfSAndroid Build Coastguard Worker
109*d95af8dfSAndroid Build Coastguard Worker if (fd < 0)
110*d95af8dfSAndroid Build Coastguard Worker return NULL;
111*d95af8dfSAndroid Build Coastguard Worker
112*d95af8dfSAndroid Build Coastguard Worker drv = drv_create(fd);
113*d95af8dfSAndroid Build Coastguard Worker if (!drv)
114*d95af8dfSAndroid Build Coastguard Worker close(fd);
115*d95af8dfSAndroid Build Coastguard Worker
116*d95af8dfSAndroid Build Coastguard Worker return drv;
117*d95af8dfSAndroid Build Coastguard Worker }
118*d95af8dfSAndroid Build Coastguard Worker
init_try_nodes()119*d95af8dfSAndroid Build Coastguard Worker static struct driver *init_try_nodes()
120*d95af8dfSAndroid Build Coastguard Worker {
121*d95af8dfSAndroid Build Coastguard Worker /*
122*d95af8dfSAndroid Build Coastguard Worker * Create a driver from render nodes first, then try card
123*d95af8dfSAndroid Build Coastguard Worker * nodes.
124*d95af8dfSAndroid Build Coastguard Worker *
125*d95af8dfSAndroid Build Coastguard Worker * TODO(gsingh): Enable render nodes on udl/evdi.
126*d95af8dfSAndroid Build Coastguard Worker */
127*d95af8dfSAndroid Build Coastguard Worker
128*d95af8dfSAndroid Build Coastguard Worker struct driver *drv;
129*d95af8dfSAndroid Build Coastguard Worker char const *render_nodes_fmt = "%s/renderD%d";
130*d95af8dfSAndroid Build Coastguard Worker char const *card_nodes_fmt = "%s/card%d";
131*d95af8dfSAndroid Build Coastguard Worker uint32_t num_nodes = DRM_NUM_NODES;
132*d95af8dfSAndroid Build Coastguard Worker uint32_t min_render_node = DRM_RENDER_NODE_START;
133*d95af8dfSAndroid Build Coastguard Worker uint32_t max_render_node = (min_render_node + num_nodes);
134*d95af8dfSAndroid Build Coastguard Worker uint32_t min_card_node = DRM_CARD_NODE_START;
135*d95af8dfSAndroid Build Coastguard Worker uint32_t max_card_node = (min_card_node + num_nodes);
136*d95af8dfSAndroid Build Coastguard Worker
137*d95af8dfSAndroid Build Coastguard Worker // Try render nodes...
138*d95af8dfSAndroid Build Coastguard Worker for (uint32_t i = min_render_node; i < max_render_node; i++) {
139*d95af8dfSAndroid Build Coastguard Worker drv = init_try_node(i, render_nodes_fmt);
140*d95af8dfSAndroid Build Coastguard Worker if (drv)
141*d95af8dfSAndroid Build Coastguard Worker return drv;
142*d95af8dfSAndroid Build Coastguard Worker }
143*d95af8dfSAndroid Build Coastguard Worker
144*d95af8dfSAndroid Build Coastguard Worker // Try card nodes... for vkms mostly.
145*d95af8dfSAndroid Build Coastguard Worker for (uint32_t i = min_card_node; i < max_card_node; i++) {
146*d95af8dfSAndroid Build Coastguard Worker drv = init_try_node(i, card_nodes_fmt);
147*d95af8dfSAndroid Build Coastguard Worker if (drv)
148*d95af8dfSAndroid Build Coastguard Worker return drv;
149*d95af8dfSAndroid Build Coastguard Worker }
150*d95af8dfSAndroid Build Coastguard Worker
151*d95af8dfSAndroid Build Coastguard Worker return nullptr;
152*d95af8dfSAndroid Build Coastguard Worker }
153*d95af8dfSAndroid Build Coastguard Worker
drv_destroy_and_close(struct driver * drv)154*d95af8dfSAndroid Build Coastguard Worker static void drv_destroy_and_close(struct driver *drv)
155*d95af8dfSAndroid Build Coastguard Worker {
156*d95af8dfSAndroid Build Coastguard Worker int fd = drv_get_fd(drv);
157*d95af8dfSAndroid Build Coastguard Worker drv_destroy(drv);
158*d95af8dfSAndroid Build Coastguard Worker close(fd);
159*d95af8dfSAndroid Build Coastguard Worker }
160*d95af8dfSAndroid Build Coastguard Worker
is_running_with_software_rendering()161*d95af8dfSAndroid Build Coastguard Worker static bool is_running_with_software_rendering()
162*d95af8dfSAndroid Build Coastguard Worker {
163*d95af8dfSAndroid Build Coastguard Worker const char *vulkan_driver = drv_get_os_option("ro.hardware.vulkan");
164*d95af8dfSAndroid Build Coastguard Worker return (vulkan_driver != nullptr && strstr(vulkan_driver, "pastel") != nullptr);
165*d95af8dfSAndroid Build Coastguard Worker }
166*d95af8dfSAndroid Build Coastguard Worker
cros_gralloc_driver()167*d95af8dfSAndroid Build Coastguard Worker cros_gralloc_driver::cros_gralloc_driver()
168*d95af8dfSAndroid Build Coastguard Worker : drv_(init_try_nodes(), drv_destroy_and_close),
169*d95af8dfSAndroid Build Coastguard Worker is_running_with_software_rendering_(is_running_with_software_rendering())
170*d95af8dfSAndroid Build Coastguard Worker {
171*d95af8dfSAndroid Build Coastguard Worker }
172*d95af8dfSAndroid Build Coastguard Worker
~cros_gralloc_driver()173*d95af8dfSAndroid Build Coastguard Worker cros_gralloc_driver::~cros_gralloc_driver()
174*d95af8dfSAndroid Build Coastguard Worker {
175*d95af8dfSAndroid Build Coastguard Worker buffers_.clear();
176*d95af8dfSAndroid Build Coastguard Worker handles_.clear();
177*d95af8dfSAndroid Build Coastguard Worker }
178*d95af8dfSAndroid Build Coastguard Worker
is_initialized()179*d95af8dfSAndroid Build Coastguard Worker bool cros_gralloc_driver::is_initialized()
180*d95af8dfSAndroid Build Coastguard Worker {
181*d95af8dfSAndroid Build Coastguard Worker return drv_ != nullptr;
182*d95af8dfSAndroid Build Coastguard Worker }
183*d95af8dfSAndroid Build Coastguard Worker
get_resolved_format_and_use_flags(const struct cros_gralloc_buffer_descriptor * descriptor,uint32_t * out_format,uint64_t * out_use_flags)184*d95af8dfSAndroid Build Coastguard Worker bool cros_gralloc_driver::get_resolved_format_and_use_flags(
185*d95af8dfSAndroid Build Coastguard Worker const struct cros_gralloc_buffer_descriptor *descriptor, uint32_t *out_format,
186*d95af8dfSAndroid Build Coastguard Worker uint64_t *out_use_flags)
187*d95af8dfSAndroid Build Coastguard Worker {
188*d95af8dfSAndroid Build Coastguard Worker uint32_t resolved_format;
189*d95af8dfSAndroid Build Coastguard Worker uint64_t resolved_use_flags;
190*d95af8dfSAndroid Build Coastguard Worker struct combination *combo;
191*d95af8dfSAndroid Build Coastguard Worker
192*d95af8dfSAndroid Build Coastguard Worker uint64_t use_flags = descriptor->use_flags;
193*d95af8dfSAndroid Build Coastguard Worker if (is_running_with_software_rendering_ && (use_flags & BO_USE_GPU_HW) != 0) {
194*d95af8dfSAndroid Build Coastguard Worker use_flags |= (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN);
195*d95af8dfSAndroid Build Coastguard Worker }
196*d95af8dfSAndroid Build Coastguard Worker
197*d95af8dfSAndroid Build Coastguard Worker drv_resolve_format_and_use_flags(drv_.get(), descriptor->drm_format, descriptor->use_flags,
198*d95af8dfSAndroid Build Coastguard Worker &resolved_format, &resolved_use_flags);
199*d95af8dfSAndroid Build Coastguard Worker
200*d95af8dfSAndroid Build Coastguard Worker combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
201*d95af8dfSAndroid Build Coastguard Worker if (!combo && (descriptor->droid_usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
202*d95af8dfSAndroid Build Coastguard Worker descriptor->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
203*d95af8dfSAndroid Build Coastguard Worker // Unmask BO_USE_HW_VIDEO_ENCODER for other formats. They are mostly
204*d95af8dfSAndroid Build Coastguard Worker // intermediate formats not passed directly to the encoder (e.g.
205*d95af8dfSAndroid Build Coastguard Worker // camera). YV12 is passed to the encoder component, but it is converted
206*d95af8dfSAndroid Build Coastguard Worker // to YCbCr_420_888 before being passed to the hw encoder.
207*d95af8dfSAndroid Build Coastguard Worker resolved_use_flags &= ~BO_USE_HW_VIDEO_ENCODER;
208*d95af8dfSAndroid Build Coastguard Worker combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
209*d95af8dfSAndroid Build Coastguard Worker }
210*d95af8dfSAndroid Build Coastguard Worker if (!combo && (descriptor->droid_usage & BUFFER_USAGE_FRONT_RENDERING_MASK)) {
211*d95af8dfSAndroid Build Coastguard Worker resolved_use_flags &= ~BO_USE_FRONT_RENDERING;
212*d95af8dfSAndroid Build Coastguard Worker resolved_use_flags |= BO_USE_LINEAR;
213*d95af8dfSAndroid Build Coastguard Worker combo = drv_get_combination(drv_.get(), resolved_format, resolved_use_flags);
214*d95af8dfSAndroid Build Coastguard Worker }
215*d95af8dfSAndroid Build Coastguard Worker if (!combo)
216*d95af8dfSAndroid Build Coastguard Worker return false;
217*d95af8dfSAndroid Build Coastguard Worker
218*d95af8dfSAndroid Build Coastguard Worker *out_format = resolved_format;
219*d95af8dfSAndroid Build Coastguard Worker *out_use_flags = resolved_use_flags;
220*d95af8dfSAndroid Build Coastguard Worker return true;
221*d95af8dfSAndroid Build Coastguard Worker }
222*d95af8dfSAndroid Build Coastguard Worker
is_supported(const struct cros_gralloc_buffer_descriptor * descriptor)223*d95af8dfSAndroid Build Coastguard Worker bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descriptor *descriptor)
224*d95af8dfSAndroid Build Coastguard Worker {
225*d95af8dfSAndroid Build Coastguard Worker uint32_t resolved_format;
226*d95af8dfSAndroid Build Coastguard Worker uint64_t resolved_use_flags;
227*d95af8dfSAndroid Build Coastguard Worker uint32_t max_texture_size = drv_get_max_texture_2d_size(drv_.get());
228*d95af8dfSAndroid Build Coastguard Worker if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags))
229*d95af8dfSAndroid Build Coastguard Worker return false;
230*d95af8dfSAndroid Build Coastguard Worker
231*d95af8dfSAndroid Build Coastguard Worker // Allow blob buffers to go beyond the limit.
232*d95af8dfSAndroid Build Coastguard Worker if (descriptor->droid_format == HAL_PIXEL_FORMAT_BLOB)
233*d95af8dfSAndroid Build Coastguard Worker return true;
234*d95af8dfSAndroid Build Coastguard Worker
235*d95af8dfSAndroid Build Coastguard Worker return descriptor->width <= max_texture_size && descriptor->height <= max_texture_size;
236*d95af8dfSAndroid Build Coastguard Worker }
237*d95af8dfSAndroid Build Coastguard Worker
create_reserved_region(const std::string & buffer_name,uint64_t reserved_region_size)238*d95af8dfSAndroid Build Coastguard Worker int cros_gralloc_driver::create_reserved_region(const std::string &buffer_name,
239*d95af8dfSAndroid Build Coastguard Worker uint64_t reserved_region_size)
240*d95af8dfSAndroid Build Coastguard Worker {
241*d95af8dfSAndroid Build Coastguard Worker int ret;
242*d95af8dfSAndroid Build Coastguard Worker
243*d95af8dfSAndroid Build Coastguard Worker #if ANDROID_API_LEVEL >= 31 && defined(HAS_DMABUF_SYSTEM_HEAP)
244*d95af8dfSAndroid Build Coastguard Worker ret = allocator_.Alloc(kDmabufSystemHeapName, reserved_region_size);
245*d95af8dfSAndroid Build Coastguard Worker if (ret >= 0)
246*d95af8dfSAndroid Build Coastguard Worker return ret;
247*d95af8dfSAndroid Build Coastguard Worker #endif
248*d95af8dfSAndroid Build Coastguard Worker
249*d95af8dfSAndroid Build Coastguard Worker ret = memfd_create_reserved_region(buffer_name, reserved_region_size);
250*d95af8dfSAndroid Build Coastguard Worker if (ret >= 0)
251*d95af8dfSAndroid Build Coastguard Worker return ret;
252*d95af8dfSAndroid Build Coastguard Worker
253*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to create_reserved_region.");
254*d95af8dfSAndroid Build Coastguard Worker return -1;
255*d95af8dfSAndroid Build Coastguard Worker }
256*d95af8dfSAndroid Build Coastguard Worker
allocate(const struct cros_gralloc_buffer_descriptor * descriptor,native_handle_t ** out_handle)257*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descriptor *descriptor,
258*d95af8dfSAndroid Build Coastguard Worker native_handle_t **out_handle)
259*d95af8dfSAndroid Build Coastguard Worker {
260*d95af8dfSAndroid Build Coastguard Worker int ret = 0;
261*d95af8dfSAndroid Build Coastguard Worker size_t num_planes;
262*d95af8dfSAndroid Build Coastguard Worker size_t num_fds;
263*d95af8dfSAndroid Build Coastguard Worker size_t num_ints;
264*d95af8dfSAndroid Build Coastguard Worker uint32_t resolved_format;
265*d95af8dfSAndroid Build Coastguard Worker uint32_t bytes_per_pixel;
266*d95af8dfSAndroid Build Coastguard Worker uint64_t resolved_use_flags;
267*d95af8dfSAndroid Build Coastguard Worker struct bo *bo;
268*d95af8dfSAndroid Build Coastguard Worker struct cros_gralloc_handle *hnd;
269*d95af8dfSAndroid Build Coastguard Worker std::unique_ptr<cros_gralloc_buffer> buffer;
270*d95af8dfSAndroid Build Coastguard Worker
271*d95af8dfSAndroid Build Coastguard Worker if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags)) {
272*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to resolve format and use_flags.");
273*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
274*d95af8dfSAndroid Build Coastguard Worker }
275*d95af8dfSAndroid Build Coastguard Worker
276*d95af8dfSAndroid Build Coastguard Worker bo = drv_bo_create(drv_.get(), descriptor->width, descriptor->height, resolved_format,
277*d95af8dfSAndroid Build Coastguard Worker resolved_use_flags);
278*d95af8dfSAndroid Build Coastguard Worker if (!bo) {
279*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to create bo.");
280*d95af8dfSAndroid Build Coastguard Worker return -errno;
281*d95af8dfSAndroid Build Coastguard Worker }
282*d95af8dfSAndroid Build Coastguard Worker
283*d95af8dfSAndroid Build Coastguard Worker num_planes = drv_bo_get_num_planes(bo);
284*d95af8dfSAndroid Build Coastguard Worker num_fds = num_planes;
285*d95af8dfSAndroid Build Coastguard Worker
286*d95af8dfSAndroid Build Coastguard Worker if (descriptor->enable_metadata_fd)
287*d95af8dfSAndroid Build Coastguard Worker num_fds += 1;
288*d95af8dfSAndroid Build Coastguard Worker
289*d95af8dfSAndroid Build Coastguard Worker num_ints = ((sizeof(struct cros_gralloc_handle) - sizeof(native_handle_t)) / sizeof(int)) -
290*d95af8dfSAndroid Build Coastguard Worker num_fds;
291*d95af8dfSAndroid Build Coastguard Worker
292*d95af8dfSAndroid Build Coastguard Worker hnd =
293*d95af8dfSAndroid Build Coastguard Worker reinterpret_cast<struct cros_gralloc_handle *>(native_handle_create(num_fds, num_ints));
294*d95af8dfSAndroid Build Coastguard Worker
295*d95af8dfSAndroid Build Coastguard Worker for (size_t i = 0; i < DRV_MAX_FDS; i++)
296*d95af8dfSAndroid Build Coastguard Worker hnd->fds[i] = -1;
297*d95af8dfSAndroid Build Coastguard Worker
298*d95af8dfSAndroid Build Coastguard Worker hnd->num_planes = num_planes;
299*d95af8dfSAndroid Build Coastguard Worker for (size_t plane = 0; plane < num_planes; plane++) {
300*d95af8dfSAndroid Build Coastguard Worker ret = drv_bo_get_plane_fd(bo, plane);
301*d95af8dfSAndroid Build Coastguard Worker if (ret < 0)
302*d95af8dfSAndroid Build Coastguard Worker goto destroy_hnd;
303*d95af8dfSAndroid Build Coastguard Worker
304*d95af8dfSAndroid Build Coastguard Worker hnd->fds[plane] = ret;
305*d95af8dfSAndroid Build Coastguard Worker hnd->strides[plane] = drv_bo_get_plane_stride(bo, plane);
306*d95af8dfSAndroid Build Coastguard Worker hnd->offsets[plane] = drv_bo_get_plane_offset(bo, plane);
307*d95af8dfSAndroid Build Coastguard Worker hnd->sizes[plane] = drv_bo_get_plane_size(bo, plane);
308*d95af8dfSAndroid Build Coastguard Worker }
309*d95af8dfSAndroid Build Coastguard Worker
310*d95af8dfSAndroid Build Coastguard Worker hnd->reserved_region_size = 0;
311*d95af8dfSAndroid Build Coastguard Worker if (descriptor->enable_metadata_fd)
312*d95af8dfSAndroid Build Coastguard Worker hnd->reserved_region_size =
313*d95af8dfSAndroid Build Coastguard Worker sizeof(struct cros_gralloc_buffer_metadata) + descriptor->client_metadata_size;
314*d95af8dfSAndroid Build Coastguard Worker
315*d95af8dfSAndroid Build Coastguard Worker if (hnd->reserved_region_size > 0) {
316*d95af8dfSAndroid Build Coastguard Worker ret = create_reserved_region(descriptor->name, hnd->reserved_region_size);
317*d95af8dfSAndroid Build Coastguard Worker if (ret < 0)
318*d95af8dfSAndroid Build Coastguard Worker goto destroy_hnd;
319*d95af8dfSAndroid Build Coastguard Worker
320*d95af8dfSAndroid Build Coastguard Worker hnd->fds[hnd->num_planes] = ret;
321*d95af8dfSAndroid Build Coastguard Worker }
322*d95af8dfSAndroid Build Coastguard Worker
323*d95af8dfSAndroid Build Coastguard Worker static std::atomic<uint32_t> next_buffer_id{ 1 };
324*d95af8dfSAndroid Build Coastguard Worker hnd->id = next_buffer_id++;
325*d95af8dfSAndroid Build Coastguard Worker hnd->width = drv_bo_get_width(bo);
326*d95af8dfSAndroid Build Coastguard Worker hnd->height = drv_bo_get_height(bo);
327*d95af8dfSAndroid Build Coastguard Worker hnd->format = drv_bo_get_format(bo);
328*d95af8dfSAndroid Build Coastguard Worker hnd->tiling = drv_bo_get_tiling(bo);
329*d95af8dfSAndroid Build Coastguard Worker hnd->format_modifier = drv_bo_get_format_modifier(bo);
330*d95af8dfSAndroid Build Coastguard Worker hnd->use_flags = drv_bo_get_use_flags(bo);
331*d95af8dfSAndroid Build Coastguard Worker bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0);
332*d95af8dfSAndroid Build Coastguard Worker hnd->pixel_stride = DIV_ROUND_UP(hnd->strides[0], bytes_per_pixel);
333*d95af8dfSAndroid Build Coastguard Worker hnd->magic = cros_gralloc_magic;
334*d95af8dfSAndroid Build Coastguard Worker hnd->droid_format = descriptor->droid_format;
335*d95af8dfSAndroid Build Coastguard Worker hnd->usage = descriptor->droid_usage;
336*d95af8dfSAndroid Build Coastguard Worker hnd->total_size = hnd->reserved_region_size + drv_bo_get_total_size(bo);
337*d95af8dfSAndroid Build Coastguard Worker
338*d95af8dfSAndroid Build Coastguard Worker buffer = cros_gralloc_buffer::create(bo, hnd);
339*d95af8dfSAndroid Build Coastguard Worker if (!buffer) {
340*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to allocate: failed to create cros_gralloc_buffer.");
341*d95af8dfSAndroid Build Coastguard Worker ret = -1;
342*d95af8dfSAndroid Build Coastguard Worker goto destroy_hnd;
343*d95af8dfSAndroid Build Coastguard Worker }
344*d95af8dfSAndroid Build Coastguard Worker
345*d95af8dfSAndroid Build Coastguard Worker ret = buffer->initialize_metadata(descriptor);
346*d95af8dfSAndroid Build Coastguard Worker if (ret) {
347*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to allocate: failed to initialize cros_gralloc_buffer metadata.");
348*d95af8dfSAndroid Build Coastguard Worker goto destroy_hnd;
349*d95af8dfSAndroid Build Coastguard Worker }
350*d95af8dfSAndroid Build Coastguard Worker
351*d95af8dfSAndroid Build Coastguard Worker {
352*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
353*d95af8dfSAndroid Build Coastguard Worker
354*d95af8dfSAndroid Build Coastguard Worker struct cros_gralloc_imported_handle_info hnd_info = {
355*d95af8dfSAndroid Build Coastguard Worker .buffer = buffer.get(),
356*d95af8dfSAndroid Build Coastguard Worker .refcount = 1,
357*d95af8dfSAndroid Build Coastguard Worker };
358*d95af8dfSAndroid Build Coastguard Worker handles_.emplace(hnd, hnd_info);
359*d95af8dfSAndroid Build Coastguard Worker buffers_.emplace(hnd->id, std::move(buffer));
360*d95af8dfSAndroid Build Coastguard Worker }
361*d95af8dfSAndroid Build Coastguard Worker
362*d95af8dfSAndroid Build Coastguard Worker *out_handle = hnd;
363*d95af8dfSAndroid Build Coastguard Worker return 0;
364*d95af8dfSAndroid Build Coastguard Worker
365*d95af8dfSAndroid Build Coastguard Worker destroy_hnd:
366*d95af8dfSAndroid Build Coastguard Worker native_handle_close(hnd);
367*d95af8dfSAndroid Build Coastguard Worker native_handle_delete(hnd);
368*d95af8dfSAndroid Build Coastguard Worker
369*d95af8dfSAndroid Build Coastguard Worker drv_bo_destroy(bo);
370*d95af8dfSAndroid Build Coastguard Worker return ret;
371*d95af8dfSAndroid Build Coastguard Worker }
372*d95af8dfSAndroid Build Coastguard Worker
retain(buffer_handle_t handle)373*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
374*d95af8dfSAndroid Build Coastguard Worker {
375*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
376*d95af8dfSAndroid Build Coastguard Worker
377*d95af8dfSAndroid Build Coastguard Worker auto hnd = cros_gralloc_convert_handle(handle);
378*d95af8dfSAndroid Build Coastguard Worker if (!hnd) {
379*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid handle.");
380*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
381*d95af8dfSAndroid Build Coastguard Worker }
382*d95af8dfSAndroid Build Coastguard Worker
383*d95af8dfSAndroid Build Coastguard Worker auto hnd_it = handles_.find(hnd);
384*d95af8dfSAndroid Build Coastguard Worker if (hnd_it != handles_.end()) {
385*d95af8dfSAndroid Build Coastguard Worker // The underlying buffer (as multiple handles can refer to the same buffer)
386*d95af8dfSAndroid Build Coastguard Worker // has already been imported into this process and the given handle has
387*d95af8dfSAndroid Build Coastguard Worker // already been registered in this process. Increase both the buffer and
388*d95af8dfSAndroid Build Coastguard Worker // handle reference count.
389*d95af8dfSAndroid Build Coastguard Worker auto &hnd_info = hnd_it->second;
390*d95af8dfSAndroid Build Coastguard Worker
391*d95af8dfSAndroid Build Coastguard Worker hnd_info.buffer->increase_refcount();
392*d95af8dfSAndroid Build Coastguard Worker hnd_info.refcount++;
393*d95af8dfSAndroid Build Coastguard Worker
394*d95af8dfSAndroid Build Coastguard Worker return 0;
395*d95af8dfSAndroid Build Coastguard Worker }
396*d95af8dfSAndroid Build Coastguard Worker
397*d95af8dfSAndroid Build Coastguard Worker uint32_t id = hnd->id;
398*d95af8dfSAndroid Build Coastguard Worker
399*d95af8dfSAndroid Build Coastguard Worker cros_gralloc_buffer *buffer = nullptr;
400*d95af8dfSAndroid Build Coastguard Worker
401*d95af8dfSAndroid Build Coastguard Worker auto buffer_it = buffers_.find(id);
402*d95af8dfSAndroid Build Coastguard Worker if (buffer_it != buffers_.end()) {
403*d95af8dfSAndroid Build Coastguard Worker // The underlying buffer (as multiple handles can refer to the same buffer)
404*d95af8dfSAndroid Build Coastguard Worker // has already been imported into this process but the given handle has not
405*d95af8dfSAndroid Build Coastguard Worker // yet been registered. Increase the buffer reference count (here) and start
406*d95af8dfSAndroid Build Coastguard Worker // to track the handle (below).
407*d95af8dfSAndroid Build Coastguard Worker buffer = buffer_it->second.get();
408*d95af8dfSAndroid Build Coastguard Worker buffer->increase_refcount();
409*d95af8dfSAndroid Build Coastguard Worker } else {
410*d95af8dfSAndroid Build Coastguard Worker // The underlying buffer has not yet been imported into this process. Import
411*d95af8dfSAndroid Build Coastguard Worker // and start to track the buffer (here) and start to track the handle (below).
412*d95af8dfSAndroid Build Coastguard Worker struct drv_import_fd_data data = {
413*d95af8dfSAndroid Build Coastguard Worker .format_modifier = hnd->format_modifier,
414*d95af8dfSAndroid Build Coastguard Worker .width = hnd->width,
415*d95af8dfSAndroid Build Coastguard Worker .height = hnd->height,
416*d95af8dfSAndroid Build Coastguard Worker .format = hnd->format,
417*d95af8dfSAndroid Build Coastguard Worker .tiling = hnd->tiling,
418*d95af8dfSAndroid Build Coastguard Worker .use_flags = hnd->use_flags,
419*d95af8dfSAndroid Build Coastguard Worker };
420*d95af8dfSAndroid Build Coastguard Worker memcpy(data.fds, hnd->fds, sizeof(data.fds));
421*d95af8dfSAndroid Build Coastguard Worker memcpy(data.strides, hnd->strides, sizeof(data.strides));
422*d95af8dfSAndroid Build Coastguard Worker memcpy(data.offsets, hnd->offsets, sizeof(data.offsets));
423*d95af8dfSAndroid Build Coastguard Worker
424*d95af8dfSAndroid Build Coastguard Worker struct bo *bo = drv_bo_import(drv_.get(), &data);
425*d95af8dfSAndroid Build Coastguard Worker if (!bo)
426*d95af8dfSAndroid Build Coastguard Worker return -EFAULT;
427*d95af8dfSAndroid Build Coastguard Worker
428*d95af8dfSAndroid Build Coastguard Worker auto scoped_buffer = cros_gralloc_buffer::create(bo, hnd);
429*d95af8dfSAndroid Build Coastguard Worker if (!scoped_buffer) {
430*d95af8dfSAndroid Build Coastguard Worker ALOGE("Failed to import: failed to create cros_gralloc_buffer.");
431*d95af8dfSAndroid Build Coastguard Worker return -1;
432*d95af8dfSAndroid Build Coastguard Worker }
433*d95af8dfSAndroid Build Coastguard Worker buffer = scoped_buffer.get();
434*d95af8dfSAndroid Build Coastguard Worker buffers_.emplace(id, std::move(scoped_buffer));
435*d95af8dfSAndroid Build Coastguard Worker }
436*d95af8dfSAndroid Build Coastguard Worker
437*d95af8dfSAndroid Build Coastguard Worker struct cros_gralloc_imported_handle_info hnd_info = {
438*d95af8dfSAndroid Build Coastguard Worker .buffer = buffer,
439*d95af8dfSAndroid Build Coastguard Worker .refcount = 1,
440*d95af8dfSAndroid Build Coastguard Worker };
441*d95af8dfSAndroid Build Coastguard Worker handles_.emplace(hnd, hnd_info);
442*d95af8dfSAndroid Build Coastguard Worker return 0;
443*d95af8dfSAndroid Build Coastguard Worker }
444*d95af8dfSAndroid Build Coastguard Worker
release(buffer_handle_t handle)445*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::release(buffer_handle_t handle)
446*d95af8dfSAndroid Build Coastguard Worker {
447*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
448*d95af8dfSAndroid Build Coastguard Worker
449*d95af8dfSAndroid Build Coastguard Worker auto hnd = cros_gralloc_convert_handle(handle);
450*d95af8dfSAndroid Build Coastguard Worker if (!hnd) {
451*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid handle.");
452*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
453*d95af8dfSAndroid Build Coastguard Worker }
454*d95af8dfSAndroid Build Coastguard Worker
455*d95af8dfSAndroid Build Coastguard Worker auto buffer = get_buffer(hnd);
456*d95af8dfSAndroid Build Coastguard Worker if (!buffer) {
457*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid reference (release() called on unregistered handle).");
458*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
459*d95af8dfSAndroid Build Coastguard Worker }
460*d95af8dfSAndroid Build Coastguard Worker
461*d95af8dfSAndroid Build Coastguard Worker if (!--handles_[hnd].refcount)
462*d95af8dfSAndroid Build Coastguard Worker handles_.erase(hnd);
463*d95af8dfSAndroid Build Coastguard Worker
464*d95af8dfSAndroid Build Coastguard Worker if (buffer->decrease_refcount() == 0) {
465*d95af8dfSAndroid Build Coastguard Worker buffers_.erase(buffer->get_id());
466*d95af8dfSAndroid Build Coastguard Worker }
467*d95af8dfSAndroid Build Coastguard Worker
468*d95af8dfSAndroid Build Coastguard Worker return 0;
469*d95af8dfSAndroid Build Coastguard Worker }
470*d95af8dfSAndroid Build Coastguard Worker
lock(buffer_handle_t handle,int32_t acquire_fence,bool close_acquire_fence,const struct rectangle * rect,uint32_t map_flags,uint8_t * addr[DRV_MAX_PLANES])471*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence,
472*d95af8dfSAndroid Build Coastguard Worker bool close_acquire_fence, const struct rectangle *rect,
473*d95af8dfSAndroid Build Coastguard Worker uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES])
474*d95af8dfSAndroid Build Coastguard Worker {
475*d95af8dfSAndroid Build Coastguard Worker int32_t ret = cros_gralloc_sync_wait(acquire_fence, close_acquire_fence);
476*d95af8dfSAndroid Build Coastguard Worker if (ret)
477*d95af8dfSAndroid Build Coastguard Worker return ret;
478*d95af8dfSAndroid Build Coastguard Worker
479*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
480*d95af8dfSAndroid Build Coastguard Worker
481*d95af8dfSAndroid Build Coastguard Worker auto hnd = cros_gralloc_convert_handle(handle);
482*d95af8dfSAndroid Build Coastguard Worker if (!hnd) {
483*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid handle.");
484*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
485*d95af8dfSAndroid Build Coastguard Worker }
486*d95af8dfSAndroid Build Coastguard Worker
487*d95af8dfSAndroid Build Coastguard Worker if (!is_running_with_software_rendering_) {
488*d95af8dfSAndroid Build Coastguard Worker if ((hnd->usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) ==
489*d95af8dfSAndroid Build Coastguard Worker 0) {
490*d95af8dfSAndroid Build Coastguard Worker ALOGE("Attempted to lock() a buffer that was not allocated with a "
491*d95af8dfSAndroid Build Coastguard Worker "BufferUsage::CPU_* usage.");
492*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
493*d95af8dfSAndroid Build Coastguard Worker }
494*d95af8dfSAndroid Build Coastguard Worker }
495*d95af8dfSAndroid Build Coastguard Worker
496*d95af8dfSAndroid Build Coastguard Worker auto buffer = get_buffer(hnd);
497*d95af8dfSAndroid Build Coastguard Worker if (!buffer) {
498*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid reference (lock() called on unregistered handle).");
499*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
500*d95af8dfSAndroid Build Coastguard Worker }
501*d95af8dfSAndroid Build Coastguard Worker
502*d95af8dfSAndroid Build Coastguard Worker return buffer->lock(rect, map_flags, addr);
503*d95af8dfSAndroid Build Coastguard Worker }
504*d95af8dfSAndroid Build Coastguard Worker
unlock(buffer_handle_t handle,int32_t * release_fence)505*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fence)
506*d95af8dfSAndroid Build Coastguard Worker {
507*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
508*d95af8dfSAndroid Build Coastguard Worker
509*d95af8dfSAndroid Build Coastguard Worker auto hnd = cros_gralloc_convert_handle(handle);
510*d95af8dfSAndroid Build Coastguard Worker if (!hnd) {
511*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid handle.");
512*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
513*d95af8dfSAndroid Build Coastguard Worker }
514*d95af8dfSAndroid Build Coastguard Worker
515*d95af8dfSAndroid Build Coastguard Worker auto buffer = get_buffer(hnd);
516*d95af8dfSAndroid Build Coastguard Worker if (!buffer) {
517*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid reference (unlock() called on unregistered handle).");
518*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
519*d95af8dfSAndroid Build Coastguard Worker }
520*d95af8dfSAndroid Build Coastguard Worker
521*d95af8dfSAndroid Build Coastguard Worker /*
522*d95af8dfSAndroid Build Coastguard Worker * From the ANativeWindow::dequeueBuffer documentation:
523*d95af8dfSAndroid Build Coastguard Worker *
524*d95af8dfSAndroid Build Coastguard Worker * "A value of -1 indicates that the caller may access the buffer immediately without
525*d95af8dfSAndroid Build Coastguard Worker * waiting on a fence."
526*d95af8dfSAndroid Build Coastguard Worker */
527*d95af8dfSAndroid Build Coastguard Worker *release_fence = -1;
528*d95af8dfSAndroid Build Coastguard Worker return buffer->unlock();
529*d95af8dfSAndroid Build Coastguard Worker }
530*d95af8dfSAndroid Build Coastguard Worker
invalidate(buffer_handle_t handle)531*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::invalidate(buffer_handle_t handle)
532*d95af8dfSAndroid Build Coastguard Worker {
533*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
534*d95af8dfSAndroid Build Coastguard Worker
535*d95af8dfSAndroid Build Coastguard Worker auto hnd = cros_gralloc_convert_handle(handle);
536*d95af8dfSAndroid Build Coastguard Worker if (!hnd) {
537*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid handle.");
538*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
539*d95af8dfSAndroid Build Coastguard Worker }
540*d95af8dfSAndroid Build Coastguard Worker
541*d95af8dfSAndroid Build Coastguard Worker auto buffer = get_buffer(hnd);
542*d95af8dfSAndroid Build Coastguard Worker if (!buffer) {
543*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid reference (invalidate() called on unregistered handle).");
544*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
545*d95af8dfSAndroid Build Coastguard Worker }
546*d95af8dfSAndroid Build Coastguard Worker
547*d95af8dfSAndroid Build Coastguard Worker return buffer->invalidate();
548*d95af8dfSAndroid Build Coastguard Worker }
549*d95af8dfSAndroid Build Coastguard Worker
flush(buffer_handle_t handle)550*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::flush(buffer_handle_t handle)
551*d95af8dfSAndroid Build Coastguard Worker {
552*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
553*d95af8dfSAndroid Build Coastguard Worker
554*d95af8dfSAndroid Build Coastguard Worker auto hnd = cros_gralloc_convert_handle(handle);
555*d95af8dfSAndroid Build Coastguard Worker if (!hnd) {
556*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid handle.");
557*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
558*d95af8dfSAndroid Build Coastguard Worker }
559*d95af8dfSAndroid Build Coastguard Worker
560*d95af8dfSAndroid Build Coastguard Worker auto buffer = get_buffer(hnd);
561*d95af8dfSAndroid Build Coastguard Worker if (!buffer) {
562*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid reference (flush() called on unregistered handle).");
563*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
564*d95af8dfSAndroid Build Coastguard Worker }
565*d95af8dfSAndroid Build Coastguard Worker
566*d95af8dfSAndroid Build Coastguard Worker return buffer->flush();
567*d95af8dfSAndroid Build Coastguard Worker }
568*d95af8dfSAndroid Build Coastguard Worker
get_backing_store(buffer_handle_t handle,uint64_t * out_store)569*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t *out_store)
570*d95af8dfSAndroid Build Coastguard Worker {
571*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
572*d95af8dfSAndroid Build Coastguard Worker
573*d95af8dfSAndroid Build Coastguard Worker auto hnd = cros_gralloc_convert_handle(handle);
574*d95af8dfSAndroid Build Coastguard Worker if (!hnd) {
575*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid handle.");
576*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
577*d95af8dfSAndroid Build Coastguard Worker }
578*d95af8dfSAndroid Build Coastguard Worker
579*d95af8dfSAndroid Build Coastguard Worker auto buffer = get_buffer(hnd);
580*d95af8dfSAndroid Build Coastguard Worker if (!buffer) {
581*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid reference (get_backing_store() called on unregistered handle).");
582*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
583*d95af8dfSAndroid Build Coastguard Worker }
584*d95af8dfSAndroid Build Coastguard Worker
585*d95af8dfSAndroid Build Coastguard Worker *out_store = static_cast<uint64_t>(buffer->get_id());
586*d95af8dfSAndroid Build Coastguard Worker return 0;
587*d95af8dfSAndroid Build Coastguard Worker }
588*d95af8dfSAndroid Build Coastguard Worker
resource_info(buffer_handle_t handle,uint32_t strides[DRV_MAX_PLANES],uint32_t offsets[DRV_MAX_PLANES],uint64_t * format_modifier)589*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_driver::resource_info(buffer_handle_t handle, uint32_t strides[DRV_MAX_PLANES],
590*d95af8dfSAndroid Build Coastguard Worker uint32_t offsets[DRV_MAX_PLANES],
591*d95af8dfSAndroid Build Coastguard Worker uint64_t *format_modifier)
592*d95af8dfSAndroid Build Coastguard Worker {
593*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
594*d95af8dfSAndroid Build Coastguard Worker
595*d95af8dfSAndroid Build Coastguard Worker auto hnd = cros_gralloc_convert_handle(handle);
596*d95af8dfSAndroid Build Coastguard Worker if (!hnd) {
597*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid handle.");
598*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
599*d95af8dfSAndroid Build Coastguard Worker }
600*d95af8dfSAndroid Build Coastguard Worker
601*d95af8dfSAndroid Build Coastguard Worker auto buffer = get_buffer(hnd);
602*d95af8dfSAndroid Build Coastguard Worker if (!buffer) {
603*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid reference (resource_info() called on unregistered handle).");
604*d95af8dfSAndroid Build Coastguard Worker return -EINVAL;
605*d95af8dfSAndroid Build Coastguard Worker }
606*d95af8dfSAndroid Build Coastguard Worker
607*d95af8dfSAndroid Build Coastguard Worker return buffer->resource_info(strides, offsets, format_modifier);
608*d95af8dfSAndroid Build Coastguard Worker }
609*d95af8dfSAndroid Build Coastguard Worker
get_resolved_drm_format(uint32_t drm_format,uint64_t use_flags)610*d95af8dfSAndroid Build Coastguard Worker uint32_t cros_gralloc_driver::get_resolved_drm_format(uint32_t drm_format, uint64_t use_flags)
611*d95af8dfSAndroid Build Coastguard Worker {
612*d95af8dfSAndroid Build Coastguard Worker uint32_t resolved_format;
613*d95af8dfSAndroid Build Coastguard Worker uint64_t resolved_use_flags;
614*d95af8dfSAndroid Build Coastguard Worker
615*d95af8dfSAndroid Build Coastguard Worker drv_resolve_format_and_use_flags(drv_.get(), drm_format, use_flags, &resolved_format,
616*d95af8dfSAndroid Build Coastguard Worker &resolved_use_flags);
617*d95af8dfSAndroid Build Coastguard Worker
618*d95af8dfSAndroid Build Coastguard Worker return resolved_format;
619*d95af8dfSAndroid Build Coastguard Worker }
620*d95af8dfSAndroid Build Coastguard Worker
get_buffer(cros_gralloc_handle_t hnd)621*d95af8dfSAndroid Build Coastguard Worker cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd)
622*d95af8dfSAndroid Build Coastguard Worker {
623*d95af8dfSAndroid Build Coastguard Worker /* Assumes driver mutex is held. */
624*d95af8dfSAndroid Build Coastguard Worker if (handles_.count(hnd))
625*d95af8dfSAndroid Build Coastguard Worker return handles_[hnd].buffer;
626*d95af8dfSAndroid Build Coastguard Worker
627*d95af8dfSAndroid Build Coastguard Worker return nullptr;
628*d95af8dfSAndroid Build Coastguard Worker }
629*d95af8dfSAndroid Build Coastguard Worker
with_buffer(cros_gralloc_handle_t hnd,const std::function<void (cros_gralloc_buffer *)> & function)630*d95af8dfSAndroid Build Coastguard Worker void cros_gralloc_driver::with_buffer(cros_gralloc_handle_t hnd,
631*d95af8dfSAndroid Build Coastguard Worker const std::function<void(cros_gralloc_buffer *)> &function)
632*d95af8dfSAndroid Build Coastguard Worker {
633*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
634*d95af8dfSAndroid Build Coastguard Worker
635*d95af8dfSAndroid Build Coastguard Worker auto buffer = get_buffer(hnd);
636*d95af8dfSAndroid Build Coastguard Worker if (!buffer) {
637*d95af8dfSAndroid Build Coastguard Worker ALOGE("Invalid reference (with_buffer() called on unregistered handle).");
638*d95af8dfSAndroid Build Coastguard Worker return;
639*d95af8dfSAndroid Build Coastguard Worker }
640*d95af8dfSAndroid Build Coastguard Worker
641*d95af8dfSAndroid Build Coastguard Worker function(buffer);
642*d95af8dfSAndroid Build Coastguard Worker }
643*d95af8dfSAndroid Build Coastguard Worker
with_each_buffer(const std::function<void (cros_gralloc_buffer *)> & function)644*d95af8dfSAndroid Build Coastguard Worker void cros_gralloc_driver::with_each_buffer(
645*d95af8dfSAndroid Build Coastguard Worker const std::function<void(cros_gralloc_buffer *)> &function)
646*d95af8dfSAndroid Build Coastguard Worker {
647*d95af8dfSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mutex_);
648*d95af8dfSAndroid Build Coastguard Worker
649*d95af8dfSAndroid Build Coastguard Worker for (const auto &pair : buffers_)
650*d95af8dfSAndroid Build Coastguard Worker function(pair.second.get());
651*d95af8dfSAndroid Build Coastguard Worker }
652