1 /*
2  * Copyright (C) 2017-2019 ARM Limited. All rights reserved.
3  *
4  * Copyright (C) 2008 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 #include "GrallocAllocator.h"
20 #include "GrallocBufferDescriptor.h"
21 #include "mali_gralloc_bufferallocation.h"
22 #include "mali_gralloc_bufferdescriptor.h"
23 #include "mali_gralloc_ion.h"
24 #include "framebuffer_device.h"
25 
26 namespace android {
27 namespace hardware {
28 namespace graphics {
29 namespace allocator {
30 namespace HIDL_IALLOCATOR_NAMESPACE {
31 namespace implementation {
32 
33 /**
34  *  IAllocator constructor. All the state information required for the Gralloc
35  *  private module is populated in its default constructor. Gralloc 2.0 specific
36  *  state information can be populated here.
37  *
38  * @return None
39  */
40 
GrallocAllocator()41 GrallocAllocator::GrallocAllocator()
42 {
43 }
44 
45 /*
46  *  IAllocator destructor. All the resources acquired for Gralloc private module
47  *  are released
48  *
49  * @return None
50  */
~GrallocAllocator()51 GrallocAllocator::~GrallocAllocator()
52 {
53 	mali_gralloc_ion_close();
54 }
55 
56 /*
57  * Retrieves implementation-defined debug information
58  *
59  * Retrieves implementation-defined debug information, which will be
60  * displayed during, for example, `dumpsys SurfaceFlinger`
61  *
62  * @param hidl_cb [in] HIDL callback function generating -
63  *                String of debug information
64  *
65  * @return Void
66  */
dumpDebugInfo(dumpDebugInfo_cb hidl_cb)67 Return<void> GrallocAllocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
68 {
69 	hidl_cb(hidl_string());
70 	return Void();
71 }
72 
73 /*
74  * Allocates buffers with the properties specified by the descriptor
75  *
76  * @param descriptor: Specifies the properties of the buffers to allocate.
77  * @param count: Number of buffers to allocate.
78  * @param hidl_cb [in] HIDL callback function generating -
79  *        error : NONE upon success. Otherwise,
80  *                BAD_DESCRIPTOR when the descriptor is invalid.
81  *                NO_RESOURCES when the allocation cannot be fulfilled
82  *                UNSUPPORTED when any of the property encoded in the descriptor
83  *                            is not supported
84  *        stride: Number of pixels between two consecutive rows of the
85  *                buffers, when the concept of consecutive rows is defined.
86  *        buffers: An array of raw handles to the newly allocated buffers
87  *
88  * @return Void
89  */
allocate(const BufferDescriptor & descriptor,uint32_t count,allocate_cb hidl_cb)90 Return<void> GrallocAllocator::allocate(const BufferDescriptor& descriptor,
91                                         uint32_t count, allocate_cb hidl_cb)
92 {
93 	buffer_descriptor_t bufferDescriptor;
94 	Error error = Error::NONE;
95 	int stride = 0, tmpStride = 0;
96 	std::vector<hidl_handle> grallocBuffers;
97 	gralloc_buffer_descriptor_t grallocBufferDescriptor[1];
98 
99 	if (!mapper::HIDL_IMAPPER_NAMESPACE::implementation::grallocDecodeBufferDescriptor(descriptor, bufferDescriptor))
100 	{
101 		hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
102 		return Void();
103 	}
104 
105 	grallocBufferDescriptor[0] = (gralloc_buffer_descriptor_t)(&bufferDescriptor);
106 	grallocBuffers.reserve(count);
107 
108 	for (uint32_t i = 0; i < count; i++)
109 	{
110 		buffer_handle_t tmpBuffer;
111 
112 		int allocResult = 0;
113 #if DISABLE_FRAMEBUFFER_HAL != 1
114 		if ((bufferDescriptor.producer_usage & GRALLOC_USAGE_HW_FB) ||
115 		    (bufferDescriptor.consumer_usage & GRALLOC_USAGE_HW_FB))
116 		{
117 			allocResult = mali_gralloc_fb_allocate(&privateModule, &bufferDescriptor,
118 			                                       &tmpBuffer);
119 		}
120 		else
121 #endif
122 		{
123 			allocResult = mali_gralloc_buffer_allocate(&privateModule, grallocBufferDescriptor,
124 			                                            1, &tmpBuffer, nullptr);
125 		}
126 
127 		if (allocResult < 0)
128 		{
129 			AERR("%s, buffer allocation failed with %d", __func__, allocResult);
130 			error = Error::NO_RESOURCES;
131 			break;
132 		}
133 
134 		mali_gralloc_query_getstride(tmpBuffer, &tmpStride);
135 
136 		if (stride == 0)
137 		{
138 			stride = tmpStride;
139 		}
140 		else if (stride != tmpStride)
141 		{
142 			/* Stride must be the same for all allocations */
143 			mali_gralloc_buffer_free(tmpBuffer);
144 			stride = 0;
145 			error = Error::UNSUPPORTED;
146 			break;
147 		}
148 
149 		grallocBuffers.emplace_back(hidl_handle(tmpBuffer));
150 	}
151 
152 	/* Populate the array of buffers for application consumption */
153 	hidl_vec<hidl_handle> hidlBuffers;
154 	if (error == Error::NONE)
155 	{
156 		hidlBuffers.setToExternal(grallocBuffers.data(), grallocBuffers.size());
157 	}
158 	hidl_cb(error, stride, hidlBuffers);
159 
160 	/* The application should import the Gralloc buffers using IMapper for
161 	 * further usage. Free the allocated buffers in IAllocator context
162 	 */
163 	for (const auto& buffer : grallocBuffers)
164 	{
165 		mali_gralloc_buffer_free(buffer.getNativeHandle());
166 	}
167 
168 	return Void();
169 }
170 
HIDL_FETCH_IAllocator(const char *)171 IAllocator* HIDL_FETCH_IAllocator(const char* /* name */)
172 {
173 	ALOGV("Arm Module IAllocator %d.%d, pid = %d ppid = %d", GRALLOC_VERSION_MAJOR,
174 	       (HIDL_ALLOCATOR_VERSION_SCALED - (GRALLOC_VERSION_MAJOR * 100)) / 10, getpid(), getppid());
175 
176 	return new GrallocAllocator();
177 }
178 
179 } // namespace implementation
180 } // namespace HIDL_IALLOCATOR_NAMESPACE
181 } // namespace allocator
182 } // namespace graphics
183 } // namespace hardware
184 } // namespace android
185