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