From 422b94e002e2187dd3e313768ab8906be9ed1f9c Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 19 Jan 2018 15:04:17 -0800 Subject: [PATCH 1/4] graphics: make allocator passthrough library header-only android.hardware.graphics.allocator@2.0-passthrough should be a header-only library to be fully reusable by vendor HALs. This also allows us to switch from virtual inheritance to templates, which is more straightforward. This changes nothing to the users and we still have these relations - AllocatorHal is an abstract class to be implemented by vendors or the default implementations - Gralloc[01]Hal are our default implementations - Allocator implements HIDL IAllocator interface on top of AllocatorHal What we do not like about virtual inheritance is that, given // abstract class B and D class B { virtual void foo() = 0; virtual void bar() = 0; }; class D : public virtual B { // foo is superceded by fooEnhanced in D void foo() { fooEnhanced(); } virtual void fooEnhanced() = 0; }; // an implementation of B class BImpl : public virtual B { void foo() {} void bar() {} }; // an implementation of D on top of BImpl class DImpl : public virtual D, public virtual BImpl { void fooEnhanced() {} }; we get "no unique final overrider" becase both D and BImpl implement foo. With non-virtual inheritance, on the other hand, we get "DImpl is abstract" because foo is still pure virtual implemented in DImpl. Templates solve the issue by allowing namespace detail{ template class BImpl : public T { ... }; template class DImpl : public BImpl { ... }; } // namespace detail using BImpl = detail::BImpl; using DImpl = detail::DImpl; Test: boots Change-Id: Iccb513e4fc751e9a687a1ed2d9fb2192c8324a50 --- graphics/allocator/2.0/default/Android.bp | 6 +- .../hal/include/allocator-hal/2.0/Allocator.h | 10 +- .../2.0/utils/passthrough/Android.bp | 9 +- .../2.0/utils/passthrough/Gralloc0Hal.cpp | 141 -------- .../2.0/utils/passthrough/Gralloc1Hal.cpp | 323 ------------------ .../2.0/utils/passthrough/GrallocLoader.cpp | 76 ----- .../allocator-passthrough/2.0/Gralloc0Hal.h | 123 ++++++- .../allocator-passthrough/2.0/Gralloc1Hal.h | 300 +++++++++++++++- .../allocator-passthrough/2.0/GrallocLoader.h | 50 ++- 9 files changed, 449 insertions(+), 589 deletions(-) delete mode 100644 graphics/allocator/2.0/utils/passthrough/Gralloc0Hal.cpp delete mode 100644 graphics/allocator/2.0/utils/passthrough/Gralloc1Hal.cpp delete mode 100644 graphics/allocator/2.0/utils/passthrough/GrallocLoader.cpp diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp index ed2ecbb508..9980ae0f2f 100644 --- a/graphics/allocator/2.0/default/Android.bp +++ b/graphics/allocator/2.0/default/Android.bp @@ -4,11 +4,8 @@ cc_library_shared { vendor: true, relative_install_path: "hw", srcs: ["passthrough.cpp"], - static_libs: [ - "android.hardware.graphics.allocator@2.0-passthrough", - ], header_libs: [ - "android.hardware.graphics.allocator@2.0-hal", + "android.hardware.graphics.allocator@2.0-passthrough", ], shared_libs: [ "android.hardware.graphics.allocator@2.0", @@ -20,6 +17,7 @@ cc_library_shared { "liblog", "libutils", ], + cflags: ["-DLOG_TAG=\"AllocatorHal\""], } cc_binary { diff --git a/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/Allocator.h b/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/Allocator.h index 2f3022e440..8ca820026e 100644 --- a/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/Allocator.h +++ b/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/Allocator.h @@ -39,11 +39,11 @@ using mapper::V2_0::Error; namespace detail { -// AllocatorImpl implements IAllocator on top of AllocatorHal -template -class AllocatorImpl : public IALLOCATOR { +// AllocatorImpl implements V2_*::IAllocator on top of V2_*::hal::AllocatorHal +template +class AllocatorImpl : public Interface { public: - bool init(std::unique_ptr hal) { + bool init(std::unique_ptr hal) { mHal = std::move(hal); return true; } @@ -74,7 +74,7 @@ class AllocatorImpl : public IALLOCATOR { } protected: - std::unique_ptr mHal; + std::unique_ptr mHal; }; } // namespace detail diff --git a/graphics/allocator/2.0/utils/passthrough/Android.bp b/graphics/allocator/2.0/utils/passthrough/Android.bp index b95656572d..ff9280add6 100644 --- a/graphics/allocator/2.0/utils/passthrough/Android.bp +++ b/graphics/allocator/2.0/utils/passthrough/Android.bp @@ -1,12 +1,7 @@ -cc_library_static { +cc_library_headers { name: "android.hardware.graphics.allocator@2.0-passthrough", defaults: ["hidl_defaults"], vendor: true, - srcs: [ - "Gralloc0Hal.cpp", - "Gralloc1Hal.cpp", - "GrallocLoader.cpp", - ], shared_libs: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.mapper@2.0", @@ -23,7 +18,7 @@ cc_library_static { ], export_header_lib_headers: [ "android.hardware.graphics.allocator@2.0-hal", + "libgrallocmapperincludes", ], export_include_dirs: ["include"], - cflags: ["-DLOG_TAG=\"AllocatorHal\""], } diff --git a/graphics/allocator/2.0/utils/passthrough/Gralloc0Hal.cpp b/graphics/allocator/2.0/utils/passthrough/Gralloc0Hal.cpp deleted file mode 100644 index 8edb7dc500..0000000000 --- a/graphics/allocator/2.0/utils/passthrough/Gralloc0Hal.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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. - */ - -#include - -#include - -#include -#include -#include - -namespace android { -namespace hardware { -namespace graphics { -namespace allocator { -namespace V2_0 { -namespace passthrough { - -using mapper::V2_0::implementation::grallocDecodeBufferDescriptor; - -Gralloc0Hal::~Gralloc0Hal() { - if (mDevice) { - gralloc_close(mDevice); - } -} - -bool Gralloc0Hal::initWithModule(const hw_module_t* module) { - int result = gralloc_open(module, &mDevice); - if (result) { - ALOGE("failed to open gralloc0 device: %s", strerror(-result)); - mDevice = nullptr; - return false; - } - - return true; -} - -std::string Gralloc0Hal::dumpDebugInfo() { - char buf[4096] = {}; - if (mDevice->dump) { - mDevice->dump(mDevice, buf, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - } - - return buf; -} - -Error Gralloc0Hal::allocateBuffers(const BufferDescriptor& descriptor, uint32_t count, - uint32_t* outStride, - std::vector* outBuffers) { - mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo; - if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) { - return Error::BAD_DESCRIPTOR; - } - - Error error = Error::NONE; - uint32_t stride = 0; - std::vector buffers; - buffers.reserve(count); - - // allocate the buffers - for (uint32_t i = 0; i < count; i++) { - const native_handle_t* tmpBuffer; - uint32_t tmpStride; - error = allocateOneBuffer(descriptorInfo, &tmpBuffer, &tmpStride); - if (error != Error::NONE) { - break; - } - - buffers.push_back(tmpBuffer); - - if (stride == 0) { - stride = tmpStride; - } else if (stride != tmpStride) { - // non-uniform strides - error = Error::UNSUPPORTED; - break; - } - } - - if (error != Error::NONE) { - freeBuffers(buffers); - return error; - } - - *outStride = stride; - *outBuffers = std::move(buffers); - - return Error::NONE; -} - -void Gralloc0Hal::freeBuffers(const std::vector& buffers) { - for (auto buffer : buffers) { - int result = mDevice->free(mDevice, buffer); - if (result != 0) { - ALOGE("failed to free buffer %p: %d", buffer, result); - } - } -} - -Error Gralloc0Hal::allocateOneBuffer(const mapper::V2_0::IMapper::BufferDescriptorInfo& info, - const native_handle_t** outBuffer, uint32_t* outStride) { - if (info.layerCount > 1 || (info.usage >> 32) != 0) { - return Error::BAD_VALUE; - } - - const native_handle_t* buffer = nullptr; - int stride = 0; - int result = mDevice->alloc(mDevice, info.width, info.height, static_cast(info.format), - info.usage, &buffer, &stride); - switch (result) { - case 0: - *outBuffer = buffer; - *outStride = stride; - return Error::NONE; - case -EINVAL: - return Error::BAD_VALUE; - default: - return Error::NO_RESOURCES; - } -} - -} // namespace passthrough -} // namespace V2_0 -} // namespace allocator -} // namespace graphics -} // namespace hardware -} // namespace android diff --git a/graphics/allocator/2.0/utils/passthrough/Gralloc1Hal.cpp b/graphics/allocator/2.0/utils/passthrough/Gralloc1Hal.cpp deleted file mode 100644 index e343ecd294..0000000000 --- a/graphics/allocator/2.0/utils/passthrough/Gralloc1Hal.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - * 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. - */ - -#include - -#include - -#include -#include - -namespace android { -namespace hardware { -namespace graphics { -namespace allocator { -namespace V2_0 { -namespace passthrough { - -using android::hardware::graphics::common::V1_0::BufferUsage; -using mapper::V2_0::implementation::grallocDecodeBufferDescriptor; - -Gralloc1Hal::~Gralloc1Hal() { - if (mDevice) { - gralloc1_close(mDevice); - } -} - -bool Gralloc1Hal::initWithModule(const hw_module_t* module) { - int result = gralloc1_open(module, &mDevice); - if (result) { - ALOGE("failed to open gralloc1 device: %s", strerror(-result)); - mDevice = nullptr; - return false; - } - - initCapabilities(); - if (!initDispatch()) { - gralloc1_close(mDevice); - mDevice = nullptr; - return false; - } - - return true; -} - -void Gralloc1Hal::initCapabilities() { - uint32_t count = 0; - mDevice->getCapabilities(mDevice, &count, nullptr); - - std::vector capabilities(count); - mDevice->getCapabilities(mDevice, &count, capabilities.data()); - capabilities.resize(count); - - for (auto capability : capabilities) { - if (capability == GRALLOC1_CAPABILITY_LAYERED_BUFFERS) { - mCapabilities.layeredBuffers = true; - break; - } - } -} - -gralloc1_function_pointer_t Gralloc1Hal::getDispatchFunction( - gralloc1_function_descriptor_t desc) const { - auto pfn = mDevice->getFunction(mDevice, desc); - if (!pfn) { - ALOGE("failed to get gralloc1 function %d", desc); - return nullptr; - } - return pfn; -} - -bool Gralloc1Hal::initDispatch() { - if (!initDispatchFunction(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump) || - !initDispatchFunction(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR, &mDispatch.createDescriptor) || - !initDispatchFunction(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR, &mDispatch.destroyDescriptor) || - !initDispatchFunction(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions) || - !initDispatchFunction(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat) || - !initDispatchFunction(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE, &mDispatch.setConsumerUsage) || - !initDispatchFunction(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE, &mDispatch.setProducerUsage) || - !initDispatchFunction(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride) || - !initDispatchFunction(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate) || - !initDispatchFunction(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release)) { - return false; - } - - if (mCapabilities.layeredBuffers) { - if (!initDispatchFunction(GRALLOC1_FUNCTION_SET_LAYER_COUNT, &mDispatch.setLayerCount)) { - return false; - } - } - - return true; -} - -std::string Gralloc1Hal::dumpDebugInfo() { - uint32_t len = 0; - mDispatch.dump(mDevice, &len, nullptr); - - std::vector buf(len + 1); - mDispatch.dump(mDevice, &len, buf.data()); - buf.resize(len + 1); - buf[len] = '\0'; - - return buf.data(); -} - -Error Gralloc1Hal::allocateBuffers(const BufferDescriptor& descriptor, uint32_t count, - uint32_t* outStride, - std::vector* outBuffers) { - mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo; - if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) { - return Error::BAD_DESCRIPTOR; - } - - gralloc1_buffer_descriptor_t desc; - Error error = createDescriptor(descriptorInfo, &desc); - if (error != Error::NONE) { - return error; - } - - uint32_t stride = 0; - std::vector buffers; - buffers.reserve(count); - - // allocate the buffers - for (uint32_t i = 0; i < count; i++) { - const native_handle_t* tmpBuffer; - uint32_t tmpStride; - error = allocateOneBuffer(desc, &tmpBuffer, &tmpStride); - if (error != Error::NONE) { - break; - } - - buffers.push_back(tmpBuffer); - - if (stride == 0) { - stride = tmpStride; - } else if (stride != tmpStride) { - // non-uniform strides - error = Error::UNSUPPORTED; - break; - } - } - - mDispatch.destroyDescriptor(mDevice, desc); - - if (error != Error::NONE) { - freeBuffers(buffers); - return error; - } - - *outStride = stride; - *outBuffers = std::move(buffers); - - return Error::NONE; -} - -void Gralloc1Hal::freeBuffers(const std::vector& buffers) { - for (auto buffer : buffers) { - int32_t error = mDispatch.release(mDevice, buffer); - if (error != GRALLOC1_ERROR_NONE) { - ALOGE("failed to free buffer %p: %d", buffer, error); - } - } -} - -Error Gralloc1Hal::toError(int32_t error) { - switch (error) { - case GRALLOC1_ERROR_NONE: - return Error::NONE; - case GRALLOC1_ERROR_BAD_DESCRIPTOR: - return Error::BAD_DESCRIPTOR; - case GRALLOC1_ERROR_BAD_HANDLE: - return Error::BAD_BUFFER; - case GRALLOC1_ERROR_BAD_VALUE: - return Error::BAD_VALUE; - case GRALLOC1_ERROR_NOT_SHARED: - return Error::NONE; // this is fine - case GRALLOC1_ERROR_NO_RESOURCES: - return Error::NO_RESOURCES; - case GRALLOC1_ERROR_UNDEFINED: - case GRALLOC1_ERROR_UNSUPPORTED: - default: - return Error::UNSUPPORTED; - } -} - -uint64_t Gralloc1Hal::toProducerUsage(uint64_t usage) { - // this is potentially broken as we have no idea which private flags - // should be filtered out - uint64_t producerUsage = - usage & ~static_cast(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | - BufferUsage::GPU_DATA_BUFFER); - - switch (usage & BufferUsage::CPU_WRITE_MASK) { - case static_cast(BufferUsage::CPU_WRITE_RARELY): - producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE; - break; - case static_cast(BufferUsage::CPU_WRITE_OFTEN): - producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN; - break; - default: - break; - } - - switch (usage & BufferUsage::CPU_READ_MASK) { - case static_cast(BufferUsage::CPU_READ_RARELY): - producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ; - break; - case static_cast(BufferUsage::CPU_READ_OFTEN): - producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN; - break; - default: - break; - } - - // BufferUsage::GPU_DATA_BUFFER is always filtered out - - return producerUsage; -} - -uint64_t Gralloc1Hal::toConsumerUsage(uint64_t usage) { - // this is potentially broken as we have no idea which private flags - // should be filtered out - uint64_t consumerUsage = - usage & - ~static_cast(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | - BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::GPU_DATA_BUFFER); - - switch (usage & BufferUsage::CPU_READ_MASK) { - case static_cast(BufferUsage::CPU_READ_RARELY): - consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ; - break; - case static_cast(BufferUsage::CPU_READ_OFTEN): - consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN; - break; - default: - break; - } - - // BufferUsage::SENSOR_DIRECT_DATA is always filtered out - - if (usage & BufferUsage::GPU_DATA_BUFFER) { - consumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER; - } - - return consumerUsage; -} - -Error Gralloc1Hal::createDescriptor(const mapper::V2_0::IMapper::BufferDescriptorInfo& info, - gralloc1_buffer_descriptor_t* outDescriptor) { - gralloc1_buffer_descriptor_t descriptor; - - int32_t error = mDispatch.createDescriptor(mDevice, &descriptor); - - if (error == GRALLOC1_ERROR_NONE) { - error = mDispatch.setDimensions(mDevice, descriptor, info.width, info.height); - } - if (error == GRALLOC1_ERROR_NONE) { - error = mDispatch.setFormat(mDevice, descriptor, static_cast(info.format)); - } - if (error == GRALLOC1_ERROR_NONE) { - if (mCapabilities.layeredBuffers) { - error = mDispatch.setLayerCount(mDevice, descriptor, info.layerCount); - } else if (info.layerCount > 1) { - error = GRALLOC1_ERROR_UNSUPPORTED; - } - } - if (error == GRALLOC1_ERROR_NONE) { - error = mDispatch.setProducerUsage(mDevice, descriptor, toProducerUsage(info.usage)); - } - if (error == GRALLOC1_ERROR_NONE) { - error = mDispatch.setConsumerUsage(mDevice, descriptor, toConsumerUsage(info.usage)); - } - - if (error == GRALLOC1_ERROR_NONE) { - *outDescriptor = descriptor; - } else { - mDispatch.destroyDescriptor(mDevice, descriptor); - } - - return toError(error); -} - -Error Gralloc1Hal::allocateOneBuffer(gralloc1_buffer_descriptor_t descriptor, - const native_handle_t** outBuffer, uint32_t* outStride) { - const native_handle_t* buffer = nullptr; - int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer); - if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) { - return toError(error); - } - - uint32_t stride = 0; - error = mDispatch.getStride(mDevice, buffer, &stride); - if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) { - mDispatch.release(mDevice, buffer); - return toError(error); - } - - *outBuffer = buffer; - *outStride = stride; - - return Error::NONE; -} - -} // namespace passthrough -} // namespace V2_0 -} // namespace allocator -} // namespace graphics -} // namespace hardware -} // namespace android diff --git a/graphics/allocator/2.0/utils/passthrough/GrallocLoader.cpp b/graphics/allocator/2.0/utils/passthrough/GrallocLoader.cpp deleted file mode 100644 index dae7a78ca5..0000000000 --- a/graphics/allocator/2.0/utils/passthrough/GrallocLoader.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 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. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace android { -namespace hardware { -namespace graphics { -namespace allocator { -namespace V2_0 { -namespace passthrough { - -const hw_module_t* GrallocLoader::loadModule() { - const hw_module_t* module; - int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); - if (error) { - ALOGE("failed to get gralloc module"); - return nullptr; - } - - return module; -} - -int GrallocLoader::getModuleMajorApiVersion(const hw_module_t* module) { - return (module->module_api_version >> 8) & 0xff; -} - -std::unique_ptr GrallocLoader::createHal(const hw_module_t* module) { - int major = getModuleMajorApiVersion(module); - switch (major) { - case 1: { - auto hal = std::make_unique(); - return hal->initWithModule(module) ? std::move(hal) : nullptr; - } - case 0: { - auto hal = std::make_unique(); - return hal->initWithModule(module) ? std::move(hal) : nullptr; - } - default: - ALOGE("unknown gralloc module major version %d", major); - return nullptr; - } -} - -IAllocator* GrallocLoader::createAllocator(std::unique_ptr hal) { - auto allocator = std::make_unique(); - return allocator->init(std::move(hal)) ? allocator.release() : nullptr; -} - -} // namespace passthrough -} // namespace V2_0 -} // namespace allocator -} // namespace graphics -} // namespace hardware -} // namespace android diff --git a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h index 8f433b0f56..2665b40030 100644 --- a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h +++ b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h @@ -16,10 +16,16 @@ #pragma once -#include +#ifndef LOG_TAG +#warning "Gralloc0Hal.h included without LOG_TAG" +#endif -struct alloc_device_t; -struct hw_module_t; +#include // for strerror + +#include +#include +#include +#include namespace android { namespace hardware { @@ -28,28 +34,125 @@ namespace allocator { namespace V2_0 { namespace passthrough { +namespace detail { + using mapper::V2_0::BufferDescriptor; using mapper::V2_0::Error; +using mapper::V2_0::implementation::grallocDecodeBufferDescriptor; -class Gralloc0Hal : public virtual hal::AllocatorHal { +// Gralloc0HalImpl implements V2_*::hal::AllocatorHal on top of gralloc0 +template +class Gralloc0HalImpl : public Hal { public: - ~Gralloc0Hal(); - bool initWithModule(const hw_module_t* module); + ~Gralloc0HalImpl() { + if (mDevice) { + gralloc_close(mDevice); + } + } - std::string dumpDebugInfo() override; + bool initWithModule(const hw_module_t* module) { + int result = gralloc_open(module, &mDevice); + if (result) { + ALOGE("failed to open gralloc0 device: %s", strerror(-result)); + mDevice = nullptr; + return false; + } + + return true; + } + + std::string dumpDebugInfo() override { + char buf[4096] = {}; + if (mDevice->dump) { + mDevice->dump(mDevice, buf, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + } + + return buf; + } Error allocateBuffers(const BufferDescriptor& descriptor, uint32_t count, uint32_t* outStride, - std::vector* outBuffers) override; + std::vector* outBuffers) override { + mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo; + if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) { + return Error::BAD_DESCRIPTOR; + } - void freeBuffers(const std::vector& buffers) override; + Error error = Error::NONE; + uint32_t stride = 0; + std::vector buffers; + buffers.reserve(count); + + // allocate the buffers + for (uint32_t i = 0; i < count; i++) { + const native_handle_t* tmpBuffer; + uint32_t tmpStride; + error = allocateOneBuffer(descriptorInfo, &tmpBuffer, &tmpStride); + if (error != Error::NONE) { + break; + } + + buffers.push_back(tmpBuffer); + + if (stride == 0) { + stride = tmpStride; + } else if (stride != tmpStride) { + // non-uniform strides + error = Error::UNSUPPORTED; + break; + } + } + + if (error != Error::NONE) { + freeBuffers(buffers); + return error; + } + + *outStride = stride; + *outBuffers = std::move(buffers); + + return Error::NONE; + } + + void freeBuffers(const std::vector& buffers) override { + for (auto buffer : buffers) { + int result = mDevice->free(mDevice, buffer); + if (result != 0) { + ALOGE("failed to free buffer %p: %d", buffer, result); + } + } + } protected: Error allocateOneBuffer(const mapper::V2_0::IMapper::BufferDescriptorInfo& info, - const native_handle_t** outBuffer, uint32_t* outStride); + const native_handle_t** outBuffer, uint32_t* outStride) { + if (info.layerCount > 1 || (info.usage >> 32) != 0) { + return Error::BAD_VALUE; + } + + const native_handle_t* buffer = nullptr; + int stride = 0; + int result = mDevice->alloc(mDevice, info.width, info.height, static_cast(info.format), + info.usage, &buffer, &stride); + switch (result) { + case 0: + *outBuffer = buffer; + *outStride = stride; + return Error::NONE; + case -EINVAL: + return Error::BAD_VALUE; + default: + return Error::NO_RESOURCES; + } + } alloc_device_t* mDevice = nullptr; }; +} // namespace detail + +using Gralloc0Hal = detail::Gralloc0HalImpl; + } // namespace passthrough } // namespace V2_0 } // namespace allocator diff --git a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h index 3126e91506..3979f0d761 100644 --- a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h +++ b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h @@ -16,8 +16,16 @@ #pragma once +#ifndef LOG_TAG +#warning "Gralloc1Hal.h included without LOG_TAG" +#endif + +#include // for strerror + +#include #include #include +#include namespace android { namespace hardware { @@ -26,46 +34,302 @@ namespace allocator { namespace V2_0 { namespace passthrough { +namespace detail { + +using common::V1_0::BufferUsage; using mapper::V2_0::BufferDescriptor; using mapper::V2_0::Error; +using mapper::V2_0::implementation::grallocDecodeBufferDescriptor; -class Gralloc1Hal : public virtual hal::AllocatorHal { +// Gralloc1HalImpl implements V2_*::hal::AllocatorHal on top of gralloc1 +template +class Gralloc1HalImpl : public Hal { public: - ~Gralloc1Hal(); - bool initWithModule(const hw_module_t* module); + ~Gralloc1HalImpl() { + if (mDevice) { + gralloc1_close(mDevice); + } + } - std::string dumpDebugInfo() override; + bool initWithModule(const hw_module_t* module) { + int result = gralloc1_open(module, &mDevice); + if (result) { + ALOGE("failed to open gralloc1 device: %s", strerror(-result)); + mDevice = nullptr; + return false; + } + + initCapabilities(); + if (!initDispatch()) { + gralloc1_close(mDevice); + mDevice = nullptr; + return false; + } + + return true; + } + + std::string dumpDebugInfo() override { + uint32_t len = 0; + mDispatch.dump(mDevice, &len, nullptr); + + std::vector buf(len + 1); + mDispatch.dump(mDevice, &len, buf.data()); + buf.resize(len + 1); + buf[len] = '\0'; + + return buf.data(); + } Error allocateBuffers(const BufferDescriptor& descriptor, uint32_t count, uint32_t* outStride, - std::vector* outBuffers) override; + std::vector* outBuffers) override { + mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo; + if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) { + return Error::BAD_DESCRIPTOR; + } - void freeBuffers(const std::vector& buffers) override; + gralloc1_buffer_descriptor_t desc; + Error error = createDescriptor(descriptorInfo, &desc); + if (error != Error::NONE) { + return error; + } + + uint32_t stride = 0; + std::vector buffers; + buffers.reserve(count); + + // allocate the buffers + for (uint32_t i = 0; i < count; i++) { + const native_handle_t* tmpBuffer; + uint32_t tmpStride; + error = allocateOneBuffer(desc, &tmpBuffer, &tmpStride); + if (error != Error::NONE) { + break; + } + + buffers.push_back(tmpBuffer); + + if (stride == 0) { + stride = tmpStride; + } else if (stride != tmpStride) { + // non-uniform strides + error = Error::UNSUPPORTED; + break; + } + } + + mDispatch.destroyDescriptor(mDevice, desc); + + if (error != Error::NONE) { + freeBuffers(buffers); + return error; + } + + *outStride = stride; + *outBuffers = std::move(buffers); + + return Error::NONE; + } + + void freeBuffers(const std::vector& buffers) override { + for (auto buffer : buffers) { + int32_t error = mDispatch.release(mDevice, buffer); + if (error != GRALLOC1_ERROR_NONE) { + ALOGE("failed to free buffer %p: %d", buffer, error); + } + } + } protected: + virtual void initCapabilities() { + uint32_t count = 0; + mDevice->getCapabilities(mDevice, &count, nullptr); + + std::vector capabilities(count); + mDevice->getCapabilities(mDevice, &count, capabilities.data()); + capabilities.resize(count); + + for (auto capability : capabilities) { + if (capability == GRALLOC1_CAPABILITY_LAYERED_BUFFERS) { + mCapabilities.layeredBuffers = true; + break; + } + } + } + template - bool initDispatchFunction(gralloc1_function_descriptor_t desc, T* outPfn) { - auto pfn = getDispatchFunction(desc); + bool initDispatch(gralloc1_function_descriptor_t desc, T* outPfn) { + auto pfn = mDevice->getFunction(mDevice, desc); if (pfn) { *outPfn = reinterpret_cast(pfn); return true; } else { + ALOGE("failed to get gralloc1 function %d", desc); return false; } } - gralloc1_function_pointer_t getDispatchFunction(gralloc1_function_descriptor_t desc) const; - virtual void initCapabilities(); - virtual bool initDispatch(); + virtual bool initDispatch() { + if (!initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump) || + !initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR, &mDispatch.createDescriptor) || + !initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR, &mDispatch.destroyDescriptor) || + !initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions) || + !initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat) || + !initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE, &mDispatch.setConsumerUsage) || + !initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE, &mDispatch.setProducerUsage) || + !initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride) || + !initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate) || + !initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release)) { + return false; + } - static Error toError(int32_t error); - static uint64_t toProducerUsage(uint64_t usage); - static uint64_t toConsumerUsage(uint64_t usage); + if (mCapabilities.layeredBuffers) { + if (!initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT, &mDispatch.setLayerCount)) { + return false; + } + } + + return true; + } + + static Error toError(int32_t error) { + switch (error) { + case GRALLOC1_ERROR_NONE: + return Error::NONE; + case GRALLOC1_ERROR_BAD_DESCRIPTOR: + return Error::BAD_DESCRIPTOR; + case GRALLOC1_ERROR_BAD_HANDLE: + return Error::BAD_BUFFER; + case GRALLOC1_ERROR_BAD_VALUE: + return Error::BAD_VALUE; + case GRALLOC1_ERROR_NOT_SHARED: + return Error::NONE; // this is fine + case GRALLOC1_ERROR_NO_RESOURCES: + return Error::NO_RESOURCES; + case GRALLOC1_ERROR_UNDEFINED: + case GRALLOC1_ERROR_UNSUPPORTED: + default: + return Error::UNSUPPORTED; + } + } + + static uint64_t toProducerUsage(uint64_t usage) { + // this is potentially broken as we have no idea which private flags + // should be filtered out + uint64_t producerUsage = usage & ~static_cast(BufferUsage::CPU_READ_MASK | + BufferUsage::CPU_WRITE_MASK | + BufferUsage::GPU_DATA_BUFFER); + + switch (usage & BufferUsage::CPU_WRITE_MASK) { + case static_cast(BufferUsage::CPU_WRITE_RARELY): + producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE; + break; + case static_cast(BufferUsage::CPU_WRITE_OFTEN): + producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN; + break; + default: + break; + } + + switch (usage & BufferUsage::CPU_READ_MASK) { + case static_cast(BufferUsage::CPU_READ_RARELY): + producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ; + break; + case static_cast(BufferUsage::CPU_READ_OFTEN): + producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN; + break; + default: + break; + } + + // BufferUsage::GPU_DATA_BUFFER is always filtered out + + return producerUsage; + } + + static uint64_t toConsumerUsage(uint64_t usage) { + // this is potentially broken as we have no idea which private flags + // should be filtered out + uint64_t consumerUsage = + usage & + ~static_cast(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | + BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::GPU_DATA_BUFFER); + + switch (usage & BufferUsage::CPU_READ_MASK) { + case static_cast(BufferUsage::CPU_READ_RARELY): + consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ; + break; + case static_cast(BufferUsage::CPU_READ_OFTEN): + consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN; + break; + default: + break; + } + + // BufferUsage::SENSOR_DIRECT_DATA is always filtered out + + if (usage & BufferUsage::GPU_DATA_BUFFER) { + consumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER; + } + + return consumerUsage; + } Error createDescriptor(const mapper::V2_0::IMapper::BufferDescriptorInfo& info, - gralloc1_buffer_descriptor_t* outDescriptor); + gralloc1_buffer_descriptor_t* outDescriptor) { + gralloc1_buffer_descriptor_t descriptor; + + int32_t error = mDispatch.createDescriptor(mDevice, &descriptor); + + if (error == GRALLOC1_ERROR_NONE) { + error = mDispatch.setDimensions(mDevice, descriptor, info.width, info.height); + } + if (error == GRALLOC1_ERROR_NONE) { + error = mDispatch.setFormat(mDevice, descriptor, static_cast(info.format)); + } + if (error == GRALLOC1_ERROR_NONE) { + if (mCapabilities.layeredBuffers) { + error = mDispatch.setLayerCount(mDevice, descriptor, info.layerCount); + } else if (info.layerCount > 1) { + error = GRALLOC1_ERROR_UNSUPPORTED; + } + } + if (error == GRALLOC1_ERROR_NONE) { + error = mDispatch.setProducerUsage(mDevice, descriptor, toProducerUsage(info.usage)); + } + if (error == GRALLOC1_ERROR_NONE) { + error = mDispatch.setConsumerUsage(mDevice, descriptor, toConsumerUsage(info.usage)); + } + + if (error == GRALLOC1_ERROR_NONE) { + *outDescriptor = descriptor; + } else { + mDispatch.destroyDescriptor(mDevice, descriptor); + } + + return toError(error); + } Error allocateOneBuffer(gralloc1_buffer_descriptor_t descriptor, - const native_handle_t** outBuffer, uint32_t* outStride); + const native_handle_t** outBuffer, uint32_t* outStride) { + const native_handle_t* buffer = nullptr; + int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer); + if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) { + return toError(error); + } + + uint32_t stride = 0; + error = mDispatch.getStride(mDevice, buffer, &stride); + if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) { + mDispatch.release(mDevice, buffer); + return toError(error); + } + + *outBuffer = buffer; + *outStride = stride; + + return Error::NONE; + } gralloc1_device_t* mDevice = nullptr; @@ -88,6 +352,10 @@ class Gralloc1Hal : public virtual hal::AllocatorHal { } mDispatch = {}; }; +} // namespace detail + +using Gralloc1Hal = detail::Gralloc1HalImpl; + } // namespace passthrough } // namespace V2_0 } // namespace allocator diff --git a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/GrallocLoader.h b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/GrallocLoader.h index a0b9503c30..660099bb14 100644 --- a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/GrallocLoader.h +++ b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/GrallocLoader.h @@ -16,11 +16,18 @@ #pragma once +#ifndef LOG_TAG +#warning "GrallocLoader.h included without LOG_TAG" +#endif + #include -#include - -struct hw_module_t; +#include +#include +#include +#include +#include +#include namespace android { namespace hardware { @@ -44,16 +51,45 @@ class GrallocLoader { } // load the gralloc module - static const hw_module_t* loadModule(); + static const hw_module_t* loadModule() { + const hw_module_t* module; + int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + if (error) { + ALOGE("failed to get gralloc module"); + return nullptr; + } + + return module; + } // return the major api version of the module - static int getModuleMajorApiVersion(const hw_module_t* module); + static int getModuleMajorApiVersion(const hw_module_t* module) { + return (module->module_api_version >> 8) & 0xff; + } // create an AllocatorHal instance - static std::unique_ptr createHal(const hw_module_t* module); + static std::unique_ptr createHal(const hw_module_t* module) { + int major = getModuleMajorApiVersion(module); + switch (major) { + case 1: { + auto hal = std::make_unique(); + return hal->initWithModule(module) ? std::move(hal) : nullptr; + } + case 0: { + auto hal = std::make_unique(); + return hal->initWithModule(module) ? std::move(hal) : nullptr; + } + default: + ALOGE("unknown gralloc module major version %d", major); + return nullptr; + } + } // create an IAllocator instance - static IAllocator* createAllocator(std::unique_ptr hal); + static IAllocator* createAllocator(std::unique_ptr hal) { + auto allocator = std::make_unique(); + return allocator->init(std::move(hal)) ? allocator.release() : nullptr; + } }; } // namespace passthrough From fd1924f6f5a1638a50efb4757e584f60dad93694 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 8 Jan 2018 12:51:00 -0800 Subject: [PATCH 2/4] graphics: add mapper HAL support library Add a header-only support library android.hardware.graphics.mapper@2.0-hal that can be used by implementations. There are two classes in the support library. MapperHal is an abstract class to be implemented by implementations. Mapper is an implementation of HIDL IMapper interface on top of MapperHal. An implementation can class VendorHal : public MapperHal { ... }; auto mapper = std::make_unique(); mapper->init(std::make_unique(...)); Or, if vendor extensions are to be added to the IMapper, class MapperHalExt : public MapperHal { ... }; class VendorHal : public MapperHalExt { ... }; class MapperExt : public MapperImpl { ... }; auto mapper = std::make_unique(); mapper->init(std::make_unique(...)); Test: builds Change-Id: Ib23c1f5977744f7e116bb93db53e882e2dad7ce3 --- graphics/mapper/2.0/utils/OWNERS | 4 + graphics/mapper/2.0/utils/hal/Android.bp | 27 +++ .../utils/hal/include/mapper-hal/2.0/Mapper.h | 210 ++++++++++++++++++ .../hal/include/mapper-hal/2.0/MapperHal.h | 63 ++++++ 4 files changed, 304 insertions(+) create mode 100644 graphics/mapper/2.0/utils/OWNERS create mode 100644 graphics/mapper/2.0/utils/hal/Android.bp create mode 100644 graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h create mode 100644 graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/MapperHal.h diff --git a/graphics/mapper/2.0/utils/OWNERS b/graphics/mapper/2.0/utils/OWNERS new file mode 100644 index 0000000000..3aa5fa1ffd --- /dev/null +++ b/graphics/mapper/2.0/utils/OWNERS @@ -0,0 +1,4 @@ +# Graphics team +jessehall@google.com +olv@google.com +stoza@google.com diff --git a/graphics/mapper/2.0/utils/hal/Android.bp b/graphics/mapper/2.0/utils/hal/Android.bp new file mode 100644 index 0000000000..5610a69aac --- /dev/null +++ b/graphics/mapper/2.0/utils/hal/Android.bp @@ -0,0 +1,27 @@ +// +// Copyright (C) 2018 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. + +cc_library_headers { + name: "android.hardware.graphics.mapper@2.0-hal", + defaults: ["hidl_defaults"], + vendor: true, + shared_libs: [ + "android.hardware.graphics.mapper@2.0", + ], + export_shared_lib_headers: [ + "android.hardware.graphics.mapper@2.0", + ], + export_include_dirs: ["include"], +} diff --git a/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h new file mode 100644 index 0000000000..5ad2a6564c --- /dev/null +++ b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h @@ -0,0 +1,210 @@ +/* + * Copyright 2018 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. + */ + +#pragma once + +#ifndef LOG_TAG +#warning "Mapper.h included without LOG_TAG" +#endif + +#include + +#include +#include +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace mapper { +namespace V2_0 { +namespace hal { + +namespace detail { + +// MapperImpl implements V2_*::IMapper on top of V2_*::hal::MapperHal +template +class MapperImpl : public Interface { + public: + bool init(std::unique_ptr hal) { + mHal = std::move(hal); + return true; + } + + // IMapper 2.0 interface + + Return createDescriptor(const V2_0::IMapper::BufferDescriptorInfo& descriptorInfo, + IMapper::createDescriptor_cb hidl_cb) override { + BufferDescriptor descriptor; + Error error = mHal->createDescriptor(descriptorInfo, &descriptor); + hidl_cb(error, descriptor); + return Void(); + } + + Return importBuffer(const hidl_handle& rawHandle, + IMapper::importBuffer_cb hidl_cb) override { + if (!rawHandle.getNativeHandle()) { + hidl_cb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + native_handle_t* bufferHandle = nullptr; + Error error = mHal->importBuffer(rawHandle.getNativeHandle(), &bufferHandle); + if (error != Error::NONE) { + hidl_cb(error, nullptr); + return Void(); + } + + void* buffer = addImportedBuffer(bufferHandle); + if (!buffer) { + mHal->freeBuffer(bufferHandle); + hidl_cb(Error::NO_RESOURCES, nullptr); + return Void(); + } + + hidl_cb(error, buffer); + return Void(); + } + + Return freeBuffer(void* buffer) override { + native_handle_t* bufferHandle = removeImportedBuffer(buffer); + if (!bufferHandle) { + return Error::BAD_BUFFER; + } + + return mHal->freeBuffer(bufferHandle); + } + + Return lock(void* buffer, uint64_t cpuUsage, const V2_0::IMapper::Rect& accessRegion, + const hidl_handle& acquireFence, IMapper::lock_cb hidl_cb) override { + const native_handle_t* bufferHandle = getImportedBuffer(buffer); + if (!bufferHandle) { + hidl_cb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + base::unique_fd fenceFd; + Error error = getFenceFd(acquireFence, &fenceFd); + if (error != Error::NONE) { + hidl_cb(error, nullptr); + return Void(); + } + + void* data = nullptr; + error = mHal->lock(bufferHandle, cpuUsage, accessRegion, std::move(fenceFd), &data); + hidl_cb(error, data); + return Void(); + } + + Return lockYCbCr(void* buffer, uint64_t cpuUsage, const V2_0::IMapper::Rect& accessRegion, + const hidl_handle& acquireFence, + IMapper::lockYCbCr_cb hidl_cb) override { + const native_handle_t* bufferHandle = getImportedBuffer(buffer); + if (!bufferHandle) { + hidl_cb(Error::BAD_BUFFER, YCbCrLayout{}); + return Void(); + } + + base::unique_fd fenceFd; + Error error = getFenceFd(acquireFence, &fenceFd); + if (error != Error::NONE) { + hidl_cb(error, YCbCrLayout{}); + return Void(); + } + + YCbCrLayout layout{}; + error = mHal->lockYCbCr(bufferHandle, cpuUsage, accessRegion, std::move(fenceFd), &layout); + hidl_cb(error, layout); + return Void(); + } + + Return unlock(void* buffer, IMapper::unlock_cb hidl_cb) override { + const native_handle_t* bufferHandle = getImportedBuffer(buffer); + if (!bufferHandle) { + hidl_cb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + base::unique_fd fenceFd; + Error error = mHal->unlock(bufferHandle, &fenceFd); + if (error != Error::NONE) { + hidl_cb(error, nullptr); + return Void(); + } + + NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0); + hidl_cb(error, getFenceHandle(fenceFd, fenceStorage)); + return Void(); + } + + protected: + // these functions can be overriden to do true imported buffer management + virtual void* addImportedBuffer(native_handle_t* bufferHandle) { + return static_cast(bufferHandle); + } + + virtual native_handle_t* removeImportedBuffer(void* buffer) { + return static_cast(buffer); + } + + virtual const native_handle_t* getImportedBuffer(void* buffer) const { + return static_cast(buffer); + } + + // convert fenceFd to or from hidl_handle + static Error getFenceFd(const hidl_handle& fenceHandle, base::unique_fd* outFenceFd) { + auto handle = fenceHandle.getNativeHandle(); + if (handle && handle->numFds > 1) { + ALOGE("invalid fence handle with %d fds", handle->numFds); + return Error::BAD_VALUE; + } + + int fenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1; + if (fenceFd >= 0) { + fenceFd = dup(fenceFd); + if (fenceFd < 0) { + return Error::NO_RESOURCES; + } + } + + outFenceFd->reset(fenceFd); + + return Error::NONE; + } + + static hidl_handle getFenceHandle(const base::unique_fd& fenceFd, char* handleStorage) { + native_handle_t* handle = nullptr; + if (fenceFd >= 0) { + handle = native_handle_init(handleStorage, 1, 0); + handle->data[0] = fenceFd; + } + + return hidl_handle(handle); + } + + std::unique_ptr mHal; +}; + +} // namespace detail + +using Mapper = detail::MapperImpl; + +} // namespace hal +} // namespace V2_0 +} // namespace mapper +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/MapperHal.h b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/MapperHal.h new file mode 100644 index 0000000000..ab2e5cf9b6 --- /dev/null +++ b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/MapperHal.h @@ -0,0 +1,63 @@ +/* + * Copyright 2018 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. + */ + +#pragma once + +#include +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace mapper { +namespace V2_0 { +namespace hal { + +class MapperHal { + public: + virtual ~MapperHal() = default; + + // create a BufferDescriptor + virtual Error createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo, + BufferDescriptor* outDescriptor) = 0; + + // import a raw handle owned by the caller + virtual Error importBuffer(const native_handle_t* rawHandle, + native_handle_t** outBufferHandle) = 0; + + // free an imported buffer handle + virtual Error freeBuffer(native_handle_t* bufferHandle) = 0; + + // lock a buffer + virtual Error lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, + const IMapper::Rect& accessRegion, base::unique_fd fenceFd, + void** outData) = 0; + + // lock a YCbCr buffer + virtual Error lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage, + const IMapper::Rect& accessRegion, base::unique_fd fenceFd, + YCbCrLayout* outLayout) = 0; + + // unlock a buffer + virtual Error unlock(const native_handle_t* bufferHandle, base::unique_fd* outFenceFd) = 0; +}; + +} // namespace hal +} // namespace V2_0 +} // namespace mapper +} // namespace graphics +} // namespace hardware +} // namespace android From 821c4c4a9d717f79f9bef75e9f7b2a915bb1c165 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 12 Dec 2017 15:12:02 -0800 Subject: [PATCH 3/4] graphics: make mapper default impl a header library Reimplement the default impl as a header-only library, android.hardware.graphics.mapper@2.0-passthrough, based on the HAL support library. Effectively, this renames Gralloc[01]Mapper to Gralloc[01]Hal, and make adjustments here and there to meet the requirements of the HAL support library. This also adds GrallocLoader to load either of Gralloc[01]Hal and create an IMapper instance. libgrallocmapperincludes is renamed to follow the new naming and include path conventions. Test: boots and VTS Change-Id: I924cadce9a10a6e544f99ceba63aadc38ec431ac --- .../2.0/utils/passthrough/Android.bp | 4 +- .../allocator-passthrough/2.0/Gralloc0Hal.h | 4 +- .../allocator-passthrough/2.0/Gralloc1Hal.h | 4 +- graphics/mapper/2.0/default/Android.bp | 13 +- .../mapper/2.0/default/Gralloc0Mapper.cpp | 156 -------- graphics/mapper/2.0/default/Gralloc0Mapper.h | 56 --- .../mapper/2.0/default/Gralloc1Mapper.cpp | 273 -------------- graphics/mapper/2.0/default/Gralloc1Mapper.h | 76 ---- graphics/mapper/2.0/default/GrallocMapper.cpp | 321 ----------------- graphics/mapper/2.0/default/GrallocMapper.h | 96 ----- graphics/mapper/2.0/default/passthrough.cpp | 24 ++ .../mapper/2.0/utils/passthrough/Android.bp | 43 +++ .../mapper-passthrough/2.0/Gralloc0Hal.h | 214 +++++++++++ .../mapper-passthrough/2.0/Gralloc1Hal.h | 338 ++++++++++++++++++ .../2.0}/GrallocBufferDescriptor.h | 14 +- .../mapper-passthrough/2.0/GrallocLoader.h | 161 +++++++++ 16 files changed, 796 insertions(+), 1001 deletions(-) delete mode 100644 graphics/mapper/2.0/default/Gralloc0Mapper.cpp delete mode 100644 graphics/mapper/2.0/default/Gralloc0Mapper.h delete mode 100644 graphics/mapper/2.0/default/Gralloc1Mapper.cpp delete mode 100644 graphics/mapper/2.0/default/Gralloc1Mapper.h delete mode 100644 graphics/mapper/2.0/default/GrallocMapper.cpp delete mode 100644 graphics/mapper/2.0/default/GrallocMapper.h create mode 100644 graphics/mapper/2.0/default/passthrough.cpp create mode 100644 graphics/mapper/2.0/utils/passthrough/Android.bp create mode 100644 graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc0Hal.h create mode 100644 graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h rename graphics/mapper/2.0/{default => utils/passthrough/include/mapper-passthrough/2.0}/GrallocBufferDescriptor.h (84%) create mode 100644 graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h diff --git a/graphics/allocator/2.0/utils/passthrough/Android.bp b/graphics/allocator/2.0/utils/passthrough/Android.bp index ff9280add6..95b92cfb55 100644 --- a/graphics/allocator/2.0/utils/passthrough/Android.bp +++ b/graphics/allocator/2.0/utils/passthrough/Android.bp @@ -14,11 +14,11 @@ cc_library_headers { ], header_libs: [ "android.hardware.graphics.allocator@2.0-hal", - "libgrallocmapperincludes", + "android.hardware.graphics.mapper@2.0-passthrough_headers", ], export_header_lib_headers: [ "android.hardware.graphics.allocator@2.0-hal", - "libgrallocmapperincludes", + "android.hardware.graphics.mapper@2.0-passthrough_headers", ], export_include_dirs: ["include"], } diff --git a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h index 2665b40030..6c179be722 100644 --- a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h +++ b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h @@ -22,10 +22,10 @@ #include // for strerror -#include #include #include #include +#include namespace android { namespace hardware { @@ -38,7 +38,7 @@ namespace detail { using mapper::V2_0::BufferDescriptor; using mapper::V2_0::Error; -using mapper::V2_0::implementation::grallocDecodeBufferDescriptor; +using mapper::V2_0::passthrough::grallocDecodeBufferDescriptor; // Gralloc0HalImpl implements V2_*::hal::AllocatorHal on top of gralloc0 template diff --git a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h index 3979f0d761..53b5c14de7 100644 --- a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h +++ b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h @@ -22,10 +22,10 @@ #include // for strerror -#include #include #include #include +#include namespace android { namespace hardware { @@ -39,7 +39,7 @@ namespace detail { using common::V1_0::BufferUsage; using mapper::V2_0::BufferDescriptor; using mapper::V2_0::Error; -using mapper::V2_0::implementation::grallocDecodeBufferDescriptor; +using mapper::V2_0::passthrough::grallocDecodeBufferDescriptor; // Gralloc1HalImpl implements V2_*::hal::AllocatorHal on top of gralloc1 template diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp index 677d966113..8874799d10 100644 --- a/graphics/mapper/2.0/default/Android.bp +++ b/graphics/mapper/2.0/default/Android.bp @@ -18,8 +18,10 @@ cc_library_shared { defaults: ["hidl_defaults"], vendor: true, relative_install_path: "hw", - srcs: ["GrallocMapper.cpp", "Gralloc0Mapper.cpp", "Gralloc1Mapper.cpp"], - cppflags: ["-Wall", "-Wextra"], + srcs: ["passthrough.cpp"], + header_libs: [ + "android.hardware.graphics.mapper@2.0-passthrough" + ], shared_libs: [ "android.hardware.graphics.mapper@2.0", "libbase", @@ -31,10 +33,5 @@ cc_library_shared { "libsync", "libutils", ], -} - -cc_library_headers { - name: "libgrallocmapperincludes", - vendor: true, - export_include_dirs: ["."], + cflags: ["-DLOG_TAG=\"MapperHal\""], } diff --git a/graphics/mapper/2.0/default/Gralloc0Mapper.cpp b/graphics/mapper/2.0/default/Gralloc0Mapper.cpp deleted file mode 100644 index 28f50161c7..0000000000 --- a/graphics/mapper/2.0/default/Gralloc0Mapper.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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 "Gralloc0Mapper" - -#include "Gralloc0Mapper.h" - -#include - -namespace android { -namespace hardware { -namespace graphics { -namespace mapper { -namespace V2_0 { -namespace implementation { - -Gralloc0Mapper::Gralloc0Mapper(const hw_module_t* module) - : mModule(reinterpret_cast(module)), - mMinor(module->module_api_version & 0xff) { - mCapabilities.highUsageBits = false; - mCapabilities.layeredBuffers = false; - mCapabilities.unregisterImplyDelete = false; -} - -Error Gralloc0Mapper::registerBuffer(buffer_handle_t bufferHandle) { - int result = mModule->registerBuffer(mModule, bufferHandle); - return result ? Error::BAD_BUFFER : Error::NONE; -} - -void Gralloc0Mapper::unregisterBuffer(buffer_handle_t bufferHandle) { - mModule->unregisterBuffer(mModule, bufferHandle); -} - -Error Gralloc0Mapper::lockBuffer(buffer_handle_t bufferHandle, - uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - void** outData) { - int result; - void* data = nullptr; - if (mMinor >= 3 && mModule->lockAsync) { - // Dup fenceFd as it is going to be owned by gralloc. Note that it is - // gralloc's responsibility to close it, even on locking errors. - if (fenceFd >= 0) { - fenceFd = dup(fenceFd); - if (fenceFd < 0) { - return Error::NO_RESOURCES; - } - } - - result = mModule->lockAsync(mModule, bufferHandle, cpuUsage, - accessRegion.left, accessRegion.top, - accessRegion.width, accessRegion.height, - &data, fenceFd); - } else { - waitFenceFd(fenceFd, "Gralloc0Mapper::lock"); - - result = mModule->lock(mModule, bufferHandle, cpuUsage, - accessRegion.left, accessRegion.top, - accessRegion.width, accessRegion.height, &data); - } - - if (result) { - return Error::BAD_VALUE; - } else { - *outData = data; - return Error::NONE; - } -} - -Error Gralloc0Mapper::lockBuffer(buffer_handle_t bufferHandle, - uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - YCbCrLayout* outLayout) { - int result; - android_ycbcr ycbcr = {}; - if (mMinor >= 3 && mModule->lockAsync_ycbcr) { - // Dup fenceFd as it is going to be owned by gralloc. Note that it is - // gralloc's responsibility to close it, even on locking errors. - if (fenceFd >= 0) { - fenceFd = dup(fenceFd); - if (fenceFd < 0) { - return Error::NO_RESOURCES; - } - } - - result = mModule->lockAsync_ycbcr(mModule, bufferHandle, cpuUsage, - accessRegion.left, accessRegion.top, - accessRegion.width, - accessRegion.height, &ycbcr, fenceFd); - } else { - waitFenceFd(fenceFd, "Gralloc0Mapper::lockYCbCr"); - - if (mModule->lock_ycbcr) { - result = mModule->lock_ycbcr(mModule, bufferHandle, cpuUsage, - accessRegion.left, accessRegion.top, - accessRegion.width, - accessRegion.height, &ycbcr); - } else { - result = -EINVAL; - } - } - - if (result) { - return Error::BAD_VALUE; - } else { - outLayout->y = ycbcr.y; - outLayout->cb = ycbcr.cb; - outLayout->cr = ycbcr.cr; - outLayout->yStride = ycbcr.ystride; - outLayout->cStride = ycbcr.cstride; - outLayout->chromaStep = ycbcr.chroma_step; - return Error::NONE; - } -} - -Error Gralloc0Mapper::unlockBuffer(buffer_handle_t bufferHandle, - int* outFenceFd) { - int result; - int fenceFd = -1; - if (mMinor >= 3 && mModule->unlockAsync) { - result = mModule->unlockAsync(mModule, bufferHandle, &fenceFd); - } else { - result = mModule->unlock(mModule, bufferHandle); - } - - if (result) { - // we always own the fenceFd even when unlock failed - if (fenceFd >= 0) { - close(fenceFd); - } - - return Error::BAD_VALUE; - } else { - *outFenceFd = fenceFd; - return Error::NONE; - } -} - -} // namespace implementation -} // namespace V2_0 -} // namespace mapper -} // namespace graphics -} // namespace hardware -} // namespace android diff --git a/graphics/mapper/2.0/default/Gralloc0Mapper.h b/graphics/mapper/2.0/default/Gralloc0Mapper.h deleted file mode 100644 index e792a69703..0000000000 --- a/graphics/mapper/2.0/default/Gralloc0Mapper.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC0MAPPER_H -#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC0MAPPER_H - -#include "GrallocMapper.h" - -#include - -namespace android { -namespace hardware { -namespace graphics { -namespace mapper { -namespace V2_0 { -namespace implementation { - -class Gralloc0Mapper : public GrallocMapper { - public: - Gralloc0Mapper(const hw_module_t* module); - - private: - Error registerBuffer(buffer_handle_t bufferHandle) override; - void unregisterBuffer(buffer_handle_t bufferHandle) override; - Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - void** outData) override; - Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - YCbCrLayout* outLayout) override; - Error unlockBuffer(buffer_handle_t bufferHandle, int* outFenceFd) override; - - const gralloc_module_t* mModule; - uint8_t mMinor; -}; - -} // namespace implementation -} // namespace V2_0 -} // namespace mapper -} // namespace graphics -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC0MAPPER_H diff --git a/graphics/mapper/2.0/default/Gralloc1Mapper.cpp b/graphics/mapper/2.0/default/Gralloc1Mapper.cpp deleted file mode 100644 index c1e5adcd64..0000000000 --- a/graphics/mapper/2.0/default/Gralloc1Mapper.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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 "Gralloc1Mapper" - -#include "Gralloc1Mapper.h" - -#include - -#include - -namespace android { -namespace hardware { -namespace graphics { -namespace mapper { -namespace V2_0 { -namespace implementation { - -using android::hardware::graphics::common::V1_0::BufferUsage; - -Gralloc1Mapper::Gralloc1Mapper(const hw_module_t* module) - : mDevice(nullptr), mDispatch() { - int result = gralloc1_open(module, &mDevice); - if (result) { - LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s", - strerror(-result)); - } - - initCapabilities(); - initDispatch(); -} - -Gralloc1Mapper::~Gralloc1Mapper() { - gralloc1_close(mDevice); -} - -void Gralloc1Mapper::initCapabilities() { - mCapabilities.highUsageBits = true; - mCapabilities.layeredBuffers = false; - mCapabilities.unregisterImplyDelete = false; - - uint32_t count = 0; - mDevice->getCapabilities(mDevice, &count, nullptr); - - std::vector capabilities(count); - mDevice->getCapabilities(mDevice, &count, capabilities.data()); - capabilities.resize(count); - - for (auto capability : capabilities) { - switch (capability) { - case GRALLOC1_CAPABILITY_LAYERED_BUFFERS: - mCapabilities.layeredBuffers = true; - break; - case GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE: - mCapabilities.unregisterImplyDelete = true; - break; - } - } -} - -template -void Gralloc1Mapper::initDispatch(gralloc1_function_descriptor_t desc, - T* outPfn) { - auto pfn = mDevice->getFunction(mDevice, desc); - if (!pfn) { - LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc); - } - - *outPfn = reinterpret_cast(pfn); -} - -void Gralloc1Mapper::initDispatch() { - initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain); - initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release); - initDispatch(GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES, - &mDispatch.getNumFlexPlanes); - initDispatch(GRALLOC1_FUNCTION_LOCK, &mDispatch.lock); - initDispatch(GRALLOC1_FUNCTION_LOCK_FLEX, &mDispatch.lockFlex); - initDispatch(GRALLOC1_FUNCTION_UNLOCK, &mDispatch.unlock); -} - -Error Gralloc1Mapper::toError(int32_t error) { - switch (error) { - case GRALLOC1_ERROR_NONE: - return Error::NONE; - case GRALLOC1_ERROR_BAD_DESCRIPTOR: - return Error::BAD_DESCRIPTOR; - case GRALLOC1_ERROR_BAD_HANDLE: - return Error::BAD_BUFFER; - case GRALLOC1_ERROR_BAD_VALUE: - return Error::BAD_VALUE; - case GRALLOC1_ERROR_NOT_SHARED: - return Error::NONE; // this is fine - case GRALLOC1_ERROR_NO_RESOURCES: - return Error::NO_RESOURCES; - case GRALLOC1_ERROR_UNDEFINED: - case GRALLOC1_ERROR_UNSUPPORTED: - default: - return Error::UNSUPPORTED; - } -} - -bool Gralloc1Mapper::toYCbCrLayout(const android_flex_layout& flex, - YCbCrLayout* outLayout) { - // must be YCbCr - if (flex.format != FLEX_FORMAT_YCbCr || flex.num_planes < 3) { - return false; - } - - for (int i = 0; i < 3; i++) { - const auto& plane = flex.planes[i]; - // must have 8-bit depth - if (plane.bits_per_component != 8 || plane.bits_used != 8) { - return false; - } - - if (plane.component == FLEX_COMPONENT_Y) { - // Y must not be interleaved - if (plane.h_increment != 1) { - return false; - } - } else { - // Cb and Cr can be interleaved - if (plane.h_increment != 1 && plane.h_increment != 2) { - return false; - } - } - - if (!plane.v_increment) { - return false; - } - } - - if (flex.planes[0].component != FLEX_COMPONENT_Y || - flex.planes[1].component != FLEX_COMPONENT_Cb || - flex.planes[2].component != FLEX_COMPONENT_Cr) { - return false; - } - - const auto& y = flex.planes[0]; - const auto& cb = flex.planes[1]; - const auto& cr = flex.planes[2]; - - if (cb.h_increment != cr.h_increment || cb.v_increment != cr.v_increment) { - return false; - } - - outLayout->y = y.top_left; - outLayout->cb = cb.top_left; - outLayout->cr = cr.top_left; - outLayout->yStride = y.v_increment; - outLayout->cStride = cb.v_increment; - outLayout->chromaStep = cb.h_increment; - - return true; -} - -gralloc1_rect_t Gralloc1Mapper::asGralloc1Rect(const IMapper::Rect& rect) { - return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height}; -} - -Error Gralloc1Mapper::registerBuffer(buffer_handle_t bufferHandle) { - return toError(mDispatch.retain(mDevice, bufferHandle)); -} - -void Gralloc1Mapper::unregisterBuffer(buffer_handle_t bufferHandle) { - mDispatch.release(mDevice, bufferHandle); -} - -Error Gralloc1Mapper::lockBuffer(buffer_handle_t bufferHandle, - uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - void** outData) { - // Dup fenceFd as it is going to be owned by gralloc. Note that it is - // gralloc's responsibility to close it, even on locking errors. - if (fenceFd >= 0) { - fenceFd = dup(fenceFd); - if (fenceFd < 0) { - return Error::NO_RESOURCES; - } - } - - const uint64_t consumerUsage = - cpuUsage & ~static_cast(BufferUsage::CPU_WRITE_MASK); - const auto accessRect = asGralloc1Rect(accessRegion); - void* data = nullptr; - int32_t error = mDispatch.lock(mDevice, bufferHandle, cpuUsage, - consumerUsage, &accessRect, &data, fenceFd); - - if (error == GRALLOC1_ERROR_NONE) { - *outData = data; - } - - return toError(error); -} - -Error Gralloc1Mapper::lockBuffer(buffer_handle_t bufferHandle, - uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - YCbCrLayout* outLayout) { - // prepare flex layout - android_flex_layout flex = {}; - int32_t error = - mDispatch.getNumFlexPlanes(mDevice, bufferHandle, &flex.num_planes); - if (error != GRALLOC1_ERROR_NONE) { - return toError(error); - } - std::vector flexPlanes(flex.num_planes); - flex.planes = flexPlanes.data(); - - // Dup fenceFd as it is going to be owned by gralloc. Note that it is - // gralloc's responsibility to close it, even on locking errors. - if (fenceFd >= 0) { - fenceFd = dup(fenceFd); - if (fenceFd < 0) { - return Error::NO_RESOURCES; - } - } - - const uint64_t consumerUsage = - cpuUsage & ~static_cast(BufferUsage::CPU_WRITE_MASK); - const auto accessRect = asGralloc1Rect(accessRegion); - error = mDispatch.lockFlex(mDevice, bufferHandle, cpuUsage, consumerUsage, - &accessRect, &flex, fenceFd); - if (error == GRALLOC1_ERROR_NONE && !toYCbCrLayout(flex, outLayout)) { - ALOGD("unable to convert android_flex_layout to YCbCrLayout"); - - // undo the lock - fenceFd = -1; - mDispatch.unlock(mDevice, bufferHandle, &fenceFd); - if (fenceFd >= 0) { - close(fenceFd); - } - - error = GRALLOC1_ERROR_BAD_HANDLE; - } - - return toError(error); -} - -Error Gralloc1Mapper::unlockBuffer(buffer_handle_t bufferHandle, - int* outFenceFd) { - int fenceFd = -1; - int32_t error = mDispatch.unlock(mDevice, bufferHandle, &fenceFd); - - if (error == GRALLOC1_ERROR_NONE) { - *outFenceFd = fenceFd; - } else if (fenceFd >= 0) { - // we always own the fenceFd even when unlock failed - close(fenceFd); - } - - return toError(error); -} - -} // namespace implementation -} // namespace V2_0 -} // namespace mapper -} // namespace graphics -} // namespace hardware -} // namespace android diff --git a/graphics/mapper/2.0/default/Gralloc1Mapper.h b/graphics/mapper/2.0/default/Gralloc1Mapper.h deleted file mode 100644 index 452afdf820..0000000000 --- a/graphics/mapper/2.0/default/Gralloc1Mapper.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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. - */ - -#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC1MAPPER_H -#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC1MAPPER_H - -#include "GrallocMapper.h" - -#include - -namespace android { -namespace hardware { -namespace graphics { -namespace mapper { -namespace V2_0 { -namespace implementation { - -class Gralloc1Mapper : public GrallocMapper { - public: - Gralloc1Mapper(const hw_module_t* module); - ~Gralloc1Mapper(); - - private: - void initCapabilities(); - - template - void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn); - void initDispatch(); - - static Error toError(int32_t error); - static bool toYCbCrLayout(const android_flex_layout& flex, - YCbCrLayout* outLayout); - static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect); - - Error registerBuffer(buffer_handle_t bufferHandle) override; - void unregisterBuffer(buffer_handle_t bufferHandle) override; - Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - void** outData) override; - Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - YCbCrLayout* outLayout) override; - Error unlockBuffer(buffer_handle_t bufferHandle, int* outFenceFd) override; - - gralloc1_device_t* mDevice; - - struct { - GRALLOC1_PFN_RETAIN retain; - GRALLOC1_PFN_RELEASE release; - GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes; - GRALLOC1_PFN_LOCK lock; - GRALLOC1_PFN_LOCK_FLEX lockFlex; - GRALLOC1_PFN_UNLOCK unlock; - } mDispatch; -}; - -} // namespace implementation -} // namespace V2_0 -} // namespace mapper -} // namespace graphics -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC1MAPPER_H diff --git a/graphics/mapper/2.0/default/GrallocMapper.cpp b/graphics/mapper/2.0/default/GrallocMapper.cpp deleted file mode 100644 index d16143da49..0000000000 --- a/graphics/mapper/2.0/default/GrallocMapper.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 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 "GrallocMapperPassthrough" - -#include "GrallocMapper.h" - -#include "Gralloc0Mapper.h" -#include "Gralloc1Mapper.h" -#include "GrallocBufferDescriptor.h" - -#include - -#include -#include - -namespace android { -namespace hardware { -namespace graphics { -namespace mapper { -namespace V2_0 { -namespace implementation { - -using android::hardware::graphics::common::V1_0::BufferUsage; -using android::hardware::graphics::common::V1_0::PixelFormat; - -namespace { - -class RegisteredHandlePool { - public: - bool add(buffer_handle_t bufferHandle) { - std::lock_guard lock(mMutex); - return mHandles.insert(bufferHandle).second; - } - - native_handle_t* pop(void* buffer) { - auto bufferHandle = static_cast(buffer); - - std::lock_guard lock(mMutex); - return mHandles.erase(bufferHandle) == 1 ? bufferHandle : nullptr; - } - - buffer_handle_t get(const void* buffer) { - auto bufferHandle = static_cast(buffer); - - std::lock_guard lock(mMutex); - return mHandles.count(bufferHandle) == 1 ? bufferHandle : nullptr; - } - - private: - std::mutex mMutex; - std::unordered_set mHandles; -}; - -// GraphicBufferMapper is expected to be valid (and leaked) during process -// termination. We need to make sure IMapper, and in turn, gRegisteredHandles -// are valid as well. Create the registered handle pool on the heap, and let -// it leak for simplicity. -// -// However, there is no way to make sure gralloc0/gralloc1 are valid. Any use -// of static/global object in gralloc0/gralloc1 that may have been destructed -// is potentially broken. -RegisteredHandlePool* gRegisteredHandles = new RegisteredHandlePool; - -} // anonymous namespace - -bool GrallocMapper::validateDescriptorInfo( - const BufferDescriptorInfo& descriptorInfo) const { - const uint64_t validUsageBits = - BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | - BufferUsage::GPU_TEXTURE | BufferUsage::GPU_RENDER_TARGET | - BufferUsage::COMPOSER_OVERLAY | BufferUsage::COMPOSER_CLIENT_TARGET | - BufferUsage::PROTECTED | BufferUsage::COMPOSER_CURSOR | - BufferUsage::VIDEO_ENCODER | BufferUsage::CAMERA_OUTPUT | - BufferUsage::CAMERA_INPUT | BufferUsage::RENDERSCRIPT | - BufferUsage::VIDEO_DECODER | BufferUsage::SENSOR_DIRECT_DATA | - BufferUsage::GPU_DATA_BUFFER | BufferUsage::VENDOR_MASK | - (mCapabilities.highUsageBits ? BufferUsage::VENDOR_MASK_HI - : static_cast(0)); - - if (!descriptorInfo.width || !descriptorInfo.height || - !descriptorInfo.layerCount) { - return false; - } - - if (!mCapabilities.layeredBuffers && descriptorInfo.layerCount > 1) { - return false; - } - - if (descriptorInfo.format == static_cast(0)) { - return false; - } - - if (descriptorInfo.usage & ~validUsageBits) { - // could not fail as gralloc may use the reserved bits... - ALOGW("buffer descriptor with invalid usage bits 0x%" PRIx64, - descriptorInfo.usage & ~validUsageBits); - } - - return true; -} - -Return GrallocMapper::createDescriptor( - const BufferDescriptorInfo& descriptorInfo, createDescriptor_cb hidl_cb) { - if (validateDescriptorInfo(descriptorInfo)) { - hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo)); - } else { - hidl_cb(Error::BAD_VALUE, BufferDescriptor()); - } - - return Void(); -} - -Return GrallocMapper::importBuffer(const hidl_handle& rawHandle, - importBuffer_cb hidl_cb) { - // because of passthrough HALs, we must not generate an error when - // rawHandle has been imported - - if (!rawHandle.getNativeHandle()) { - hidl_cb(Error::BAD_BUFFER, nullptr); - return Void(); - } - - native_handle_t* bufferHandle = - native_handle_clone(rawHandle.getNativeHandle()); - if (!bufferHandle) { - hidl_cb(Error::NO_RESOURCES, nullptr); - return Void(); - } - - Error error = registerBuffer(bufferHandle); - if (error != Error::NONE) { - native_handle_close(bufferHandle); - native_handle_delete(bufferHandle); - - hidl_cb(error, nullptr); - return Void(); - } - - // The newly cloned handle is already registered? This can only happen - // when a handle previously registered was native_handle_delete'd instead - // of freeBuffer'd. - if (!gRegisteredHandles->add(bufferHandle)) { - ALOGE("handle %p has already been imported; potential fd leaking", - bufferHandle); - unregisterBuffer(bufferHandle); - if (!mCapabilities.unregisterImplyDelete) { - native_handle_close(bufferHandle); - native_handle_delete(bufferHandle); - } - - hidl_cb(Error::NO_RESOURCES, nullptr); - return Void(); - } - - hidl_cb(Error::NONE, bufferHandle); - return Void(); -} - -Return GrallocMapper::freeBuffer(void* buffer) { - native_handle_t* bufferHandle = gRegisteredHandles->pop(buffer); - if (!bufferHandle) { - return Error::BAD_BUFFER; - } - - unregisterBuffer(bufferHandle); - if (!mCapabilities.unregisterImplyDelete) { - native_handle_close(bufferHandle); - native_handle_delete(bufferHandle); - } - - return Error::NONE; -} - -void GrallocMapper::waitFenceFd(int fenceFd, const char* logname) { - if (fenceFd < 0) { - return; - } - - const int warningTimeout = 3500; - const int error = sync_wait(fenceFd, warningTimeout); - if (error < 0 && errno == ETIME) { - ALOGE("%s: fence %d didn't signal in %u ms", logname, fenceFd, - warningTimeout); - sync_wait(fenceFd, -1); - } -} - -bool GrallocMapper::getFenceFd(const hidl_handle& fenceHandle, - int* outFenceFd) { - auto handle = fenceHandle.getNativeHandle(); - if (handle && handle->numFds > 1) { - ALOGE("invalid fence handle with %d fds", handle->numFds); - return false; - } - - *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1; - return true; -} - -hidl_handle GrallocMapper::getFenceHandle(int fenceFd, char* handleStorage) { - native_handle_t* handle = nullptr; - if (fenceFd >= 0) { - handle = native_handle_init(handleStorage, 1, 0); - handle->data[0] = fenceFd; - } - - return hidl_handle(handle); -} - -Return GrallocMapper::lock(void* buffer, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, - const hidl_handle& acquireFence, - lock_cb hidl_cb) { - buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); - if (!bufferHandle) { - hidl_cb(Error::BAD_BUFFER, nullptr); - return Void(); - } - - int fenceFd; - if (!getFenceFd(acquireFence, &fenceFd)) { - hidl_cb(Error::BAD_VALUE, nullptr); - return Void(); - } - - void* data = nullptr; - Error error = - lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data); - - hidl_cb(error, data); - return Void(); -} - -Return GrallocMapper::lockYCbCr(void* buffer, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, - const hidl_handle& acquireFence, - lockYCbCr_cb hidl_cb) { - YCbCrLayout layout = {}; - - buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); - if (!bufferHandle) { - hidl_cb(Error::BAD_BUFFER, layout); - return Void(); - } - - int fenceFd; - if (!getFenceFd(acquireFence, &fenceFd)) { - hidl_cb(Error::BAD_VALUE, layout); - return Void(); - } - - Error error = - lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &layout); - - hidl_cb(error, layout); - return Void(); -} - -Return GrallocMapper::unlock(void* buffer, unlock_cb hidl_cb) { - buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); - if (!bufferHandle) { - hidl_cb(Error::BAD_BUFFER, nullptr); - return Void(); - } - - int fenceFd; - Error error = unlockBuffer(bufferHandle, &fenceFd); - if (error == Error::NONE) { - NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0); - - hidl_cb(error, getFenceHandle(fenceFd, fenceStorage)); - - if (fenceFd >= 0) { - close(fenceFd); - } - } else { - hidl_cb(error, nullptr); - } - - return Void(); -} - -IMapper* HIDL_FETCH_IMapper(const char* /* name */) { - const hw_module_t* module = nullptr; - int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); - if (err) { - ALOGE("failed to get gralloc module"); - return nullptr; - } - - uint8_t major = (module->module_api_version >> 8) & 0xff; - switch (major) { - case 1: - return new Gralloc1Mapper(module); - case 0: - return new Gralloc0Mapper(module); - default: - ALOGE("unknown gralloc module major version %d", major); - return nullptr; - } -} - -} // namespace implementation -} // namespace V2_0 -} // namespace mapper -} // namespace graphics -} // namespace hardware -} // namespace android diff --git a/graphics/mapper/2.0/default/GrallocMapper.h b/graphics/mapper/2.0/default/GrallocMapper.h deleted file mode 100644 index e876fe4494..0000000000 --- a/graphics/mapper/2.0/default/GrallocMapper.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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. - */ - -#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H -#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H - -#include -#include - -#include -#include - -namespace android { -namespace hardware { -namespace graphics { -namespace mapper { -namespace V2_0 { -namespace implementation { - -class GrallocMapper : public IMapper { - public: - // IMapper interface - Return createDescriptor(const BufferDescriptorInfo& descriptorInfo, - createDescriptor_cb hidl_cb) override; - Return importBuffer(const hidl_handle& rawHandle, - importBuffer_cb hidl_cb) override; - Return freeBuffer(void* buffer) override; - Return lock(void* buffer, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, - const hidl_handle& acquireFence, - lock_cb hidl_cb) override; - Return lockYCbCr(void* buffer, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, - const hidl_handle& acquireFence, - lockYCbCr_cb hidl_cb) override; - Return unlock(void* buffer, unlock_cb hidl_cb) override; - - protected: - static void waitFenceFd(int fenceFd, const char* logname); - - struct { - bool highUsageBits; - bool layeredBuffers; - bool unregisterImplyDelete; - } mCapabilities = {}; - - private: - virtual bool validateDescriptorInfo( - const BufferDescriptorInfo& descriptorInfo) const; - - // Register a buffer. The handle is already cloned by the caller. - virtual Error registerBuffer(buffer_handle_t bufferHandle) = 0; - - // Unregister a buffer. The handle is closed and deleted by the - // callee if and only if mCapabilities.unregisterImplyDelete is set. - virtual void unregisterBuffer(buffer_handle_t bufferHandle) = 0; - - // Lock a buffer. The fence is owned by the caller. - virtual Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - void** outData) = 0; - virtual Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - YCbCrLayout* outLayout) = 0; - - // Unlock a buffer. The returned fence is owned by the caller. - virtual Error unlockBuffer(buffer_handle_t bufferHandle, - int* outFenceFd) = 0; - - static bool getFenceFd(const hidl_handle& fenceHandle, int* outFenceFd); - static hidl_handle getFenceHandle(int fenceFd, char* handleStorage); -}; - -extern "C" IMapper* HIDL_FETCH_IMapper(const char* name); - -} // namespace implementation -} // namespace V2_0 -} // namespace mapper -} // namespace graphics -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H diff --git a/graphics/mapper/2.0/default/passthrough.cpp b/graphics/mapper/2.0/default/passthrough.cpp new file mode 100644 index 0000000000..e18b88fb84 --- /dev/null +++ b/graphics/mapper/2.0/default/passthrough.cpp @@ -0,0 +1,24 @@ +/* + * 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. + */ + +#include +#include + +using android::hardware::graphics::mapper::V2_0::IMapper; +using android::hardware::graphics::mapper::V2_0::passthrough::GrallocLoader; + +extern "C" IMapper* HIDL_FETCH_IMapper(const char* /*name*/) { + return GrallocLoader::load(); +} diff --git a/graphics/mapper/2.0/utils/passthrough/Android.bp b/graphics/mapper/2.0/utils/passthrough/Android.bp new file mode 100644 index 0000000000..4f700c867a --- /dev/null +++ b/graphics/mapper/2.0/utils/passthrough/Android.bp @@ -0,0 +1,43 @@ +// +// Copyright (C) 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. + +cc_library_headers { + name: "android.hardware.graphics.mapper@2.0-passthrough", + defaults: ["hidl_defaults"], + vendor: true, + shared_libs: [ + "android.hardware.graphics.mapper@2.0", + "libhardware", + "libsync", + ], + export_shared_lib_headers: [ + "android.hardware.graphics.mapper@2.0", + "libhardware", + "libsync", + ], + header_libs: [ + "android.hardware.graphics.mapper@2.0-hal", + ], + export_header_lib_headers: [ + "android.hardware.graphics.mapper@2.0-hal", + ], + export_include_dirs: ["include"], +} + +cc_library_headers { + name: "android.hardware.graphics.mapper@2.0-passthrough_headers", + vendor: true, + export_include_dirs: ["include"], +} diff --git a/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc0Hal.h b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc0Hal.h new file mode 100644 index 0000000000..7369ac7593 --- /dev/null +++ b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc0Hal.h @@ -0,0 +1,214 @@ +/* + * 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. + */ + +#pragma once + +#ifndef LOG_TAG +#warning "Gralloc0Hal.h included without LOG_TAG" +#endif + +#include + +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace mapper { +namespace V2_0 { +namespace passthrough { + +namespace detail { + +using common::V1_0::BufferUsage; + +// Gralloc0HalImpl implements V2_*::hal::MapperHal on top of gralloc0 +template +class Gralloc0HalImpl : public Hal { + public: + bool initWithModule(const hw_module_t* module) { + mModule = reinterpret_cast(module); + mMinor = module->module_api_version & 0xff; + return true; + } + + Error createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo, + BufferDescriptor* outDescriptor) override { + if (!descriptorInfo.width || !descriptorInfo.height || !descriptorInfo.layerCount) { + return Error::BAD_VALUE; + } + + if (descriptorInfo.layerCount != 1) { + return Error::UNSUPPORTED; + } + + if (descriptorInfo.format == static_cast(0)) { + return Error::BAD_VALUE; + } + + const uint64_t validUsageBits = getValidBufferUsageMask(); + if (descriptorInfo.usage & ~validUsageBits) { + ALOGW("buffer descriptor with invalid usage bits 0x%" PRIx64, + descriptorInfo.usage & ~validUsageBits); + } + + *outDescriptor = grallocEncodeBufferDescriptor(descriptorInfo); + + return Error::NONE; + } + + Error importBuffer(const native_handle_t* rawHandle, + native_handle_t** outBufferHandle) override { + native_handle_t* bufferHandle = native_handle_clone(rawHandle); + if (!bufferHandle) { + return Error::NO_RESOURCES; + } + + if (mModule->registerBuffer(mModule, bufferHandle)) { + native_handle_close(bufferHandle); + native_handle_delete(bufferHandle); + return Error::BAD_BUFFER; + } + + *outBufferHandle = bufferHandle; + + return Error::NONE; + } + + Error freeBuffer(native_handle_t* bufferHandle) override { + if (mModule->unregisterBuffer(mModule, bufferHandle)) { + return Error::BAD_BUFFER; + } + + native_handle_close(bufferHandle); + native_handle_delete(bufferHandle); + return Error::NONE; + } + + Error lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, + const IMapper::Rect& accessRegion, base::unique_fd fenceFd, + void** outData) override { + int result; + void* data = nullptr; + if (mMinor >= 3 && mModule->lockAsync) { + result = mModule->lockAsync(mModule, bufferHandle, cpuUsage, accessRegion.left, + accessRegion.top, accessRegion.width, accessRegion.height, + &data, fenceFd.release()); + } else { + waitFenceFd(fenceFd, "Gralloc0Hal::lock"); + + result = + mModule->lock(mModule, bufferHandle, cpuUsage, accessRegion.left, accessRegion.top, + accessRegion.width, accessRegion.height, &data); + } + + if (result) { + return Error::BAD_VALUE; + } + + *outData = data; + return Error::NONE; + } + + Error lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage, + const IMapper::Rect& accessRegion, base::unique_fd fenceFd, + YCbCrLayout* outLayout) override { + int result; + android_ycbcr ycbcr = {}; + if (mMinor >= 3 && mModule->lockAsync_ycbcr) { + result = mModule->lockAsync_ycbcr(mModule, bufferHandle, cpuUsage, accessRegion.left, + accessRegion.top, accessRegion.width, + accessRegion.height, &ycbcr, fenceFd.release()); + } else { + waitFenceFd(fenceFd, "Gralloc0Hal::lockYCbCr"); + + if (mModule->lock_ycbcr) { + result = mModule->lock_ycbcr(mModule, bufferHandle, cpuUsage, accessRegion.left, + accessRegion.top, accessRegion.width, + accessRegion.height, &ycbcr); + } else { + result = -EINVAL; + } + } + + if (result) { + return Error::BAD_VALUE; + } + + outLayout->y = ycbcr.y; + outLayout->cb = ycbcr.cb; + outLayout->cr = ycbcr.cr; + outLayout->yStride = ycbcr.ystride; + outLayout->cStride = ycbcr.cstride; + outLayout->chromaStep = ycbcr.chroma_step; + return Error::NONE; + } + + Error unlock(const native_handle_t* bufferHandle, base::unique_fd* outFenceFd) override { + int result; + int fenceFd = -1; + if (mMinor >= 3 && mModule->unlockAsync) { + result = mModule->unlockAsync(mModule, bufferHandle, &fenceFd); + } else { + result = mModule->unlock(mModule, bufferHandle); + } + + // we always own the fenceFd even when unlock failed + outFenceFd->reset(fenceFd); + return result ? Error::BAD_VALUE : Error::NONE; + } + + protected: + virtual uint64_t getValidBufferUsageMask() const { + return BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | BufferUsage::GPU_TEXTURE | + BufferUsage::GPU_RENDER_TARGET | BufferUsage::COMPOSER_OVERLAY | + BufferUsage::COMPOSER_CLIENT_TARGET | BufferUsage::PROTECTED | + BufferUsage::COMPOSER_CURSOR | BufferUsage::VIDEO_ENCODER | + BufferUsage::CAMERA_OUTPUT | BufferUsage::CAMERA_INPUT | BufferUsage::RENDERSCRIPT | + BufferUsage::VIDEO_DECODER | BufferUsage::SENSOR_DIRECT_DATA | + BufferUsage::GPU_DATA_BUFFER | BufferUsage::VENDOR_MASK; + } + + static void waitFenceFd(const base::unique_fd& fenceFd, const char* logname) { + if (fenceFd < 0) { + return; + } + + const int warningTimeout = 3500; + const int error = sync_wait(fenceFd, warningTimeout); + if (error < 0 && errno == ETIME) { + ALOGE("%s: fence %d didn't signal in %u ms", logname, fenceFd.get(), warningTimeout); + sync_wait(fenceFd, -1); + } + } + + const gralloc_module_t* mModule = nullptr; + uint8_t mMinor = 0; +}; + +} // namespace detail + +using Gralloc0Hal = detail::Gralloc0HalImpl; + +} // namespace passthrough +} // namespace V2_0 +} // namespace mapper +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h new file mode 100644 index 0000000000..d9beb4f678 --- /dev/null +++ b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h @@ -0,0 +1,338 @@ +/* + * 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. + */ + +#pragma once + +#ifndef LOG_TAG +#warning "Gralloc1Hal.h included without LOG_TAG" +#endif + +#include + +#include + +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace mapper { +namespace V2_0 { +namespace passthrough { + +namespace detail { + +using common::V1_0::BufferUsage; + +// Gralloc1HalImpl implements V2_*::hal::MapperHal on top of gralloc1 +template +class Gralloc1HalImpl : public Hal { + public: + ~Gralloc1HalImpl() { + if (mDevice) { + gralloc1_close(mDevice); + } + } + + bool initWithModule(const hw_module_t* module) { + int result = gralloc1_open(module, &mDevice); + if (result) { + ALOGE("failed to open gralloc1 device: %s", strerror(-result)); + mDevice = nullptr; + return false; + } + + initCapabilities(); + + if (!initDispatch()) { + gralloc1_close(mDevice); + mDevice = nullptr; + return false; + } + + return true; + } + + Error createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo, + BufferDescriptor* outDescriptor) override { + if (!descriptorInfo.width || !descriptorInfo.height || !descriptorInfo.layerCount) { + return Error::BAD_VALUE; + } + + if (!mCapabilities.layeredBuffers && descriptorInfo.layerCount != 1) { + return Error::UNSUPPORTED; + } + + if (descriptorInfo.format == static_cast(0)) { + return Error::BAD_VALUE; + } + + const uint64_t validUsageBits = getValidBufferUsageMask(); + if (descriptorInfo.usage & ~validUsageBits) { + ALOGW("buffer descriptor with invalid usage bits 0x%" PRIx64, + descriptorInfo.usage & ~validUsageBits); + } + + *outDescriptor = grallocEncodeBufferDescriptor(descriptorInfo); + + return Error::NONE; + } + + Error importBuffer(const native_handle_t* rawHandle, + native_handle_t** outBufferHandle) override { + native_handle_t* bufferHandle = native_handle_clone(rawHandle); + if (!bufferHandle) { + return Error::NO_RESOURCES; + } + + int32_t error = mDispatch.retain(mDevice, bufferHandle); + if (error != GRALLOC1_ERROR_NONE) { + native_handle_close(bufferHandle); + native_handle_delete(bufferHandle); + return toError(error); + } + + *outBufferHandle = bufferHandle; + + return Error::NONE; + } + + Error freeBuffer(native_handle_t* bufferHandle) override { + int32_t error = mDispatch.release(mDevice, bufferHandle); + if (error == GRALLOC1_ERROR_NONE && !mCapabilities.releaseImplyDelete) { + native_handle_close(bufferHandle); + native_handle_delete(bufferHandle); + } + return toError(error); + } + + Error lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, + const IMapper::Rect& accessRegion, base::unique_fd fenceFd, + void** outData) override { + const uint64_t consumerUsage = + cpuUsage & ~static_cast(BufferUsage::CPU_WRITE_MASK); + const auto accessRect = asGralloc1Rect(accessRegion); + void* data = nullptr; + int32_t error = mDispatch.lock(mDevice, bufferHandle, cpuUsage, consumerUsage, &accessRect, + &data, fenceFd.release()); + if (error == GRALLOC1_ERROR_NONE) { + *outData = data; + } + + return toError(error); + } + + Error lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage, + const IMapper::Rect& accessRegion, base::unique_fd fenceFd, + YCbCrLayout* outLayout) override { + // prepare flex layout + android_flex_layout flex = {}; + int32_t error = mDispatch.getNumFlexPlanes(mDevice, bufferHandle, &flex.num_planes); + if (error != GRALLOC1_ERROR_NONE) { + return toError(error); + } + std::vector flexPlanes(flex.num_planes); + flex.planes = flexPlanes.data(); + + const uint64_t consumerUsage = + cpuUsage & ~static_cast(BufferUsage::CPU_WRITE_MASK); + const auto accessRect = asGralloc1Rect(accessRegion); + error = mDispatch.lockFlex(mDevice, bufferHandle, cpuUsage, consumerUsage, &accessRect, + &flex, fenceFd.release()); + if (error == GRALLOC1_ERROR_NONE && !toYCbCrLayout(flex, outLayout)) { + ALOGD("unable to convert android_flex_layout to YCbCrLayout"); + // undo the lock + unlock(bufferHandle, &fenceFd); + error = GRALLOC1_ERROR_BAD_HANDLE; + } + + return toError(error); + } + + Error unlock(const native_handle_t* bufferHandle, base::unique_fd* outFenceFd) override { + int fenceFd = -1; + int32_t error = mDispatch.unlock(mDevice, bufferHandle, &fenceFd); + + // we always own the fenceFd even when unlock failed + outFenceFd->reset(fenceFd); + return toError(error); + } + + protected: + virtual void initCapabilities() { + uint32_t count = 0; + mDevice->getCapabilities(mDevice, &count, nullptr); + + std::vector capabilities(count); + mDevice->getCapabilities(mDevice, &count, capabilities.data()); + capabilities.resize(count); + + for (auto capability : capabilities) { + switch (capability) { + case GRALLOC1_CAPABILITY_LAYERED_BUFFERS: + mCapabilities.layeredBuffers = true; + break; + case GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE: + mCapabilities.releaseImplyDelete = true; + break; + } + } + } + + template + bool initDispatch(gralloc1_function_descriptor_t desc, T* outPfn) { + auto pfn = mDevice->getFunction(mDevice, desc); + if (pfn) { + *outPfn = reinterpret_cast(pfn); + return true; + } else { + ALOGE("failed to get gralloc1 function %d", desc); + return false; + } + } + + virtual bool initDispatch() { + if (!initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain) || + !initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release) || + !initDispatch(GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES, &mDispatch.getNumFlexPlanes) || + !initDispatch(GRALLOC1_FUNCTION_LOCK, &mDispatch.lock) || + !initDispatch(GRALLOC1_FUNCTION_LOCK_FLEX, &mDispatch.lockFlex) || + !initDispatch(GRALLOC1_FUNCTION_UNLOCK, &mDispatch.unlock)) { + return false; + } + + return true; + } + + virtual uint64_t getValidBufferUsageMask() const { + return BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | BufferUsage::GPU_TEXTURE | + BufferUsage::GPU_RENDER_TARGET | BufferUsage::COMPOSER_OVERLAY | + BufferUsage::COMPOSER_CLIENT_TARGET | BufferUsage::PROTECTED | + BufferUsage::COMPOSER_CURSOR | BufferUsage::VIDEO_ENCODER | + BufferUsage::CAMERA_OUTPUT | BufferUsage::CAMERA_INPUT | BufferUsage::RENDERSCRIPT | + BufferUsage::VIDEO_DECODER | BufferUsage::SENSOR_DIRECT_DATA | + BufferUsage::GPU_DATA_BUFFER | BufferUsage::VENDOR_MASK | + BufferUsage::VENDOR_MASK_HI; + } + + static Error toError(int32_t error) { + switch (error) { + case GRALLOC1_ERROR_NONE: + return Error::NONE; + case GRALLOC1_ERROR_BAD_DESCRIPTOR: + return Error::BAD_DESCRIPTOR; + case GRALLOC1_ERROR_BAD_HANDLE: + return Error::BAD_BUFFER; + case GRALLOC1_ERROR_BAD_VALUE: + return Error::BAD_VALUE; + case GRALLOC1_ERROR_NOT_SHARED: + return Error::NONE; // this is fine + case GRALLOC1_ERROR_NO_RESOURCES: + return Error::NO_RESOURCES; + case GRALLOC1_ERROR_UNDEFINED: + case GRALLOC1_ERROR_UNSUPPORTED: + default: + return Error::UNSUPPORTED; + } + } + + static bool toYCbCrLayout(const android_flex_layout& flex, YCbCrLayout* outLayout) { + // must be YCbCr + if (flex.format != FLEX_FORMAT_YCbCr || flex.num_planes < 3) { + return false; + } + + for (int i = 0; i < 3; i++) { + const auto& plane = flex.planes[i]; + // must have 8-bit depth + if (plane.bits_per_component != 8 || plane.bits_used != 8) { + return false; + } + + if (plane.component == FLEX_COMPONENT_Y) { + // Y must not be interleaved + if (plane.h_increment != 1) { + return false; + } + } else { + // Cb and Cr can be interleaved + if (plane.h_increment != 1 && plane.h_increment != 2) { + return false; + } + } + + if (!plane.v_increment) { + return false; + } + } + + if (flex.planes[0].component != FLEX_COMPONENT_Y || + flex.planes[1].component != FLEX_COMPONENT_Cb || + flex.planes[2].component != FLEX_COMPONENT_Cr) { + return false; + } + + const auto& y = flex.planes[0]; + const auto& cb = flex.planes[1]; + const auto& cr = flex.planes[2]; + + if (cb.h_increment != cr.h_increment || cb.v_increment != cr.v_increment) { + return false; + } + + outLayout->y = y.top_left; + outLayout->cb = cb.top_left; + outLayout->cr = cr.top_left; + outLayout->yStride = y.v_increment; + outLayout->cStride = cb.v_increment; + outLayout->chromaStep = cb.h_increment; + + return true; + } + + static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect) { + return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height}; + } + + gralloc1_device_t* mDevice = nullptr; + + struct { + bool layeredBuffers; + bool releaseImplyDelete; + } mCapabilities = {}; + + struct { + GRALLOC1_PFN_RETAIN retain; + GRALLOC1_PFN_RELEASE release; + GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes; + GRALLOC1_PFN_LOCK lock; + GRALLOC1_PFN_LOCK_FLEX lockFlex; + GRALLOC1_PFN_UNLOCK unlock; + } mDispatch = {}; +}; + +} // namespace detail + +using Gralloc1Hal = detail::Gralloc1HalImpl; + +} // namespace passthrough +} // namespace V2_0 +} // namespace mapper +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/graphics/mapper/2.0/default/GrallocBufferDescriptor.h b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocBufferDescriptor.h similarity index 84% rename from graphics/mapper/2.0/default/GrallocBufferDescriptor.h rename to graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocBufferDescriptor.h index 9b5ab04562..4c477e12a5 100644 --- a/graphics/mapper/2.0/default/GrallocBufferDescriptor.h +++ b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocBufferDescriptor.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOCBUFFERDESCRIPTOR_H -#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOCBUFFERDESCRIPTOR_H +#pragma once #include @@ -24,7 +23,7 @@ namespace hardware { namespace graphics { namespace mapper { namespace V2_0 { -namespace implementation { +namespace passthrough { using android::hardware::graphics::common::V1_0::PixelFormat; @@ -50,9 +49,8 @@ inline BufferDescriptor grallocEncodeBufferDescriptor( return descriptor; } -inline bool grallocDecodeBufferDescriptor( - const BufferDescriptor& descriptor, - IMapper::BufferDescriptorInfo* outDescriptorInfo) { +inline bool grallocDecodeBufferDescriptor(const BufferDescriptor& descriptor, + IMapper::BufferDescriptorInfo* outDescriptorInfo) { if (descriptor.size() != grallocBufferDescriptorSize || descriptor[0] != grallocBufferDescriptorMagicVersion) { return false; @@ -69,11 +67,9 @@ inline bool grallocDecodeBufferDescriptor( return true; } -} // namespace implementation +} // namespace passthrough } // namespace V2_0 } // namespace mapper } // namespace graphics } // namespace hardware } // namespace android - -#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOCBUFFERDESCRIPTOR_H diff --git a/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h new file mode 100644 index 0000000000..e8b1b4b837 --- /dev/null +++ b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h @@ -0,0 +1,161 @@ +/* + * Copyright 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. + */ + +#pragma once + +#ifndef LOG_TAG +#warning "GrallocLoader.h included without LOG_TAG" +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace graphics { +namespace mapper { +namespace V2_0 { +namespace passthrough { + +class GrallocImportedBufferPool { + public: + static GrallocImportedBufferPool& getInstance() { + // GraphicBufferMapper in framework is expected to be valid (and + // leaked) during process termination. We need to make sure IMapper, + // and in turn, GrallocImportedBufferPool is valid as well. Create + // imported buffer pool on the heap (and let it leak) for the purpose. + // Besides, all IMapper instances must share the same pool. Make it a + // singleton. + // + // However, there is no way to make sure gralloc0/gralloc1 are valid + // during process termination. Any use of static/global object in + // gralloc0/gralloc1 that may be destructed during process termination + // is potentially broken. + static GrallocImportedBufferPool* singleton = new GrallocImportedBufferPool; + return *singleton; + } + + void* add(native_handle_t* bufferHandle) { + std::lock_guard lock(mMutex); + return mBufferHandles.insert(bufferHandle).second ? bufferHandle : nullptr; + } + + native_handle_t* remove(void* buffer) { + auto bufferHandle = static_cast(buffer); + + std::lock_guard lock(mMutex); + return mBufferHandles.erase(bufferHandle) == 1 ? bufferHandle : nullptr; + } + + const native_handle_t* get(void* buffer) { + auto bufferHandle = static_cast(buffer); + + std::lock_guard lock(mMutex); + return mBufferHandles.count(bufferHandle) == 1 ? bufferHandle : nullptr; + } + + private: + std::mutex mMutex; + std::unordered_set mBufferHandles; +}; + +// Inherit from V2_*::hal::Mapper and override imported buffer management functions +template +class GrallocMapper : public T { + protected: + void* addImportedBuffer(native_handle_t* bufferHandle) override { + return GrallocImportedBufferPool::getInstance().add(bufferHandle); + } + + native_handle_t* removeImportedBuffer(void* buffer) override { + return GrallocImportedBufferPool::getInstance().remove(buffer); + } + + const native_handle_t* getImportedBuffer(void* buffer) const override { + return GrallocImportedBufferPool::getInstance().get(buffer); + } +}; + +class GrallocLoader { + public: + static IMapper* load() { + const hw_module_t* module = loadModule(); + if (!module) { + return nullptr; + } + auto hal = createHal(module); + if (!hal) { + return nullptr; + } + return createMapper(std::move(hal)); + } + + // load the gralloc module + static const hw_module_t* loadModule() { + const hw_module_t* module; + int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + if (error) { + ALOGE("failed to get gralloc module"); + return nullptr; + } + + return module; + } + + // return the major api version of the module + static int getModuleMajorApiVersion(const hw_module_t* module) { + return (module->module_api_version >> 8) & 0xff; + } + + // create a MapperHal instance + static std::unique_ptr createHal(const hw_module_t* module) { + int major = getModuleMajorApiVersion(module); + switch (major) { + case 1: { + auto hal = std::make_unique(); + return hal->initWithModule(module) ? std::move(hal) : nullptr; + } + case 0: { + auto hal = std::make_unique(); + return hal->initWithModule(module) ? std::move(hal) : nullptr; + } + default: + ALOGE("unknown gralloc module major version %d", major); + return nullptr; + } + } + + // create an IAllocator instance + static IMapper* createMapper(std::unique_ptr hal) { + auto mapper = std::make_unique>(); + return mapper->init(std::move(hal)) ? mapper.release() : nullptr; + } +}; + +} // namespace passthrough +} // namespace V2_0 +} // namespace mapper +} // namespace graphics +} // namespace hardware +} // namespace android From 5255c35a70ebbe615d2ce4dd42f9c90a5c1cc62f Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 15 Dec 2017 11:33:25 -0800 Subject: [PATCH 4/4] graphics: move libVtsHalGraphicsMapperTestUtils Move libVtsHalGraphicsMapperTestUtils from 2.0/vts/functional/ to 2.0/utils/vts/. Run clang-format. Test: VTS Change-Id: I1e87129cbdc12167160f7e2f1cd76478e88bbf41 --- graphics/mapper/2.0/utils/vts/Android.bp | 38 +++++ .../vts}/VtsHalGraphicsMapperTestUtils.cpp | 90 +++++------ .../vts}/VtsHalGraphicsMapperTestUtils.h | 18 +-- graphics/mapper/2.0/vts/functional/Android.bp | 21 --- .../VtsHalGraphicsMapperV2_0TargetTest.cpp | 140 ++++++++---------- 5 files changed, 141 insertions(+), 166 deletions(-) create mode 100644 graphics/mapper/2.0/utils/vts/Android.bp rename graphics/mapper/2.0/{vts/functional => utils/vts}/VtsHalGraphicsMapperTestUtils.cpp (69%) rename graphics/mapper/2.0/{vts/functional => utils/vts}/VtsHalGraphicsMapperTestUtils.h (83%) diff --git a/graphics/mapper/2.0/utils/vts/Android.bp b/graphics/mapper/2.0/utils/vts/Android.bp new file mode 100644 index 0000000000..8bca152afa --- /dev/null +++ b/graphics/mapper/2.0/utils/vts/Android.bp @@ -0,0 +1,38 @@ +// +// Copyright (C) 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. +// + +cc_library_static { + name: "libVtsHalGraphicsMapperTestUtils", + defaults: ["hidl_defaults"], + srcs: ["VtsHalGraphicsMapperTestUtils.cpp"], + cflags: [ + "-O0", + "-g", + ], + shared_libs: [ + "libutils", + ], + static_libs: [ + "VtsHalHidlTargetTestBase", + "android.hardware.graphics.allocator@2.0", + "android.hardware.graphics.mapper@2.0", + ], + export_static_lib_headers: [ + "android.hardware.graphics.allocator@2.0", + "android.hardware.graphics.mapper@2.0", + ], + export_include_dirs: ["."], +} diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp b/graphics/mapper/2.0/utils/vts/VtsHalGraphicsMapperTestUtils.cpp similarity index 69% rename from graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp rename to graphics/mapper/2.0/utils/vts/VtsHalGraphicsMapperTestUtils.cpp index 671c4b14ec..e3229caf2d 100644 --- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp +++ b/graphics/mapper/2.0/utils/vts/VtsHalGraphicsMapperTestUtils.cpp @@ -50,8 +50,7 @@ Gralloc::~Gralloc() { for (auto bufferHandle : mImportedBuffers) { auto buffer = const_cast(bufferHandle); - EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) - << "failed to free buffer " << buffer; + EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) << "failed to free buffer " << buffer; } mImportedBuffers.clear(); } @@ -62,15 +61,13 @@ sp Gralloc::getAllocator() const { std::string Gralloc::dumpDebugInfo() { std::string debugInfo; - mAllocator->dumpDebugInfo( - [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); }); + mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); }); return debugInfo; } const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) { - const native_handle_t* bufferHandle = - native_handle_clone(rawHandle.getNativeHandle()); + const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle()); EXPECT_NE(nullptr, bufferHandle); if (bufferHandle) { @@ -80,24 +77,22 @@ const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) { return bufferHandle; } -std::vector Gralloc::allocate( - const BufferDescriptor& descriptor, uint32_t count, bool import, - uint32_t* outStride) { +std::vector Gralloc::allocate(const BufferDescriptor& descriptor, + uint32_t count, bool import, + uint32_t* outStride) { std::vector bufferHandles; bufferHandles.reserve(count); mAllocator->allocate( - descriptor, count, [&](const auto& tmpError, const auto& tmpStride, - const auto& tmpBuffers) { + descriptor, count, + [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) { ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers"; ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array"; for (uint32_t i = 0; i < count; i++) { if (import) { - ASSERT_NO_FATAL_FAILURE( - bufferHandles.push_back(importBuffer(tmpBuffers[i]))); + ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(importBuffer(tmpBuffers[i]))); } else { - ASSERT_NO_FATAL_FAILURE( - bufferHandles.push_back(cloneBuffer(tmpBuffers[i]))); + ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(cloneBuffer(tmpBuffers[i]))); } } @@ -113,9 +108,8 @@ std::vector Gralloc::allocate( return bufferHandles; } -const native_handle_t* Gralloc::allocate( - const IMapper::BufferDescriptorInfo& descriptorInfo, bool import, - uint32_t* outStride) { +const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo, + bool import, uint32_t* outStride) { BufferDescriptor descriptor = createDescriptor(descriptorInfo); if (::testing::Test::HasFatalFailure()) { return nullptr; @@ -133,26 +127,23 @@ sp Gralloc::getMapper() const { return mMapper; } -BufferDescriptor Gralloc::createDescriptor( - const IMapper::BufferDescriptorInfo& descriptorInfo) { +BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) { BufferDescriptor descriptor; - mMapper->createDescriptor( - descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) { - ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor"; - descriptor = tmpDescriptor; - }); + mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) { + ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor"; + descriptor = tmpDescriptor; + }); return descriptor; } const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) { const native_handle_t* bufferHandle = nullptr; - mMapper->importBuffer( - rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) { - ASSERT_EQ(Error::NONE, tmpError) << "failed to import buffer %p" - << rawHandle.getNativeHandle(); - bufferHandle = static_cast(tmpBuffer); - }); + mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) { + ASSERT_EQ(Error::NONE, tmpError) + << "failed to import buffer %p" << rawHandle.getNativeHandle(); + bufferHandle = static_cast(tmpBuffer); + }); if (bufferHandle) { mImportedBuffers.insert(bufferHandle); @@ -189,8 +180,7 @@ void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, void* data = nullptr; mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle, [&](const auto& tmpError, const auto& tmpData) { - ASSERT_EQ(Error::NONE, tmpError) - << "failed to lock buffer " << buffer; + ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer; data = tmpData; }); @@ -201,10 +191,8 @@ void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, return data; } -YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, - uint64_t cpuUsage, - const IMapper::Rect& accessRegion, - int acquireFence) { +YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage, + const IMapper::Rect& accessRegion, int acquireFence) { auto buffer = const_cast(bufferHandle); NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); @@ -234,24 +222,20 @@ int Gralloc::unlock(const native_handle_t* bufferHandle) { auto buffer = const_cast(bufferHandle); int releaseFence = -1; - mMapper->unlock( - buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) { - ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " - << buffer; + mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) { + ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer; - auto fenceHandle = tmpReleaseFence.getNativeHandle(); - if (fenceHandle) { - ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " - << fenceHandle; - if (fenceHandle->numFds == 1) { - releaseFence = dup(fenceHandle->data[0]); - ASSERT_LT(0, releaseFence) << "failed to dup fence fd"; - } else { - ASSERT_EQ(0, fenceHandle->numFds) - << " invalid fence handle " << fenceHandle; - } + auto fenceHandle = tmpReleaseFence.getNativeHandle(); + if (fenceHandle) { + ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle; + if (fenceHandle->numFds == 1) { + releaseFence = dup(fenceHandle->data[0]); + ASSERT_LT(0, releaseFence) << "failed to dup fence fd"; + } else { + ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle; } - }); + } + }); return releaseFence; } diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h b/graphics/mapper/2.0/utils/vts/VtsHalGraphicsMapperTestUtils.h similarity index 83% rename from graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h rename to graphics/mapper/2.0/utils/vts/VtsHalGraphicsMapperTestUtils.h index 9cf60a375a..1f7d88aefc 100644 --- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h +++ b/graphics/mapper/2.0/utils/vts/VtsHalGraphicsMapperTestUtils.h @@ -49,19 +49,16 @@ class Gralloc { // is true, the returned buffers are also imported into the mapper. // // Either case, the returned buffers must be freed with freeBuffer. - std::vector allocate( - const BufferDescriptor& descriptor, uint32_t count, bool import = true, - uint32_t* outStride = nullptr); - const native_handle_t* allocate( - const IMapper::BufferDescriptorInfo& descriptorInfo, bool import = true, - uint32_t* outStride = nullptr); + std::vector allocate(const BufferDescriptor& descriptor, uint32_t count, + bool import = true, uint32_t* outStride = nullptr); + const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo, + bool import = true, uint32_t* outStride = nullptr); // IMapper methods sp getMapper() const; - BufferDescriptor createDescriptor( - const IMapper::BufferDescriptorInfo& descriptorInfo); + BufferDescriptor createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo); const native_handle_t* importBuffer(const hidl_handle& rawHandle); void freeBuffer(const native_handle_t* bufferHandle); @@ -71,9 +68,8 @@ class Gralloc { // with each of these functions. void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, const IMapper::Rect& accessRegion, int acquireFence); - YCbCrLayout lockYCbCr(const native_handle_t* bufferHandle, - uint64_t cpuUsage, const IMapper::Rect& accessRegion, - int acquireFence); + YCbCrLayout lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage, + const IMapper::Rect& accessRegion, int acquireFence); int unlock(const native_handle_t* bufferHandle); private: diff --git a/graphics/mapper/2.0/vts/functional/Android.bp b/graphics/mapper/2.0/vts/functional/Android.bp index ac6cb47a68..8093b08676 100644 --- a/graphics/mapper/2.0/vts/functional/Android.bp +++ b/graphics/mapper/2.0/vts/functional/Android.bp @@ -14,27 +14,6 @@ // limitations under the License. // -cc_library_static { - name: "libVtsHalGraphicsMapperTestUtils", - defaults: ["hidl_defaults"], - srcs: ["VtsHalGraphicsMapperTestUtils.cpp"], - shared_libs: [ - "android.hardware.graphics.allocator@2.0", - "android.hardware.graphics.mapper@2.0", - ], - static_libs: [ - "VtsHalHidlTargetTestBase", - ], - cflags: [ - "-Wall", - "-Wextra", - "-Werror", - "-O0", - "-g", - ], - export_include_dirs: ["."], -} - cc_test { name: "VtsHalGraphicsMapperV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp index 1f9489851f..21ea66d7cd 100644 --- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp +++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp @@ -33,22 +33,22 @@ using android::hardware::graphics::common::V1_0::BufferUsage; using android::hardware::graphics::common::V1_0::PixelFormat; class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase { - protected: - void SetUp() override { - ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique()); + protected: + void SetUp() override { + ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique()); - mDummyDescriptorInfo.width = 64; - mDummyDescriptorInfo.height = 64; - mDummyDescriptorInfo.layerCount = 1; - mDummyDescriptorInfo.format = PixelFormat::RGBA_8888; - mDummyDescriptorInfo.usage = static_cast( - BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN); - } + mDummyDescriptorInfo.width = 64; + mDummyDescriptorInfo.height = 64; + mDummyDescriptorInfo.layerCount = 1; + mDummyDescriptorInfo.format = PixelFormat::RGBA_8888; + mDummyDescriptorInfo.usage = + static_cast(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN); + } - void TearDown() override {} + void TearDown() override {} - std::unique_ptr mGralloc; - IMapper::BufferDescriptorInfo mDummyDescriptorInfo{}; + std::unique_ptr mGralloc; + IMapper::BufferDescriptorInfo mDummyDescriptorInfo{}; }; /** @@ -63,18 +63,16 @@ TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) { */ TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) { BufferDescriptor descriptor; - ASSERT_NO_FATAL_FAILURE( - descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo)); + ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo)); for (uint32_t count = 0; count < 5; count++) { std::vector bufferHandles; uint32_t stride; - ASSERT_NO_FATAL_FAILURE(bufferHandles = mGralloc->allocate( - descriptor, count, false, &stride)); + ASSERT_NO_FATAL_FAILURE(bufferHandles = + mGralloc->allocate(descriptor, count, false, &stride)); if (count >= 1) { - EXPECT_LE(mDummyDescriptorInfo.width, stride) - << "invalid buffer stride"; + EXPECT_LE(mDummyDescriptorInfo.width, stride) << "invalid buffer stride"; } for (auto bufferHandle : bufferHandles) { @@ -89,10 +87,10 @@ TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) { TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) { // this assumes any valid descriptor is non-empty BufferDescriptor descriptor; - mGralloc->getAllocator()->allocate( - descriptor, 1, [&](const auto& tmpError, const auto&, const auto&) { - EXPECT_EQ(Error::BAD_DESCRIPTOR, tmpError); - }); + mGralloc->getAllocator()->allocate(descriptor, 1, + [&](const auto& tmpError, const auto&, const auto&) { + EXPECT_EQ(Error::BAD_DESCRIPTOR, tmpError); + }); } /** @@ -122,11 +120,9 @@ TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) { TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) { auto info = mDummyDescriptorInfo; info.width = 0; - mGralloc->getMapper()->createDescriptor( - info, [&](const auto& tmpError, const auto&) { - EXPECT_EQ(Error::BAD_VALUE, tmpError) - << "createDescriptor did not fail with BAD_VALUE"; - }); + mGralloc->getMapper()->createDescriptor(info, [&](const auto& tmpError, const auto&) { + EXPECT_EQ(Error::BAD_VALUE, tmpError) << "createDescriptor did not fail with BAD_VALUE"; + }); } /** @@ -134,8 +130,7 @@ TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) { */ TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) { const native_handle_t* bufferHandle; - ASSERT_NO_FATAL_FAILURE(bufferHandle = - mGralloc->allocate(mDummyDescriptorInfo, true)); + ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true)); ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle)); } @@ -144,16 +139,13 @@ TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) { */ TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) { const native_handle_t* clonedBufferHandle; - ASSERT_NO_FATAL_FAILURE( - clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false)); + ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false)); // A cloned handle is a raw handle. Check that we can import it multiple // times. const native_handle_t* importedBufferHandles[2]; - ASSERT_NO_FATAL_FAILURE(importedBufferHandles[0] = - mGralloc->importBuffer(clonedBufferHandle)); - ASSERT_NO_FATAL_FAILURE(importedBufferHandles[1] = - mGralloc->importBuffer(clonedBufferHandle)); + ASSERT_NO_FATAL_FAILURE(importedBufferHandles[0] = mGralloc->importBuffer(clonedBufferHandle)); + ASSERT_NO_FATAL_FAILURE(importedBufferHandles[1] = mGralloc->importBuffer(clonedBufferHandle)); ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[0])); ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[1])); @@ -165,15 +157,13 @@ TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) { */ TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) { const native_handle_t* rawHandle; - ASSERT_NO_FATAL_FAILURE( - rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false)); + ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false)); native_handle_t* importedHandle = nullptr; - mGralloc->getMapper()->importBuffer( - rawHandle, [&](const auto& tmpError, const auto& buffer) { - ASSERT_EQ(Error::NONE, tmpError); - importedHandle = static_cast(buffer); - }); + mGralloc->getMapper()->importBuffer(rawHandle, [&](const auto& tmpError, const auto& buffer) { + ASSERT_EQ(Error::NONE, tmpError); + importedHandle = static_cast(buffer); + }); // free the imported handle with another mapper std::unique_ptr anotherGralloc; @@ -203,15 +193,13 @@ TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) { */ TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) { native_handle_t* invalidHandle = nullptr; - mGralloc->getMapper()->importBuffer( - invalidHandle, [&](const auto& tmpError, const auto&) { - EXPECT_EQ(Error::BAD_BUFFER, tmpError) - << "importBuffer with nullptr did not fail with BAD_BUFFER"; - }); + mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) { + EXPECT_EQ(Error::BAD_BUFFER, tmpError) + << "importBuffer with nullptr did not fail with BAD_BUFFER"; + }); invalidHandle = native_handle_create(0, 0); - mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, - const auto&) { + mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_BUFFER, tmpError) << "importBuffer with invalid handle did not fail with BAD_BUFFER"; }); @@ -224,8 +212,7 @@ TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) { TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) { native_handle_t* invalidHandle = nullptr; Error error = mGralloc->getMapper()->freeBuffer(invalidHandle); - EXPECT_EQ(Error::BAD_BUFFER, error) - << "freeBuffer with nullptr did not fail with BAD_BUFFER"; + EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with nullptr did not fail with BAD_BUFFER"; invalidHandle = native_handle_create(0, 0); error = mGralloc->getMapper()->freeBuffer(invalidHandle); @@ -234,8 +221,7 @@ TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) { native_handle_delete(invalidHandle); const native_handle_t* clonedBufferHandle; - ASSERT_NO_FATAL_FAILURE( - clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false)); + ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false)); error = mGralloc->getMapper()->freeBuffer(invalidHandle); EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with un-imported handle did not fail with BAD_BUFFER"; @@ -251,16 +237,15 @@ TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) { const native_handle_t* bufferHandle; uint32_t stride; - ASSERT_NO_FATAL_FAILURE(bufferHandle = - mGralloc->allocate(info, true, &stride)); + ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride)); // lock buffer for writing const IMapper::Rect region{0, 0, static_cast(info.width), static_cast(info.height)}; int fence = -1; uint8_t* data; - ASSERT_NO_FATAL_FAILURE(data = static_cast(mGralloc->lock( - bufferHandle, info.usage, region, fence))); + ASSERT_NO_FATAL_FAILURE( + data = static_cast(mGralloc->lock(bufferHandle, info.usage, region, fence))); // RGBA_8888 size_t strideInBytes = stride * 4; @@ -274,8 +259,8 @@ TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) { ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle)); // lock again for reading - ASSERT_NO_FATAL_FAILURE(data = static_cast(mGralloc->lock( - bufferHandle, info.usage, region, fence))); + ASSERT_NO_FATAL_FAILURE( + data = static_cast(mGralloc->lock(bufferHandle, info.usage, region, fence))); for (uint32_t y = 0; y < info.height; y++) { for (size_t i = 0; i < writeInBytes; i++) { EXPECT_EQ(static_cast(y), data[i]); @@ -299,16 +284,14 @@ TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) { const native_handle_t* bufferHandle; uint32_t stride; - ASSERT_NO_FATAL_FAILURE(bufferHandle = - mGralloc->allocate(info, true, &stride)); + ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride)); // lock buffer for writing const IMapper::Rect region{0, 0, static_cast(info.width), static_cast(info.height)}; int fence = -1; YCbCrLayout layout; - ASSERT_NO_FATAL_FAILURE( - layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence)); + ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence)); auto yData = static_cast(layout.y); auto cbData = static_cast(layout.cb); @@ -328,8 +311,7 @@ TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) { ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle)); // lock again for reading - ASSERT_NO_FATAL_FAILURE( - layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence)); + ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence)); yData = static_cast(layout.y); cbData = static_cast(layout.cb); @@ -357,25 +339,21 @@ TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) { */ TEST_F(GraphicsMapperHidlTest, UnlockNegative) { native_handle_t* invalidHandle = nullptr; - mGralloc->getMapper()->unlock( - invalidHandle, [&](const auto& tmpError, const auto&) { - EXPECT_EQ(Error::BAD_BUFFER, tmpError) - << "unlock with nullptr did not fail with BAD_BUFFER"; - }); + mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) { + EXPECT_EQ(Error::BAD_BUFFER, tmpError) + << "unlock with nullptr did not fail with BAD_BUFFER"; + }); invalidHandle = native_handle_create(0, 0); - mGralloc->getMapper()->unlock( - invalidHandle, [&](const auto& tmpError, const auto&) { - EXPECT_EQ(Error::BAD_BUFFER, tmpError) - << "unlock with invalid handle did not fail with BAD_BUFFER"; - }); + mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) { + EXPECT_EQ(Error::BAD_BUFFER, tmpError) + << "unlock with invalid handle did not fail with BAD_BUFFER"; + }); native_handle_delete(invalidHandle); - ASSERT_NO_FATAL_FAILURE(invalidHandle = - const_cast(mGralloc->allocate( - mDummyDescriptorInfo, false))); - mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, - const auto&) { + ASSERT_NO_FATAL_FAILURE(invalidHandle = const_cast( + mGralloc->allocate(mDummyDescriptorInfo, false))); + mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_BUFFER, tmpError) << "unlock with un-imported handle did not fail with BAD_BUFFER"; });