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/gralloc3/CrosGralloc3Allocator.h"
8
9 #include <optional>
10
11 #include <android/hardware/graphics/mapper/3.0/IMapper.h>
12
13 #include "cros_gralloc/cros_gralloc_helpers.h"
14 #include "cros_gralloc/gralloc3/CrosGralloc3Utils.h"
15
16 using android::hardware::hidl_handle;
17 using android::hardware::hidl_vec;
18 using android::hardware::Return;
19 using android::hardware::Void;
20 using android::hardware::graphics::common::V1_2::BufferUsage;
21 using android::hardware::graphics::common::V1_2::PixelFormat;
22 using android::hardware::graphics::mapper::V3_0::Error;
23
24 using BufferDescriptorInfo =
25 android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo;
26
CrosGralloc3Allocator()27 CrosGralloc3Allocator::CrosGralloc3Allocator() : mDriver(std::make_unique<cros_gralloc_driver>()) {
28 if (mDriver->init()) {
29 drv_log("Failed to initialize driver.\n");
30 mDriver = nullptr;
31 }
32 }
33
allocate(const BufferDescriptorInfo & descriptor,uint32_t * outStride,hidl_handle * outHandle)34 Error CrosGralloc3Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride,
35 hidl_handle* outHandle) {
36 if (!mDriver) {
37 drv_log("Failed to allocate. Driver is uninitialized.\n");
38 return Error::NO_RESOURCES;
39 }
40
41 if (!outStride || !outHandle) {
42 return Error::NO_RESOURCES;
43 }
44
45 struct cros_gralloc_buffer_descriptor crosDescriptor;
46 if (convertToCrosDescriptor(descriptor, &crosDescriptor)) {
47 return Error::UNSUPPORTED;
48 }
49
50 bool supported = mDriver->is_supported(&crosDescriptor);
51 if (!supported && (descriptor.usage & BufferUsage::COMPOSER_OVERLAY)) {
52 crosDescriptor.use_flags &= ~BO_USE_SCANOUT;
53 supported = mDriver->is_supported(&crosDescriptor);
54 }
55
56 if (!supported) {
57 std::string drmFormatString = get_drm_format_string(crosDescriptor.drm_format);
58 std::string pixelFormatString = getPixelFormatString(descriptor.format);
59 std::string usageString = getUsageString(descriptor.usage);
60 drv_log("Unsupported combination -- pixel format: %s, drm format:%s, usage: %s\n",
61 pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str());
62 return Error::UNSUPPORTED;
63 }
64
65 buffer_handle_t handle;
66 int ret = mDriver->allocate(&crosDescriptor, &handle);
67 if (ret) {
68 return Error::NO_RESOURCES;
69 }
70
71 cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle);
72 if (!crosHandle) {
73 return Error::NO_RESOURCES;
74 }
75
76 *outHandle = handle;
77 *outStride = crosHandle->pixel_stride;
78
79 return Error::NONE;
80 }
81
allocate(const hidl_vec<uint32_t> & encoded,uint32_t count,allocate_cb hidlCb)82 Return<void> CrosGralloc3Allocator::allocate(const hidl_vec<uint32_t>& encoded, uint32_t count,
83 allocate_cb hidlCb) {
84 hidl_vec<hidl_handle> handles;
85
86 if (!mDriver) {
87 drv_log("Failed to allocate. Driver is uninitialized.\n");
88 hidlCb(Error::NO_RESOURCES, 0, handles);
89 return Void();
90 }
91
92 auto descriptor_opt = decodeBufferDescriptorInfo(encoded);
93 if (!descriptor_opt) {
94 drv_log("Failed to allocate. Failed to decode buffer descriptor.\n");
95 hidlCb(Error::BAD_DESCRIPTOR, 0, handles);
96 return Void();
97 }
98
99 BufferDescriptorInfo descriptor = *descriptor_opt;
100
101 handles.resize(count);
102
103 uint32_t stride = 0;
104 for (int i = 0; i < handles.size(); i++) {
105 Error err = allocate(descriptor, &stride, &(handles[i]));
106 if (err != Error::NONE) {
107 for (int j = 0; j < i; j++) {
108 mDriver->release(handles[j].getNativeHandle());
109 }
110 handles.resize(0);
111 hidlCb(err, 0, handles);
112 return Void();
113 }
114 }
115
116 hidlCb(Error::NONE, stride, handles);
117
118 for (const hidl_handle& handle : handles) {
119 mDriver->release(handle.getNativeHandle());
120 }
121
122 return Void();
123 }
124
dumpDebugInfo(dumpDebugInfo_cb hidl_cb)125 Return<void> CrosGralloc3Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
126 hidl_cb("CrosGralloc3Allocator::dumpDebugInfo unimplemented.");
127 return Void();
128 }
129