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
30namespace android {
31
32namespace Gralloc2 {
33
34namespace {
35
36static constexpr Error kTransactionError = Error::NO_RESOURCES;
37
38uint64_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
53uint64_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
67void Mapper::preload() {
68    android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>();
69}
70
71Mapper::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
85Gralloc2::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
100Error 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
136Error 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
154void 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
164Error 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
178void 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
208Error 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
243Error 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
279int 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
316Allocator::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
325std::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
336Error 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