1 /*
2 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation. nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #define DEBUG 0
31 #include "QtiAllocator.h"
32
33 #include <cutils/properties.h>
34 #include <log/log.h>
35 #include <vendor/qti/hardware/display/mapper/3.0/IQtiMapper.h>
36 #include <vendor/qti/hardware/display/mapper/4.0/IQtiMapper.h>
37
38 #include <vector>
39
40 #include "QtiMapper.h"
41 #include "QtiMapper4.h"
42 #include "gr_utils.h"
43
get_properties(gralloc::GrallocProperties * props)44 static void get_properties(gralloc::GrallocProperties *props) {
45 props->use_system_heap_for_sensors =
46 property_get_bool("vendor.gralloc.use_system_heap_for_sensors", 1);
47
48 props->ubwc_disable = property_get_bool("vendor.gralloc.disable_ubwc", 0);
49
50 props->ahardware_buffer_disable = property_get_bool("vendor.gralloc.disable_ahardware_buffer", 0);
51 }
52
53 namespace vendor {
54 namespace qti {
55 namespace hardware {
56 namespace display {
57 namespace allocator {
58 namespace V3_0 {
59 namespace implementation {
60
61 using android::hardware::hidl_handle;
62 using gralloc::BufferDescriptor;
63 using IMapper_3_0_Error = android::hardware::graphics::mapper::V3_0::Error;
64 using gralloc::Error;
65
QtiAllocator()66 QtiAllocator::QtiAllocator() {
67 gralloc::GrallocProperties properties;
68 get_properties(&properties);
69 buf_mgr_ = BufferManager::GetInstance();
70 buf_mgr_->SetGrallocDebugProperties(properties);
71 }
72
73 // Methods from ::android::hardware::graphics::allocator::V2_0::IAllocator follow.
dumpDebugInfo(dumpDebugInfo_cb hidl_cb)74 Return<void> QtiAllocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
75 std::ostringstream os;
76 buf_mgr_->Dump(&os);
77 hidl_string reply;
78 reply.setToExternal(os.str().c_str(), os.str().length());
79 hidl_cb(reply);
80 return Void();
81 }
82
allocate(const hidl_vec<uint32_t> & descriptor,uint32_t count,allocate_cb hidl_cb)83 Return<void> QtiAllocator::allocate(const hidl_vec<uint32_t> &descriptor, uint32_t count,
84 allocate_cb hidl_cb) {
85 ALOGD_IF(DEBUG, "Allocating buffers count: %d", count);
86 gralloc::BufferDescriptor desc;
87
88 auto err = ::vendor::qti::hardware::display::mapper::V3_0::implementation::QtiMapper::Decode(
89 descriptor, &desc);
90 if (err != Error::NONE) {
91 hidl_cb(static_cast<IMapper_3_0_Error>(err), 0, hidl_vec<hidl_handle>());
92 return Void();
93 }
94
95 std::vector<hidl_handle> buffers;
96 buffers.reserve(count);
97 for (uint32_t i = 0; i < count; i++) {
98 buffer_handle_t buffer;
99 ALOGD_IF(DEBUG, "buffer: %p", &buffer);
100 err = buf_mgr_->AllocateBuffer(desc, &buffer);
101 if (err != Error::NONE) {
102 break;
103 }
104 buffers.emplace_back(hidl_handle(buffer));
105 }
106
107 uint32_t stride = 0;
108 hidl_vec<hidl_handle> hidl_buffers;
109 if (err == Error::NONE && buffers.size() > 0) {
110 stride = static_cast<uint32_t>(PRIV_HANDLE_CONST(buffers[0].getNativeHandle())->width);
111 hidl_buffers.setToExternal(buffers.data(), buffers.size());
112 }
113 hidl_cb(static_cast<IMapper_3_0_Error>(err), stride, hidl_buffers);
114
115 for (const auto &b : buffers) {
116 buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(b.getNativeHandle()));
117 }
118
119 return Void();
120 }
121
122 } // namespace implementation
123 } // namespace V3_0
124 } // namespace allocator
125 } // namespace display
126 } // namespace hardware
127 } // namespace qti
128 } // namespace vendor
129
130 namespace vendor {
131 namespace qti {
132 namespace hardware {
133 namespace display {
134 namespace allocator {
135 namespace V4_0 {
136 namespace implementation {
137
138 using android::hardware::hidl_handle;
139 using gralloc::BufferDescriptor;
140 using IMapper_4_0_Error = android::hardware::graphics::mapper::V4_0::Error;
141 using gralloc::Error;
142
QtiAllocator()143 QtiAllocator::QtiAllocator() {
144 gralloc::GrallocProperties properties;
145 get_properties(&properties);
146 buf_mgr_ = BufferManager::GetInstance();
147 buf_mgr_->SetGrallocDebugProperties(properties);
148 }
149
allocate(const hidl_vec<uint8_t> & descriptor,uint32_t count,allocate_cb hidl_cb)150 Return<void> QtiAllocator::allocate(const hidl_vec<uint8_t> &descriptor, uint32_t count,
151 allocate_cb hidl_cb) {
152 ALOGD_IF(DEBUG, "Allocating buffers count: %d", count);
153 gralloc::BufferDescriptor desc;
154
155 auto err = ::vendor::qti::hardware::display::mapper::V4_0::implementation::QtiMapper::Decode(
156 descriptor, &desc);
157 if (err != Error::NONE) {
158 hidl_cb(static_cast<IMapper_4_0_Error>(err), 0, hidl_vec<hidl_handle>());
159 return Void();
160 }
161
162 std::vector<hidl_handle> buffers;
163 buffers.reserve(count);
164 for (uint32_t i = 0; i < count; i++) {
165 buffer_handle_t buffer;
166 ALOGD_IF(DEBUG, "buffer: %p", &buffer);
167 err = buf_mgr_->AllocateBuffer(desc, &buffer);
168 if (err != Error::NONE) {
169 break;
170 }
171 buffers.emplace_back(hidl_handle(buffer));
172 }
173
174 uint32_t stride = 0;
175 hidl_vec<hidl_handle> hidl_buffers;
176 if (err == Error::NONE && buffers.size() > 0) {
177 stride = static_cast<uint32_t>(PRIV_HANDLE_CONST(buffers[0].getNativeHandle())->width);
178 hidl_buffers.setToExternal(buffers.data(), buffers.size());
179 }
180 hidl_cb(static_cast<IMapper_4_0_Error>(err), stride, hidl_buffers);
181
182 for (const auto &b : buffers) {
183 buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(b.getNativeHandle()));
184 }
185
186 return Void();
187 }
188
189 } // namespace implementation
190 } // namespace V4_0
191 } // namespace allocator
192 } // namespace display
193 } // namespace hardware
194 } // namespace qti
195 } // namespace vendor
196