| /* | |
| * Copyright 2016 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #define LOG_TAG "GrallocMapper" | |
| #include <ui/GrallocMapper.h> | |
| #include <log/log.h> | |
| namespace android { | |
| namespace Gralloc2 { | |
| static constexpr Error kDefaultError = Error::NO_RESOURCES; | |
| Mapper::Mapper() | |
| { | |
| mMapper = IMapper::getService(); | |
| if (mMapper != nullptr && mMapper->isRemote()) { | |
| LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode"); | |
| } | |
| } | |
| Error Mapper::retain(buffer_handle_t handle) const | |
| { | |
| auto ret = mMapper->retain(handle); | |
| return (ret.isOk()) ? static_cast<Error>(ret) : kDefaultError; | |
| } | |
| void Mapper::release(buffer_handle_t handle) const | |
| { | |
| auto ret = mMapper->release(handle); | |
| auto error = (ret.isOk()) ? static_cast<Error>(ret) : kDefaultError; | |
| ALOGE_IF(error != Error::NONE, | |
| "release(%p) failed with %d", handle, error); | |
| } | |
| Error Mapper::getDimensions(buffer_handle_t handle, | |
| uint32_t* outWidth, uint32_t* outHeight) const | |
| { | |
| Error error = kDefaultError; | |
| mMapper->getDimensions(handle, | |
| [&](const auto& tmpError, const auto& tmpWidth, | |
| const auto& tmpHeight) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| *outWidth = tmpWidth; | |
| *outHeight = tmpHeight; | |
| }); | |
| return error; | |
| } | |
| Error Mapper::getFormat(buffer_handle_t handle, int32_t* outFormat) const | |
| { | |
| Error error = kDefaultError; | |
| mMapper->getFormat(handle, | |
| [&](const auto& tmpError, const auto& tmpFormat) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| *outFormat = static_cast<int32_t>(tmpFormat); | |
| }); | |
| return error; | |
| } | |
| Error Mapper::getLayerCount(buffer_handle_t handle, | |
| uint32_t* outLayerCount) const | |
| { | |
| Error error = kDefaultError; | |
| mMapper->getLayerCount(handle, | |
| [&](const auto& tmpError, const auto& tmpLayerCount) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| *outLayerCount = tmpLayerCount; | |
| }); | |
| return error; | |
| } | |
| Error Mapper::getProducerUsage(buffer_handle_t handle, | |
| uint64_t* outProducerUsage) const | |
| { | |
| Error error = kDefaultError; | |
| mMapper->getProducerUsageMask(handle, | |
| [&](const auto& tmpError, const auto& tmpProducerUsage) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| *outProducerUsage = tmpProducerUsage; | |
| }); | |
| return error; | |
| } | |
| Error Mapper::getConsumerUsage(buffer_handle_t handle, | |
| uint64_t* outConsumerUsage) const | |
| { | |
| Error error = kDefaultError; | |
| mMapper->getConsumerUsageMask(handle, | |
| [&](const auto& tmpError, const auto& tmpConsumerUsage) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| *outConsumerUsage = tmpConsumerUsage; | |
| }); | |
| return error; | |
| } | |
| Error Mapper::getBackingStore(buffer_handle_t handle, | |
| uint64_t* outBackingStore) const | |
| { | |
| Error error = kDefaultError; | |
| mMapper->getBackingStore(handle, | |
| [&](const auto& tmpError, const auto& tmpStore) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| *outBackingStore = tmpStore; | |
| }); | |
| return error; | |
| } | |
| Error Mapper::getStride(buffer_handle_t handle, uint32_t* outStride) const | |
| { | |
| Error error = kDefaultError; | |
| mMapper->getStride(handle, | |
| [&](const auto& tmpError, const auto& tmpStride) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| *outStride = tmpStride; | |
| }); | |
| return error; | |
| } | |
| Error Mapper::lock(buffer_handle_t handle, | |
| uint64_t producerUsage, | |
| uint64_t consumerUsage, | |
| const IMapper::Rect& accessRegion, | |
| int acquireFence, void** outData) const | |
| { | |
| hardware::hidl_handle acquireFenceHandle; | |
| NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); | |
| if (acquireFence >= 0) { | |
| auto h = native_handle_init(acquireFenceStorage, 1, 0); | |
| h->data[0] = acquireFence; | |
| acquireFenceHandle = h; | |
| } | |
| Error error = kDefaultError; | |
| mMapper->lock(handle, producerUsage, consumerUsage, | |
| accessRegion, acquireFenceHandle, | |
| [&](const auto& tmpError, const auto& tmpData) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| *outData = tmpData; | |
| }); | |
| if (error == Error::NONE && acquireFence >= 0) { | |
| close(acquireFence); | |
| } | |
| return error; | |
| } | |
| Error Mapper::lock(buffer_handle_t handle, | |
| uint64_t producerUsage, | |
| uint64_t consumerUsage, | |
| const IMapper::Rect& accessRegion, | |
| int acquireFence, FlexLayout* outLayout) const | |
| { | |
| hardware::hidl_handle acquireFenceHandle; | |
| NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); | |
| if (acquireFence >= 0) { | |
| auto h = native_handle_init(acquireFenceStorage, 1, 0); | |
| h->data[0] = acquireFence; | |
| acquireFenceHandle = h; | |
| } | |
| Error error = kDefaultError; | |
| mMapper->lockFlex(handle, producerUsage, consumerUsage, | |
| accessRegion, acquireFenceHandle, | |
| [&](const auto& tmpError, const auto& tmpLayout) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| *outLayout = tmpLayout; | |
| }); | |
| if (error == Error::NONE && acquireFence >= 0) { | |
| close(acquireFence); | |
| } | |
| return error; | |
| } | |
| int Mapper::unlock(buffer_handle_t handle) const | |
| { | |
| int releaseFence = -1; | |
| Error error = kDefaultError; | |
| mMapper->unlock(handle, | |
| [&](const auto& tmpError, const auto& tmpReleaseFence) | |
| { | |
| error = tmpError; | |
| if (error != Error::NONE) { | |
| return; | |
| } | |
| auto fenceHandle = tmpReleaseFence.getNativeHandle(); | |
| if (fenceHandle && fenceHandle->numFds == 1) { | |
| int fd = dup(fenceHandle->data[0]); | |
| if (fd >= 0) { | |
| releaseFence = fd; | |
| } else { | |
| error = Error::NO_RESOURCES; | |
| } | |
| } else { | |
| releaseFence = -1; | |
| } | |
| }); | |
| if (error != Error::NONE) { | |
| ALOGE("unlock(%p) failed with %d", handle, error); | |
| releaseFence = -1; | |
| } | |
| return releaseFence; | |
| } | |
| } // namespace Gralloc2 | |
| } // namespace android |