xref: /aosp_15_r20/external/minigbm/cros_gralloc/cros_gralloc_buffer.cc (revision d95af8df99a05bcb8679a54dc3ab8e5cd312b38e)
1 /*
2  * Copyright 2017 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_buffer.h"
8 
9 #include <assert.h>
10 #include <sys/mman.h>
11 
12 #include <cutils/native_handle.h>
13 
14 #include "cros_gralloc_buffer_metadata.h"
15 
16 using aidl::android::hardware::graphics::common::BlendMode;
17 using aidl::android::hardware::graphics::common::Cta861_3;
18 using aidl::android::hardware::graphics::common::Dataspace;
19 using aidl::android::hardware::graphics::common::Smpte2086;
20 
21 /*static*/
22 std::unique_ptr<cros_gralloc_buffer>
create(struct bo * acquire_bo,const struct cros_gralloc_handle * borrowed_handle)23 cros_gralloc_buffer::create(struct bo *acquire_bo,
24 			    const struct cros_gralloc_handle *borrowed_handle)
25 {
26 	auto acquire_hnd =
27 	    reinterpret_cast<struct cros_gralloc_handle *>(native_handle_clone(borrowed_handle));
28 	if (!acquire_hnd) {
29 		ALOGE("Failed to create cros_gralloc_buffer: failed to clone handle.");
30 		return {};
31 	}
32 
33 	std::unique_ptr<cros_gralloc_buffer> buffer(
34 	    new cros_gralloc_buffer(acquire_bo, acquire_hnd));
35 	if (!buffer) {
36 		ALOGE("Failed to create cros_gralloc_buffer: failed to allocate.");
37 		native_handle_close(acquire_hnd);
38 		native_handle_delete(acquire_hnd);
39 		return {};
40 	}
41 
42 	return buffer;
43 }
44 
45 int32_t
initialize_metadata(const struct cros_gralloc_buffer_descriptor * descriptor)46 cros_gralloc_buffer::initialize_metadata(const struct cros_gralloc_buffer_descriptor *descriptor)
47 {
48 	struct cros_gralloc_buffer_metadata *metadata;
49 
50 	int ret = get_metadata(&metadata);
51 	if (ret) {
52 		ALOGE("Failed to initialize metadata: failed to get metadata region.");
53 		return ret;
54 	}
55 
56 	if (metadata == nullptr) {
57 		ALOGE("Failed to initialize metadata: invalid metadata address.");
58 		return -1;
59 	}
60 
61 	new (metadata) cros_gralloc_buffer_metadata();
62 
63 	snprintf(metadata->name, CROS_GRALLOC_BUFFER_METADATA_MAX_NAME_SIZE, "%s",
64 		 descriptor->name.c_str());
65 	metadata->dataspace = descriptor->dataspace;
66 	metadata->blend_mode = descriptor->blend;
67 	return 0;
68 }
69 
cros_gralloc_buffer(struct bo * acquire_bo,struct cros_gralloc_handle * acquire_handle)70 cros_gralloc_buffer::cros_gralloc_buffer(struct bo *acquire_bo,
71 					 struct cros_gralloc_handle *acquire_handle)
72     : bo_(acquire_bo), hnd_(acquire_handle)
73 {
74 	assert(bo_);
75 	assert(hnd_);
76 	for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++)
77 		lock_data_[plane] = nullptr;
78 }
79 
~cros_gralloc_buffer()80 cros_gralloc_buffer::~cros_gralloc_buffer()
81 {
82 	drv_bo_destroy(bo_);
83 	if (reserved_region_addr_) {
84 		munmap(reserved_region_addr_, hnd_->reserved_region_size);
85 	}
86 	native_handle_close(hnd_);
87 	native_handle_delete(hnd_);
88 }
89 
get_id() const90 uint32_t cros_gralloc_buffer::get_id() const
91 {
92 	return hnd_->id;
93 }
94 
get_width() const95 uint32_t cros_gralloc_buffer::get_width() const
96 {
97 	return hnd_->width;
98 }
99 
get_pixel_stride() const100 uint32_t cros_gralloc_buffer::get_pixel_stride() const
101 {
102 	return hnd_->pixel_stride;
103 }
104 
get_height() const105 uint32_t cros_gralloc_buffer::get_height() const
106 {
107 	return hnd_->height;
108 }
109 
get_format() const110 uint32_t cros_gralloc_buffer::get_format() const
111 {
112 	return hnd_->format;
113 }
114 
get_format_modifier() const115 uint64_t cros_gralloc_buffer::get_format_modifier() const
116 {
117 	return hnd_->format_modifier;
118 }
119 
get_total_size() const120 uint64_t cros_gralloc_buffer::get_total_size() const
121 {
122 	return hnd_->total_size;
123 }
124 
get_num_planes() const125 uint32_t cros_gralloc_buffer::get_num_planes() const
126 {
127 	return hnd_->num_planes;
128 }
129 
get_plane_offset(uint32_t plane) const130 uint32_t cros_gralloc_buffer::get_plane_offset(uint32_t plane) const
131 {
132 	return hnd_->offsets[plane];
133 }
134 
get_plane_stride(uint32_t plane) const135 uint32_t cros_gralloc_buffer::get_plane_stride(uint32_t plane) const
136 {
137 	return hnd_->strides[plane];
138 }
139 
get_plane_size(uint32_t plane) const140 uint32_t cros_gralloc_buffer::get_plane_size(uint32_t plane) const
141 {
142 	return hnd_->sizes[plane];
143 }
144 
get_android_format() const145 int32_t cros_gralloc_buffer::get_android_format() const
146 {
147 	return hnd_->droid_format;
148 }
149 
get_android_usage() const150 int64_t cros_gralloc_buffer::get_android_usage() const
151 {
152 	return hnd_->usage;
153 }
154 
get_name(std::optional<std::string> * name) const155 int32_t cros_gralloc_buffer::get_name(std::optional<std::string> *name) const
156 {
157 	const struct cros_gralloc_buffer_metadata *metadata;
158 
159 	int ret = get_metadata(&metadata);
160 	if (ret) {
161 		ALOGE("Failed to get_name: failed to get metadata.");
162 		return ret;
163 	}
164 
165 	*name = metadata->name;
166 	return 0;
167 }
168 
get_blend_mode(std::optional<BlendMode> * blend_mode) const169 int32_t cros_gralloc_buffer::get_blend_mode(std::optional<BlendMode> *blend_mode) const
170 {
171 	const struct cros_gralloc_buffer_metadata *metadata;
172 
173 	int ret = get_metadata(&metadata);
174 	if (ret) {
175 		ALOGE("Failed to get_blend_mode: failed to get metadata.");
176 		return ret;
177 	}
178 
179 	*blend_mode = metadata->blend_mode;
180 	return 0;
181 }
182 
set_blend_mode(BlendMode blend_mode)183 int32_t cros_gralloc_buffer::set_blend_mode(BlendMode blend_mode)
184 {
185 	struct cros_gralloc_buffer_metadata *metadata;
186 
187 	int ret = get_metadata(&metadata);
188 	if (ret) {
189 		ALOGE("Failed to set_blend_mode: failed to get metadata.");
190 		return ret;
191 	}
192 
193 	metadata->blend_mode = blend_mode;
194 	return 0;
195 }
196 
get_dataspace(std::optional<Dataspace> * dataspace) const197 int32_t cros_gralloc_buffer::get_dataspace(std::optional<Dataspace> *dataspace) const
198 {
199 	const struct cros_gralloc_buffer_metadata *metadata;
200 
201 	int ret = get_metadata(&metadata);
202 	if (ret) {
203 		ALOGE("Failed to get_dataspace: failed to get metadata.");
204 		return ret;
205 	}
206 
207 	*dataspace = metadata->dataspace;
208 	return 0;
209 }
210 
set_dataspace(Dataspace dataspace)211 int32_t cros_gralloc_buffer::set_dataspace(Dataspace dataspace)
212 {
213 	struct cros_gralloc_buffer_metadata *metadata;
214 
215 	int ret = get_metadata(&metadata);
216 	if (ret) {
217 		ALOGE("Failed to set_dataspace: failed to get metadata.");
218 		return ret;
219 	}
220 
221 	metadata->dataspace = dataspace;
222 	return 0;
223 }
224 
get_cta861_3(std::optional<Cta861_3> * cta) const225 int32_t cros_gralloc_buffer::get_cta861_3(std::optional<Cta861_3> *cta) const
226 {
227 	const struct cros_gralloc_buffer_metadata *metadata;
228 
229 	int ret = get_metadata(&metadata);
230 	if (ret) {
231 		ALOGE("Failed to get_cta861_3: failed to get metadata.");
232 		return ret;
233 	}
234 
235 	*cta = metadata->cta861_3.to_std_optional();
236 	return 0;
237 }
238 
set_cta861_3(std::optional<Cta861_3> cta)239 int32_t cros_gralloc_buffer::set_cta861_3(std::optional<Cta861_3> cta)
240 {
241 	struct cros_gralloc_buffer_metadata *metadata;
242 
243 	int ret = get_metadata(&metadata);
244 	if (ret) {
245 		ALOGE("Failed to set_cta861_3: failed to get metadata.");
246 		return ret;
247 	}
248 
249 	metadata->cta861_3 = cta;
250 	return 0;
251 }
252 
get_smpte2086(std::optional<Smpte2086> * smpte) const253 int32_t cros_gralloc_buffer::get_smpte2086(std::optional<Smpte2086> *smpte) const
254 {
255 	const struct cros_gralloc_buffer_metadata *metadata;
256 
257 	int ret = get_metadata(&metadata);
258 	if (ret) {
259 		ALOGE("Failed to get_smpte2086: failed to get metadata.");
260 		return ret;
261 	}
262 
263 	*smpte = metadata->smpte2086.to_std_optional();
264 	return 0;
265 }
266 
set_smpte2086(std::optional<Smpte2086> smpte)267 int32_t cros_gralloc_buffer::set_smpte2086(std::optional<Smpte2086> smpte)
268 {
269 	struct cros_gralloc_buffer_metadata *metadata;
270 
271 	int ret = get_metadata(&metadata);
272 	if (ret) {
273 		ALOGE("Failed to set_cta861_3: failed to get metadata.");
274 		return ret;
275 	}
276 
277 	metadata->smpte2086 = smpte;
278 	return 0;
279 }
280 
increase_refcount()281 int32_t cros_gralloc_buffer::increase_refcount()
282 {
283 	return ++refcount_;
284 }
285 
decrease_refcount()286 int32_t cros_gralloc_buffer::decrease_refcount()
287 {
288 	assert(refcount_ > 0);
289 	return --refcount_;
290 }
291 
lock(const struct rectangle * rect,uint32_t map_flags,uint8_t * addr[DRV_MAX_PLANES])292 int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_flags,
293 				  uint8_t *addr[DRV_MAX_PLANES])
294 {
295 	void *vaddr = nullptr;
296 
297 	memset(addr, 0, DRV_MAX_PLANES * sizeof(*addr));
298 
299 	if (map_flags) {
300 		if (lock_data_[0]) {
301 			drv_bo_invalidate(bo_, lock_data_[0]);
302 			vaddr = lock_data_[0]->vma->addr;
303 		} else {
304 			struct rectangle r = *rect;
305 
306 			if (!r.width && !r.height && !r.x && !r.y) {
307 				/*
308 				 * Android IMapper.hal: An accessRegion of all-zeros means the
309 				 * entire buffer.
310 				 */
311 				r.width = drv_bo_get_width(bo_);
312 				r.height = drv_bo_get_height(bo_);
313 			}
314 
315 			vaddr = drv_bo_map(bo_, &r, map_flags, &lock_data_[0], 0);
316 		}
317 
318 		if (vaddr == MAP_FAILED) {
319 			ALOGE("Mapping failed.");
320 			return -EFAULT;
321 		}
322 	}
323 
324 	for (uint32_t plane = 0; plane < hnd_->num_planes; plane++)
325 		addr[plane] = static_cast<uint8_t *>(vaddr) + drv_bo_get_plane_offset(bo_, plane);
326 
327 	lockcount_++;
328 	return 0;
329 }
330 
unlock()331 int32_t cros_gralloc_buffer::unlock()
332 {
333 	if (lockcount_ <= 0) {
334 		ALOGE("Buffer was not locked.");
335 		return -EINVAL;
336 	}
337 
338 	if (!--lockcount_) {
339 		if (lock_data_[0]) {
340 			drv_bo_flush_or_unmap(bo_, lock_data_[0]);
341 			lock_data_[0] = nullptr;
342 		}
343 	}
344 
345 	return 0;
346 }
347 
resource_info(uint32_t strides[DRV_MAX_PLANES],uint32_t offsets[DRV_MAX_PLANES],uint64_t * format_modifier)348 int32_t cros_gralloc_buffer::resource_info(uint32_t strides[DRV_MAX_PLANES],
349 					   uint32_t offsets[DRV_MAX_PLANES],
350 					   uint64_t *format_modifier)
351 {
352 	return drv_resource_info(bo_, strides, offsets, format_modifier);
353 }
354 
invalidate()355 int32_t cros_gralloc_buffer::invalidate()
356 {
357 	if (lockcount_ <= 0) {
358 		ALOGE("Buffer was not locked.");
359 		return -EINVAL;
360 	}
361 
362 	if (lock_data_[0])
363 		return drv_bo_invalidate(bo_, lock_data_[0]);
364 
365 	return 0;
366 }
367 
flush()368 int32_t cros_gralloc_buffer::flush()
369 {
370 	if (lockcount_ <= 0) {
371 		ALOGE("Buffer was not locked.");
372 		return -EINVAL;
373 	}
374 
375 	if (lock_data_[0])
376 		return drv_bo_flush(bo_, lock_data_[0]);
377 
378 	return 0;
379 }
380 
get_reserved_region(void ** addr,uint64_t * size) const381 int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size) const
382 {
383 	int32_t reserved_region_fd = hnd_->fds[hnd_->num_planes];
384 	if (reserved_region_fd < 0) {
385 		ALOGE("Buffer does not have reserved region.");
386 		return -EINVAL;
387 	}
388 
389 	if (!reserved_region_addr_) {
390 		reserved_region_addr_ =
391 		    mmap(nullptr, hnd_->reserved_region_size, PROT_WRITE | PROT_READ, MAP_SHARED,
392 			 reserved_region_fd, 0);
393 		if (reserved_region_addr_ == MAP_FAILED) {
394 			ALOGE("Failed to mmap reserved region: %s.", strerror(errno));
395 			return -errno;
396 		}
397 	}
398 
399 	*addr = reserved_region_addr_;
400 	*size = hnd_->reserved_region_size;
401 	return 0;
402 }
403 
get_client_reserved_region(void ** client_reserved_region_addr,uint64_t * client_reserved_region_size) const404 int32_t cros_gralloc_buffer::get_client_reserved_region(void **client_reserved_region_addr,
405 							uint64_t *client_reserved_region_size) const
406 {
407 	int32_t ret = get_reserved_region(client_reserved_region_addr, client_reserved_region_size);
408 	if (ret) {
409 		return ret;
410 	}
411 
412 	*client_reserved_region_addr =
413 	    reinterpret_cast<void *>(reinterpret_cast<char *>(*client_reserved_region_addr) +
414 				     sizeof(struct cros_gralloc_buffer_metadata));
415 	*client_reserved_region_size =
416 	    *client_reserved_region_size - sizeof(struct cros_gralloc_buffer_metadata);
417 	return 0;
418 }
419 
get_metadata(struct cros_gralloc_buffer_metadata ** metadata)420 int32_t cros_gralloc_buffer::get_metadata(struct cros_gralloc_buffer_metadata **metadata)
421 {
422 	void *metadata_addr;
423 	uint64_t metadata_region_size;
424 	int32_t ret = get_reserved_region(&metadata_addr, &metadata_region_size);
425 	if (ret) {
426 		return ret;
427 	}
428 
429 	if (metadata_addr == nullptr) {
430 		return -1;
431 	}
432 
433 	*metadata = reinterpret_cast<struct cros_gralloc_buffer_metadata *>(metadata_addr);
434 	return 0;
435 }
436 
437 int32_t
get_metadata(const struct cros_gralloc_buffer_metadata ** metadata) const438 cros_gralloc_buffer::get_metadata(const struct cros_gralloc_buffer_metadata **metadata) const
439 {
440 	void *metadata_addr;
441 	uint64_t metadata_region_size;
442 	int32_t ret = get_reserved_region(&metadata_addr, &metadata_region_size);
443 	if (ret) {
444 		return ret;
445 	}
446 
447 	if (metadata_addr == nullptr) {
448 		return -1;
449 	}
450 
451 	*metadata = reinterpret_cast<const struct cros_gralloc_buffer_metadata *>(metadata_addr);
452 	return 0;
453 }
454