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