1 /*
2  * Copyright 2016 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 "Gralloc2"
18 
19 #include <hidl/ServiceManagement.h>
20 #include <hwbinder/IPCThreadState.h>
21 #include <ui/Gralloc2.h>
22 
23 #include <inttypes.h>
24 #include <log/log.h>
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wzero-length-array"
27 #include <sync/sync.h>
28 #pragma clang diagnostic pop
29 
30 namespace android {
31 
32 namespace Gralloc2 {
33 
34 namespace {
35 
36 static constexpr Error kTransactionError = Error::NO_RESOURCES;
37 
getValid10UsageBits()38 uint64_t getValid10UsageBits() {
39     static const uint64_t valid10UsageBits = []() -> uint64_t {
40         using hardware::graphics::common::V1_0::BufferUsage;
41         uint64_t bits = 0;
42         for (const auto bit : hardware::hidl_enum_iterator<BufferUsage>()) {
43             bits = bits | bit;
44         }
45         // TODO(b/72323293, b/72703005): Remove these additional bits
46         bits = bits | (1 << 10) | (1 << 13);
47 
48         return bits;
49     }();
50     return valid10UsageBits;
51 }
52 
getValid11UsageBits()53 uint64_t getValid11UsageBits() {
54     static const uint64_t valid11UsageBits = []() -> uint64_t {
55         using hardware::graphics::common::V1_1::BufferUsage;
56         uint64_t bits = 0;
57         for (const auto bit : hardware::hidl_enum_iterator<BufferUsage>()) {
58             bits = bits | bit;
59         }
60         return bits;
61     }();
62     return valid11UsageBits;
63 }
64 
65 }  // anonymous namespace
66 
preload()67 void Mapper::preload() {
68     android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>();
69 }
70 
Mapper()71 Mapper::Mapper()
72 {
73     mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
74     if (mMapper == nullptr) {
75         LOG_ALWAYS_FATAL("gralloc-mapper is missing");
76     }
77     if (mMapper->isRemote()) {
78         LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
79     }
80 
81     // IMapper 2.1 is optional
82     mMapperV2_1 = IMapper::castFrom(mMapper);
83 }
84 
validateBufferDescriptorInfo(const IMapper::BufferDescriptorInfo & descriptorInfo) const85 Gralloc2::Error Mapper::validateBufferDescriptorInfo(
86         const IMapper::BufferDescriptorInfo& descriptorInfo) const {
87     uint64_t validUsageBits = getValid10UsageBits();
88     if (mMapperV2_1 != nullptr) {
89         validUsageBits = validUsageBits | getValid11UsageBits();
90     }
91 
92     if (descriptorInfo.usage & ~validUsageBits) {
93         ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
94               descriptorInfo.usage & ~validUsageBits);
95         return Error::BAD_VALUE;
96     }
97     return Error::NONE;
98 }
99 
createDescriptor(const IMapper::BufferDescriptorInfo & descriptorInfo,BufferDescriptor * outDescriptor) const100 Error Mapper::createDescriptor(
101         const IMapper::BufferDescriptorInfo& descriptorInfo,
102         BufferDescriptor* outDescriptor) const
103 {
104     Error error = validateBufferDescriptorInfo(descriptorInfo);
105     if (error != Error::NONE) {
106         return error;
107     }
108 
109     auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor)
110                    {
111                        error = tmpError;
112                        if (error != Error::NONE) {
113                            return;
114                        }
115 
116                        *outDescriptor = tmpDescriptor;
117                    };
118 
119     hardware::Return<void> ret;
120     if (mMapperV2_1 != nullptr) {
121         ret = mMapperV2_1->createDescriptor_2_1(descriptorInfo, hidl_cb);
122     } else {
123         const hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo info = {
124             descriptorInfo.width,
125             descriptorInfo.height,
126             descriptorInfo.layerCount,
127             static_cast<hardware::graphics::common::V1_0::PixelFormat>(descriptorInfo.format),
128             descriptorInfo.usage,
129         };
130         ret = mMapper->createDescriptor(info, hidl_cb);
131     }
132 
133     return (ret.isOk()) ? error : kTransactionError;
134 }
135 
importBuffer(const hardware::hidl_handle & rawHandle,buffer_handle_t * outBufferHandle) const136 Error Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
137         buffer_handle_t* outBufferHandle) const
138 {
139     Error error;
140     auto ret = mMapper->importBuffer(rawHandle,
141             [&](const auto& tmpError, const auto& tmpBuffer)
142             {
143                 error = tmpError;
144                 if (error != Error::NONE) {
145                     return;
146                 }
147 
148                 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
149             });
150 
151     return (ret.isOk()) ? error : kTransactionError;
152 }
153 
freeBuffer(buffer_handle_t bufferHandle) const154 void Mapper::freeBuffer(buffer_handle_t bufferHandle) const
155 {
156     auto buffer = const_cast<native_handle_t*>(bufferHandle);
157     auto ret = mMapper->freeBuffer(buffer);
158 
159     auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
160     ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
161             buffer, error);
162 }
163 
validateBufferSize(buffer_handle_t bufferHandle,const IMapper::BufferDescriptorInfo & descriptorInfo,uint32_t stride) const164 Error Mapper::validateBufferSize(buffer_handle_t bufferHandle,
165         const IMapper::BufferDescriptorInfo& descriptorInfo,
166         uint32_t stride) const
167 {
168     if (mMapperV2_1 == nullptr) {
169         return Error::NONE;
170     }
171 
172     auto buffer = const_cast<native_handle_t*>(bufferHandle);
173     auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride);
174 
175     return (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
176 }
177 
getTransportSize(buffer_handle_t bufferHandle,uint32_t * outNumFds,uint32_t * outNumInts) const178 void Mapper::getTransportSize(buffer_handle_t bufferHandle,
179         uint32_t* outNumFds, uint32_t* outNumInts) const
180 {
181     *outNumFds = uint32_t(bufferHandle->numFds);
182     *outNumInts = uint32_t(bufferHandle->numInts);
183 
184     if (mMapperV2_1 == nullptr) {
185         return;
186     }
187 
188     Error error;
189     auto buffer = const_cast<native_handle_t*>(bufferHandle);
190     auto ret = mMapperV2_1->getTransportSize(buffer,
191             [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
192                 error = tmpError;
193                 if (error != Error::NONE) {
194                     return;
195                 }
196 
197                 *outNumFds = tmpNumFds;
198                 *outNumInts = tmpNumInts;
199             });
200 
201     if (!ret.isOk()) {
202         error = kTransactionError;
203     }
204     ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d",
205             buffer, error);
206 }
207 
lock(buffer_handle_t bufferHandle,uint64_t usage,const IMapper::Rect & accessRegion,int acquireFence,void ** outData) const208 Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
209         const IMapper::Rect& accessRegion,
210         int acquireFence, void** outData) const
211 {
212     auto buffer = const_cast<native_handle_t*>(bufferHandle);
213 
214     // put acquireFence in a hidl_handle
215     hardware::hidl_handle acquireFenceHandle;
216     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
217     if (acquireFence >= 0) {
218         auto h = native_handle_init(acquireFenceStorage, 1, 0);
219         h->data[0] = acquireFence;
220         acquireFenceHandle = h;
221     }
222 
223     Error error;
224     auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
225             [&](const auto& tmpError, const auto& tmpData)
226             {
227                 error = tmpError;
228                 if (error != Error::NONE) {
229                     return;
230                 }
231 
232                 *outData = tmpData;
233             });
234 
235     // we own acquireFence even on errors
236     if (acquireFence >= 0) {
237         close(acquireFence);
238     }
239 
240     return (ret.isOk()) ? error : kTransactionError;
241 }
242 
lock(buffer_handle_t bufferHandle,uint64_t usage,const IMapper::Rect & accessRegion,int acquireFence,YCbCrLayout * outLayout) const243 Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
244         const IMapper::Rect& accessRegion,
245         int acquireFence, YCbCrLayout* outLayout) const
246 {
247     auto buffer = const_cast<native_handle_t*>(bufferHandle);
248 
249     // put acquireFence in a hidl_handle
250     hardware::hidl_handle acquireFenceHandle;
251     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
252     if (acquireFence >= 0) {
253         auto h = native_handle_init(acquireFenceStorage, 1, 0);
254         h->data[0] = acquireFence;
255         acquireFenceHandle = h;
256     }
257 
258     Error error;
259     auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
260             acquireFenceHandle,
261             [&](const auto& tmpError, const auto& tmpLayout)
262             {
263                 error = tmpError;
264                 if (error != Error::NONE) {
265                     return;
266                 }
267 
268                 *outLayout = tmpLayout;
269             });
270 
271     // we own acquireFence even on errors
272     if (acquireFence >= 0) {
273         close(acquireFence);
274     }
275 
276     return (ret.isOk()) ? error : kTransactionError;
277 }
278 
unlock(buffer_handle_t bufferHandle) const279 int Mapper::unlock(buffer_handle_t bufferHandle) const
280 {
281     auto buffer = const_cast<native_handle_t*>(bufferHandle);
282 
283     int releaseFence = -1;
284     Error error;
285     auto ret = mMapper->unlock(buffer,
286             [&](const auto& tmpError, const auto& tmpReleaseFence)
287             {
288                 error = tmpError;
289                 if (error != Error::NONE) {
290                     return;
291                 }
292 
293                 auto fenceHandle = tmpReleaseFence.getNativeHandle();
294                 if (fenceHandle && fenceHandle->numFds == 1) {
295                     int fd = dup(fenceHandle->data[0]);
296                     if (fd >= 0) {
297                         releaseFence = fd;
298                     } else {
299                         ALOGD("failed to dup unlock release fence");
300                         sync_wait(fenceHandle->data[0], -1);
301                     }
302                 }
303             });
304 
305     if (!ret.isOk()) {
306         error = kTransactionError;
307     }
308 
309     if (error != Error::NONE) {
310         ALOGE("unlock(%p) failed with %d", buffer, error);
311     }
312 
313     return releaseFence;
314 }
315 
Allocator(const Mapper & mapper)316 Allocator::Allocator(const Mapper& mapper)
317     : mMapper(mapper)
318 {
319     mAllocator = IAllocator::getService();
320     if (mAllocator == nullptr) {
321         LOG_ALWAYS_FATAL("gralloc-alloc is missing");
322     }
323 }
324 
dumpDebugInfo() const325 std::string Allocator::dumpDebugInfo() const
326 {
327     std::string debugInfo;
328 
329     mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
330         debugInfo = tmpDebugInfo.c_str();
331     });
332 
333     return debugInfo;
334 }
335 
allocate(BufferDescriptor descriptor,uint32_t count,uint32_t * outStride,buffer_handle_t * outBufferHandles) const336 Error Allocator::allocate(BufferDescriptor descriptor, uint32_t count,
337         uint32_t* outStride, buffer_handle_t* outBufferHandles) const
338 {
339     Error error;
340     auto ret = mAllocator->allocate(descriptor, count,
341             [&](const auto& tmpError, const auto& tmpStride,
342                 const auto& tmpBuffers) {
343                 error = tmpError;
344                 if (tmpError != Error::NONE) {
345                     return;
346                 }
347 
348                 // import buffers
349                 for (uint32_t i = 0; i < count; i++) {
350                     error = mMapper.importBuffer(tmpBuffers[i],
351                             &outBufferHandles[i]);
352                     if (error != Error::NONE) {
353                         for (uint32_t j = 0; j < i; j++) {
354                             mMapper.freeBuffer(outBufferHandles[j]);
355                             outBufferHandles[j] = nullptr;
356                         }
357                         return;
358                     }
359                 }
360 
361                 *outStride = tmpStride;
362             });
363 
364     // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
365     hardware::IPCThreadState::self()->flushCommands();
366 
367     return (ret.isOk()) ? error : kTransactionError;
368 }
369 
370 } // namespace Gralloc2
371 
372 } // namespace android
373