blob: e3898a9333732664eb214a08cd436480f534a03e [file] [log] [blame]
Jason Macnak2a77d942020-09-10 10:57:46 -07001/*
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
21using aidl::android::hardware::graphics::common::PlaneLayout;
22using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
23using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
24using android::hardware::hidl_bitfield;
25using android::hardware::hidl_handle;
26using android::hardware::graphics::common::V1_2::BufferUsage;
27using android::hardware::graphics::common::V1_2::PixelFormat;
28
29using BufferDescriptorInfo =
30 android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
31
Jason Macnak2a77d942020-09-10 10:57:46 -070032std::string getPixelFormatString(PixelFormat format) {
Yiwei Zhang3c8db482021-09-14 20:10:07 +000033 return android::hardware::graphics::common::V1_2::toString(format);
Jason Macnak2a77d942020-09-10 10:57:46 -070034}
35
36std::string getUsageString(hidl_bitfield<BufferUsage> bufferUsage) {
Yiwei Zhang3c8db482021-09-14 20:10:07 +000037 static_assert(std::is_same<std::underlying_type<BufferUsage>::type, uint64_t>::value);
Jason Macnak2a77d942020-09-10 10:57:46 -070038
Yiwei Zhang3c8db482021-09-14 20:10:07 +000039 const uint64_t usage = static_cast<uint64_t>(bufferUsage);
40 return android::hardware::graphics::common::V1_2::toString<BufferUsage>(usage);
Jason Macnak2a77d942020-09-10 10:57:46 -070041}
42
43int convertToDrmFormat(PixelFormat format, uint32_t* outDrmFormat) {
Yiwei Zhang6aad1352021-09-14 18:26:05 +000044 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;
Jason Macnak2a77d942020-09-10 10:57:46 -070051}
52
53int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) {
Yiwei Zhang6b894b12021-09-16 22:28:22 +000054 *outBufferUsage = cros_gralloc_convert_usage(grallocUsage);
Jason Macnak2a77d942020-09-10 10:57:46 -070055 return 0;
56}
57
58int 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;
Jason Macnak07f62092020-12-10 11:42:54 -080066 if (descriptor.layerCount > 1) {
67 drv_log("Failed to convert descriptor. Unsupported layerCount: %d\n",
68 descriptor.layerCount);
Gurchetan Singhcadc54f2021-02-01 12:03:11 -080069 return -EINVAL;
Jason Macnak07f62092020-12-10 11:42:54 -080070 }
Jason Macnak2a77d942020-09-10 10:57:46 -070071 if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) {
72 std::string pixelFormatString = getPixelFormatString(descriptor.format);
Jason Macnak07f62092020-12-10 11:42:54 -080073 drv_log("Failed to convert descriptor. Unsupported format %s\n", pixelFormatString.c_str());
Gurchetan Singhcadc54f2021-02-01 12:03:11 -080074 return -EINVAL;
Jason Macnak2a77d942020-09-10 10:57:46 -070075 }
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());
Gurchetan Singhcadc54f2021-02-01 12:03:11 -080079 return -EINVAL;
Jason Macnak2a77d942020-09-10 10:57:46 -070080 }
81 return 0;
82}
83
84int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage) {
85 uint32_t mapUsage = BO_MAP_NONE;
86
87 if (grallocUsage & BufferUsage::CPU_READ_MASK) {
88 mapUsage |= BO_MAP_READ;
89 }
90 if (grallocUsage & BufferUsage::CPU_WRITE_MASK) {
91 mapUsage |= BO_MAP_WRITE;
92 }
93
94 *outMapUsage = mapUsage;
95 return 0;
96}
97
98int convertToFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) {
99 if (!outFenceFd) {
100 return -EINVAL;
101 }
102
103 const native_handle_t* nativeHandle = fenceHandle.getNativeHandle();
104 if (nativeHandle && nativeHandle->numFds > 1) {
105 return -EINVAL;
106 }
107
108 *outFenceFd = (nativeHandle && nativeHandle->numFds == 1) ? nativeHandle->data[0] : -1;
109 return 0;
110}
111
112int convertToFenceHandle(int fenceFd, hidl_handle* outFenceHandle) {
113 if (!outFenceHandle) {
114 return -EINVAL;
115 }
116 if (fenceFd < 0) {
117 return 0;
118 }
119
120 NATIVE_HANDLE_DECLARE_STORAGE(handleStorage, 1, 0);
121 auto fenceHandle = native_handle_init(handleStorage, 1, 0);
122 fenceHandle->data[0] = fenceFd;
123
124 *outFenceHandle = fenceHandle;
125 return 0;
126}
127
128const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap() {
129 static const auto* kPlaneLayoutsMap =
130 new std::unordered_map<uint32_t, std::vector<PlaneLayout>>({
131 {DRM_FORMAT_ABGR8888,
132 {{
133 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
134 .offsetInBits = 0,
135 .sizeInBits = 8},
136 {.type = android::gralloc4::PlaneLayoutComponentType_G,
137 .offsetInBits = 8,
138 .sizeInBits = 8},
139 {.type = android::gralloc4::PlaneLayoutComponentType_B,
140 .offsetInBits = 16,
141 .sizeInBits = 8},
142 {.type = android::gralloc4::PlaneLayoutComponentType_A,
143 .offsetInBits = 24,
144 .sizeInBits = 8}},
145 .sampleIncrementInBits = 32,
146 .horizontalSubsampling = 1,
147 .verticalSubsampling = 1,
148 }}},
149
150 {DRM_FORMAT_ABGR2101010,
151 {{
152 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
153 .offsetInBits = 0,
154 .sizeInBits = 10},
155 {.type = android::gralloc4::PlaneLayoutComponentType_G,
156 .offsetInBits = 10,
157 .sizeInBits = 10},
158 {.type = android::gralloc4::PlaneLayoutComponentType_B,
159 .offsetInBits = 20,
160 .sizeInBits = 10},
161 {.type = android::gralloc4::PlaneLayoutComponentType_A,
162 .offsetInBits = 30,
163 .sizeInBits = 2}},
164 .sampleIncrementInBits = 32,
165 .horizontalSubsampling = 1,
166 .verticalSubsampling = 1,
167 }}},
168
169 {DRM_FORMAT_ABGR16161616F,
170 {{
171 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
172 .offsetInBits = 0,
173 .sizeInBits = 16},
174 {.type = android::gralloc4::PlaneLayoutComponentType_G,
175 .offsetInBits = 16,
176 .sizeInBits = 16},
177 {.type = android::gralloc4::PlaneLayoutComponentType_B,
178 .offsetInBits = 32,
179 .sizeInBits = 16},
180 {.type = android::gralloc4::PlaneLayoutComponentType_A,
181 .offsetInBits = 48,
182 .sizeInBits = 16}},
183 .sampleIncrementInBits = 64,
184 .horizontalSubsampling = 1,
185 .verticalSubsampling = 1,
186 }}},
187
188 {DRM_FORMAT_ARGB8888,
189 {{
190 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
191 .offsetInBits = 0,
192 .sizeInBits = 8},
193 {.type = android::gralloc4::PlaneLayoutComponentType_G,
194 .offsetInBits = 8,
195 .sizeInBits = 8},
196 {.type = android::gralloc4::PlaneLayoutComponentType_R,
197 .offsetInBits = 16,
198 .sizeInBits = 8},
199 {.type = android::gralloc4::PlaneLayoutComponentType_A,
200 .offsetInBits = 24,
201 .sizeInBits = 8}},
202 .sampleIncrementInBits = 32,
203 .horizontalSubsampling = 1,
204 .verticalSubsampling = 1,
205 }}},
206
207 {DRM_FORMAT_NV12,
208 {{
209 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
210 .offsetInBits = 0,
211 .sizeInBits = 8}},
212 .sampleIncrementInBits = 8,
213 .horizontalSubsampling = 1,
214 .verticalSubsampling = 1,
215 },
216 {
217 .components =
218 {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
219 .offsetInBits = 0,
220 .sizeInBits = 8},
221 {.type = android::gralloc4::PlaneLayoutComponentType_CR,
222 .offsetInBits = 8,
223 .sizeInBits = 8}},
224 .sampleIncrementInBits = 16,
225 .horizontalSubsampling = 2,
226 .verticalSubsampling = 2,
227 }}},
228
229 {DRM_FORMAT_NV21,
230 {{
231 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
232 .offsetInBits = 0,
233 .sizeInBits = 8}},
234 .sampleIncrementInBits = 8,
235 .horizontalSubsampling = 1,
236 .verticalSubsampling = 1,
237 },
238 {
239 .components =
240 {{.type = android::gralloc4::PlaneLayoutComponentType_CR,
241 .offsetInBits = 0,
242 .sizeInBits = 8},
243 {.type = android::gralloc4::PlaneLayoutComponentType_CB,
244 .offsetInBits = 8,
245 .sizeInBits = 8}},
246 .sampleIncrementInBits = 16,
247 .horizontalSubsampling = 2,
248 .verticalSubsampling = 2,
249 }}},
250
251 {DRM_FORMAT_P010,
252 {{
253 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
254 .offsetInBits = 6,
255 .sizeInBits = 10}},
256 .sampleIncrementInBits = 16,
257 .horizontalSubsampling = 1,
258 .verticalSubsampling = 1,
259 },
260 {
261 .components =
262 {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
263 .offsetInBits = 6,
264 .sizeInBits = 10},
265 {.type = android::gralloc4::PlaneLayoutComponentType_CR,
266 .offsetInBits = 22,
267 .sizeInBits = 10}},
268 .sampleIncrementInBits = 32,
269 .horizontalSubsampling = 2,
270 .verticalSubsampling = 2,
271 }}},
272
273 {DRM_FORMAT_R8,
274 {{
275 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
276 .offsetInBits = 0,
277 .sizeInBits = 8}},
278 .sampleIncrementInBits = 8,
279 .horizontalSubsampling = 1,
280 .verticalSubsampling = 1,
281 }}},
282
283 {DRM_FORMAT_R16,
284 {{
285 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
286 .offsetInBits = 0,
287 .sizeInBits = 16}},
288 .sampleIncrementInBits = 16,
289 .horizontalSubsampling = 1,
290 .verticalSubsampling = 1,
291 }}},
292
293 {DRM_FORMAT_RGB565,
294 {{
295 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
296 .offsetInBits = 0,
297 .sizeInBits = 5},
298 {.type = android::gralloc4::PlaneLayoutComponentType_G,
299 .offsetInBits = 5,
300 .sizeInBits = 6},
301 {.type = android::gralloc4::PlaneLayoutComponentType_B,
302 .offsetInBits = 11,
303 .sizeInBits = 5}},
304 .sampleIncrementInBits = 16,
305 .horizontalSubsampling = 1,
306 .verticalSubsampling = 1,
307 }}},
308
309 {DRM_FORMAT_RGB888,
310 {{
311 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
312 .offsetInBits = 0,
313 .sizeInBits = 8},
314 {.type = android::gralloc4::PlaneLayoutComponentType_G,
315 .offsetInBits = 8,
316 .sizeInBits = 8},
317 {.type = android::gralloc4::PlaneLayoutComponentType_B,
318 .offsetInBits = 16,
319 .sizeInBits = 8}},
320 .sampleIncrementInBits = 24,
321 .horizontalSubsampling = 1,
322 .verticalSubsampling = 1,
323 }}},
324
325 {DRM_FORMAT_XBGR8888,
326 {{
327 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
328 .offsetInBits = 0,
329 .sizeInBits = 8},
330 {.type = android::gralloc4::PlaneLayoutComponentType_G,
331 .offsetInBits = 8,
332 .sizeInBits = 8},
333 {.type = android::gralloc4::PlaneLayoutComponentType_R,
334 .offsetInBits = 16,
335 .sizeInBits = 8}},
336 .sampleIncrementInBits = 32,
337 .horizontalSubsampling = 1,
338 .verticalSubsampling = 1,
339 }}},
340
341 {DRM_FORMAT_YVU420,
342 {
343 {
344 .components = {{.type = android::gralloc4::
345 PlaneLayoutComponentType_Y,
346 .offsetInBits = 0,
347 .sizeInBits = 8}},
348 .sampleIncrementInBits = 8,
349 .horizontalSubsampling = 1,
350 .verticalSubsampling = 1,
351 },
352 {
353 .components = {{.type = android::gralloc4::
354 PlaneLayoutComponentType_CB,
355 .offsetInBits = 0,
356 .sizeInBits = 8}},
357 .sampleIncrementInBits = 8,
358 .horizontalSubsampling = 2,
359 .verticalSubsampling = 2,
360 },
361 {
362 .components = {{.type = android::gralloc4::
363 PlaneLayoutComponentType_CR,
364 .offsetInBits = 0,
365 .sizeInBits = 8}},
366 .sampleIncrementInBits = 8,
367 .horizontalSubsampling = 2,
368 .verticalSubsampling = 2,
369 },
370 }},
371
372 {DRM_FORMAT_YVU420_ANDROID,
373 {
374 {
375 .components = {{.type = android::gralloc4::
376 PlaneLayoutComponentType_Y,
377 .offsetInBits = 0,
378 .sizeInBits = 8}},
379 .sampleIncrementInBits = 8,
380 .horizontalSubsampling = 1,
381 .verticalSubsampling = 1,
382 },
383 {
384 .components = {{.type = android::gralloc4::
385 PlaneLayoutComponentType_CR,
386 .offsetInBits = 0,
387 .sizeInBits = 8}},
388 .sampleIncrementInBits = 8,
389 .horizontalSubsampling = 2,
390 .verticalSubsampling = 2,
391 },
392 {
393 .components = {{.type = android::gralloc4::
394 PlaneLayoutComponentType_CB,
395 .offsetInBits = 0,
396 .sizeInBits = 8}},
397 .sampleIncrementInBits = 8,
398 .horizontalSubsampling = 2,
399 .verticalSubsampling = 2,
400 },
401 }},
402 });
403 return *kPlaneLayoutsMap;
404}
405
406int getPlaneLayouts(uint32_t drmFormat, std::vector<PlaneLayout>* outPlaneLayouts) {
407 const auto& planeLayoutsMap = GetPlaneLayoutsMap();
408 const auto it = planeLayoutsMap.find(drmFormat);
409 if (it == planeLayoutsMap.end()) {
410 drv_log("Unknown plane layout for format %d\n", drmFormat);
Gurchetan Singhcadc54f2021-02-01 12:03:11 -0800411 return -EINVAL;
Jason Macnak2a77d942020-09-10 10:57:46 -0700412 }
413
414 *outPlaneLayouts = it->second;
415 return 0;
Gurchetan Singh2d482e02020-10-05 17:17:13 -0700416}