1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2021 GlobalLogic Ukraine
5 * Copyright (C) 2021-2022 Roman Stratiienko ([email protected])
6 * SPDX-License-Identifier: MIT
7 */
8
9 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
10 #include <aidl/android/hardware/graphics/common/ChromaSiting.h>
11 #include <aidl/android/hardware/graphics/common/Dataspace.h>
12 #include <aidl/android/hardware/graphics/common/ExtendableType.h>
13 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h>
14 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
15 #include <gralloctypes/Gralloc4.h>
16 #include <system/window.h>
17
18 #include "util/log.h"
19 #include "u_gralloc_internal.h"
20
21 using aidl::android::hardware::graphics::common::BufferUsage;
22 using aidl::android::hardware::graphics::common::ChromaSiting;
23 using aidl::android::hardware::graphics::common::Dataspace;
24 using aidl::android::hardware::graphics::common::ExtendableType;
25 using aidl::android::hardware::graphics::common::PlaneLayout;
26 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
27 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
28 using android::hardware::hidl_handle;
29 using android::hardware::hidl_vec;
30 using android::hardware::graphics::mapper::V4_0::Error;
31 using android::hardware::graphics::mapper::V4_0::IMapper;
32
33 using MetadataType =
34 android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
35
36 Error
GetMetadata(android::sp<IMapper> mapper,const native_handle_t * buffer,MetadataType type,hidl_vec<uint8_t> * metadata)37 GetMetadata(android::sp<IMapper> mapper, const native_handle_t *buffer,
38 MetadataType type, hidl_vec<uint8_t> *metadata)
39 {
40 Error error = Error::NONE;
41
42 auto native_handle = const_cast<native_handle_t *>(buffer);
43
44 auto ret =
45 mapper->get(native_handle, type,
46 [&](const auto &get_error, const auto &get_metadata) {
47 error = get_error;
48 *metadata = get_metadata;
49 });
50
51 if (!ret.isOk())
52 error = Error::NO_RESOURCES;
53
54 return error;
55 }
56
57 std::optional<std::vector<PlaneLayout>>
GetPlaneLayouts(android::sp<IMapper> mapper,const native_handle_t * buffer)58 GetPlaneLayouts(android::sp<IMapper> mapper, const native_handle_t *buffer)
59 {
60 hidl_vec<uint8_t> encoded_layouts;
61
62 Error error = GetMetadata(mapper, buffer,
63 android::gralloc4::MetadataType_PlaneLayouts,
64 &encoded_layouts);
65
66 if (error != Error::NONE)
67 return std::nullopt;
68
69 std::vector<PlaneLayout> plane_layouts;
70
71 auto status =
72 android::gralloc4::decodePlaneLayouts(encoded_layouts, &plane_layouts);
73
74 if (status != android::OK)
75 return std::nullopt;
76
77 return plane_layouts;
78 }
79
80 struct gralloc4 {
81 struct u_gralloc base;
82 android::sp<IMapper> mapper;
83 };
84
85 extern "C" {
86
87 static int
mapper4_get_buffer_basic_info(struct u_gralloc * gralloc,struct u_gralloc_buffer_handle * hnd,struct u_gralloc_buffer_basic_info * out)88 mapper4_get_buffer_basic_info(struct u_gralloc *gralloc,
89 struct u_gralloc_buffer_handle *hnd,
90 struct u_gralloc_buffer_basic_info *out)
91 {
92 gralloc4 *gr4 = (gralloc4 *)gralloc;
93
94 if (gr4->mapper == nullptr)
95 return -EINVAL;
96
97 if (!hnd->handle)
98 return -EINVAL;
99
100 hidl_vec<uint8_t> encoded_format;
101 auto err = GetMetadata(gr4->mapper, hnd->handle,
102 android::gralloc4::MetadataType_PixelFormatFourCC,
103 &encoded_format);
104 if (err != Error::NONE)
105 return -EINVAL;
106
107 uint32_t drm_fourcc;
108
109 auto status =
110 android::gralloc4::decodePixelFormatFourCC(encoded_format, &drm_fourcc);
111 if (status != android::OK)
112 return -EINVAL;
113
114 uint64_t drm_modifier;
115
116 hidl_vec<uint8_t> encoded_modifier;
117 err = GetMetadata(gr4->mapper, hnd->handle,
118 android::gralloc4::MetadataType_PixelFormatModifier,
119 &encoded_modifier);
120 if (err != Error::NONE)
121 return -EINVAL;
122
123 status = android::gralloc4::decodePixelFormatModifier(encoded_modifier,
124 &drm_modifier);
125 if (status != android::OK)
126 return -EINVAL;
127
128 out->drm_fourcc = drm_fourcc;
129 out->modifier = drm_modifier;
130
131 auto layouts_opt = GetPlaneLayouts(gr4->mapper, hnd->handle);
132
133 if (!layouts_opt)
134 return -EINVAL;
135
136 std::vector<PlaneLayout> &layouts = *layouts_opt;
137
138 out->num_planes = layouts.size();
139
140 int fd_index = 0;
141
142 for (uint32_t i = 0; i < layouts.size(); i++) {
143 out->strides[i] = layouts[i].strideInBytes;
144 out->offsets[i] = layouts[i].offsetInBytes;
145
146 /* offset == 0 means layer is located in different dma-buf */
147 if (out->offsets[i] == 0 && i > 0)
148 fd_index++;
149
150 if (fd_index >= hnd->handle->numFds)
151 return -EINVAL;
152
153 out->fds[i] = hnd->handle->data[fd_index];
154 }
155
156 return 0;
157 }
158
159 static int
mapper4_get_buffer_color_info(struct u_gralloc * gralloc,struct u_gralloc_buffer_handle * hnd,struct u_gralloc_buffer_color_info * out)160 mapper4_get_buffer_color_info(struct u_gralloc *gralloc,
161 struct u_gralloc_buffer_handle *hnd,
162 struct u_gralloc_buffer_color_info *out)
163 {
164 gralloc4 *gr4 = (gralloc4 *)gralloc;
165
166 if (gr4->mapper == nullptr)
167 return -EINVAL;
168
169 if (!hnd->handle)
170 return -EINVAL;
171
172 /* optional attributes */
173 hidl_vec<uint8_t> encoded_chroma_siting;
174 std::optional<ChromaSiting> chroma_siting;
175 auto err = GetMetadata(gr4->mapper, hnd->handle,
176 android::gralloc4::MetadataType_ChromaSiting,
177 &encoded_chroma_siting);
178 if (err == Error::NONE) {
179 ExtendableType chroma_siting_ext;
180 auto status = android::gralloc4::decodeChromaSiting(
181 encoded_chroma_siting, &chroma_siting_ext);
182 if (status != android::OK)
183 return -EINVAL;
184
185 chroma_siting =
186 android::gralloc4::getStandardChromaSitingValue(chroma_siting_ext);
187 }
188
189 hidl_vec<uint8_t> encoded_dataspace;
190 err = GetMetadata(gr4->mapper, hnd->handle,
191 android::gralloc4::MetadataType_Dataspace,
192 &encoded_dataspace);
193 if (err == Error::NONE) {
194 Dataspace dataspace;
195 auto status =
196 android::gralloc4::decodeDataspace(encoded_dataspace, &dataspace);
197 if (status != android::OK)
198 return -EINVAL;
199
200 Dataspace standard =
201 (Dataspace)((int)dataspace & (uint32_t)Dataspace::STANDARD_MASK);
202 switch (standard) {
203 case Dataspace::STANDARD_BT709:
204 out->yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC709;
205 break;
206 case Dataspace::STANDARD_BT601_625:
207 case Dataspace::STANDARD_BT601_625_UNADJUSTED:
208 case Dataspace::STANDARD_BT601_525:
209 case Dataspace::STANDARD_BT601_525_UNADJUSTED:
210 out->yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC601;
211 break;
212 case Dataspace::STANDARD_BT2020:
213 case Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE:
214 out->yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC2020;
215 break;
216 default:
217 break;
218 }
219
220 Dataspace range =
221 (Dataspace)((int)dataspace & (uint32_t)Dataspace::RANGE_MASK);
222 switch (range) {
223 case Dataspace::RANGE_FULL:
224 out->sample_range = __DRI_YUV_FULL_RANGE;
225 break;
226 case Dataspace::RANGE_LIMITED:
227 out->sample_range = __DRI_YUV_NARROW_RANGE;
228 break;
229 default:
230 break;
231 }
232 }
233
234 if (chroma_siting) {
235 switch (*chroma_siting) {
236 case ChromaSiting::SITED_INTERSTITIAL:
237 out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0_5;
238 out->vertical_siting = __DRI_YUV_CHROMA_SITING_0_5;
239 break;
240 case ChromaSiting::COSITED_HORIZONTAL:
241 out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0;
242 out->vertical_siting = __DRI_YUV_CHROMA_SITING_0_5;
243 break;
244 default:
245 break;
246 }
247 }
248
249 return 0;
250 }
251
252 static int
mapper4_get_front_rendering_usage(struct u_gralloc * gralloc,uint64_t * out_usage)253 mapper4_get_front_rendering_usage(struct u_gralloc *gralloc,
254 uint64_t *out_usage)
255 {
256 assert(out_usage);
257 #if ANDROID_API_LEVEL >= 33
258 *out_usage = static_cast<uint64_t>(BufferUsage::FRONT_BUFFER);
259
260 return 0;
261 #else
262 return -ENOTSUP;
263 #endif
264 }
265
266 static int
destroy(struct u_gralloc * gralloc)267 destroy(struct u_gralloc *gralloc)
268 {
269 gralloc4 *gr = (struct gralloc4 *)gralloc;
270 delete gr;
271
272 return 0;
273 }
274
275 struct u_gralloc *
u_gralloc_imapper_api_create()276 u_gralloc_imapper_api_create()
277 {
278 auto mapper = IMapper::getService();
279 if (!mapper)
280 return NULL;
281
282 auto gr = new gralloc4;
283 gr->mapper = mapper;
284 gr->base.ops.get_buffer_basic_info = mapper4_get_buffer_basic_info;
285 gr->base.ops.get_buffer_color_info = mapper4_get_buffer_color_info;
286 gr->base.ops.get_front_rendering_usage = mapper4_get_front_rendering_usage;
287 gr->base.ops.destroy = destroy;
288
289 mesa_logi("Using IMapper v4 API");
290
291 return &gr->base;
292 }
293
294 } // extern "C"
295