1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "GrallocWrapper"
18
19 #include "GrallocWrapper.h"
20
21 #include <utils/Log.h>
22
23 namespace android {
24
GrallocWrapper()25 GrallocWrapper::GrallocWrapper() {
26 init();
27 }
28
init()29 void GrallocWrapper::init() {
30 mAllocator = allocator2::IAllocator::getService();
31 if (mAllocator == nullptr) {
32 ALOGE("Failed to get allocator service");
33 }
34
35 mMapper = mapper2::IMapper::getService();
36 if (mMapper == nullptr) {
37 ALOGE("Failed to get mapper service");
38 }
39 if (mMapper->isRemote()) {
40 ALOGE("Mapper is not in passthrough mode");
41 }
42 }
43
~GrallocWrapper()44 GrallocWrapper::~GrallocWrapper() {
45 for (auto bufferHandle : mClonedBuffers) {
46 auto buffer = const_cast<native_handle_t*>(bufferHandle);
47 native_handle_close(buffer);
48 native_handle_delete(buffer);
49 }
50 mClonedBuffers.clear();
51
52 for (auto bufferHandle : mImportedBuffers) {
53 auto buffer = const_cast<native_handle_t*>(bufferHandle);
54 if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) {
55 ALOGE("Failed to free buffer %p", buffer);
56 }
57 }
58 mImportedBuffers.clear();
59 }
60
getAllocator() const61 sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const {
62 return mAllocator;
63 }
64
dumpDebugInfo()65 std::string GrallocWrapper::dumpDebugInfo() {
66 std::string debugInfo;
67 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
68
69 return debugInfo;
70 }
71
cloneBuffer(const hardware::hidl_handle & rawHandle)72 const native_handle_t* GrallocWrapper::cloneBuffer(const hardware::hidl_handle& rawHandle) {
73 const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
74
75 if (bufferHandle) {
76 mClonedBuffers.insert(bufferHandle);
77 }
78 return bufferHandle;
79 }
80
allocate(const mapper2::BufferDescriptor & descriptor,uint32_t count,bool import,uint32_t * outStride)81 std::vector<const native_handle_t*> GrallocWrapper::allocate(
82 const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import, uint32_t* outStride) {
83 std::vector<const native_handle_t*> bufferHandles;
84 bufferHandles.reserve(count);
85 mAllocator->allocate(descriptor, count,
86 [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
87 if (mapper2::Error::NONE != tmpError) {
88 ALOGE("Failed to allocate buffers");
89 }
90 if (count != tmpBuffers.size()) {
91 ALOGE("Invalid buffer array");
92 }
93
94 for (uint32_t i = 0; i < count; i++) {
95 if (import) {
96 bufferHandles.push_back(importBuffer(tmpBuffers[i]));
97 } else {
98 bufferHandles.push_back(cloneBuffer(tmpBuffers[i]));
99 }
100 }
101
102 if (outStride) {
103 *outStride = tmpStride;
104 }
105 });
106
107 return bufferHandles;
108 }
109
allocate(const mapper2::IMapper::BufferDescriptorInfo & descriptorInfo,bool import,uint32_t * outStride)110 const native_handle_t* GrallocWrapper::allocate(
111 const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import,
112 uint32_t* outStride) {
113 mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo);
114 auto buffers = allocate(descriptor, 1, import, outStride);
115 return buffers[0];
116 }
117
getMapper() const118 sp<mapper2::IMapper> GrallocWrapper::getMapper() const {
119 return mMapper;
120 }
121
createDescriptor(const mapper2::IMapper::BufferDescriptorInfo & descriptorInfo)122 mapper2::BufferDescriptor GrallocWrapper::createDescriptor(
123 const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) {
124 mapper2::BufferDescriptor descriptor;
125 mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
126 if (tmpError != mapper2::Error::NONE) {
127 ALOGE("Failed to create descriptor");
128 }
129 descriptor = tmpDescriptor;
130 });
131
132 return descriptor;
133 }
134
importBuffer(const hardware::hidl_handle & rawHandle)135 const native_handle_t* GrallocWrapper::importBuffer(const hardware::hidl_handle& rawHandle) {
136 const native_handle_t* bufferHandle = nullptr;
137 mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
138 if (tmpError != mapper2::Error::NONE) {
139 ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle());
140 }
141 bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
142 });
143
144 if (bufferHandle) {
145 mImportedBuffers.insert(bufferHandle);
146 }
147
148 return bufferHandle;
149 }
150
freeBuffer(const native_handle_t * bufferHandle)151 void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) {
152 auto buffer = const_cast<native_handle_t*>(bufferHandle);
153
154 if (mImportedBuffers.erase(bufferHandle)) {
155 mapper2::Error error = mMapper->freeBuffer(buffer);
156 if (error != mapper2::Error::NONE) {
157 ALOGE("Failed to free %p", buffer);
158 }
159 } else {
160 mClonedBuffers.erase(bufferHandle);
161 native_handle_close(buffer);
162 native_handle_delete(buffer);
163 }
164 }
165
lock(const native_handle_t * bufferHandle,uint64_t cpuUsage,const mapper2::IMapper::Rect & accessRegion,int acquireFence)166 void* GrallocWrapper::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
167 const mapper2::IMapper::Rect& accessRegion, int acquireFence) {
168 auto buffer = const_cast<native_handle_t*>(bufferHandle);
169
170 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
171 hardware::hidl_handle acquireFenceHandle;
172 if (acquireFence >= 0) {
173 auto h = native_handle_init(acquireFenceStorage, 1, 0);
174 h->data[0] = acquireFence;
175 acquireFenceHandle = h;
176 }
177
178 void* data = nullptr;
179 mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
180 [&](const auto& tmpError, const auto& tmpData) {
181 if (tmpError != mapper2::Error::NONE) {
182 ALOGE("Failed to lock buffer %p", buffer);
183 }
184 data = tmpData;
185 });
186
187 if (acquireFence >= 0) {
188 close(acquireFence);
189 }
190
191 return data;
192 }
193
unlock(const native_handle_t * bufferHandle)194 int GrallocWrapper::unlock(const native_handle_t* bufferHandle) {
195 auto buffer = const_cast<native_handle_t*>(bufferHandle);
196
197 int releaseFence = -1;
198 mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
199 if (tmpError != mapper2::Error::NONE) {
200 ALOGE("Failed to unlock buffer %p", buffer);
201 }
202
203 auto fenceHandle = tmpReleaseFence.getNativeHandle();
204 if (fenceHandle) {
205 if (fenceHandle->numInts != 0) {
206 ALOGE("Invalid fence handle %p", fenceHandle);
207 }
208 if (fenceHandle->numFds == 1) {
209 releaseFence = dup(fenceHandle->data[0]);
210 if (releaseFence < 0) {
211 ALOGE("Failed to dup fence fd");
212 }
213 } else {
214 if (fenceHandle->numFds != 0) {
215 ALOGE("Invalid fence handle %p", fenceHandle);
216 }
217 }
218 }
219 });
220
221 return releaseFence;
222 }
223
224 } // namespace android
225