diff options
author | Brian Stack <bstack@google.com> | 2018-09-26 14:53:25 -0700 |
---|---|---|
committer | Brian Stack <bstack@google.com> | 2018-10-05 10:03:32 -0700 |
commit | eb755f55bb19e2a879c5607554ff21e6e7b5f076 (patch) | |
tree | 454c87b80557bbcb856f7377022931c683275a9b /sensors/common/vts/utils/GrallocWrapper.cpp | |
parent | 1c2f523a993ed5860a62e18b4f65507510f4c118 (diff) |
Move GrallocWrapper to common directory
Moves GrallocWrapper to a common directory so that it is able to be
used by different versions of Sensors HAL VTS testing.
Bug: 111070257
Test: Builds
Change-Id: I3b110a8b45a870d762c9ed09063115afa31e6ce3
Diffstat (limited to 'sensors/common/vts/utils/GrallocWrapper.cpp')
-rw-r--r-- | sensors/common/vts/utils/GrallocWrapper.cpp | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/sensors/common/vts/utils/GrallocWrapper.cpp b/sensors/common/vts/utils/GrallocWrapper.cpp new file mode 100644 index 0000000000..7bed16d6c4 --- /dev/null +++ b/sensors/common/vts/utils/GrallocWrapper.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2017 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 "GrallocWrapper" + +#include "GrallocWrapper.h" + +#include <utils/Log.h> + +namespace android { + +GrallocWrapper::GrallocWrapper() { + init(); +} + +void GrallocWrapper::init() { + mAllocator = allocator2::IAllocator::getService(); + if (mAllocator == nullptr) { + ALOGE("Failed to get allocator service"); + } + + mMapper = mapper2::IMapper::getService(); + if (mMapper == nullptr) { + ALOGE("Failed to get mapper service"); + } + if (mMapper->isRemote()) { + ALOGE("Mapper is not in passthrough mode"); + } +} + +GrallocWrapper::~GrallocWrapper() { + for (auto bufferHandle : mClonedBuffers) { + auto buffer = const_cast<native_handle_t*>(bufferHandle); + native_handle_close(buffer); + native_handle_delete(buffer); + } + mClonedBuffers.clear(); + + for (auto bufferHandle : mImportedBuffers) { + auto buffer = const_cast<native_handle_t*>(bufferHandle); + if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) { + ALOGE("Failed to free buffer %p", buffer); + } + } + mImportedBuffers.clear(); +} + +sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const { + return mAllocator; +} + +std::string GrallocWrapper::dumpDebugInfo() { + std::string debugInfo; + mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); }); + + return debugInfo; +} + +const native_handle_t* GrallocWrapper::cloneBuffer(const hardware::hidl_handle& rawHandle) { + const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle()); + + if (bufferHandle) { + mClonedBuffers.insert(bufferHandle); + } + return bufferHandle; +} + +std::vector<const native_handle_t*> GrallocWrapper::allocate( + const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import, uint32_t* outStride) { + std::vector<const native_handle_t*> bufferHandles; + bufferHandles.reserve(count); + mAllocator->allocate(descriptor, count, + [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) { + if (mapper2::Error::NONE != tmpError) { + ALOGE("Failed to allocate buffers"); + } + if (count != tmpBuffers.size()) { + ALOGE("Invalid buffer array"); + } + + for (uint32_t i = 0; i < count; i++) { + if (import) { + bufferHandles.push_back(importBuffer(tmpBuffers[i])); + } else { + bufferHandles.push_back(cloneBuffer(tmpBuffers[i])); + } + } + + if (outStride) { + *outStride = tmpStride; + } + }); + + return bufferHandles; +} + +const native_handle_t* GrallocWrapper::allocate( + const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import, + uint32_t* outStride) { + mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo); + auto buffers = allocate(descriptor, 1, import, outStride); + return buffers[0]; +} + +sp<mapper2::IMapper> GrallocWrapper::getMapper() const { + return mMapper; +} + +mapper2::BufferDescriptor GrallocWrapper::createDescriptor( + const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) { + mapper2::BufferDescriptor descriptor; + mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) { + if (tmpError != mapper2::Error::NONE) { + ALOGE("Failed to create descriptor"); + } + descriptor = tmpDescriptor; + }); + + return descriptor; +} + +const native_handle_t* GrallocWrapper::importBuffer(const hardware::hidl_handle& rawHandle) { + const native_handle_t* bufferHandle = nullptr; + mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) { + if (tmpError != mapper2::Error::NONE) { + ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle()); + } + bufferHandle = static_cast<const native_handle_t*>(tmpBuffer); + }); + + if (bufferHandle) { + mImportedBuffers.insert(bufferHandle); + } + + return bufferHandle; +} + +void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) { + auto buffer = const_cast<native_handle_t*>(bufferHandle); + + if (mImportedBuffers.erase(bufferHandle)) { + mapper2::Error error = mMapper->freeBuffer(buffer); + if (error != mapper2::Error::NONE) { + ALOGE("Failed to free %p", buffer); + } + } else { + mClonedBuffers.erase(bufferHandle); + native_handle_close(buffer); + native_handle_delete(buffer); + } +} + +void* GrallocWrapper::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, + const mapper2::IMapper::Rect& accessRegion, int acquireFence) { + auto buffer = const_cast<native_handle_t*>(bufferHandle); + + NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); + hardware::hidl_handle acquireFenceHandle; + if (acquireFence >= 0) { + auto h = native_handle_init(acquireFenceStorage, 1, 0); + h->data[0] = acquireFence; + acquireFenceHandle = h; + } + + void* data = nullptr; + mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle, + [&](const auto& tmpError, const auto& tmpData) { + if (tmpError != mapper2::Error::NONE) { + ALOGE("Failed to lock buffer %p", buffer); + } + data = tmpData; + }); + + if (acquireFence >= 0) { + close(acquireFence); + } + + return data; +} + +int GrallocWrapper::unlock(const native_handle_t* bufferHandle) { + auto buffer = const_cast<native_handle_t*>(bufferHandle); + + int releaseFence = -1; + mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) { + if (tmpError != mapper2::Error::NONE) { + ALOGE("Failed to unlock buffer %p", buffer); + } + + auto fenceHandle = tmpReleaseFence.getNativeHandle(); + if (fenceHandle) { + if (fenceHandle->numInts != 0) { + ALOGE("Invalid fence handle %p", fenceHandle); + } + if (fenceHandle->numFds == 1) { + releaseFence = dup(fenceHandle->data[0]); + if (releaseFence < 0) { + ALOGE("Failed to dup fence fd"); + } + } else { + if (fenceHandle->numFds != 0) { + ALOGE("Invalid fence handle %p", fenceHandle); + } + } + } + }); + + return releaseFence; +} + +} // namespace android |