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.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/MapperMetadata.h"
30 #include "hidl_common/SharedMetadata.h"
31 #include "hidl_common/hidl_common.h"
32
33 namespace arm {
34 namespace mapper {
35
36 using namespace android::hardware::graphics::mapper;
37 using PixelMetadataType = ::pixel::graphics::MetadataType;
38
39
importBuffer(const native_handle_t * _Nonnull handle,buffer_handle_t _Nullable * _Nonnull outBufferHandle)40 AIMapper_Error GrallocMapper::importBuffer(const native_handle_t* _Nonnull handle,
41 buffer_handle_t _Nullable* _Nonnull outBufferHandle) {
42 if (handle == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
43 AIMapper_Error err = static_cast<AIMapper_Error>(common::importBuffer(handle, outBufferHandle));
44 return err;
45 }
46
freeBuffer(buffer_handle_t _Nonnull buffer)47 AIMapper_Error GrallocMapper::freeBuffer(buffer_handle_t _Nonnull buffer) {
48 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
49 native_handle_t* bufferHandle = const_cast<native_handle_t*>(buffer);
50 return static_cast<AIMapper_Error>(common::freeBuffer(bufferHandle));
51 }
52
lock(buffer_handle_t _Nonnull buffer,uint64_t cpuUsage,ARect accessRegion,int acquireFence,void * _Nullable * _Nonnull outData)53 AIMapper_Error GrallocMapper::lock(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage,
54 ARect accessRegion, int acquireFence,
55 void* _Nullable* _Nonnull outData) {
56 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
57 AIMapper_Error err = static_cast<AIMapper_Error>(common::lock(buffer, cpuUsage,
58 common::GrallocRect(accessRegion),
59 acquireFence, outData));
60 return err;
61 }
62
unlock(buffer_handle_t _Nonnull buffer,int * _Nonnull releaseFence)63 AIMapper_Error GrallocMapper::unlock(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence) {
64 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
65
66 AIMapper_Error err = static_cast<AIMapper_Error>(common::unlock(buffer, releaseFence));
67 return err;
68 }
69
flushLockedBuffer(buffer_handle_t _Nonnull buffer)70 AIMapper_Error GrallocMapper::flushLockedBuffer(buffer_handle_t _Nonnull buffer) {
71 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
72
73 AIMapper_Error err = static_cast<AIMapper_Error>(common::flushLockedBuffer(buffer));
74 return err;
75 }
76
rereadLockedBuffer(buffer_handle_t _Nonnull buffer)77 AIMapper_Error GrallocMapper::rereadLockedBuffer(buffer_handle_t _Nonnull buffer) {
78 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
79 return static_cast<AIMapper_Error>(common::rereadLockedBuffer(buffer));
80 }
81
82
83 // TODO(b/315854439): getStandardMetadataHelper should be in the common code.
84 template <typename F, StandardMetadataType metadataType>
getStandardMetadataHelper(const private_handle_t * hnd,F && provide,StandardMetadata<metadataType>)85 int32_t getStandardMetadataHelper(const private_handle_t* hnd, F&& provide,
86 StandardMetadata<metadataType>) {
87 if constexpr (metadataType == StandardMetadataType::BUFFER_ID) {
88 return provide(hnd->backing_store_id);
89 }
90 if constexpr (metadataType == StandardMetadataType::WIDTH) {
91 return provide(hnd->width);
92 }
93 if constexpr (metadataType == StandardMetadataType::HEIGHT) {
94 return provide(hnd->height);
95 }
96 if constexpr (metadataType == StandardMetadataType::LAYER_COUNT) {
97 return provide(hnd->layer_count);
98 }
99 if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_REQUESTED) {
100 return provide(static_cast<PixelFormat>(hnd->req_format));
101 }
102 if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_FOURCC) {
103 return provide(drm_fourcc_from_handle(hnd));
104 }
105 if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_MODIFIER) {
106 return provide(drm_modifier_from_handle(hnd));
107 }
108 if constexpr (metadataType == StandardMetadataType::USAGE) {
109 return provide(static_cast<BufferUsage>(hnd->consumer_usage | hnd->producer_usage));
110 }
111 if constexpr (metadataType == StandardMetadataType::ALLOCATION_SIZE) {
112 uint64_t total_size = 0;
113 for (int fidx = 0; fidx < hnd->fd_count; fidx++) {
114 total_size += hnd->alloc_sizes[fidx];
115 }
116 return provide(total_size);
117 }
118 if constexpr (metadataType == StandardMetadataType::PROTECTED_CONTENT) {
119 return provide((((hnd->consumer_usage | hnd->producer_usage) &
120 static_cast<uint64_t>(BufferUsage::PROTECTED)) == 0)
121 ? 0
122 : 1);
123 }
124 if constexpr (metadataType == StandardMetadataType::COMPRESSION) {
125 ExtendableType compression = android::gralloc4::Compression_None;
126 if (hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
127 compression = common::Compression_AFBC;
128 return provide(compression);
129 }
130 if constexpr (metadataType == StandardMetadataType::INTERLACED) {
131 return provide(android::gralloc4::Interlaced_None);
132 }
133 if constexpr (metadataType == StandardMetadataType::CHROMA_SITING) {
134 ExtendableType siting = android::gralloc4::ChromaSiting_None;
135 int format_index = get_format_index(hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
136 if (formats[format_index].is_yuv) siting = android::gralloc4::ChromaSiting_Unknown;
137 return provide(siting);
138 }
139 if constexpr (metadataType == StandardMetadataType::PLANE_LAYOUTS) {
140 std::vector<PlaneLayout> layouts;
141 Error err = static_cast<Error>(common::get_plane_layouts(hnd, &layouts));
142 return provide(layouts);
143 }
144 if constexpr (metadataType == StandardMetadataType::NAME) {
145 std::string name;
146 common::get_name(hnd, &name);
147 return provide(name);
148 }
149 if constexpr (metadataType == StandardMetadataType::CROP) {
150 const int num_planes = common::get_num_planes(hnd);
151 std::vector<Rect> crops(num_planes);
152 for (size_t plane_index = 0; plane_index < num_planes; ++plane_index) {
153 Rect rect = {.top = 0,
154 .left = 0,
155 .right = static_cast<int32_t>(hnd->plane_info[plane_index].alloc_width),
156 .bottom = static_cast<int32_t>(hnd->plane_info[plane_index].alloc_height)};
157 if (plane_index == 0) {
158 std::optional<Rect> crop_rect;
159 common::get_crop_rect(hnd, &crop_rect);
160 if (crop_rect.has_value()) {
161 rect = crop_rect.value();
162 } else {
163 rect = {.top = 0, .left = 0, .right = hnd->width, .bottom = hnd->height};
164 }
165 }
166 crops[plane_index] = rect;
167 }
168 return provide(crops);
169 }
170 if constexpr (metadataType == StandardMetadataType::DATASPACE) {
171 std::optional<Dataspace> dataspace;
172 common::get_dataspace(hnd, &dataspace);
173 return provide(dataspace.value_or(Dataspace::UNKNOWN));
174 }
175 if constexpr (metadataType == StandardMetadataType::BLEND_MODE) {
176 std::optional<BlendMode> blendmode;
177 common::get_blend_mode(hnd, &blendmode);
178 return provide(blendmode.value_or(BlendMode::INVALID));
179 }
180 if constexpr (metadataType == StandardMetadataType::SMPTE2086) {
181 std::optional<Smpte2086> smpte2086;
182 common::get_smpte2086(hnd, &smpte2086);
183 return provide(smpte2086);
184 }
185 if constexpr (metadataType == StandardMetadataType::CTA861_3) {
186 std::optional<Cta861_3> cta861_3;
187 common::get_cta861_3(hnd, &cta861_3);
188 return provide(cta861_3);
189 }
190 if constexpr (metadataType == StandardMetadataType::SMPTE2094_40) {
191 std::optional<std::vector<uint8_t>> smpte2094_40;
192 common::get_smpte2094_40(hnd, &smpte2094_40);
193 return provide(smpte2094_40);
194 }
195 if constexpr (metadataType == StandardMetadataType::STRIDE) {
196 std::vector<PlaneLayout> layouts;
197 Error err = static_cast<Error>(common::get_plane_layouts(hnd, &layouts));
198 uint64_t stride = 0;
199 switch (hnd->get_alloc_format())
200 {
201 case HAL_PIXEL_FORMAT_RAW10:
202 case HAL_PIXEL_FORMAT_RAW12:
203 stride = layouts[0].strideInBytes;
204 break;
205 default:
206 stride = (layouts[0].strideInBytes * 8) / layouts[0].sampleIncrementInBits;
207 break;
208 }
209 return provide(stride);
210 }
211 return -AIMapper_Error::AIMAPPER_ERROR_UNSUPPORTED;
212 }
213
getStandardMetadata(buffer_handle_t _Nonnull buffer,int64_t standardMetadataType,void * _Nonnull outData,size_t outDataSize)214 int32_t GrallocMapper::getStandardMetadata(buffer_handle_t _Nonnull buffer,
215 int64_t standardMetadataType, void* _Nonnull outData,
216 size_t outDataSize) {
217 if (buffer == nullptr) return -AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
218
219 auto provider = [&]<StandardMetadataType meta>(auto&& provide) -> int32_t {
220 return getStandardMetadataHelper(static_cast<const private_handle_t*>(buffer), provide,
221 StandardMetadata<meta>{});
222 };
223 return provideStandardMetadata(static_cast<StandardMetadataType>(standardMetadataType), outData,
224 outDataSize, provider);
225 }
226
isPixelMetadataType(common::MetadataType meta)227 bool isPixelMetadataType(common::MetadataType meta) {
228 return (meta.name == ::pixel::graphics::kPixelMetadataTypeName);
229 }
230
getPixelMetadataHelper(buffer_handle_t handle,const PixelMetadataType meta,void * outData,size_t outDataSize)231 int32_t getPixelMetadataHelper(buffer_handle_t handle, const PixelMetadataType meta, void* outData,
232 size_t outDataSize) {
233 switch (meta) {
234 case PixelMetadataType::VIDEO_HDR: {
235 auto result = ::pixel::graphics::utils::encode(
236 common::get_video_hdr(static_cast<const private_handle_t*>(handle)));
237
238 if (result.size() <= outDataSize)
239 std::memcpy(outData, result.data(), result.size());
240 return result.size();
241 }
242 case PixelMetadataType::VIDEO_ROI: {
243 auto result = ::pixel::graphics::utils::encode(
244 common::get_video_roiinfo(static_cast<const private_handle_t*>(handle)));
245 if (result.size() <= outDataSize)
246 std::memcpy(outData, result.data(), result.size());
247 return result.size();
248 }
249 case PixelMetadataType::VIDEO_GMV: {
250 auto result = ::pixel::graphics::utils::encode(
251 common::get_video_gmv(static_cast<const private_handle_t*>(handle)));
252 if (result.size() <= outDataSize) std::memcpy(outData, result.data(), result.size());
253 return result.size();
254 }
255
256 default:
257 return -AIMapper_Error::AIMAPPER_ERROR_BAD_VALUE;
258 }
259 }
260
getMetadata(buffer_handle_t _Nonnull buffer,AIMapper_MetadataType metadataType,void * _Nonnull outData,size_t outDataSize)261 int32_t GrallocMapper::getMetadata(buffer_handle_t _Nonnull buffer,
262 AIMapper_MetadataType metadataType, void* _Nonnull outData,
263 size_t outDataSize) {
264 if (buffer == nullptr) return -AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
265
266 if (isStandardMetadataType(common::MetadataType(metadataType))) {
267 return getStandardMetadata(buffer, metadataType.value, outData, outDataSize);
268 } else if (isPixelMetadataType(common::MetadataType(metadataType))) {
269 const PixelMetadataType pixelMeta = static_cast<PixelMetadataType>(metadataType.value);
270 return getPixelMetadataHelper(buffer, pixelMeta, outData, outDataSize);
271 } else {
272 return -AIMapper_Error::AIMAPPER_ERROR_UNSUPPORTED;
273 }
274 }
275
276 template <StandardMetadataType TYPE>
setStandardMetadataHelper(const private_handle_t * hnd,typename StandardMetadata<TYPE>::value_type && value)277 AIMapper_Error setStandardMetadataHelper(const private_handle_t* hnd,
278 typename StandardMetadata<TYPE>::value_type&& value) {
279 if constexpr (TYPE == StandardMetadataType::DATASPACE) {
280 common::set_dataspace(hnd, value);
281 }
282 if constexpr (TYPE == StandardMetadataType::CROP) {
283 common::set_crop_rect(hnd, value[0]);
284 }
285 if constexpr (TYPE == StandardMetadataType::BLEND_MODE) {
286 common::set_blend_mode(hnd, value);
287 }
288 if constexpr (TYPE == StandardMetadataType::SMPTE2086) {
289 common::set_smpte2086(hnd, value);
290 }
291 if constexpr (TYPE == StandardMetadataType::CTA861_3) {
292 common::set_cta861_3(hnd, value);
293 }
294 if constexpr (TYPE == StandardMetadataType::SMPTE2094_40) {
295 common::set_smpte2094_40(hnd, value);
296 }
297 return AIMapper_Error::AIMAPPER_ERROR_NONE;
298 }
299
setStandardMetadata(buffer_handle_t _Nonnull bufferHandle,int64_t standardTypeRaw,const void * _Nonnull metadata,size_t metadataSize)300 AIMapper_Error GrallocMapper::setStandardMetadata(buffer_handle_t _Nonnull bufferHandle,
301 int64_t standardTypeRaw,
302 const void* _Nonnull metadata,
303 size_t metadataSize) {
304 if (bufferHandle == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
305 auto standardMeta = static_cast<StandardMetadataType>(standardTypeRaw);
306 switch (standardMeta) {
307 // Read-only values
308 case StandardMetadataType::BUFFER_ID:
309 case StandardMetadataType::NAME:
310 case StandardMetadataType::WIDTH:
311 case StandardMetadataType::HEIGHT:
312 case StandardMetadataType::LAYER_COUNT:
313 case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
314 case StandardMetadataType::USAGE:
315 return AIMAPPER_ERROR_BAD_VALUE;
316
317 // Supported to set
318 case StandardMetadataType::BLEND_MODE:
319 case StandardMetadataType::CTA861_3:
320 case StandardMetadataType::DATASPACE:
321 case StandardMetadataType::SMPTE2086:
322 case StandardMetadataType::SMPTE2094_40:
323 case StandardMetadataType::CROP:
324 break;
325
326 // Everything else unsupported
327 default:
328 return AIMAPPER_ERROR_UNSUPPORTED;
329 }
330
331 auto applier = [&]<StandardMetadataType meta>(auto&& value) -> AIMapper_Error {
332 return setStandardMetadataHelper<meta>(static_cast<const private_handle_t*>(bufferHandle),
333 std::forward<decltype(value)>(value));
334 };
335
336 return applyStandardMetadata(standardMeta, metadata, metadataSize, applier);
337 }
338
setPixelMetadata(buffer_handle_t handle,const PixelMetadataType meta,const void * metadata,size_t metadataSize)339 AIMapper_Error setPixelMetadata(buffer_handle_t handle, const PixelMetadataType meta,
340 const void* metadata, size_t metadataSize) {
341 if (meta == PixelMetadataType::VIDEO_GMV) {
342 std::vector<uint8_t> in_data(metadataSize);
343 std::memcpy(in_data.data(), metadata, metadataSize);
344 auto gmv = ::pixel::graphics::utils::decode<common::VideoGMV>(in_data);
345 if (!gmv.has_value()) return AIMapper_Error::AIMAPPER_ERROR_BAD_VALUE;
346 auto result =
347 common::set_video_gmv(static_cast<const private_handle_t*>(handle), gmv.value());
348 if (result == android::OK) return AIMapper_Error::AIMAPPER_ERROR_NONE;
349 }
350 return AIMapper_Error::AIMAPPER_ERROR_BAD_VALUE;
351 }
352
setMetadata(buffer_handle_t _Nonnull buffer,AIMapper_MetadataType metadataType,const void * _Nonnull metadata,size_t metadataSize)353 AIMapper_Error GrallocMapper::setMetadata(buffer_handle_t _Nonnull buffer,
354 AIMapper_MetadataType metadataType,
355 const void* _Nonnull metadata, size_t metadataSize) {
356 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
357 if (isStandardMetadataType(common::MetadataType(metadataType))) {
358 return setStandardMetadata(buffer, metadataType.value, metadata, metadataSize);
359 } else if (isPixelMetadataType(common::MetadataType(metadataType))) {
360 const PixelMetadataType pixelMeta = static_cast<PixelMetadataType>(metadataType.value);
361 return setPixelMetadata(buffer, pixelMeta, metadata, metadataSize);
362 } else
363 return AIMapper_Error::AIMAPPER_ERROR_NONE;
364 }
365
getTransportSize(buffer_handle_t _Nonnull buffer,uint32_t * _Nonnull outNumFds,uint32_t * _Nonnull outNumInts)366 AIMapper_Error GrallocMapper::getTransportSize(buffer_handle_t _Nonnull buffer,
367 uint32_t* _Nonnull outNumFds,
368 uint32_t* _Nonnull outNumInts) {
369 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
370 AIMapper_Error err =
371 static_cast<AIMapper_Error>(common::getTransportSize(buffer, outNumFds, outNumInts));
372 return err;
373 }
374
listSupportedMetadataTypes(const AIMapper_MetadataTypeDescription * _Nullable * _Nonnull outDescriptionList,size_t * _Nonnull outNumberOfDescriptions)375 AIMapper_Error GrallocMapper::listSupportedMetadataTypes(
376 const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
377 size_t* _Nonnull outNumberOfDescriptions) {
378 std::vector<common::MetadataTypeDescription> desc = common::listSupportedMetadataTypes();
379 std::vector<AIMapper_MetadataTypeDescription> outDesc;
380 for (auto x : desc) {
381 outDesc.push_back(static_cast<AIMapper_MetadataTypeDescription>(x));
382 }
383
384 *outDescriptionList = outDesc.data();
385 *outNumberOfDescriptions = outDesc.size();
386 return AIMapper_Error::AIMAPPER_ERROR_NONE;
387 }
388
dumpBuffer(buffer_handle_t _Nonnull bufferHandle,AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,void * _Null_unspecified context)389 AIMapper_Error GrallocMapper::dumpBuffer(buffer_handle_t _Nonnull bufferHandle,
390 AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
391 void* _Null_unspecified context) {
392 if (bufferHandle == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
393 common::BufferDump out;
394 AIMapper_Error err = static_cast<AIMapper_Error>(common::dumpBuffer(bufferHandle, out));
395 for (auto metadump : out.metadataDump) {
396 dumpBufferCallback(context, static_cast<AIMapper_MetadataType>(metadump.metadataType),
397 static_cast<void*>((metadump.metadata).data()),
398 sizeof(metadump.metadata));
399 }
400 return AIMapper_Error::AIMAPPER_ERROR_NONE;
401 }
402
dumpAllBuffers(AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,void * _Null_unspecified context)403 AIMapper_Error GrallocMapper::dumpAllBuffers(
404 AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
405 AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback, void* _Null_unspecified context) {
406 std::vector<common::BufferDump> bufferDump = common::dumpBuffers();
407 for (auto dump : bufferDump) {
408 beginDumpBufferCallback(context);
409 for (auto metadump : dump.metadataDump) {
410 dumpBufferCallback(context, static_cast<AIMapper_MetadataType>(metadump.metadataType),
411 static_cast<void*>((metadump.metadata).data()),
412 sizeof(metadump.metadata));
413 }
414 }
415 return AIMapper_Error::AIMAPPER_ERROR_NONE;
416 }
417
getReservedRegion(buffer_handle_t _Nonnull buffer,void * _Nullable * _Nonnull outReservedRegion,uint64_t * _Nonnull outReservedSize)418 AIMapper_Error GrallocMapper::getReservedRegion(buffer_handle_t _Nonnull buffer,
419 void* _Nullable* _Nonnull outReservedRegion,
420 uint64_t* _Nonnull outReservedSize) {
421 if (buffer == nullptr) return AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
422 uint64_t reservedSize = 0;
423 AIMapper_Error err = static_cast<AIMapper_Error>(
424 common::getReservedRegion(buffer, outReservedRegion, reservedSize));
425 *outReservedSize = reservedSize;
426 return err;
427 }
428
429 } // namespace mapper
430 } // namespace arm
431
432 extern "C" uint32_t ANDROID_HAL_MAPPER_VERSION = AIMAPPER_VERSION_5;
433
AIMapper_loadIMapper(AIMapper * _Nullable * _Nonnull outImplementation)434 extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
435 static vendor::mapper::IMapperProvider<arm::mapper::GrallocMapper> provider;
436 return provider.load(outImplementation);
437 }
438