mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Add support for new gralloc HAL versions am: df6e2b70ae
am: 1eee061c84
Change-Id: I0e1d3c2a620ec6027825815c9726e911e4600ddd
This commit is contained in:
@@ -24,7 +24,10 @@ cc_test {
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
"android.hardware.graphics.allocator@3.0",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.sensors@1.0",
|
||||
"VtsHalSensorsTargetTestUtils",
|
||||
],
|
||||
|
||||
@@ -24,7 +24,10 @@ cc_test {
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
"android.hardware.graphics.allocator@3.0",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.sensors@1.0",
|
||||
"android.hardware.sensors@2.0",
|
||||
"libfmq",
|
||||
|
||||
@@ -31,7 +31,10 @@ cc_library_static {
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.graphics.allocator@2.0",
|
||||
"android.hardware.graphics.allocator@3.0",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.sensors@1.0",
|
||||
"VtsHalHidlTargetTestBase",
|
||||
],
|
||||
|
||||
@@ -16,206 +16,262 @@
|
||||
|
||||
#include "GrallocWrapper.h"
|
||||
|
||||
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
|
||||
#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
|
||||
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
|
||||
#include <android/hardware/graphics/mapper/2.1/IMapper.h>
|
||||
#include <android/hardware/graphics/mapper/3.0/IMapper.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <cinttypes>
|
||||
#include <type_traits>
|
||||
|
||||
using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator;
|
||||
using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator;
|
||||
using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper;
|
||||
using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper;
|
||||
using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper;
|
||||
|
||||
using Error2 = ::android::hardware::graphics::mapper::V2_0::Error;
|
||||
using Error3 = ::android::hardware::graphics::mapper::V3_0::Error;
|
||||
|
||||
using ::android::hardware::graphics::common::V1_0::BufferUsage;
|
||||
using ::android::hardware::graphics::common::V1_0::PixelFormat;
|
||||
|
||||
// This is a typedef to the same underlying type across v2.0 and v3.0
|
||||
using ::android::hardware::graphics::mapper::V2_0::BufferDescriptor;
|
||||
|
||||
using ::android::hardware::hidl_handle;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
|
||||
namespace android {
|
||||
|
||||
GrallocWrapper::GrallocWrapper() {
|
||||
init();
|
||||
// Since we use the same APIs across allocator/mapper HALs but they have major
|
||||
// version differences (meaning they are not related through inheritance), we
|
||||
// create a common interface abstraction for the IAllocator + IMapper combination
|
||||
// (major versions need to match in the current HALs, e.g. IAllocator 3.0 needs to
|
||||
// be paired with IMapper 3.0, so these are tied together)
|
||||
class IGrallocHalWrapper {
|
||||
public:
|
||||
virtual ~IGrallocHalWrapper() = default;
|
||||
|
||||
// IAllocator
|
||||
virtual std::string dumpDebugInfo() = 0;
|
||||
virtual native_handle_t* allocate(uint32_t size) = 0;
|
||||
virtual void freeBuffer(native_handle_t* bufferHandle) = 0;
|
||||
|
||||
// IMapper
|
||||
virtual void* lock(native_handle_t* bufferHandle) = 0;
|
||||
virtual void unlock(native_handle_t* bufferHandle) = 0;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
bool failed(Error2 error) {
|
||||
return (error != Error2::NONE);
|
||||
}
|
||||
bool failed(Error3 error) {
|
||||
return (error != Error3::NONE);
|
||||
}
|
||||
|
||||
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");
|
||||
} else 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);
|
||||
// Since all the type and function names are the same for the things we use across the major HAL
|
||||
// versions, we use template magic to avoid repeating ourselves.
|
||||
template <typename AllocatorT, typename MapperT>
|
||||
class GrallocHalWrapper : public IGrallocHalWrapper {
|
||||
public:
|
||||
GrallocHalWrapper(const sp<AllocatorT>& allocator, const sp<MapperT>& mapper)
|
||||
: mAllocator(allocator), mMapper(mapper) {
|
||||
if (mapper->isRemote()) {
|
||||
ALOGE("Mapper is in passthrough mode");
|
||||
}
|
||||
}
|
||||
mImportedBuffers.clear();
|
||||
}
|
||||
|
||||
sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const {
|
||||
return mAllocator;
|
||||
}
|
||||
virtual std::string dumpDebugInfo() override;
|
||||
virtual native_handle_t* allocate(uint32_t size) override;
|
||||
virtual void freeBuffer(native_handle_t* bufferHandle) override;
|
||||
|
||||
std::string GrallocWrapper::dumpDebugInfo() {
|
||||
virtual void* lock(native_handle_t* bufferHandle) override;
|
||||
virtual void unlock(native_handle_t* bufferHandle) override;
|
||||
|
||||
private:
|
||||
static constexpr uint64_t kBufferUsage =
|
||||
static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::CPU_READ_OFTEN);
|
||||
sp<AllocatorT> mAllocator;
|
||||
sp<MapperT> mMapper;
|
||||
|
||||
BufferDescriptor getDescriptor(uint32_t size);
|
||||
native_handle_t* importBuffer(const hidl_handle& rawHandle);
|
||||
};
|
||||
|
||||
template <typename AllocatorT, typename MapperT>
|
||||
std::string GrallocHalWrapper<AllocatorT, MapperT>::dumpDebugInfo() {
|
||||
std::string debugInfo;
|
||||
mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
|
||||
|
||||
mAllocator->dumpDebugInfo([&](const hidl_string& tmpDebugInfo) { debugInfo = tmpDebugInfo; });
|
||||
return debugInfo;
|
||||
}
|
||||
|
||||
const native_handle_t* GrallocWrapper::cloneBuffer(const hardware::hidl_handle& rawHandle) {
|
||||
const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
|
||||
template <typename AllocatorT, typename MapperT>
|
||||
native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::allocate(uint32_t size) {
|
||||
constexpr uint32_t kBufferCount = 1;
|
||||
BufferDescriptor descriptor = getDescriptor(size);
|
||||
native_handle_t* bufferHandle = nullptr;
|
||||
|
||||
if (bufferHandle) {
|
||||
mClonedBuffers.insert(bufferHandle);
|
||||
}
|
||||
auto callback = [&](auto error, uint32_t /*stride*/, const hidl_vec<hidl_handle>& buffers) {
|
||||
if (failed(error)) {
|
||||
ALOGE("Failed to allocate buffer: %" PRId32, static_cast<int32_t>(error));
|
||||
} else if (buffers.size() != kBufferCount) {
|
||||
ALOGE("Invalid buffer array size (got %zu, expected %" PRIu32 ")", buffers.size(),
|
||||
kBufferCount);
|
||||
} else {
|
||||
bufferHandle = importBuffer(buffers[0]);
|
||||
}
|
||||
};
|
||||
|
||||
mAllocator->allocate(descriptor, kBufferCount, callback);
|
||||
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;
|
||||
template <typename AllocatorT, typename MapperT>
|
||||
void GrallocHalWrapper<AllocatorT, MapperT>::freeBuffer(native_handle_t* bufferHandle) {
|
||||
auto error = mMapper->freeBuffer(bufferHandle);
|
||||
if (!error.isOk() || failed(error)) {
|
||||
ALOGE("Failed to free buffer %p", bufferHandle);
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
template <typename AllocatorT, typename MapperT>
|
||||
BufferDescriptor GrallocHalWrapper<AllocatorT, MapperT>::getDescriptor(uint32_t size) {
|
||||
typename MapperT::BufferDescriptorInfo descriptorInfo = {
|
||||
.width = size,
|
||||
.height = 1,
|
||||
.layerCount = 1,
|
||||
.usage = kBufferUsage,
|
||||
.format = static_cast<decltype(descriptorInfo.format)>(PixelFormat::BLOB),
|
||||
};
|
||||
|
||||
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");
|
||||
BufferDescriptor descriptor;
|
||||
auto callback = [&](auto error, const BufferDescriptor& tmpDescriptor) {
|
||||
if (failed(error)) {
|
||||
ALOGE("Failed to create descriptor: %" PRId32, static_cast<int32_t>(error));
|
||||
} else {
|
||||
descriptor = tmpDescriptor;
|
||||
}
|
||||
descriptor = tmpDescriptor;
|
||||
});
|
||||
};
|
||||
|
||||
mMapper->createDescriptor(descriptorInfo, callback);
|
||||
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);
|
||||
});
|
||||
template <typename AllocatorT, typename MapperT>
|
||||
native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::importBuffer(
|
||||
const hidl_handle& rawHandle) {
|
||||
native_handle_t* bufferHandle = nullptr;
|
||||
|
||||
if (bufferHandle) {
|
||||
mImportedBuffers.insert(bufferHandle);
|
||||
}
|
||||
mMapper->importBuffer(rawHandle, [&](auto error, void* tmpBuffer) {
|
||||
if (failed(error)) {
|
||||
ALOGE("Failed to import buffer %p: %" PRId32, rawHandle.getNativeHandle(),
|
||||
static_cast<int32_t>(error));
|
||||
} else {
|
||||
bufferHandle = static_cast<native_handle_t*>(tmpBuffer);
|
||||
}
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
template <typename AllocatorT, typename MapperT>
|
||||
void* GrallocHalWrapper<AllocatorT, MapperT>::lock(native_handle_t* bufferHandle) {
|
||||
// Per the HAL, all-zeros Rect means the entire buffer
|
||||
typename MapperT::Rect accessRegion = {};
|
||||
hidl_handle acquireFenceHandle; // No fence needed, already safe to lock
|
||||
|
||||
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);
|
||||
mMapper->lock(bufferHandle, kBufferUsage, accessRegion, acquireFenceHandle,
|
||||
[&](auto error, void* tmpData, ...) { // V3_0 passes extra args we don't use
|
||||
if (failed(error)) {
|
||||
ALOGE("Failed to lock buffer %p: %" PRId32, bufferHandle,
|
||||
static_cast<int32_t>(error));
|
||||
} else {
|
||||
data = tmpData;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
template <typename AllocatorT, typename MapperT>
|
||||
void GrallocHalWrapper<AllocatorT, MapperT>::unlock(native_handle_t* bufferHandle) {
|
||||
mMapper->unlock(bufferHandle, [&](auto error, const hidl_handle& /*releaseFence*/) {
|
||||
if (failed(error)) {
|
||||
ALOGE("Failed to unlock buffer %p: %" PRId32, bufferHandle,
|
||||
static_cast<int32_t>(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return releaseFence;
|
||||
} // anonymous namespace
|
||||
|
||||
GrallocWrapper::GrallocWrapper() {
|
||||
sp<IAllocator3> allocator3 = IAllocator3::getService();
|
||||
sp<IMapper3> mapper3 = IMapper3::getService();
|
||||
|
||||
if (allocator3 != nullptr && mapper3 != nullptr) {
|
||||
mGrallocHal = std::unique_ptr<IGrallocHalWrapper>(
|
||||
new GrallocHalWrapper<IAllocator3, IMapper3>(allocator3, mapper3));
|
||||
} else {
|
||||
ALOGD("Graphics HALs 3.0 not found (allocator %d mapper %d), falling back to 2.x",
|
||||
(allocator3 != nullptr), (mapper3 != nullptr));
|
||||
|
||||
sp<IAllocator2> allocator2 = IAllocator2::getService();
|
||||
sp<IMapper2> mapper2 = IMapper2_1::getService();
|
||||
if (mapper2 == nullptr) {
|
||||
mapper2 = IMapper2::getService();
|
||||
}
|
||||
|
||||
if (allocator2 != nullptr && mapper2 != nullptr) {
|
||||
mGrallocHal = std::unique_ptr<IGrallocHalWrapper>(
|
||||
new GrallocHalWrapper<IAllocator2, IMapper2>(allocator2, mapper2));
|
||||
} else {
|
||||
ALOGE("Couldn't open 2.x/3.0 graphics HALs (2.x allocator %d mapper %d)",
|
||||
(allocator2 != nullptr), (mapper2 != nullptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GrallocWrapper::~GrallocWrapper() {
|
||||
for (auto bufferHandle : mAllocatedBuffers) {
|
||||
mGrallocHal->unlock(bufferHandle);
|
||||
mGrallocHal->freeBuffer(bufferHandle);
|
||||
}
|
||||
mAllocatedBuffers.clear();
|
||||
}
|
||||
|
||||
std::string GrallocWrapper::dumpDebugInfo() {
|
||||
return mGrallocHal->dumpDebugInfo();
|
||||
}
|
||||
|
||||
std::pair<native_handle_t*, void*> GrallocWrapper::allocate(uint32_t size) {
|
||||
native_handle_t* bufferHandle = mGrallocHal->allocate(size);
|
||||
void* buffer = nullptr;
|
||||
if (bufferHandle) {
|
||||
buffer = mGrallocHal->lock(bufferHandle);
|
||||
if (buffer) {
|
||||
mAllocatedBuffers.insert(bufferHandle);
|
||||
} else {
|
||||
mGrallocHal->freeBuffer(bufferHandle);
|
||||
bufferHandle = nullptr;
|
||||
}
|
||||
}
|
||||
return std::make_pair<>(bufferHandle, buffer);
|
||||
}
|
||||
|
||||
void GrallocWrapper::freeBuffer(native_handle_t* bufferHandle) {
|
||||
if (mAllocatedBuffers.erase(bufferHandle)) {
|
||||
mGrallocHal->unlock(bufferHandle);
|
||||
mGrallocHal->freeBuffer(bufferHandle);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -119,32 +119,13 @@ SensorsTestSharedMemory::SensorsTestSharedMemory(SharedMemType type, size_t size
|
||||
}
|
||||
case SharedMemType::GRALLOC: {
|
||||
mGrallocWrapper = std::make_unique<::android::GrallocWrapper>();
|
||||
if (mGrallocWrapper->getAllocator() == nullptr ||
|
||||
mGrallocWrapper->getMapper() == nullptr) {
|
||||
if (!mGrallocWrapper->isInitialized()) {
|
||||
break;
|
||||
}
|
||||
using android::hardware::graphics::common::V1_0::BufferUsage;
|
||||
using android::hardware::graphics::common::V1_0::PixelFormat;
|
||||
mapper2::IMapper::BufferDescriptorInfo buf_desc_info = {
|
||||
.width = static_cast<uint32_t>(size),
|
||||
.height = 1,
|
||||
.layerCount = 1,
|
||||
.usage = static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA |
|
||||
BufferUsage::CPU_READ_OFTEN),
|
||||
.format = PixelFormat::BLOB};
|
||||
|
||||
handle = const_cast<native_handle_t*>(mGrallocWrapper->allocate(buf_desc_info));
|
||||
if (handle != nullptr) {
|
||||
mapper2::IMapper::Rect region{0, 0, static_cast<int32_t>(buf_desc_info.width),
|
||||
static_cast<int32_t>(buf_desc_info.height)};
|
||||
buffer = static_cast<char*>(
|
||||
mGrallocWrapper->lock(handle, buf_desc_info.usage, region, /*fence=*/-1));
|
||||
if (buffer != nullptr) {
|
||||
break;
|
||||
}
|
||||
mGrallocWrapper->freeBuffer(handle);
|
||||
handle = nullptr;
|
||||
}
|
||||
std::pair<native_handle_t*, void*> buf = mGrallocWrapper->allocate(size);
|
||||
handle = buf.first;
|
||||
buffer = static_cast<char*>(buf.second);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -175,9 +156,7 @@ SensorsTestSharedMemory::~SensorsTestSharedMemory() {
|
||||
}
|
||||
case SharedMemType::GRALLOC: {
|
||||
if (mSize != 0) {
|
||||
mGrallocWrapper->unlock(mNativeHandle);
|
||||
mGrallocWrapper->freeBuffer(mNativeHandle);
|
||||
|
||||
mNativeHandle = nullptr;
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
@@ -14,66 +14,47 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef GRALLO_WRAPPER_H_
|
||||
#define GRALLO_WRAPPER_H_
|
||||
#pragma once
|
||||
|
||||
#include <utils/NativeHandle.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
|
||||
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
|
||||
|
||||
namespace allocator2 = ::android::hardware::graphics::allocator::V2_0;
|
||||
namespace mapper2 = ::android::hardware::graphics::mapper::V2_0;
|
||||
#include <utility>
|
||||
|
||||
namespace android {
|
||||
|
||||
// Modified from hardware/interfaces/graphics/mapper/2.0/vts/functional/
|
||||
class IGrallocHalWrapper;
|
||||
|
||||
// Reference: hardware/interfaces/graphics/mapper/2.0/vts/functional/
|
||||
class GrallocWrapper {
|
||||
public:
|
||||
GrallocWrapper();
|
||||
~GrallocWrapper();
|
||||
|
||||
sp<allocator2::IAllocator> getAllocator() const;
|
||||
sp<mapper2::IMapper> getMapper() const;
|
||||
// After constructing this object, this function must be called to check the result. If it
|
||||
// returns false, other methods are not safe to call.
|
||||
bool isInitialized() const { return (mGrallocHal != nullptr); };
|
||||
|
||||
std::string dumpDebugInfo();
|
||||
|
||||
// When import is false, this simply calls IAllocator::allocate. When import
|
||||
// is true, the returned buffers are also imported into the mapper.
|
||||
//
|
||||
// Either case, the returned buffers must be freed with freeBuffer.
|
||||
std::vector<const native_handle_t*> allocate(const mapper2::BufferDescriptor& descriptor,
|
||||
uint32_t count, bool import = true,
|
||||
uint32_t* outStride = nullptr);
|
||||
const native_handle_t* allocate(const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo,
|
||||
bool import = true, uint32_t* outStride = nullptr);
|
||||
// Allocates a gralloc buffer suitable for direct channel sensors usage with the given size.
|
||||
// The buffer should be freed using freeBuffer when it's not needed anymore; otherwise it'll
|
||||
// be freed when this object is destroyed.
|
||||
// Returns a handle to the buffer, and a CPU-accessible pointer for reading. On failure, both
|
||||
// will be set to nullptr.
|
||||
std::pair<native_handle_t*, void*> allocate(uint32_t size);
|
||||
|
||||
mapper2::BufferDescriptor createDescriptor(
|
||||
const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo);
|
||||
// Releases a gralloc buffer previously returned by allocate()
|
||||
void freeBuffer(native_handle_t* bufferHandle);
|
||||
|
||||
const native_handle_t* importBuffer(const hardware::hidl_handle& rawHandle);
|
||||
void freeBuffer(const native_handle_t* bufferHandle);
|
||||
|
||||
// We use fd instead of hardware::hidl_handle in these functions to pass fences
|
||||
// in and out of the mapper. The ownership of the fd is always transferred
|
||||
// with each of these functions.
|
||||
void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
|
||||
const mapper2::IMapper::Rect& accessRegion, int acquireFence);
|
||||
|
||||
int unlock(const native_handle_t* bufferHandle);
|
||||
|
||||
private:
|
||||
void init();
|
||||
const native_handle_t* cloneBuffer(const hardware::hidl_handle& rawHandle);
|
||||
|
||||
sp<allocator2::IAllocator> mAllocator;
|
||||
sp<mapper2::IMapper> mMapper;
|
||||
private:
|
||||
std::unique_ptr<IGrallocHalWrapper> mGrallocHal;
|
||||
|
||||
// Keep track of all cloned and imported handles. When a test fails with
|
||||
// ASSERT_*, the destructor will free the handles for the test.
|
||||
std::unordered_set<const native_handle_t*> mClonedBuffers;
|
||||
std::unordered_set<const native_handle_t*> mImportedBuffers;
|
||||
std::unordered_set<native_handle_t*> mAllocatedBuffers;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
#endif // GRALLO_WRAPPER_H_
|
||||
|
||||
Reference in New Issue
Block a user