• 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  * 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