1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2021 GlobalLogic Ukraine
5 * Copyright (C) 2021-2022 Roman Stratiienko (r.stratiienko@gmail.com)
6 * SPDX-License-Identifier: MIT
7 */
8 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
9 #include <aidl/android/hardware/graphics/common/ChromaSiting.h>
10 #include <aidl/android/hardware/graphics/common/Dataspace.h>
11 #include <aidl/android/hardware/graphics/common/ExtendableType.h>
12 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h>
13 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
14 #include <ui/GraphicBufferMapper.h>
15
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::ExtendableType;
24 using aidl::android::hardware::graphics::common::PlaneLayout;
25 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
26 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
27 using android::hardware::graphics::common::V1_2::Dataspace;
28 using android::GraphicBufferMapper;
29 using android::OK;
30 using android::status_t;
31
32 std::optional<std::vector<PlaneLayout>>
GetPlaneLayouts(const native_handle_t * buffer)33 GetPlaneLayouts(const native_handle_t *buffer)
34 {
35 std::vector<PlaneLayout> plane_layouts;
36 status_t error = GraphicBufferMapper::get().getPlaneLayouts(buffer, &plane_layouts);
37
38 if (error != OK)
39 return std::nullopt;
40
41 return plane_layouts;
42 }
43
44 struct gralloc_mapper {
45 struct u_gralloc base;
46 };
47
48 extern "C" {
49
50 static int
mapper5_get_buffer_basic_info(struct u_gralloc * gralloc,struct u_gralloc_buffer_handle * hnd,struct u_gralloc_buffer_basic_info * out)51 mapper5_get_buffer_basic_info(struct u_gralloc *gralloc,
52 struct u_gralloc_buffer_handle *hnd,
53 struct u_gralloc_buffer_basic_info *out)
54 {
55 if (!hnd->handle)
56 return -EINVAL;
57
58 uint32_t drm_fourcc;
59 status_t error = GraphicBufferMapper::get().getPixelFormatFourCC(hnd->handle, &drm_fourcc);
60 if (error != OK)
61 return -EINVAL;
62
63 uint64_t modifier;
64 error = GraphicBufferMapper::get().getPixelFormatModifier(hnd->handle,&modifier);
65 if (error != OK)
66 return -EINVAL;
67
68
69 out->drm_fourcc = drm_fourcc;
70 out->modifier = modifier;
71
72 auto layouts_opt = GetPlaneLayouts(hnd->handle);
73
74 if (!layouts_opt)
75 return -EINVAL;
76
77 std::vector<PlaneLayout> &layouts = *layouts_opt;
78
79 out->num_planes = layouts.size();
80
81 int fd_index = 0;
82
83 for (uint32_t i = 0; i < layouts.size(); i++) {
84 out->strides[i] = layouts[i].strideInBytes;
85 out->offsets[i] = layouts[i].offsetInBytes;
86
87 /* offset == 0 means layer is located in different dma-buf */
88 if (out->offsets[i] == 0 && i > 0)
89 fd_index++;
90
91 if (fd_index >= hnd->handle->numFds)
92 return -EINVAL;
93
94 out->fds[i] = hnd->handle->data[fd_index];
95 }
96
97 return 0;
98 }
99
100 static int
mapper5_get_buffer_color_info(struct u_gralloc * gralloc,struct u_gralloc_buffer_handle * hnd,struct u_gralloc_buffer_color_info * out)101 mapper5_get_buffer_color_info(struct u_gralloc *gralloc,
102 struct u_gralloc_buffer_handle *hnd,
103 struct u_gralloc_buffer_color_info *out)
104 {
105 if (!hnd->handle)
106 return -EINVAL;
107
108 /* optional attributes */
109 ChromaSiting chroma_siting;
110 status_t error = GraphicBufferMapper::get().getChromaSiting(hnd->handle, &chroma_siting);
111 if (error != OK)
112 return -EINVAL;
113
114 Dataspace dataspace;
115 error = GraphicBufferMapper::get().getDataspace(hnd->handle, &dataspace);
116 if (error != OK)
117 return -EINVAL;
118
119 Dataspace standard =
120 (Dataspace)((int)dataspace & (uint32_t)Dataspace::STANDARD_MASK);
121 switch (standard) {
122 case Dataspace::STANDARD_BT709:
123 out->yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC709;
124 break;
125 case Dataspace::STANDARD_BT601_625:
126 case Dataspace::STANDARD_BT601_625_UNADJUSTED:
127 case Dataspace::STANDARD_BT601_525:
128 case Dataspace::STANDARD_BT601_525_UNADJUSTED:
129 out->yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC601;
130 break;
131 case Dataspace::STANDARD_BT2020:
132 case Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE:
133 out->yuv_color_space = __DRI_YUV_COLOR_SPACE_ITU_REC2020;
134 break;
135 default:
136 break;
137 }
138
139 Dataspace range =
140 (Dataspace)((int)dataspace & (uint32_t)Dataspace::RANGE_MASK);
141 switch (range) {
142 case Dataspace::RANGE_FULL:
143 out->sample_range = __DRI_YUV_FULL_RANGE;
144 break;
145 case Dataspace::RANGE_LIMITED:
146 out->sample_range = __DRI_YUV_NARROW_RANGE;
147 break;
148 default:
149 break;
150 }
151
152 switch (chroma_siting) {
153 case ChromaSiting::SITED_INTERSTITIAL:
154 out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0_5;
155 out->vertical_siting = __DRI_YUV_CHROMA_SITING_0_5;
156 break;
157 case ChromaSiting::COSITED_HORIZONTAL:
158 out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0;
159 out->vertical_siting = __DRI_YUV_CHROMA_SITING_0_5;
160 break;
161 case ChromaSiting::COSITED_VERTICAL:
162 out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0_5;
163 out->vertical_siting = __DRI_YUV_CHROMA_SITING_0;
164 break;
165 case ChromaSiting::COSITED_BOTH:
166 out->horizontal_siting = __DRI_YUV_CHROMA_SITING_0;
167 out->vertical_siting = __DRI_YUV_CHROMA_SITING_0;
168 break;
169 default:
170 break;
171 }
172
173 return 0;
174 }
175
176 static int
mapper5_get_front_rendering_usage(struct u_gralloc * gralloc,uint64_t * out_usage)177 mapper5_get_front_rendering_usage(struct u_gralloc *gralloc,
178 uint64_t *out_usage)
179 {
180 assert(out_usage);
181 #if ANDROID_API_LEVEL >= 33
182 *out_usage = static_cast<uint64_t>(BufferUsage::FRONT_BUFFER);
183
184 return 0;
185 #else
186 return -ENOTSUP;
187 #endif
188 }
189
190 static int
destroy(struct u_gralloc * gralloc)191 destroy(struct u_gralloc *gralloc)
192 {
193 gralloc_mapper *gr = (struct gralloc_mapper *)gralloc;
194 delete gr;
195
196 return 0;
197 }
198
199 struct u_gralloc *
u_gralloc_imapper_api_create()200 u_gralloc_imapper_api_create()
201 {
202 auto &mapper = GraphicBufferMapper::get();
203 if(mapper.getMapperVersion() < GraphicBufferMapper::GRALLOC_4) {
204 mesa_logi("Could not find IMapper v4/v5 API");
205 return NULL;
206 }
207 auto gr = new gralloc_mapper;
208 gr->base.ops.get_buffer_basic_info = mapper5_get_buffer_basic_info;
209 gr->base.ops.get_buffer_color_info = mapper5_get_buffer_color_info;
210 gr->base.ops.get_front_rendering_usage = mapper5_get_front_rendering_usage;
211 gr->base.ops.destroy = destroy;
212
213 mesa_logi("Using IMapper %d API", mapper.getMapperVersion());
214
215 return &gr->base;
216 }
217 } // extern "C"
218
219