xref: /aosp_15_r20/external/mesa3d/src/util/u_gralloc/u_gralloc_imapper4_api.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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