1 /*
2 * Copyright (C) 2020 Samsung Electronics Co. Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "VendorGraphicBuffer"
18
19 #include <log/log.h>
20 #include <gralloctypes/Gralloc4.h>
21 #include <android/hardware/graphics/mapper/4.0/IMapper.h>
22
23 #include "VendorGraphicBuffer.h"
24 #include "mali_gralloc_buffer.h"
25 #include "mali_gralloc_formats.h"
26 #include "hidl_common/SharedMetadata.h"
27 #include "exynos_format.h"
28
29 using namespace android;
30 using namespace vendor::graphics;
31
32 using arm::mapper::common::shared_metadata;
33 using aidl::android::hardware::graphics::common::Dataspace;
34 using android::gralloc4::encodeDataspace;
35 using android::gralloc4::decodeDataspace;
36 using android::hardware::graphics::mapper::V4_0::IMapper;
37 using android::hardware::graphics::mapper::V4_0::Error;
38
39 #define UNUSED(x) ((void)x)
40 #define SZ_4k 0x1000
41
42 // TODO(b/191912915): This is a non-thread safe version of the validate function
43 // from mapper-4.0-impl library. Ideally this should be decoupled from `impl`
44 // libraries and should depend upon HAL (and it's extension) to call into
45 // Gralloc.
mali_gralloc_reference_validate(buffer_handle_t handle)46 int mali_gralloc_reference_validate(buffer_handle_t handle) {
47 auto hnd = static_cast<const private_handle_t *>(handle);
48
49 if (hnd->allocating_pid != getpid() && hnd->remote_pid != getpid()) {
50 return -EINVAL;
51 }
52
53 return 0;
54 }
55
convertNativeHandleToPrivateHandle(buffer_handle_t handle)56 const private_handle_t * convertNativeHandleToPrivateHandle(buffer_handle_t handle) {
57 if (mali_gralloc_reference_validate(handle) < 0)
58 return nullptr;
59
60 return static_cast<const private_handle_t *>(handle);
61 }
62
get_mapper()63 android::sp<IMapper> get_mapper() {
64 static android::sp<IMapper> mapper = []() {
65 auto mapper = IMapper::getService();
66 if (!mapper) {
67 ALOGE("Failed to get mapper service");
68 }
69 return mapper;
70 }();
71
72 return mapper;
73 }
74
get_video_metadata_fd(buffer_handle_t hnd)75 int VendorGraphicBufferMeta::get_video_metadata_fd(buffer_handle_t hnd)
76 {
77 const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
78
79 if (!gralloc_hnd)
80 return -EINVAL;
81
82 uint64_t usage = gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage;
83
84 if (usage & VendorGraphicBufferUsage::VIDEO_PRIVATE_DATA)
85 return gralloc_hnd->get_share_attr_fd();
86 else
87 return -EINVAL;
88 }
89
get_dataspace(buffer_handle_t hnd)90 int VendorGraphicBufferMeta::get_dataspace(buffer_handle_t hnd)
91 {
92 native_handle_t* handle = const_cast<native_handle_t*>(hnd);
93 if (!handle) {
94 return -EINVAL;
95 }
96
97 Error error = Error::NONE;
98 Dataspace dataspace;
99 get_mapper()->get(handle, android::gralloc4::MetadataType_Dataspace,
100 [&](const auto& tmpError, const android::hardware::hidl_vec<uint8_t>& tmpVec) {
101 error = tmpError;
102 if (error != Error::NONE) {
103 return;
104 }
105 error = static_cast<Error>(decodeDataspace(tmpVec, &dataspace));
106 });
107
108
109 if (error != Error::NONE) {
110 ALOGE("Failed to get datasapce");
111 return -EINVAL;
112 }
113
114 return static_cast<int>(dataspace);
115 }
116
set_dataspace(buffer_handle_t hnd,android_dataspace_t dataspace)117 int VendorGraphicBufferMeta::set_dataspace(buffer_handle_t hnd, android_dataspace_t dataspace)
118 {
119 native_handle_t* handle = const_cast<native_handle_t*>(hnd);
120 if (!handle) {
121 return -EINVAL;
122 }
123
124 Error error = Error::NONE;
125 android::hardware::hidl_vec<uint8_t> vec;
126 error = static_cast<Error>(encodeDataspace(static_cast<Dataspace>(dataspace), &vec));
127 if (error != Error::NONE) {
128 ALOGE("Error encoding dataspace");
129 return -EINVAL;
130 }
131 error = get_mapper()->set(handle, android::gralloc4::MetadataType_Dataspace, vec);
132
133 if (error != Error::NONE) {
134 ALOGE("Failed to set datasapce");
135 return -EINVAL;
136 }
137
138 return 0;
139 }
140
is_afbc(buffer_handle_t hnd)141 int VendorGraphicBufferMeta::is_afbc(buffer_handle_t hnd)
142 {
143 const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
144
145 if (!gralloc_hnd)
146 return 0;
147
148 if (gralloc_hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
149 return 1;
150
151 return 0;
152 }
153
is_sbwc(buffer_handle_t buffer_hnd_p)154 int VendorGraphicBufferMeta::is_sbwc(buffer_handle_t buffer_hnd_p)
155 {
156 const private_handle_t *hnd = static_cast<const private_handle_t *>(buffer_hnd_p);
157
158 return is_sbwc_format(static_cast<uint32_t>(hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK));
159 }
160
161 #define GRALLOC_META_GETTER(__type__, __name__, __member__) \
162 __type__ VendorGraphicBufferMeta::get_##__name__(buffer_handle_t hnd) \
163 { \
164 const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); \
165 if (!gralloc_hnd) return 0; \
166 return gralloc_hnd->__member__; \
167 } \
168
169
get_format(buffer_handle_t hnd)170 uint32_t VendorGraphicBufferMeta::get_format(buffer_handle_t hnd)
171 {
172 const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
173 if (!gralloc_hnd)
174 return 0;
175
176 return static_cast<uint32_t>(gralloc_hnd->alloc_format);
177 }
178
get_internal_format(buffer_handle_t hnd)179 uint64_t VendorGraphicBufferMeta::get_internal_format(buffer_handle_t hnd)
180 {
181 const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
182 if (!gralloc_hnd)
183 return 0;
184
185 return static_cast<uint64_t>(gralloc_hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
186 }
187
188 GRALLOC_META_GETTER(uint64_t, frameworkFormat, req_format);
189
190 GRALLOC_META_GETTER(int, width, width);
191 GRALLOC_META_GETTER(int, height, height);
192 GRALLOC_META_GETTER(uint32_t, stride, stride);
193 GRALLOC_META_GETTER(uint32_t, vstride, plane_info[0].alloc_height);
194
195 GRALLOC_META_GETTER(uint64_t, producer_usage, producer_usage);
196 GRALLOC_META_GETTER(uint64_t, consumer_usage, consumer_usage);
197
198 GRALLOC_META_GETTER(uint64_t, flags, flags);
199
200
get_fd(buffer_handle_t hnd,int num)201 int VendorGraphicBufferMeta::get_fd(buffer_handle_t hnd, int num)
202 {
203 const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
204
205 if (!gralloc_hnd)
206 return -1;
207
208 if (num > 2)
209 return -1;
210
211 return gralloc_hnd->fds[num];
212 }
213
get_size(buffer_handle_t hnd,int num)214 int VendorGraphicBufferMeta::get_size(buffer_handle_t hnd, int num)
215 {
216 const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
217
218 if (!gralloc_hnd)
219 return 0;
220
221 if (num > 2)
222 return 0;
223
224 return gralloc_hnd->alloc_sizes[num];
225 }
226
227
get_usage(buffer_handle_t hnd)228 uint64_t VendorGraphicBufferMeta::get_usage(buffer_handle_t hnd)
229 {
230 const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
231
232 if (!gralloc_hnd)
233 return 0;
234
235 return gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage;
236 }
237
get_video_metadata(buffer_handle_t hnd)238 void* VendorGraphicBufferMeta::get_video_metadata(buffer_handle_t hnd)
239 {
240 const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);
241
242 if (gralloc_hnd == nullptr)
243 return nullptr;
244
245 return gralloc_hnd->attr_base;
246 }
247
get_video_metadata_roiinfo(buffer_handle_t hnd)248 void* VendorGraphicBufferMeta::get_video_metadata_roiinfo(buffer_handle_t hnd)
249 {
250 const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);
251
252 if (gralloc_hnd == nullptr)
253 return nullptr;
254
255 if (gralloc_hnd->get_usage() & VendorGraphicBufferUsage::ROIINFO)
256 return static_cast<char*>(gralloc_hnd->attr_base) + SZ_4k * 2;
257
258 return nullptr;
259 }
260
init(const buffer_handle_t handle)261 void VendorGraphicBufferMeta::init(const buffer_handle_t handle)
262 {
263 const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(handle);
264
265 if (!gralloc_hnd)
266 return;
267
268 fd = gralloc_hnd->fds[0];
269 fd1 = gralloc_hnd->fds[1];
270 fd2 = gralloc_hnd->fds[2];
271
272 size = gralloc_hnd->alloc_sizes[0];
273 size1 = gralloc_hnd->alloc_sizes[1];
274 size2 = gralloc_hnd->alloc_sizes[2];
275
276 offsets[0] = gralloc_hnd->plane_info[0].offset;
277 offsets[1] = gralloc_hnd->plane_info[1].offset;
278 offsets[2] = gralloc_hnd->plane_info[2].offset;
279
280 uint64_t usage = gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage;
281 if (usage & VendorGraphicBufferUsage::VIDEO_PRIVATE_DATA) {
282 switch (gralloc_hnd->get_share_attr_fd_index()) {
283 case 1:
284 size1 = gralloc_hnd->attr_size;
285 break;
286 case 2:
287 size2 = gralloc_hnd->attr_size;
288 break;
289 }
290 }
291
292 internal_format = gralloc_hnd->alloc_format;
293 frameworkFormat = gralloc_hnd->req_format;
294
295 width = gralloc_hnd->width;
296 height = gralloc_hnd->height;
297 stride = gralloc_hnd->stride;
298 vstride = gralloc_hnd->plane_info[0].alloc_height;
299
300 producer_usage = gralloc_hnd->producer_usage;
301 consumer_usage = gralloc_hnd->consumer_usage;
302
303 flags = gralloc_hnd->flags;
304
305 unique_id = gralloc_hnd->backing_store_id;
306 }
307
import_buffer(buffer_handle_t hnd)308 buffer_handle_t VendorGraphicBufferMeta::import_buffer(buffer_handle_t hnd)
309 {
310 native_handle_t* handle = const_cast<native_handle_t*>(hnd);
311 if (!handle) {
312 return nullptr;
313 }
314
315 native_handle_t* bufferHandle = nullptr;
316 Error error = Error::NONE;
317 get_mapper()->importBuffer(handle, [&](const auto& tmpError, const auto& tmpBuffer) {
318 error = tmpError;
319 if (error != Error::NONE) {
320 return;
321 }
322 bufferHandle = static_cast<native_handle_t*>(tmpBuffer);
323 });
324
325 if (error != Error::NONE) {
326 ALOGE("[%s] Unable to import buffer", __FUNCTION__);
327 return nullptr;
328 }
329
330 return bufferHandle;
331 }
332
free_buffer(buffer_handle_t hnd)333 int VendorGraphicBufferMeta::free_buffer(buffer_handle_t hnd)
334 {
335 native_handle_t* handle = const_cast<native_handle_t*>(hnd);
336 if (!handle) {
337 return -EINVAL;
338 }
339 Error error = get_mapper()->freeBuffer(handle);
340 if (error != Error::NONE) {
341 ALOGE("[%s] Failed to free buffer", __FUNCTION__);
342 return -EINVAL;
343 }
344 return 0;
345 }
346
VendorGraphicBufferMeta(buffer_handle_t handle)347 VendorGraphicBufferMeta::VendorGraphicBufferMeta(buffer_handle_t handle)
348 {
349 init(handle);
350 }
351
352