• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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