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