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() { init(); }
26
init()27 void GrallocWrapper::init() {
28 mAllocator = allocator2::IAllocator::getService();
29 if (mAllocator == nullptr) {
30 ALOGE("Failed to get allocator service");
31 }
32
33 mMapper = mapper2::IMapper::getService();
34 if (mMapper == nullptr) {
35 ALOGE("Failed to get mapper service");
36 }
37 if (mMapper->isRemote()) {
38 ALOGE("Mapper is not in passthrough mode");
39 }
40 }
41
~GrallocWrapper()42 GrallocWrapper::~GrallocWrapper() {
43 for (auto bufferHandle : mClonedBuffers) {
44 auto buffer = const_cast<native_handle_t*>(bufferHandle);
45 native_handle_close(buffer);
46 native_handle_delete(buffer);
47 }
48 mClonedBuffers.clear();
49
50 for (auto bufferHandle : mImportedBuffers) {
51 auto buffer = const_cast<native_handle_t*>(bufferHandle);
52 if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) {
53 ALOGE("Failed to free buffer %p", buffer);
54 }
55 }
56 mImportedBuffers.clear();
57 }
58
getAllocator() const59 sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const {
60 return mAllocator;
61 }
62
dumpDebugInfo()63 std::string GrallocWrapper::dumpDebugInfo() {
64 std::string debugInfo;
65 mAllocator->dumpDebugInfo(
66 [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
67
68 return debugInfo;
69 }
70
cloneBuffer(const hardware::hidl_handle & rawHandle)71 const native_handle_t* GrallocWrapper::cloneBuffer(
72 const hardware::hidl_handle& rawHandle) {
73 const native_handle_t* bufferHandle =
74 native_handle_clone(rawHandle.getNativeHandle());
75
76 if (bufferHandle) {
77 mClonedBuffers.insert(bufferHandle);
78 }
79 return bufferHandle;
80 }
81
allocate(const mapper2::BufferDescriptor & descriptor,uint32_t count,bool import,uint32_t * outStride)82 std::vector<const native_handle_t*> GrallocWrapper::allocate(
83 const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import,
84 uint32_t* outStride) {
85 std::vector<const native_handle_t*> bufferHandles;
86 bufferHandles.reserve(count);
87 mAllocator->allocate(
88 descriptor, count,
89 [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
90 if (mapper2::Error::NONE != tmpError) {
91 ALOGE("Failed to allocate buffers");
92 }
93 if (count != tmpBuffers.size()) {
94 ALOGE("Invalid buffer array");
95 }
96
97 for (uint32_t i = 0; i < count; i++) {
98 if (import) {
99 bufferHandles.push_back(importBuffer(tmpBuffers[i]));
100 } else {
101 bufferHandles.push_back(cloneBuffer(tmpBuffers[i]));
102 }
103 }
104
105 if (outStride) {
106 *outStride = tmpStride;
107 }
108 });
109
110 return bufferHandles;
111 }
112
allocate(const mapper2::IMapper::BufferDescriptorInfo & descriptorInfo,bool import,uint32_t * outStride)113 const native_handle_t* GrallocWrapper::allocate(
114 const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import,
115 uint32_t* outStride) {
116 mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo);
117 ALOGE("QQ");
118 auto buffers = allocate(descriptor, 1, import, outStride);
119 return buffers[0];
120 }
121
getMapper() const122 sp<mapper2::IMapper> GrallocWrapper::getMapper() const { return mMapper; }
123
createDescriptor(const mapper2::IMapper::BufferDescriptorInfo & descriptorInfo)124 mapper2::BufferDescriptor GrallocWrapper::createDescriptor(
125 const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) {
126 mapper2::BufferDescriptor descriptor;
127 mMapper->createDescriptor(
128 descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
129 if (tmpError != mapper2::Error::NONE) {
130 ALOGE("Failed to create descriptor");
131 }
132 descriptor = tmpDescriptor;
133 });
134
135 return descriptor;
136 }
137
importBuffer(const hardware::hidl_handle & rawHandle)138 const native_handle_t* GrallocWrapper::importBuffer(
139 const hardware::hidl_handle& rawHandle) {
140 const native_handle_t* bufferHandle = nullptr;
141 mMapper->importBuffer(
142 rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
143 if (tmpError != mapper2::Error::NONE) {
144 ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle());
145 }
146 bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
147 });
148
149 if (bufferHandle) {
150 mImportedBuffers.insert(bufferHandle);
151 }
152
153 return bufferHandle;
154 }
155
freeBuffer(const native_handle_t * bufferHandle)156 void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) {
157 auto buffer = const_cast<native_handle_t*>(bufferHandle);
158
159 if (mImportedBuffers.erase(bufferHandle)) {
160 mapper2::Error error = mMapper->freeBuffer(buffer);
161 if (error != mapper2::Error::NONE) {
162 ALOGE("Failed to free %p", buffer);
163 }
164 } else {
165 mClonedBuffers.erase(bufferHandle);
166 native_handle_close(buffer);
167 native_handle_delete(buffer);
168 }
169 }
170
lock(const native_handle_t * bufferHandle,uint64_t cpuUsage,const mapper2::IMapper::Rect & accessRegion,int acquireFence)171 void* GrallocWrapper::lock(const native_handle_t* bufferHandle,
172 uint64_t cpuUsage,
173 const mapper2::IMapper::Rect& accessRegion,
174 int acquireFence) {
175 auto buffer = const_cast<native_handle_t*>(bufferHandle);
176
177 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
178 hardware::hidl_handle acquireFenceHandle;
179 if (acquireFence >= 0) {
180 auto h = native_handle_init(acquireFenceStorage, 1, 0);
181 h->data[0] = acquireFence;
182 acquireFenceHandle = h;
183 }
184
185 void* data = nullptr;
186 mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
187 [&](const auto& tmpError, const auto& tmpData) {
188 if (tmpError != mapper2::Error::NONE) {
189 ALOGE("Failed to lock buffer %p", buffer);
190 }
191 data = tmpData;
192 });
193
194 if (acquireFence >= 0) {
195 close(acquireFence);
196 }
197
198 return data;
199 }
200
unlock(const native_handle_t * bufferHandle)201 int GrallocWrapper::unlock(const native_handle_t* bufferHandle) {
202 auto buffer = const_cast<native_handle_t*>(bufferHandle);
203
204 int releaseFence = -1;
205 mMapper->unlock(buffer, [&](const auto& tmpError,
206 const auto& tmpReleaseFence) {
207 if (tmpError != mapper2::Error::NONE) {
208 ALOGE("Failed to unlock buffer %p", buffer);
209 }
210
211 auto fenceHandle = tmpReleaseFence.getNativeHandle();
212 if (fenceHandle) {
213 if (fenceHandle->numInts != 0) {
214 ALOGE("Invalid fence handle %p", fenceHandle);
215 }
216 if (fenceHandle->numFds == 1) {
217 releaseFence = dup(fenceHandle->data[0]);
218 if (releaseFence < 0){
219 ALOGE("Failed to dup fence fd");
220 }
221 } else {
222 if (fenceHandle->numFds != 0) {
223 ALOGE("Invalid fence handle %p", fenceHandle);
224 }
225 }
226 }
227 });
228
229 return releaseFence;
230 }
231
232 } // namespace android
233