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 drv_log("Failed to convert descriptor. Unsupported layerCount: %d\n",
68 descriptor.layerCount);
69 return -EINVAL;
70 }
71 if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) {
72 std::string pixelFormatString = getPixelFormatString(descriptor.format);
73 drv_log("Failed to convert descriptor. Unsupported format %s\n", pixelFormatString.c_str());
74 return -EINVAL;
75 }
76 if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) {
77 std::string usageString = getUsageString(descriptor.usage);
78 drv_log("Failed to convert descriptor. Unsupported usage flags %s\n", usageString.c_str());
79 return -EINVAL;
80 }
81 return 0;
82 }
83
convertToMapUsage(uint64_t grallocUsage,uint32_t * outMapUsage)84 int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage) {
85 *outMapUsage = cros_gralloc_convert_map_usage(grallocUsage);
86 return 0;
87 }
88
convertToFenceFd(const hidl_handle & fenceHandle,int * outFenceFd)89 int convertToFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) {
90 if (!outFenceFd) {
91 return -EINVAL;
92 }
93
94 const native_handle_t* nativeHandle = fenceHandle.getNativeHandle();
95 if (nativeHandle && nativeHandle->numFds > 1) {
96 return -EINVAL;
97 }
98
99 *outFenceFd = (nativeHandle && nativeHandle->numFds == 1) ? nativeHandle->data[0] : -1;
100 return 0;
101 }
102
convertToFenceHandle(int fenceFd,hidl_handle * outFenceHandle)103 int convertToFenceHandle(int fenceFd, hidl_handle* outFenceHandle) {
104 if (!outFenceHandle) {
105 return -EINVAL;
106 }
107 if (fenceFd < 0) {
108 return 0;
109 }
110
111 NATIVE_HANDLE_DECLARE_STORAGE(handleStorage, 1, 0);
112 auto fenceHandle = native_handle_init(handleStorage, 1, 0);
113 fenceHandle->data[0] = fenceFd;
114
115 *outFenceHandle = fenceHandle;
116 return 0;
117 }
118
GetPlaneLayoutsMap()119 const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap() {
120 static const auto* kPlaneLayoutsMap =
121 new std::unordered_map<uint32_t, std::vector<PlaneLayout>>({
122 {DRM_FORMAT_ABGR8888,
123 {{
124 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
125 .offsetInBits = 0,
126 .sizeInBits = 8},
127 {.type = android::gralloc4::PlaneLayoutComponentType_G,
128 .offsetInBits = 8,
129 .sizeInBits = 8},
130 {.type = android::gralloc4::PlaneLayoutComponentType_B,
131 .offsetInBits = 16,
132 .sizeInBits = 8},
133 {.type = android::gralloc4::PlaneLayoutComponentType_A,
134 .offsetInBits = 24,
135 .sizeInBits = 8}},
136 .sampleIncrementInBits = 32,
137 .horizontalSubsampling = 1,
138 .verticalSubsampling = 1,
139 }}},
140
141 {DRM_FORMAT_ABGR2101010,
142 {{
143 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
144 .offsetInBits = 0,
145 .sizeInBits = 10},
146 {.type = android::gralloc4::PlaneLayoutComponentType_G,
147 .offsetInBits = 10,
148 .sizeInBits = 10},
149 {.type = android::gralloc4::PlaneLayoutComponentType_B,
150 .offsetInBits = 20,
151 .sizeInBits = 10},
152 {.type = android::gralloc4::PlaneLayoutComponentType_A,
153 .offsetInBits = 30,
154 .sizeInBits = 2}},
155 .sampleIncrementInBits = 32,
156 .horizontalSubsampling = 1,
157 .verticalSubsampling = 1,
158 }}},
159
160 {DRM_FORMAT_ABGR16161616F,
161 {{
162 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
163 .offsetInBits = 0,
164 .sizeInBits = 16},
165 {.type = android::gralloc4::PlaneLayoutComponentType_G,
166 .offsetInBits = 16,
167 .sizeInBits = 16},
168 {.type = android::gralloc4::PlaneLayoutComponentType_B,
169 .offsetInBits = 32,
170 .sizeInBits = 16},
171 {.type = android::gralloc4::PlaneLayoutComponentType_A,
172 .offsetInBits = 48,
173 .sizeInBits = 16}},
174 .sampleIncrementInBits = 64,
175 .horizontalSubsampling = 1,
176 .verticalSubsampling = 1,
177 }}},
178
179 {DRM_FORMAT_ARGB8888,
180 {{
181 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
182 .offsetInBits = 0,
183 .sizeInBits = 8},
184 {.type = android::gralloc4::PlaneLayoutComponentType_G,
185 .offsetInBits = 8,
186 .sizeInBits = 8},
187 {.type = android::gralloc4::PlaneLayoutComponentType_R,
188 .offsetInBits = 16,
189 .sizeInBits = 8},
190 {.type = android::gralloc4::PlaneLayoutComponentType_A,
191 .offsetInBits = 24,
192 .sizeInBits = 8}},
193 .sampleIncrementInBits = 32,
194 .horizontalSubsampling = 1,
195 .verticalSubsampling = 1,
196 }}},
197
198 {DRM_FORMAT_NV12,
199 {{
200 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
201 .offsetInBits = 0,
202 .sizeInBits = 8}},
203 .sampleIncrementInBits = 8,
204 .horizontalSubsampling = 1,
205 .verticalSubsampling = 1,
206 },
207 {
208 .components =
209 {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
210 .offsetInBits = 0,
211 .sizeInBits = 8},
212 {.type = android::gralloc4::PlaneLayoutComponentType_CR,
213 .offsetInBits = 8,
214 .sizeInBits = 8}},
215 .sampleIncrementInBits = 16,
216 .horizontalSubsampling = 2,
217 .verticalSubsampling = 2,
218 }}},
219
220 {DRM_FORMAT_NV21,
221 {{
222 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
223 .offsetInBits = 0,
224 .sizeInBits = 8}},
225 .sampleIncrementInBits = 8,
226 .horizontalSubsampling = 1,
227 .verticalSubsampling = 1,
228 },
229 {
230 .components =
231 {{.type = android::gralloc4::PlaneLayoutComponentType_CR,
232 .offsetInBits = 0,
233 .sizeInBits = 8},
234 {.type = android::gralloc4::PlaneLayoutComponentType_CB,
235 .offsetInBits = 8,
236 .sizeInBits = 8}},
237 .sampleIncrementInBits = 16,
238 .horizontalSubsampling = 2,
239 .verticalSubsampling = 2,
240 }}},
241
242 {DRM_FORMAT_P010,
243 {{
244 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
245 .offsetInBits = 6,
246 .sizeInBits = 10}},
247 .sampleIncrementInBits = 16,
248 .horizontalSubsampling = 1,
249 .verticalSubsampling = 1,
250 },
251 {
252 .components =
253 {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
254 .offsetInBits = 6,
255 .sizeInBits = 10},
256 {.type = android::gralloc4::PlaneLayoutComponentType_CR,
257 .offsetInBits = 22,
258 .sizeInBits = 10}},
259 .sampleIncrementInBits = 32,
260 .horizontalSubsampling = 2,
261 .verticalSubsampling = 2,
262 }}},
263
264 {DRM_FORMAT_R8,
265 {{
266 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
267 .offsetInBits = 0,
268 .sizeInBits = 8}},
269 .sampleIncrementInBits = 8,
270 .horizontalSubsampling = 1,
271 .verticalSubsampling = 1,
272 }}},
273
274 {DRM_FORMAT_R16,
275 {{
276 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
277 .offsetInBits = 0,
278 .sizeInBits = 16}},
279 .sampleIncrementInBits = 16,
280 .horizontalSubsampling = 1,
281 .verticalSubsampling = 1,
282 }}},
283
284 {DRM_FORMAT_RGB565,
285 {{
286 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
287 .offsetInBits = 0,
288 .sizeInBits = 5},
289 {.type = android::gralloc4::PlaneLayoutComponentType_G,
290 .offsetInBits = 5,
291 .sizeInBits = 6},
292 {.type = android::gralloc4::PlaneLayoutComponentType_R,
293 .offsetInBits = 11,
294 .sizeInBits = 5}},
295 .sampleIncrementInBits = 16,
296 .horizontalSubsampling = 1,
297 .verticalSubsampling = 1,
298 }}},
299
300 {DRM_FORMAT_BGR888,
301 {{
302 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
303 .offsetInBits = 0,
304 .sizeInBits = 8},
305 {.type = android::gralloc4::PlaneLayoutComponentType_G,
306 .offsetInBits = 8,
307 .sizeInBits = 8},
308 {.type = android::gralloc4::PlaneLayoutComponentType_B,
309 .offsetInBits = 16,
310 .sizeInBits = 8}},
311 .sampleIncrementInBits = 24,
312 .horizontalSubsampling = 1,
313 .verticalSubsampling = 1,
314 }}},
315
316 {DRM_FORMAT_XBGR8888,
317 {{
318 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
319 .offsetInBits = 0,
320 .sizeInBits = 8},
321 {.type = android::gralloc4::PlaneLayoutComponentType_G,
322 .offsetInBits = 8,
323 .sizeInBits = 8},
324 {.type = android::gralloc4::PlaneLayoutComponentType_B,
325 .offsetInBits = 16,
326 .sizeInBits = 8}},
327 .sampleIncrementInBits = 32,
328 .horizontalSubsampling = 1,
329 .verticalSubsampling = 1,
330 }}},
331
332 {DRM_FORMAT_YVU420,
333 {
334 {
335 .components = {{.type = android::gralloc4::
336 PlaneLayoutComponentType_Y,
337 .offsetInBits = 0,
338 .sizeInBits = 8}},
339 .sampleIncrementInBits = 8,
340 .horizontalSubsampling = 1,
341 .verticalSubsampling = 1,
342 },
343 {
344 .components = {{.type = android::gralloc4::
345 PlaneLayoutComponentType_CB,
346 .offsetInBits = 0,
347 .sizeInBits = 8}},
348 .sampleIncrementInBits = 8,
349 .horizontalSubsampling = 2,
350 .verticalSubsampling = 2,
351 },
352 {
353 .components = {{.type = android::gralloc4::
354 PlaneLayoutComponentType_CR,
355 .offsetInBits = 0,
356 .sizeInBits = 8}},
357 .sampleIncrementInBits = 8,
358 .horizontalSubsampling = 2,
359 .verticalSubsampling = 2,
360 },
361 }},
362
363 {DRM_FORMAT_YVU420_ANDROID,
364 {
365 {
366 .components = {{.type = android::gralloc4::
367 PlaneLayoutComponentType_Y,
368 .offsetInBits = 0,
369 .sizeInBits = 8}},
370 .sampleIncrementInBits = 8,
371 .horizontalSubsampling = 1,
372 .verticalSubsampling = 1,
373 },
374 {
375 .components = {{.type = android::gralloc4::
376 PlaneLayoutComponentType_CR,
377 .offsetInBits = 0,
378 .sizeInBits = 8}},
379 .sampleIncrementInBits = 8,
380 .horizontalSubsampling = 2,
381 .verticalSubsampling = 2,
382 },
383 {
384 .components = {{.type = android::gralloc4::
385 PlaneLayoutComponentType_CB,
386 .offsetInBits = 0,
387 .sizeInBits = 8}},
388 .sampleIncrementInBits = 8,
389 .horizontalSubsampling = 2,
390 .verticalSubsampling = 2,
391 },
392 }},
393 });
394 return *kPlaneLayoutsMap;
395 }
396
getPlaneLayouts(uint32_t drmFormat,std::vector<PlaneLayout> * outPlaneLayouts)397 int getPlaneLayouts(uint32_t drmFormat, std::vector<PlaneLayout>* outPlaneLayouts) {
398 const auto& planeLayoutsMap = GetPlaneLayoutsMap();
399 const auto it = planeLayoutsMap.find(drmFormat);
400 if (it == planeLayoutsMap.end()) {
401 drv_log("Unknown plane layout for format %d\n", drmFormat);
402 return -EINVAL;
403 }
404
405 *outPlaneLayouts = it->second;
406 return 0;
407 }
408