1 /*
2 * Copyright (C) 2020 Arm Limited. All rights reserved.
3 *
4 * Copyright 2016 The Android Open Source Project
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include "GrallocMapper.h"
19
20 #include <cutils/native_handle.h>
21 #include <pixel-gralloc/mapper.h>
22 #include <pixel-gralloc/metadata.h>
23 #include <pixel-gralloc/utils-internal.h>
24
25 #include "allocator/mali_gralloc_ion.h"
26 #include "core/format_info.h"
27 #include "drmutils.h"
28 #include "hidl_common/BufferDescriptor.h"
29 #include "hidl_common/Mapper.h"
30 #include "hidl_common/MapperMetadata.h"
31 #include "hidl_common/SharedMetadata.h"
32 #include "hidl_common/hidl_common.h"
33
34 namespace arm {
35 namespace mapper {
36
37 using namespace android::hardware::graphics::mapper;
38 using PixelMetadataType = ::pixel::graphics::MetadataType;
39 using aidl::android::hardware::graphics::common::StandardMetadataType;
40
41
importBuffer(const native_handle_t * _Nonnull handle,buffer_handle_t _Nullable * _Nonnull outBufferHandle)42 AIMapper_Error GrallocMapper::importBuffer(const native_handle_t* _Nonnull handle,
43 buffer_handle_t _Nullable* _Nonnull outBufferHandle) {
44 if (handle == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
45 AIMapper_Error err = static_cast<AIMapper_Error>(common::importBuffer(handle, outBufferHandle));
46 return err;
47 }
48
freeBuffer(buffer_handle_t _Nonnull buffer)49 AIMapper_Error GrallocMapper::freeBuffer(buffer_handle_t _Nonnull buffer) {
50 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
51 native_handle_t* bufferHandle = const_cast<native_handle_t*>(buffer);
52 return static_cast<AIMapper_Error>(common::freeBuffer(bufferHandle));
53 }
54
lock(buffer_handle_t _Nonnull buffer,uint64_t cpuUsage,ARect accessRegion,int acquireFence,void * _Nullable * _Nonnull outData)55 AIMapper_Error GrallocMapper::lock(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage,
56 ARect accessRegion, int acquireFence,
57 void* _Nullable* _Nonnull outData) {
58 AIMapper_Error err = AIMapper_Error::AIMAPPER_ERROR_NONE;
59 if (buffer == nullptr) {
60 err = AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
61 } else {
62 err = static_cast<AIMapper_Error>(common::lock(buffer, cpuUsage,
63 common::GrallocRect(accessRegion),
64 acquireFence, outData));
65 }
66 // we own acquireFence, but common::lock doesn't take ownership
67 // so, we have to close it anyway
68 if (acquireFence >= 0) {
69 close(acquireFence);
70 }
71 return err;
72 }
73
unlock(buffer_handle_t _Nonnull buffer,int * _Nonnull releaseFence)74 AIMapper_Error GrallocMapper::unlock(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence) {
75 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
76
77 AIMapper_Error err = static_cast<AIMapper_Error>(common::unlock(buffer, releaseFence));
78 return err;
79 }
80
flushLockedBuffer(buffer_handle_t _Nonnull buffer)81 AIMapper_Error GrallocMapper::flushLockedBuffer(buffer_handle_t _Nonnull buffer) {
82 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
83
84 AIMapper_Error err = static_cast<AIMapper_Error>(common::flushLockedBuffer(buffer));
85 return err;
86 }
87
rereadLockedBuffer(buffer_handle_t _Nonnull buffer)88 AIMapper_Error GrallocMapper::rereadLockedBuffer(buffer_handle_t _Nonnull buffer) {
89 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
90 return static_cast<AIMapper_Error>(common::rereadLockedBuffer(buffer));
91 }
92
getStandardMetadata(buffer_handle_t _Nonnull buffer,int64_t standardMetadataType,void * _Nonnull outData,size_t outDataSize)93 int32_t GrallocMapper::getStandardMetadata(buffer_handle_t _Nonnull buffer,
94 int64_t standardMetadataType, void* _Nonnull outData,
95 size_t outDataSize) {
96 if (buffer == nullptr) return -AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
97 auto standardMeta = static_cast<StandardMetadataType>(standardMetadataType);
98 return common::getStandardMetadata(static_cast<const private_handle_t*>(buffer),
99 standardMeta,
100 outData, outDataSize);
101 }
102
isPixelMetadataType(common::MetadataType meta)103 bool isPixelMetadataType(common::MetadataType meta) {
104 return (meta.name == ::pixel::graphics::kPixelMetadataTypeName);
105 }
106
getMetadata(buffer_handle_t _Nonnull buffer,AIMapper_MetadataType metadataType,void * _Nonnull outData,size_t outDataSize)107 int32_t GrallocMapper::getMetadata(buffer_handle_t _Nonnull buffer,
108 AIMapper_MetadataType metadataType, void* _Nonnull outData,
109 size_t outDataSize) {
110 if (buffer == nullptr) return -AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
111
112 if (isStandardMetadataType(common::MetadataType(metadataType))) {
113 return getStandardMetadata(static_cast<const private_handle_t *>(buffer),
114 metadataType.value,
115 outData, outDataSize);
116 } else if (isPixelMetadataType(common::MetadataType(metadataType))) {
117 const PixelMetadataType pixelMeta = static_cast<PixelMetadataType>(metadataType.value);
118 return common::getPixelMetadataHelper(static_cast<const private_handle_t*>(buffer),
119 pixelMeta, outData, outDataSize);
120 } else {
121 return -AIMapper_Error::AIMAPPER_ERROR_UNSUPPORTED;
122 }
123 }
124
125 template <StandardMetadataType TYPE>
setStandardMetadataHelper(const private_handle_t * hnd,typename StandardMetadata<TYPE>::value_type && value)126 AIMapper_Error setStandardMetadataHelper(const private_handle_t* hnd,
127 typename StandardMetadata<TYPE>::value_type&& value) {
128 if constexpr (TYPE == StandardMetadataType::DATASPACE) {
129 common::set_dataspace(hnd, value);
130 }
131 if constexpr (TYPE == StandardMetadataType::CROP) {
132 common::set_crop_rect(hnd, value[0]);
133 }
134 if constexpr (TYPE == StandardMetadataType::BLEND_MODE) {
135 common::set_blend_mode(hnd, value);
136 }
137 if constexpr (TYPE == StandardMetadataType::SMPTE2086) {
138 common::set_smpte2086(hnd, value);
139 }
140 if constexpr (TYPE == StandardMetadataType::CTA861_3) {
141 common::set_cta861_3(hnd, value);
142 }
143 if constexpr (TYPE == StandardMetadataType::SMPTE2094_40) {
144 common::set_smpte2094_40(hnd, value);
145 }
146 return AIMapper_Error::AIMAPPER_ERROR_NONE;
147 }
148
setStandardMetadata(buffer_handle_t _Nonnull bufferHandle,int64_t standardTypeRaw,const void * _Nonnull metadata,size_t metadataSize)149 AIMapper_Error GrallocMapper::setStandardMetadata(buffer_handle_t _Nonnull bufferHandle,
150 int64_t standardTypeRaw,
151 const void* _Nonnull metadata,
152 size_t metadataSize) {
153 if (bufferHandle == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
154 auto standardMeta = static_cast<StandardMetadataType>(standardTypeRaw);
155 switch (standardMeta) {
156 // Read-only values
157 case StandardMetadataType::BUFFER_ID:
158 case StandardMetadataType::NAME:
159 case StandardMetadataType::WIDTH:
160 case StandardMetadataType::HEIGHT:
161 case StandardMetadataType::LAYER_COUNT:
162 case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
163 case StandardMetadataType::USAGE:
164 return AIMAPPER_ERROR_BAD_VALUE;
165
166 // Supported to set
167 case StandardMetadataType::BLEND_MODE:
168 case StandardMetadataType::CTA861_3:
169 case StandardMetadataType::DATASPACE:
170 case StandardMetadataType::SMPTE2086:
171 case StandardMetadataType::SMPTE2094_40:
172 case StandardMetadataType::CROP:
173 break;
174
175 // Everything else unsupported
176 default:
177 return AIMAPPER_ERROR_UNSUPPORTED;
178 }
179
180 auto applier = [&]<StandardMetadataType meta>(auto&& value) -> AIMapper_Error {
181 return setStandardMetadataHelper<meta>(static_cast<const private_handle_t*>(bufferHandle),
182 std::forward<decltype(value)>(value));
183 };
184
185 return applyStandardMetadata(standardMeta, metadata, metadataSize, applier);
186 }
187
setPixelMetadata(buffer_handle_t handle,const PixelMetadataType meta,const void * metadata,size_t metadataSize)188 AIMapper_Error setPixelMetadata(buffer_handle_t handle, const PixelMetadataType meta,
189 const void* metadata, size_t metadataSize) {
190 if (meta == PixelMetadataType::VIDEO_GMV) {
191 std::vector<uint8_t> in_data(metadataSize);
192 std::memcpy(in_data.data(), metadata, metadataSize);
193 auto gmv = ::pixel::graphics::utils::decode<common::VideoGMV>(in_data);
194 if (!gmv.has_value()) return AIMapper_Error::AIMAPPER_ERROR_BAD_VALUE;
195 auto result =
196 common::set_video_gmv(static_cast<const private_handle_t*>(handle), gmv.value());
197 if (result == android::OK) return AIMapper_Error::AIMAPPER_ERROR_NONE;
198 }
199 return AIMapper_Error::AIMAPPER_ERROR_BAD_VALUE;
200 }
201
setMetadata(buffer_handle_t _Nonnull buffer,AIMapper_MetadataType metadataType,const void * _Nonnull metadata,size_t metadataSize)202 AIMapper_Error GrallocMapper::setMetadata(buffer_handle_t _Nonnull buffer,
203 AIMapper_MetadataType metadataType,
204 const void* _Nonnull metadata, size_t metadataSize) {
205 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
206 if (isStandardMetadataType(common::MetadataType(metadataType))) {
207 return setStandardMetadata(buffer, metadataType.value, metadata, metadataSize);
208 } else if (isPixelMetadataType(common::MetadataType(metadataType))) {
209 const PixelMetadataType pixelMeta = static_cast<PixelMetadataType>(metadataType.value);
210 return setPixelMetadata(buffer, pixelMeta, metadata, metadataSize);
211 } else
212 return AIMapper_Error::AIMAPPER_ERROR_NONE;
213 }
214
getTransportSize(buffer_handle_t _Nonnull buffer,uint32_t * _Nonnull outNumFds,uint32_t * _Nonnull outNumInts)215 AIMapper_Error GrallocMapper::getTransportSize(buffer_handle_t _Nonnull buffer,
216 uint32_t* _Nonnull outNumFds,
217 uint32_t* _Nonnull outNumInts) {
218 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
219 AIMapper_Error err =
220 static_cast<AIMapper_Error>(common::getTransportSize(buffer, outNumFds, outNumInts));
221 return err;
222 }
223
listSupportedMetadataTypes(const AIMapper_MetadataTypeDescription * _Nullable * _Nonnull outDescriptionList,size_t * _Nonnull outNumberOfDescriptions)224 AIMapper_Error GrallocMapper::listSupportedMetadataTypes(
225 const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
226 size_t* _Nonnull outNumberOfDescriptions) {
227 std::vector<common::MetadataTypeDescription> desc = common::listSupportedMetadataTypes();
228 std::vector<AIMapper_MetadataTypeDescription> outDesc;
229 for (auto x : desc) {
230 outDesc.push_back(static_cast<AIMapper_MetadataTypeDescription>(x));
231 }
232
233 *outDescriptionList = outDesc.data();
234 *outNumberOfDescriptions = outDesc.size();
235 return AIMapper_Error::AIMAPPER_ERROR_NONE;
236 }
237
dumpBuffer(buffer_handle_t _Nonnull bufferHandle,AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,void * _Null_unspecified context)238 AIMapper_Error GrallocMapper::dumpBuffer(buffer_handle_t _Nonnull bufferHandle,
239 AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
240 void* _Null_unspecified context) {
241 if (bufferHandle == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
242 common::BufferDump out;
243 AIMapper_Error err = static_cast<AIMapper_Error>(common::dumpBuffer(bufferHandle, out));
244 for (auto metadump : out.metadataDump) {
245 dumpBufferCallback(context, static_cast<AIMapper_MetadataType>(metadump.metadataType),
246 static_cast<void*>((metadump.metadata).data()),
247 sizeof(metadump.metadata));
248 }
249 return AIMapper_Error::AIMAPPER_ERROR_NONE;
250 }
251
dumpAllBuffers(AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,void * _Null_unspecified context)252 AIMapper_Error GrallocMapper::dumpAllBuffers(
253 AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
254 AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback, void* _Null_unspecified context) {
255 std::vector<common::BufferDump> bufferDump = common::dumpBuffers();
256 for (auto dump : bufferDump) {
257 beginDumpBufferCallback(context);
258 for (auto metadump : dump.metadataDump) {
259 dumpBufferCallback(context, static_cast<AIMapper_MetadataType>(metadump.metadataType),
260 static_cast<void*>((metadump.metadata).data()),
261 sizeof(metadump.metadata));
262 }
263 }
264 return AIMapper_Error::AIMAPPER_ERROR_NONE;
265 }
266
getReservedRegion(buffer_handle_t _Nonnull buffer,void * _Nullable * _Nonnull outReservedRegion,uint64_t * _Nonnull outReservedSize)267 AIMapper_Error GrallocMapper::getReservedRegion(buffer_handle_t _Nonnull buffer,
268 void* _Nullable* _Nonnull outReservedRegion,
269 uint64_t* _Nonnull outReservedSize) {
270 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
271 uint64_t reservedSize = 0;
272 AIMapper_Error err = static_cast<AIMapper_Error>(
273 common::getReservedRegion(buffer, outReservedRegion, reservedSize));
274 *outReservedSize = reservedSize;
275 return err;
276 }
277
278 } // namespace mapper
279 } // namespace arm
280
281 extern "C" uint32_t ANDROID_HAL_MAPPER_VERSION = AIMAPPER_VERSION_5;
282
AIMapper_loadIMapper(AIMapper * _Nullable * _Nonnull outImplementation)283 extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
284 static vendor::mapper::IMapperProvider<arm::mapper::GrallocMapper> provider;
285 return provider.load(outImplementation);
286 }
287