• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 ARM Limited. All rights reserved.
3  *
4  * Copyright 2016 The Android Open Source Project
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
20 
21 #include <utils/Trace.h>
22 
23 #include "Allocator.h"
24 #include "core/mali_gralloc_bufferallocation.h"
25 #include "core/mali_gralloc_bufferdescriptor.h"
26 #include "core/format_info.h"
27 #include "allocator/mali_gralloc_ion.h"
28 #include "gralloc_priv.h"
29 #include "SharedMetadata.h"
30 
31 namespace arm
32 {
33 namespace allocator
34 {
35 namespace common
36 {
37 
allocate(const buffer_descriptor_t & bufferDescriptor,uint32_t count,IAllocator::allocate_cb hidl_cb,std::function<int (const buffer_descriptor_t *,buffer_handle_t *)> fb_allocator)38 void allocate(const buffer_descriptor_t &bufferDescriptor, uint32_t count, IAllocator::allocate_cb hidl_cb,
39               std::function<int(const buffer_descriptor_t *, buffer_handle_t *)> fb_allocator)
40 {
41 #if DISABLE_FRAMEBUFFER_HAL
42 	GRALLOC_UNUSED(fb_allocator);
43 #endif
44 	ATRACE_CALL();
45 
46 	Error error = Error::NONE;
47 	int stride = 0;
48 	std::vector<hidl_handle> grallocBuffers;
49 	gralloc_buffer_descriptor_t grallocBufferDescriptor[1];
50 
51 	grallocBufferDescriptor[0] = (gralloc_buffer_descriptor_t)(&bufferDescriptor);
52 	grallocBuffers.reserve(count);
53 
54 	for (uint32_t i = 0; i < count; i++)
55 	{
56 		buffer_handle_t tmpBuffer = nullptr;
57 
58 		int allocResult;
59 #if (DISABLE_FRAMEBUFFER_HAL != 1)
60 		if (((bufferDescriptor.producer_usage & GRALLOC_USAGE_HW_FB) ||
61 		     (bufferDescriptor.consumer_usage & GRALLOC_USAGE_HW_FB)) &&
62 		    fb_allocator)
63 		{
64 			allocResult = fb_allocator(&bufferDescriptor, &tmpBuffer);
65 		}
66 		else
67 #endif
68 		{
69 			allocResult = mali_gralloc_buffer_allocate(grallocBufferDescriptor, 1, &tmpBuffer, nullptr);
70 			if (allocResult != 0)
71 			{
72 				MALI_GRALLOC_LOGE("%s, buffer allocation failed with %d", __func__, allocResult);
73 				error = Error::NO_RESOURCES;
74 				break;
75 			}
76 			auto hnd = const_cast<private_handle_t *>(reinterpret_cast<const private_handle_t *>(tmpBuffer));
77 			hnd->imapper_version = HIDL_MAPPER_VERSION_SCALED;
78 
79 			// 4k is rougly 7.9 MB with one byte per pixel. We are
80 			// assuming that the reserved region might be needed for
81 			// dynamic HDR and that represents the largest size.
82 			uint64_t max_reserved_region_size = 8ull * 1024 * 1024;
83 			hnd->reserved_region_size = bufferDescriptor.reserved_size;
84 			if (hnd->reserved_region_size > max_reserved_region_size) {
85 				MALI_GRALLOC_LOGE("%s, Requested reserved region size (%" PRIu64 ") is larger than allowed (%" PRIu64 ")",
86 						__func__, hnd->reserved_region_size, max_reserved_region_size);
87 				error = Error::BAD_VALUE;
88 				break;
89 			}
90 			hnd->attr_size = mapper::common::shared_metadata_size() + hnd->reserved_region_size;
91 
92 			if (hnd->get_usage() & GRALLOC_USAGE_ROIINFO)
93 			{
94 				hnd->attr_size += 32768;
95 			}
96 
97 			/* TODO: must do error checking */
98 			mali_gralloc_ion_allocate_attr(hnd);
99 
100 			/* TODO: error check for failure */
101 			void* metadata_vaddr = mmap(nullptr, hnd->attr_size, PROT_READ | PROT_WRITE,
102 					MAP_SHARED, hnd->get_share_attr_fd(), 0);
103 
104 			memset(metadata_vaddr, 0, hnd->attr_size);
105 
106 			mapper::common::shared_metadata_init(metadata_vaddr, bufferDescriptor.name);
107 
108 			const uint32_t base_format = bufferDescriptor.alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK;
109 			const uint64_t usage = bufferDescriptor.consumer_usage | bufferDescriptor.producer_usage;
110 			android_dataspace_t dataspace;
111 			get_format_dataspace(base_format, usage, hnd->width, hnd->height, &dataspace);
112 
113 			// TODO: set_dataspace API in mapper expects a buffer to be first imported before it can set the dataspace
114 			{
115 				using mapper::common::shared_metadata;
116 				using mapper::common::aligned_optional;
117 				using mapper::common::Dataspace;
118 				(static_cast<shared_metadata*>(metadata_vaddr))->dataspace = aligned_optional(static_cast<Dataspace>(dataspace));
119 			}
120 
121 			munmap(metadata_vaddr, hnd->attr_size);
122 		}
123 
124 		int tmpStride = 0;
125 		tmpStride = bufferDescriptor.pixel_stride;
126 
127 		if (stride == 0)
128 		{
129 			stride = tmpStride;
130 		}
131 		else if (stride != tmpStride)
132 		{
133 			/* Stride must be the same for all allocations */
134 			mali_gralloc_buffer_free(tmpBuffer);
135 			stride = 0;
136 			error = Error::UNSUPPORTED;
137 			break;
138 		}
139 
140 		grallocBuffers.emplace_back(hidl_handle(tmpBuffer));
141 	}
142 
143 	/* Populate the array of buffers for application consumption */
144 	hidl_vec<hidl_handle> hidlBuffers;
145 	if (error == Error::NONE)
146 	{
147 		hidlBuffers.setToExternal(grallocBuffers.data(), grallocBuffers.size());
148 	}
149 	hidl_cb(error, stride, hidlBuffers);
150 
151 	/* The application should import the Gralloc buffers using IMapper for
152 	 * further usage. Free the allocated buffers in IAllocator context
153 	 */
154 	for (const auto &buffer : grallocBuffers)
155 	{
156 		mali_gralloc_buffer_free(buffer.getNativeHandle());
157 	}
158 }
159 
160 } // namespace common
161 } // namespace allocator
162 } // namespace arm
163