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