1 /*
2 * Copyright 2020 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 #include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
8
9 #include <array>
10 #include <unordered_map>
11
12 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h>
13 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
14 #include <android-base/stringprintf.h>
15 #include <android-base/strings.h>
16 #include <cutils/native_handle.h>
17 #include <gralloctypes/Gralloc4.h>
18
19 #include "cros_gralloc/cros_gralloc_helpers.h"
20
21 using aidl::android::hardware::graphics::common::PlaneLayout;
22 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
23 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
24 using android::hardware::hidl_bitfield;
25 using android::hardware::hidl_handle;
26 using android::hardware::graphics::common::V1_2::BufferUsage;
27 using android::hardware::graphics::common::V1_2::PixelFormat;
28
29 using BufferDescriptorInfo =
30 android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
31
getPixelFormatString(PixelFormat format)32 std::string getPixelFormatString(PixelFormat format) {
33 return android::hardware::graphics::common::V1_2::toString(format);
34 }
35
getUsageString(hidl_bitfield<BufferUsage> bufferUsage)36 std::string getUsageString(hidl_bitfield<BufferUsage> bufferUsage) {
37 static_assert(std::is_same<std::underlying_type<BufferUsage>::type, uint64_t>::value);
38
39 const uint64_t usage = static_cast<uint64_t>(bufferUsage);
40 return android::hardware::graphics::common::V1_2::toString<BufferUsage>(usage);
41 }
42
convertToDrmFormat(PixelFormat format,uint32_t * outDrmFormat)43 int convertToDrmFormat(PixelFormat format, uint32_t* outDrmFormat) {
44 static_assert(std::is_same<std::underlying_type<PixelFormat>::type, int32_t>::value);
45
46 const uint32_t drmFormat = cros_gralloc_convert_format(static_cast<int32_t>(format));
47 if (drmFormat == DRM_FORMAT_NONE) return -EINVAL;
48
49 *outDrmFormat = drmFormat;
50 return 0;
51 }
52
convertToBufferUsage(uint64_t grallocUsage,uint64_t * outBufferUsage)53 int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) {
54 *outBufferUsage = cros_gralloc_convert_usage(grallocUsage);
55 return 0;
56 }
57
convertToCrosDescriptor(const BufferDescriptorInfo & descriptor,struct cros_gralloc_buffer_descriptor * outCrosDescriptor)58 int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor,
59 struct cros_gralloc_buffer_descriptor* outCrosDescriptor) {
60 outCrosDescriptor->name = descriptor.name;
61 outCrosDescriptor->width = descriptor.width;
62 outCrosDescriptor->height = descriptor.height;
63 outCrosDescriptor->droid_format = static_cast<int32_t>(descriptor.format);
64 outCrosDescriptor->droid_usage = descriptor.usage;
65 outCrosDescriptor->reserved_region_size = descriptor.reservedSize;
66 if (descriptor.layerCount > 1) {
67 ALOGE("Failed to convert descriptor. Unsupported layerCount: %d", descriptor.layerCount);
68 return -EINVAL;
69 }
70 if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) {
71 std::string pixelFormatString = getPixelFormatString(descriptor.format);
72 ALOGE("Failed to convert descriptor. Unsupported format %s", pixelFormatString.c_str());
73 return -EINVAL;
74 }
75 if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) {
76 std::string usageString = getUsageString(descriptor.usage);
77 ALOGE("Failed to convert descriptor. Unsupported usage flags %s", usageString.c_str());
78 return -EINVAL;
79 }
80 return 0;
81 }
82
convertToMapUsage(uint64_t grallocUsage,uint32_t * outMapUsage)83 int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage) {
84 *outMapUsage = cros_gralloc_convert_map_usage(grallocUsage);
85 return 0;
86 }
87
convertToFenceFd(const hidl_handle & fenceHandle,int * outFenceFd)88 int convertToFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) {
89 if (!outFenceFd) {
90 return -EINVAL;
91 }
92
93 const native_handle_t* nativeHandle = fenceHandle.getNativeHandle();
94 if (nativeHandle && nativeHandle->numFds > 1) {
95 return -EINVAL;
96 }
97
98 *outFenceFd = (nativeHandle && nativeHandle->numFds == 1) ? nativeHandle->data[0] : -1;
99 return 0;
100 }
101
convertToFenceHandle(int fenceFd,hidl_handle * outFenceHandle)102 int convertToFenceHandle(int fenceFd, hidl_handle* outFenceHandle) {
103 if (!outFenceHandle) {
104 return -EINVAL;
105 }
106 if (fenceFd < 0) {
107 return 0;
108 }
109
110 NATIVE_HANDLE_DECLARE_STORAGE(handleStorage, 1, 0);
111 auto fenceHandle = native_handle_init(handleStorage, 1, 0);
112 fenceHandle->data[0] = fenceFd;
113
114 *outFenceHandle = fenceHandle;
115 return 0;
116 }
117
GetPlaneLayoutsMap()118 const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap() {
119 static const auto* kPlaneLayoutsMap =
120 new std::unordered_map<uint32_t, std::vector<PlaneLayout>>({
121 {DRM_FORMAT_ABGR8888,
122 {{
123 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
124 .offsetInBits = 0,
125 .sizeInBits = 8},
126 {.type = android::gralloc4::PlaneLayoutComponentType_G,
127 .offsetInBits = 8,
128 .sizeInBits = 8},
129 {.type = android::gralloc4::PlaneLayoutComponentType_B,
130 .offsetInBits = 16,
131 .sizeInBits = 8},
132 {.type = android::gralloc4::PlaneLayoutComponentType_A,
133 .offsetInBits = 24,
134 .sizeInBits = 8}},
135 .sampleIncrementInBits = 32,
136 .horizontalSubsampling = 1,
137 .verticalSubsampling = 1,
138 }}},
139
140 {DRM_FORMAT_ABGR2101010,
141 {{
142 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
143 .offsetInBits = 0,
144 .sizeInBits = 10},
145 {.type = android::gralloc4::PlaneLayoutComponentType_G,
146 .offsetInBits = 10,
147 .sizeInBits = 10},
148 {.type = android::gralloc4::PlaneLayoutComponentType_B,
149 .offsetInBits = 20,
150 .sizeInBits = 10},
151 {.type = android::gralloc4::PlaneLayoutComponentType_A,
152 .offsetInBits = 30,
153 .sizeInBits = 2}},
154 .sampleIncrementInBits = 32,
155 .horizontalSubsampling = 1,
156 .verticalSubsampling = 1,
157 }}},
158
159 {DRM_FORMAT_ABGR16161616F,
160 {{
161 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
162 .offsetInBits = 0,
163 .sizeInBits = 16},
164 {.type = android::gralloc4::PlaneLayoutComponentType_G,
165 .offsetInBits = 16,
166 .sizeInBits = 16},
167 {.type = android::gralloc4::PlaneLayoutComponentType_B,
168 .offsetInBits = 32,
169 .sizeInBits = 16},
170 {.type = android::gralloc4::PlaneLayoutComponentType_A,
171 .offsetInBits = 48,
172 .sizeInBits = 16}},
173 .sampleIncrementInBits = 64,
174 .horizontalSubsampling = 1,
175 .verticalSubsampling = 1,
176 }}},
177
178 {DRM_FORMAT_ARGB8888,
179 {{
180 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
181 .offsetInBits = 0,
182 .sizeInBits = 8},
183 {.type = android::gralloc4::PlaneLayoutComponentType_G,
184 .offsetInBits = 8,
185 .sizeInBits = 8},
186 {.type = android::gralloc4::PlaneLayoutComponentType_R,
187 .offsetInBits = 16,
188 .sizeInBits = 8},
189 {.type = android::gralloc4::PlaneLayoutComponentType_A,
190 .offsetInBits = 24,
191 .sizeInBits = 8}},
192 .sampleIncrementInBits = 32,
193 .horizontalSubsampling = 1,
194 .verticalSubsampling = 1,
195 }}},
196
197 {DRM_FORMAT_NV12,
198 {{
199 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
200 .offsetInBits = 0,
201 .sizeInBits = 8}},
202 .sampleIncrementInBits = 8,
203 .horizontalSubsampling = 1,
204 .verticalSubsampling = 1,
205 },
206 {
207 .components =
208 {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
209 .offsetInBits = 0,
210 .sizeInBits = 8},
211 {.type = android::gralloc4::PlaneLayoutComponentType_CR,
212 .offsetInBits = 8,
213 .sizeInBits = 8}},
214 .sampleIncrementInBits = 16,
215 .horizontalSubsampling = 2,
216 .verticalSubsampling = 2,
217 }}},
218
219 {DRM_FORMAT_NV21,
220 {{
221 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
222 .offsetInBits = 0,
223 .sizeInBits = 8}},
224 .sampleIncrementInBits = 8,
225 .horizontalSubsampling = 1,
226 .verticalSubsampling = 1,
227 },
228 {
229 .components =
230 {{.type = android::gralloc4::PlaneLayoutComponentType_CR,
231 .offsetInBits = 0,
232 .sizeInBits = 8},
233 {.type = android::gralloc4::PlaneLayoutComponentType_CB,
234 .offsetInBits = 8,
235 .sizeInBits = 8}},
236 .sampleIncrementInBits = 16,
237 .horizontalSubsampling = 2,
238 .verticalSubsampling = 2,
239 }}},
240
241 {DRM_FORMAT_P010,
242 {{
243 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
244 .offsetInBits = 6,
245 .sizeInBits = 10}},
246 .sampleIncrementInBits = 16,
247 .horizontalSubsampling = 1,
248 .verticalSubsampling = 1,
249 },
250 {
251 .components =
252 {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
253 .offsetInBits = 6,
254 .sizeInBits = 10},
255 {.type = android::gralloc4::PlaneLayoutComponentType_CR,
256 .offsetInBits = 22,
257 .sizeInBits = 10}},
258 .sampleIncrementInBits = 32,
259 .horizontalSubsampling = 2,
260 .verticalSubsampling = 2,
261 }}},
262
263 {DRM_FORMAT_R8,
264 {{
265 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
266 .offsetInBits = 0,
267 .sizeInBits = 8}},
268 .sampleIncrementInBits = 8,
269 .horizontalSubsampling = 1,
270 .verticalSubsampling = 1,
271 }}},
272
273 {DRM_FORMAT_R16,
274 {{
275 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
276 .offsetInBits = 0,
277 .sizeInBits = 16}},
278 .sampleIncrementInBits = 16,
279 .horizontalSubsampling = 1,
280 .verticalSubsampling = 1,
281 }}},
282
283 {DRM_FORMAT_RGB565,
284 {{
285 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
286 .offsetInBits = 0,
287 .sizeInBits = 5},
288 {.type = android::gralloc4::PlaneLayoutComponentType_G,
289 .offsetInBits = 5,
290 .sizeInBits = 6},
291 {.type = android::gralloc4::PlaneLayoutComponentType_R,
292 .offsetInBits = 11,
293 .sizeInBits = 5}},
294 .sampleIncrementInBits = 16,
295 .horizontalSubsampling = 1,
296 .verticalSubsampling = 1,
297 }}},
298
299 {DRM_FORMAT_BGR888,
300 {{
301 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
302 .offsetInBits = 0,
303 .sizeInBits = 8},
304 {.type = android::gralloc4::PlaneLayoutComponentType_G,
305 .offsetInBits = 8,
306 .sizeInBits = 8},
307 {.type = android::gralloc4::PlaneLayoutComponentType_B,
308 .offsetInBits = 16,
309 .sizeInBits = 8}},
310 .sampleIncrementInBits = 24,
311 .horizontalSubsampling = 1,
312 .verticalSubsampling = 1,
313 }}},
314
315 {DRM_FORMAT_XBGR8888,
316 {{
317 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
318 .offsetInBits = 0,
319 .sizeInBits = 8},
320 {.type = android::gralloc4::PlaneLayoutComponentType_G,
321 .offsetInBits = 8,
322 .sizeInBits = 8},
323 {.type = android::gralloc4::PlaneLayoutComponentType_B,
324 .offsetInBits = 16,
325 .sizeInBits = 8}},
326 .sampleIncrementInBits = 32,
327 .horizontalSubsampling = 1,
328 .verticalSubsampling = 1,
329 }}},
330
331 {DRM_FORMAT_YVU420,
332 {
333 {
334 .components = {{.type = android::gralloc4::
335 PlaneLayoutComponentType_Y,
336 .offsetInBits = 0,
337 .sizeInBits = 8}},
338 .sampleIncrementInBits = 8,
339 .horizontalSubsampling = 1,
340 .verticalSubsampling = 1,
341 },
342 {
343 .components = {{.type = android::gralloc4::
344 PlaneLayoutComponentType_CR,
345 .offsetInBits = 0,
346 .sizeInBits = 8}},
347 .sampleIncrementInBits = 8,
348 .horizontalSubsampling = 2,
349 .verticalSubsampling = 2,
350 },
351 {
352 .components = {{.type = android::gralloc4::
353 PlaneLayoutComponentType_CB,
354 .offsetInBits = 0,
355 .sizeInBits = 8}},
356 .sampleIncrementInBits = 8,
357 .horizontalSubsampling = 2,
358 .verticalSubsampling = 2,
359 },
360 }},
361
362 {DRM_FORMAT_YVU420_ANDROID,
363 {
364 {
365 .components = {{.type = android::gralloc4::
366 PlaneLayoutComponentType_Y,
367 .offsetInBits = 0,
368 .sizeInBits = 8}},
369 .sampleIncrementInBits = 8,
370 .horizontalSubsampling = 1,
371 .verticalSubsampling = 1,
372 },
373 {
374 .components = {{.type = android::gralloc4::
375 PlaneLayoutComponentType_CR,
376 .offsetInBits = 0,
377 .sizeInBits = 8}},
378 .sampleIncrementInBits = 8,
379 .horizontalSubsampling = 2,
380 .verticalSubsampling = 2,
381 },
382 {
383 .components = {{.type = android::gralloc4::
384 PlaneLayoutComponentType_CB,
385 .offsetInBits = 0,
386 .sizeInBits = 8}},
387 .sampleIncrementInBits = 8,
388 .horizontalSubsampling = 2,
389 .verticalSubsampling = 2,
390 },
391 }},
392 });
393 return *kPlaneLayoutsMap;
394 }
395
getPlaneLayouts(uint32_t drmFormat,std::vector<PlaneLayout> * outPlaneLayouts)396 int getPlaneLayouts(uint32_t drmFormat, std::vector<PlaneLayout>* outPlaneLayouts) {
397 const auto& planeLayoutsMap = GetPlaneLayoutsMap();
398 const auto it = planeLayoutsMap.find(drmFormat);
399 if (it == planeLayoutsMap.end()) {
400 ALOGE("Unknown plane layout for format %d", drmFormat);
401 return -EINVAL;
402 }
403
404 *outPlaneLayouts = it->second;
405 return 0;
406 }
407