c1fcb010d7
Bug: 37794556 Test: sensor vts passes on 2016 and 2017 devices Change-Id: Ibe1d076c24dc2cfe61dfd19aa5055c9075aa9e14 Merged-In: Ibe1d076c24dc2cfe61dfd19aa5055c9075aa9e14
232 lines
6.7 KiB
C++
232 lines
6.7 KiB
C++
/*
|
|
* 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);
|
|
ALOGE("QQ");
|
|
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
|