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