gralloc: Upstream AIDL allocator, stablec mapper, and sepolicy

... from various developments in AOSP.

Bug: b/225198076
Test: n/a
Change-Id: I65c340cfee4a3ad3c6545f365ca60249fd338a5f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/4897925
Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org>
Tested-by: Jason Macnak <natsu@google.com>
Commit-Queue: Jason Macnak <natsu@google.com>
This commit is contained in:
Jason Macnak 2023-09-27 12:54:16 -07:00 committed by Chromeos LUCI
parent bb30e85631
commit fe5c2c0171
14 changed files with 1256 additions and 0 deletions

View file

@ -0,0 +1,19 @@
# Copyright 2022 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This directory is formatted to match the format of the interfaces implemented.
BasedOnStyle: Google
Standard: Cpp11
AccessModifierOffset: -2
AllowShortFunctionsOnASingleLine: Inline
ColumnLimit: 100
CommentPragmas: NOLINT:.*
DerivePointerAlignment: false
IncludeBlocks: Preserve
IndentWidth: 4
ContinuationIndentWidth: 8
PointerAlignment: Left
TabWidth: 4
UseTab: Never

View file

@ -0,0 +1,242 @@
/*
* Copyright 2022 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Allocator.h"
#include <aidl/android/hardware/graphics/allocator/AllocationError.h>
#include <aidlcommonsupport/NativeHandle.h>
#include <android-base/logging.h>
#include <android/binder_ibinder_platform.h>
#include <gralloctypes/Gralloc4.h>
#include <log/log.h>
#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
using aidl::android::hardware::common::NativeHandle;
using BufferDescriptorInfoV4 =
android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
namespace aidl::android::hardware::graphics::allocator::impl {
namespace {
inline ndk::ScopedAStatus ToBinderStatus(AllocationError error) {
return ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(error));
}
} // namespace
bool Allocator::init() {
mDriver = cros_gralloc_driver::get_instance();
return mDriver != nullptr;
}
// TODO(natsu): deduplicate with CrosGralloc4Allocator after the T release.
ndk::ScopedAStatus Allocator::initializeMetadata(
cros_gralloc_handle_t crosHandle,
const struct cros_gralloc_buffer_descriptor& crosDescriptor) {
if (!mDriver) {
ALOGE("Failed to initializeMetadata. Driver is uninitialized.\n");
return ToBinderStatus(AllocationError::NO_RESOURCES);
}
if (!crosHandle) {
ALOGE("Failed to initializeMetadata. Invalid handle.\n");
return ToBinderStatus(AllocationError::NO_RESOURCES);
}
void* addr;
uint64_t size;
int ret = mDriver->get_reserved_region(crosHandle, &addr, &size);
if (ret) {
ALOGE("Failed to getReservedRegion.\n");
return ToBinderStatus(AllocationError::NO_RESOURCES);
}
CrosGralloc4Metadata* crosMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr);
snprintf(crosMetadata->name, CROS_GRALLOC4_METADATA_MAX_NAME_SIZE, "%s",
crosDescriptor.name.c_str());
crosMetadata->dataspace = common::Dataspace::UNKNOWN;
crosMetadata->blendMode = common::BlendMode::INVALID;
return ndk::ScopedAStatus::ok();
}
void Allocator::releaseBufferAndHandle(native_handle_t* handle) {
mDriver->release(handle);
native_handle_close(handle);
native_handle_delete(handle);
}
ndk::ScopedAStatus Allocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count,
allocator::AllocationResult* outResult) {
if (!mDriver) {
ALOGE("Failed to allocate. Driver is uninitialized.\n");
return ToBinderStatus(AllocationError::NO_RESOURCES);
}
BufferDescriptorInfoV4 description;
int ret = ::android::gralloc4::decodeBufferDescriptorInfo(descriptor, &description);
if (ret) {
ALOGE("Failed to allocate. Failed to decode buffer descriptor: %d.\n", ret);
return ToBinderStatus(AllocationError::BAD_DESCRIPTOR);
}
std::vector<native_handle_t*> handles;
handles.resize(count, nullptr);
for (int32_t i = 0; i < count; i++) {
ndk::ScopedAStatus status = allocate(description, &outResult->stride, &handles[i]);
if (!status.isOk()) {
for (int32_t j = 0; j < i; j++) {
releaseBufferAndHandle(handles[j]);
}
return status;
}
}
outResult->buffers.resize(count);
for (int32_t i = 0; i < count; i++) {
auto handle = handles[i];
outResult->buffers[i] = ::android::dupToAidl(handle);
releaseBufferAndHandle(handle);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Allocator::allocate(const BufferDescriptorInfoV4& descriptor, int32_t* outStride,
native_handle_t** outHandle) {
if (!mDriver) {
ALOGE("Failed to allocate. Driver is uninitialized.\n");
return ToBinderStatus(AllocationError::NO_RESOURCES);
}
struct cros_gralloc_buffer_descriptor crosDescriptor;
if (convertToCrosDescriptor(descriptor, &crosDescriptor)) {
return ToBinderStatus(AllocationError::UNSUPPORTED);
}
crosDescriptor.reserved_region_size += sizeof(CrosGralloc4Metadata);
if (!mDriver->is_supported(&crosDescriptor)) {
const std::string drmFormatString = get_drm_format_string(crosDescriptor.drm_format);
const std::string pixelFormatString = getPixelFormatString(descriptor.format);
const std::string usageString = getUsageString(descriptor.usage);
ALOGE("Failed to allocate. Unsupported combination: pixel format:%s, drm format:%s, "
"usage:%s\n",
pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str());
return ToBinderStatus(AllocationError::UNSUPPORTED);
}
native_handle_t* handle;
int ret = mDriver->allocate(&crosDescriptor, &handle);
if (ret) {
return ToBinderStatus(AllocationError::NO_RESOURCES);
}
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle);
auto status = initializeMetadata(crosHandle, crosDescriptor);
if (!status.isOk()) {
ALOGE("Failed to allocate. Failed to initialize gralloc buffer metadata.");
releaseBufferAndHandle(handle);
return status;
}
*outStride = static_cast<int32_t>(crosHandle->pixel_stride);
*outHandle = handle;
return ndk::ScopedAStatus::ok();
}
static BufferDescriptorInfoV4 convertAidlToIMapperV4Descriptor(const BufferDescriptorInfo& info) {
return BufferDescriptorInfoV4 {
.name{reinterpret_cast<const char*>(info.name.data())},
.width = static_cast<uint32_t>(info.width),
.height = static_cast<uint32_t>(info.height),
.layerCount = static_cast<uint32_t>(info.layerCount),
.format = static_cast<::android::hardware::graphics::common::V1_2::PixelFormat>(info.format),
.usage = static_cast<uint64_t>(info.usage),
.reservedSize = 0,
};
}
ndk::ScopedAStatus Allocator::allocate2(const BufferDescriptorInfo& descriptor, int32_t count,
allocator::AllocationResult* outResult) {
if (!mDriver) {
ALOGE("Failed to allocate. Driver is uninitialized.\n");
return ToBinderStatus(AllocationError::NO_RESOURCES);
}
if (!descriptor.additionalOptions.empty()) {
return ToBinderStatus(AllocationError::UNSUPPORTED);
}
BufferDescriptorInfoV4 descriptionV4 = convertAidlToIMapperV4Descriptor(descriptor);
std::vector<native_handle_t*> handles;
handles.resize(count, nullptr);
for (int32_t i = 0; i < count; i++) {
ndk::ScopedAStatus status = allocate(descriptionV4, &outResult->stride, &handles[i]);
if (!status.isOk()) {
for (int32_t j = 0; j < i; j++) {
releaseBufferAndHandle(handles[j]);
}
return status;
}
}
outResult->buffers.resize(count);
for (int32_t i = 0; i < count; i++) {
auto handle = handles[i];
outResult->buffers[i] = ::android::dupToAidl(handle);
releaseBufferAndHandle(handle);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Allocator::isSupported(const BufferDescriptorInfo& descriptor,
bool* outResult) {
if (!mDriver) {
ALOGE("Failed to allocate. Driver is uninitialized.\n");
return ToBinderStatus(AllocationError::NO_RESOURCES);
}
if (!descriptor.additionalOptions.empty()) {
*outResult = false;
return ndk::ScopedAStatus::ok();
}
struct cros_gralloc_buffer_descriptor crosDescriptor;
if (convertToCrosDescriptor(convertAidlToIMapperV4Descriptor(descriptor), &crosDescriptor)) {
// Failing to convert the descriptor means the layer count, pixel format, or usage is
// unsupported, thus isSupported() = false
*outResult = false;
return ndk::ScopedAStatus::ok();
}
crosDescriptor.reserved_region_size += sizeof(CrosGralloc4Metadata);
*outResult = mDriver->is_supported(&crosDescriptor);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Allocator::getIMapperLibrarySuffix(std::string* outResult) {
*outResult = "minigbm";
return ndk::ScopedAStatus::ok();
}
::ndk::SpAIBinder Allocator::createBinder() {
auto binder = BnAllocator::createBinder();
AIBinder_setInheritRt(binder.get(), true);
return binder;
}
} // namespace aidl::android::hardware::graphics::allocator::impl

View file

@ -0,0 +1,57 @@
/*
* Copyright 2022 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef MINIGBM_CROSGRALLOC_AIDL_ALLOCATOR_H_
#define MINIGBM_CROSGRALLOC_AIDL_ALLOCATOR_H_
#include <aidl/android/hardware/graphics/allocator/AllocationResult.h>
#include <aidl/android/hardware/graphics/allocator/BnAllocator.h>
#include <android/hardware/graphics/mapper/4.0/IMapper.h>
#include "cros_gralloc/cros_gralloc_driver.h"
#include "cros_gralloc/cros_gralloc_helpers.h"
#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h"
namespace aidl::android::hardware::graphics::allocator::impl {
class Allocator : public BnAllocator {
public:
Allocator() = default;
bool init();
ndk::ScopedAStatus allocate(const std::vector<uint8_t>& descriptor, int32_t count,
allocator::AllocationResult* outResult) override;
ndk::ScopedAStatus allocate2(const BufferDescriptorInfo& descriptor, int32_t count,
allocator::AllocationResult* outResult) override;
ndk::ScopedAStatus isSupported(const BufferDescriptorInfo& descriptor,
bool* outResult) override;
ndk::ScopedAStatus getIMapperLibrarySuffix(std::string* outResult) override;
protected:
ndk::SpAIBinder createBinder() override;
private:
ndk::ScopedAStatus allocate(
const ::android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo&
descriptor,
int32_t* outStride, native_handle_t** outHandle);
ndk::ScopedAStatus initializeMetadata(
cros_gralloc_handle_t crosHandle,
const struct cros_gralloc_buffer_descriptor& crosDescriptor);
void releaseBufferAndHandle(native_handle_t* handle);
cros_gralloc_driver* mDriver = nullptr;
};
} // namespace aidl::android::hardware::graphics::allocator::impl
#endif

View file

@ -0,0 +1,51 @@
//
// Copyright (C) 2022 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.
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "external_minigbm_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
// SPDX-license-identifier-BSD
default_applicable_licenses: ["external_minigbm_license"],
}
cc_binary {
name: "android.hardware.graphics.allocator-service.minigbm",
defaults: ["minigbm_cros_gralloc_defaults"],
relative_install_path: "hw",
init_rc: ["allocator.rc"],
vintf_fragments: ["allocator.xml"],
vendor: true,
shared_libs: [
"android.hardware.graphics.allocator-V2-ndk",
"android.hardware.graphics.mapper@4.0",
"libbase",
"libbinder_ndk",
"libgralloctypes",
"libhidlbase",
"liblog",
"libminigbm_gralloc",
"libminigbm_gralloc4_utils",
],
static_libs: [
"libaidlcommonsupport",
],
srcs: [
"Allocator.cpp",
"Main.cpp",
],
}

View file

@ -0,0 +1,44 @@
/*
* Copyright 2022 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Allocator.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <log/log.h>
using aidl::android::hardware::graphics::allocator::impl::Allocator;
int main(int /*argc*/, char** /*argv*/) {
ALOGI("Minigbm AIDL allocator starting up...");
// same as SF main thread
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
ALOGI("%s: failed to set priority: %s", __FUNCTION__, strerror(errno));
}
auto allocator = ndk::SharedRefBase::make<Allocator>();
CHECK(allocator != nullptr);
if (!allocator->init()) {
ALOGE("Failed to initialize Minigbm AIDL allocator.");
return EXIT_FAILURE;
}
const std::string instance = std::string() + Allocator::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(allocator->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_setThreadPoolMaxThreadCount(4);
ABinderProcess_startThreadPool();
ABinderProcess_joinThreadPool();
return EXIT_FAILURE;
}

View file

@ -0,0 +1,7 @@
service vendor.graphics.allocator /vendor/bin/hw/android.hardware.graphics.allocator-service.minigbm
class hal animation
user system
group graphics drmrpc
capabilities SYS_NICE
onrestart restart surfaceflinger
task_profiles ServiceCapacityLow

View file

@ -0,0 +1,10 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.graphics.allocator</name>
<version>2</version>
<interface>
<name>IAllocator</name>
<instance>default</instance>
</interface>
</hal>
</manifest>

View file

@ -0,0 +1,19 @@
# Copyright 2022 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This directory is formatted to match the format of the interfaces implemented.
BasedOnStyle: Google
Standard: Cpp11
AccessModifierOffset: -2
AllowShortFunctionsOnASingleLine: Inline
ColumnLimit: 100
CommentPragmas: NOLINT:.*
DerivePointerAlignment: false
IncludeBlocks: Preserve
IndentWidth: 4
ContinuationIndentWidth: 8
PointerAlignment: Left
TabWidth: 4
UseTab: Never

View file

@ -0,0 +1,44 @@
//
// Copyright (C) 2022 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.
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "external_minigbm_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
// SPDX-license-identifier-BSD
default_applicable_licenses: ["external_minigbm_license"],
}
cc_library_shared {
name: "mapper.minigbm",
defaults: ["minigbm_gralloc4_common_defaults"],
vintf_fragments: ["mapper.minigbm.xml"],
shared_libs: [
"android.hardware.graphics.allocator-V2-ndk",
"libminigbm_gralloc",
],
header_libs: [
"libbase_headers",
"libimapper_stablec",
"libimapper_providerutils",
],
srcs: [
":minigbm_gralloc4_mapper_files",
"Mapper.cpp",
],
cpp_std: "c++20",
}

View file

@ -0,0 +1,745 @@
/*
* Copyright 2022 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.h>
#include <aidl/android/hardware/graphics/common/BufferUsage.h>
#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
#include <android-base/unique_fd.h>
#include <android/hardware/graphics/mapper/IMapper.h>
#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
#include <android/hardware/graphics/mapper/utils/IMapperProvider.h>
#include <cutils/native_handle.h>
#include <gralloctypes/Gralloc4.h>
#include "cros_gralloc/cros_gralloc_driver.h"
#include "cros_gralloc/cros_gralloc_handle.h"
#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h"
#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
using namespace ::aidl::android::hardware::graphics::common;
using namespace ::android::hardware::graphics::mapper;
using ::aidl::android::hardware::graphics::allocator::BufferDescriptorInfo;
using ::android::base::unique_fd;
#define REQUIRE_DRIVER() \
if (!mDriver) { \
ALOGE("Failed to %s. Driver is uninitialized.", __func__); \
return AIMAPPER_ERROR_NO_RESOURCES; \
}
#define VALIDATE_BUFFER_HANDLE(bufferHandle) \
if (!(bufferHandle)) { \
ALOGE("Failed to %s. Null buffer_handle_t.", __func__); \
return AIMAPPER_ERROR_BAD_BUFFER; \
}
#define VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle) \
REQUIRE_DRIVER() \
VALIDATE_BUFFER_HANDLE(bufferHandle)
static_assert(CROS_GRALLOC4_METADATA_MAX_NAME_SIZE >=
decltype(std::declval<BufferDescriptorInfo>().name){}.size(),
"Metadata name storage too small to fit a BufferDescriptorInfo::name");
constexpr const char* STANDARD_METADATA_NAME =
"android.hardware.graphics.common.StandardMetadataType";
static bool isStandardMetadata(AIMapper_MetadataType metadataType) {
return strcmp(STANDARD_METADATA_NAME, metadataType.name) == 0;
}
class CrosGrallocMapperV5 final : public vendor::mapper::IMapperV5Impl {
private:
cros_gralloc_driver* mDriver = cros_gralloc_driver::get_instance();
public:
explicit CrosGrallocMapperV5() = default;
~CrosGrallocMapperV5() override = default;
AIMapper_Error importBuffer(const native_handle_t* _Nonnull handle,
buffer_handle_t _Nullable* _Nonnull outBufferHandle) override;
AIMapper_Error freeBuffer(buffer_handle_t _Nonnull buffer) override;
AIMapper_Error getTransportSize(buffer_handle_t _Nonnull buffer, uint32_t* _Nonnull outNumFds,
uint32_t* _Nonnull outNumInts) override;
AIMapper_Error lock(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage, ARect accessRegion,
int acquireFence, void* _Nullable* _Nonnull outData) override;
AIMapper_Error unlock(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence) override;
AIMapper_Error flushLockedBuffer(buffer_handle_t _Nonnull buffer) override;
AIMapper_Error rereadLockedBuffer(buffer_handle_t _Nonnull buffer) override;
int32_t getMetadata(buffer_handle_t _Nonnull buffer, AIMapper_MetadataType metadataType,
void* _Nonnull outData, size_t outDataSize) override;
int32_t getStandardMetadata(buffer_handle_t _Nonnull buffer, int64_t standardMetadataType,
void* _Nonnull outData, size_t outDataSize) override;
AIMapper_Error setMetadata(buffer_handle_t _Nonnull buffer, AIMapper_MetadataType metadataType,
const void* _Nonnull metadata, size_t metadataSize) override;
AIMapper_Error setStandardMetadata(buffer_handle_t _Nonnull buffer,
int64_t standardMetadataType, const void* _Nonnull metadata,
size_t metadataSize) override;
AIMapper_Error listSupportedMetadataTypes(
const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
size_t* _Nonnull outNumberOfDescriptions) override;
AIMapper_Error dumpBuffer(buffer_handle_t _Nonnull bufferHandle,
AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
void* _Null_unspecified context) override;
AIMapper_Error dumpAllBuffers(AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
void* _Null_unspecified context) override;
AIMapper_Error getReservedRegion(buffer_handle_t _Nonnull buffer,
void* _Nullable* _Nonnull outReservedRegion,
uint64_t* _Nonnull outReservedSize) override;
private:
enum class ReservedRegionArea {
/* CrosGralloc4Metadata */
MAPPER4_METADATA,
/* External user metadata */
USER_METADATA,
};
AIMapper_Error getReservedRegionArea(const cros_gralloc_buffer* crosBuffer,
ReservedRegionArea area, void** outAddr,
uint64_t* outSize);
AIMapper_Error getCrosMetadata(const cros_gralloc_buffer* crosBuffer,
const CrosGralloc4Metadata** outMetadata);
AIMapper_Error getMutableCrosMetadata(cros_gralloc_buffer* crosBuffer,
CrosGralloc4Metadata** outMetadata);
template <typename F, StandardMetadataType TYPE>
int32_t getStandardMetadata(const cros_gralloc_buffer* crosBuffer, F&& provide,
StandardMetadata<TYPE>);
template <StandardMetadataType TYPE>
AIMapper_Error setStandardMetadata(CrosGralloc4Metadata* crosMetadata,
typename StandardMetadata<TYPE>::value_type&& value);
void dumpBuffer(
const cros_gralloc_buffer* crosBuffer,
std::function<void(AIMapper_MetadataType, const std::vector<uint8_t>&)> callback);
};
AIMapper_Error CrosGrallocMapperV5::importBuffer(
const native_handle_t* _Nonnull bufferHandle,
buffer_handle_t _Nullable* _Nonnull outBufferHandle) {
REQUIRE_DRIVER()
if (!bufferHandle || bufferHandle->numFds == 0) {
ALOGE("Failed to importBuffer. Bad handle.");
return AIMAPPER_ERROR_BAD_BUFFER;
}
native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle);
if (!importedBufferHandle) {
ALOGE("Failed to importBuffer. Handle clone failed: %s.", strerror(errno));
return AIMAPPER_ERROR_NO_RESOURCES;
}
int ret = mDriver->retain(importedBufferHandle);
if (ret) {
native_handle_close(importedBufferHandle);
native_handle_delete(importedBufferHandle);
return AIMAPPER_ERROR_NO_RESOURCES;
}
*outBufferHandle = importedBufferHandle;
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::freeBuffer(buffer_handle_t _Nonnull buffer) {
VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
int ret = mDriver->release(buffer);
if (ret) {
return AIMAPPER_ERROR_BAD_BUFFER;
}
native_handle_close(buffer);
native_handle_delete(const_cast<native_handle_t*>(buffer));
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::getTransportSize(buffer_handle_t _Nonnull bufferHandle,
uint32_t* _Nonnull outNumFds,
uint32_t* _Nonnull outNumInts) {
VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
// No local process data is currently stored on the native handle.
*outNumFds = bufferHandle->numFds;
*outNumInts = bufferHandle->numInts;
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::lock(buffer_handle_t _Nonnull bufferHandle, uint64_t cpuUsage,
ARect region, int acquireFenceRawFd,
void* _Nullable* _Nonnull outData) {
// We take ownership of the FD in all cases, even for errors
unique_fd acquireFence(acquireFenceRawFd);
VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
if (cpuUsage == 0) {
ALOGE("Failed to lock. Bad cpu usage: %" PRIu64 ".", cpuUsage);
return AIMAPPER_ERROR_BAD_VALUE;
}
uint32_t mapUsage = cros_gralloc_convert_map_usage(cpuUsage);
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (crosHandle == nullptr) {
ALOGE("Failed to lock. Invalid handle.");
return AIMAPPER_ERROR_BAD_VALUE;
}
struct rectangle rect;
// An access region of all zeros means the entire buffer.
if (region.left == 0 && region.top == 0 && region.right == 0 && region.bottom == 0) {
rect = {0, 0, crosHandle->width, crosHandle->height};
} else {
if (region.left < 0 || region.top < 0 || region.right <= region.left ||
region.bottom <= region.top) {
ALOGE("Failed to lock. Invalid accessRegion: [%d, %d, %d, %d]", region.left, region.top,
region.right, region.bottom);
return AIMAPPER_ERROR_BAD_VALUE;
}
if (region.right > crosHandle->width) {
ALOGE("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).",
region.right, crosHandle->width);
return AIMAPPER_ERROR_BAD_VALUE;
}
if (region.bottom > crosHandle->height) {
ALOGE("Failed to lock. Invalid region: height greater than buffer height (%d vs "
"%d).",
region.bottom, crosHandle->height);
return AIMAPPER_ERROR_BAD_VALUE;
}
rect = {static_cast<uint32_t>(region.left), static_cast<uint32_t>(region.top),
static_cast<uint32_t>(region.right - region.left),
static_cast<uint32_t>(region.bottom - region.top)};
}
uint8_t* addr[DRV_MAX_PLANES];
int32_t status = mDriver->lock(bufferHandle, acquireFence.get(),
/*close_acquire_fence=*/false, &rect, mapUsage, addr);
if (status) {
return AIMAPPER_ERROR_BAD_VALUE;
}
*outData = addr[0];
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::unlock(buffer_handle_t _Nonnull buffer,
int* _Nonnull releaseFence) {
VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
int ret = mDriver->unlock(buffer, releaseFence);
if (ret) {
ALOGE("Failed to unlock.");
return AIMAPPER_ERROR_BAD_BUFFER;
}
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::flushLockedBuffer(buffer_handle_t _Nonnull buffer) {
VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
int ret = mDriver->flush(buffer);
if (ret) {
ALOGE("Failed to flushLockedBuffer. Flush failed.");
return AIMAPPER_ERROR_BAD_BUFFER;
}
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::rereadLockedBuffer(buffer_handle_t _Nonnull buffer) {
VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
int ret = mDriver->invalidate(buffer);
if (ret) {
ALOGE("Failed to rereadLockedBuffer. Failed to invalidate.");
return AIMAPPER_ERROR_BAD_BUFFER;
}
return AIMAPPER_ERROR_NONE;
}
int32_t CrosGrallocMapperV5::getMetadata(buffer_handle_t _Nonnull buffer,
AIMapper_MetadataType metadataType, void* _Nonnull outData,
size_t outDataSize) {
// We don't have any vendor-specific metadata, so divert to getStandardMetadata after validating
// that this is a standard metadata request
if (isStandardMetadata(metadataType)) {
return getStandardMetadata(buffer, metadataType.value, outData, outDataSize);
}
return -AIMAPPER_ERROR_UNSUPPORTED;
}
int32_t CrosGrallocMapperV5::getStandardMetadata(buffer_handle_t _Nonnull bufferHandle,
int64_t standardType, void* _Nonnull outData,
size_t outDataSize) {
// Can't use VALIDATE_DRIVER_AND_BUFFER_HANDLE because we need to negate the error
// for this call
if (!mDriver) {
ALOGE("Failed to %s. Driver is uninitialized.", __func__);
return -AIMAPPER_ERROR_NO_RESOURCES;
}
if (!(bufferHandle)) {
ALOGE("Failed to %s. Null buffer_handle_t.", __func__);
return -AIMAPPER_ERROR_BAD_BUFFER;
}
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (!crosHandle) {
ALOGE("Failed to get. Invalid handle.");
return -AIMAPPER_ERROR_BAD_BUFFER;
}
int32_t retValue = -AIMAPPER_ERROR_UNSUPPORTED;
mDriver->with_buffer(crosHandle, [&](cros_gralloc_buffer* crosBuffer) {
auto provider = [&]<StandardMetadataType T>(auto&& provide) -> int32_t {
return getStandardMetadata(crosBuffer, provide, StandardMetadata<T>{});
};
retValue = provideStandardMetadata(static_cast<StandardMetadataType>(standardType), outData,
outDataSize, provider);
});
return retValue;
}
template <typename F, StandardMetadataType metadataType>
int32_t CrosGrallocMapperV5::getStandardMetadata(const cros_gralloc_buffer* crosBuffer, F&& provide,
StandardMetadata<metadataType>) {
const CrosGralloc4Metadata* crosMetadata = nullptr;
if constexpr (metadataType == StandardMetadataType::BLEND_MODE ||
metadataType == StandardMetadataType::CTA861_3 ||
metadataType == StandardMetadataType::DATASPACE ||
metadataType == StandardMetadataType::NAME ||
metadataType == StandardMetadataType::SMPTE2086) {
AIMapper_Error error = getCrosMetadata(crosBuffer, &crosMetadata);
if (error != AIMAPPER_ERROR_NONE) {
ALOGE("Failed to get. Failed to get buffer metadata.");
return -AIMAPPER_ERROR_NO_RESOURCES;
}
}
if constexpr (metadataType == StandardMetadataType::BUFFER_ID) {
return provide(crosBuffer->get_id());
}
if constexpr (metadataType == StandardMetadataType::NAME) {
return provide(crosMetadata->name);
}
if constexpr (metadataType == StandardMetadataType::WIDTH) {
return provide(crosBuffer->get_width());
}
if constexpr (metadataType == StandardMetadataType::STRIDE) {
return provide(crosBuffer->get_pixel_stride());
}
if constexpr (metadataType == StandardMetadataType::HEIGHT) {
return provide(crosBuffer->get_height());
}
if constexpr (metadataType == StandardMetadataType::LAYER_COUNT) {
return provide(1);
}
if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_REQUESTED) {
return provide(static_cast<PixelFormat>(crosBuffer->get_android_format()));
}
if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_FOURCC) {
return provide(drv_get_standard_fourcc(crosBuffer->get_format()));
}
if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_MODIFIER) {
return provide(crosBuffer->get_format_modifier());
}
if constexpr (metadataType == StandardMetadataType::USAGE) {
return provide(static_cast<BufferUsage>(crosBuffer->get_android_usage()));
}
if constexpr (metadataType == StandardMetadataType::ALLOCATION_SIZE) {
return provide(crosBuffer->get_total_size());
}
if constexpr (metadataType == StandardMetadataType::PROTECTED_CONTENT) {
uint64_t hasProtectedContent =
crosBuffer->get_android_usage() & static_cast<int64_t>(BufferUsage::PROTECTED) ? 1
: 0;
return provide(hasProtectedContent);
}
if constexpr (metadataType == StandardMetadataType::COMPRESSION) {
return provide(android::gralloc4::Compression_None);
}
if constexpr (metadataType == StandardMetadataType::INTERLACED) {
return provide(android::gralloc4::Interlaced_None);
}
if constexpr (metadataType == StandardMetadataType::CHROMA_SITING) {
return provide(android::gralloc4::ChromaSiting_None);
}
if constexpr (metadataType == StandardMetadataType::PLANE_LAYOUTS) {
std::vector<PlaneLayout> planeLayouts;
getPlaneLayouts(crosBuffer->get_format(), &planeLayouts);
for (size_t plane = 0; plane < planeLayouts.size(); plane++) {
PlaneLayout& planeLayout = planeLayouts[plane];
planeLayout.offsetInBytes = crosBuffer->get_plane_offset(plane);
planeLayout.strideInBytes = crosBuffer->get_plane_stride(plane);
planeLayout.totalSizeInBytes = crosBuffer->get_plane_size(plane);
planeLayout.widthInSamples =
crosBuffer->get_width() / planeLayout.horizontalSubsampling;
planeLayout.heightInSamples =
crosBuffer->get_height() / planeLayout.verticalSubsampling;
}
return provide(planeLayouts);
}
if constexpr (metadataType == StandardMetadataType::CROP) {
const uint32_t numPlanes = crosBuffer->get_num_planes();
const uint32_t w = crosBuffer->get_width();
const uint32_t h = crosBuffer->get_height();
std::vector<aidl::android::hardware::graphics::common::Rect> crops;
for (uint32_t plane = 0; plane < numPlanes; plane++) {
aidl::android::hardware::graphics::common::Rect crop;
crop.left = 0;
crop.top = 0;
crop.right = w;
crop.bottom = h;
crops.push_back(crop);
}
return provide(crops);
}
if constexpr (metadataType == StandardMetadataType::DATASPACE) {
return provide(crosMetadata->dataspace);
}
if constexpr (metadataType == StandardMetadataType::BLEND_MODE) {
return provide(crosMetadata->blendMode);
}
if constexpr (metadataType == StandardMetadataType::SMPTE2086) {
return crosMetadata->smpte2086 ? provide(*crosMetadata->smpte2086) : 0;
}
if constexpr (metadataType == StandardMetadataType::CTA861_3) {
return crosMetadata->cta861_3 ? provide(*crosMetadata->cta861_3) : 0;
}
return -AIMAPPER_ERROR_UNSUPPORTED;
}
AIMapper_Error CrosGrallocMapperV5::setMetadata(buffer_handle_t _Nonnull buffer,
AIMapper_MetadataType metadataType,
const void* _Nonnull metadata,
size_t metadataSize) {
// We don't have any vendor-specific metadata, so divert to setStandardMetadata after validating
// that this is a standard metadata request
if (isStandardMetadata(metadataType)) {
return setStandardMetadata(buffer, metadataType.value, metadata, metadataSize);
}
return AIMAPPER_ERROR_UNSUPPORTED;
}
AIMapper_Error CrosGrallocMapperV5::setStandardMetadata(buffer_handle_t _Nonnull bufferHandle,
int64_t standardTypeRaw,
const void* _Nonnull metadata,
size_t metadataSize) {
VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (!crosHandle) {
ALOGE("Failed to get. Invalid handle.");
return AIMAPPER_ERROR_BAD_BUFFER;
}
auto standardType = static_cast<StandardMetadataType>(standardTypeRaw);
switch (standardType) {
// Read-only values
case StandardMetadataType::BUFFER_ID:
case StandardMetadataType::NAME:
case StandardMetadataType::WIDTH:
case StandardMetadataType::HEIGHT:
case StandardMetadataType::LAYER_COUNT:
case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
case StandardMetadataType::USAGE:
return AIMAPPER_ERROR_BAD_VALUE;
// Supported to set
case StandardMetadataType::BLEND_MODE:
case StandardMetadataType::CTA861_3:
case StandardMetadataType::DATASPACE:
case StandardMetadataType::SMPTE2086:
break;
// Everything else unsupported
default:
return AIMAPPER_ERROR_UNSUPPORTED;
}
AIMapper_Error status = AIMAPPER_ERROR_UNSUPPORTED;
mDriver->with_buffer(crosHandle, [&](cros_gralloc_buffer* crosBuffer) {
CrosGralloc4Metadata* crosMetadata = nullptr;
status = getMutableCrosMetadata(crosBuffer, &crosMetadata);
if (status != AIMAPPER_ERROR_NONE) {
return;
}
auto applier = [&]<StandardMetadataType T>(auto&& value) -> AIMapper_Error {
return setStandardMetadata<T>(crosMetadata, std::forward<decltype(value)>(value));
};
status = applyStandardMetadata(standardType, metadata, metadataSize, applier);
});
return status;
}
template <StandardMetadataType TYPE>
AIMapper_Error CrosGrallocMapperV5::setStandardMetadata(
CrosGralloc4Metadata* crosMetadata, typename StandardMetadata<TYPE>::value_type&& value) {
if constexpr (TYPE == StandardMetadataType::BLEND_MODE) {
crosMetadata->blendMode = value;
}
if constexpr (TYPE == StandardMetadataType::CTA861_3) {
crosMetadata->cta861_3 = value;
}
if constexpr (TYPE == StandardMetadataType::DATASPACE) {
crosMetadata->dataspace = value;
}
if constexpr (TYPE == StandardMetadataType::SMPTE2086) {
crosMetadata->smpte2086 = value;
}
// Unsupported metadatas were already filtered before we reached this point
return AIMAPPER_ERROR_NONE;
}
constexpr AIMapper_MetadataTypeDescription describeStandard(StandardMetadataType type,
bool isGettable, bool isSettable) {
return {{STANDARD_METADATA_NAME, static_cast<int64_t>(type)},
nullptr,
isGettable,
isSettable,
{0}};
}
AIMapper_Error CrosGrallocMapperV5::listSupportedMetadataTypes(
const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
size_t* _Nonnull outNumberOfDescriptions) {
static constexpr std::array<AIMapper_MetadataTypeDescription, 22> sSupportedMetadaTypes{
describeStandard(StandardMetadataType::BUFFER_ID, true, false),
describeStandard(StandardMetadataType::NAME, true, false),
describeStandard(StandardMetadataType::WIDTH, true, false),
describeStandard(StandardMetadataType::HEIGHT, true, false),
describeStandard(StandardMetadataType::LAYER_COUNT, true, false),
describeStandard(StandardMetadataType::PIXEL_FORMAT_REQUESTED, true, false),
describeStandard(StandardMetadataType::PIXEL_FORMAT_FOURCC, true, false),
describeStandard(StandardMetadataType::PIXEL_FORMAT_MODIFIER, true, false),
describeStandard(StandardMetadataType::USAGE, true, false),
describeStandard(StandardMetadataType::ALLOCATION_SIZE, true, false),
describeStandard(StandardMetadataType::PROTECTED_CONTENT, true, false),
describeStandard(StandardMetadataType::COMPRESSION, true, false),
describeStandard(StandardMetadataType::INTERLACED, true, false),
describeStandard(StandardMetadataType::CHROMA_SITING, true, false),
describeStandard(StandardMetadataType::PLANE_LAYOUTS, true, false),
describeStandard(StandardMetadataType::CROP, true, false),
describeStandard(StandardMetadataType::DATASPACE, true, true),
describeStandard(StandardMetadataType::COMPRESSION, true, false),
describeStandard(StandardMetadataType::BLEND_MODE, true, true),
describeStandard(StandardMetadataType::SMPTE2086, true, true),
describeStandard(StandardMetadataType::CTA861_3, true, true),
describeStandard(StandardMetadataType::STRIDE, true, false),
};
*outDescriptionList = sSupportedMetadaTypes.data();
*outNumberOfDescriptions = sSupportedMetadaTypes.size();
return AIMAPPER_ERROR_NONE;
}
void CrosGrallocMapperV5::dumpBuffer(
const cros_gralloc_buffer* crosBuffer,
std::function<void(AIMapper_MetadataType, const std::vector<uint8_t>&)> callback) {
// Temp buffer of ~10kb, should be large enough for any of the metadata we want to dump
std::vector<uint8_t> tempBuffer;
tempBuffer.resize(10000);
AIMapper_MetadataType metadataType;
metadataType.name = STANDARD_METADATA_NAME;
// Take an instance of the empty StandardMetadat<T> class just to allow auto-deduction
// to happen as explicit template invocation on lambdas is ugly
auto dump = [&]<StandardMetadataType T>(StandardMetadata<T>) {
// Nested templated lambdas! Woo! But the cleanness of the result is worth it
// The outer lambda exists basically just to capture the StandardMetadataType that's
// being dumped, as the `provider` parameter of getStandardMetadata only knows
// the value_type that the enum maps to but not the enum value itself, which we need to
// construct the `AIMapper_MetadataType` to pass to the dump callback
auto dumpInner = [&](const typename StandardMetadata<T>::value_type& value) -> int32_t {
int32_t size =
StandardMetadata<T>::value::encode(value, tempBuffer.data(), tempBuffer.size());
// The initial size should always be large enough, but just in case...
if (size > tempBuffer.size()) {
tempBuffer.resize(size * 2);
size = StandardMetadata<T>::value::encode(value, tempBuffer.data(),
tempBuffer.size());
}
// If the first resize failed _somehow_, just give up. Also don't notify if any
// errors occurred during encoding.
if (size >= 0 && size <= tempBuffer.size()) {
metadataType.value = static_cast<int64_t>(T);
callback(metadataType, tempBuffer);
}
// We don't actually care about the return value in this case, but why not use the
// real value anyway
return size;
};
getStandardMetadata(crosBuffer, dumpInner, StandardMetadata<T>{});
};
// So clean. So pretty.
dump(StandardMetadata<StandardMetadataType::BUFFER_ID>{});
dump(StandardMetadata<StandardMetadataType::NAME>{});
dump(StandardMetadata<StandardMetadataType::WIDTH>{});
dump(StandardMetadata<StandardMetadataType::HEIGHT>{});
dump(StandardMetadata<StandardMetadataType::LAYER_COUNT>{});
dump(StandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>{});
dump(StandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>{});
dump(StandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>{});
dump(StandardMetadata<StandardMetadataType::USAGE>{});
dump(StandardMetadata<StandardMetadataType::ALLOCATION_SIZE>{});
dump(StandardMetadata<StandardMetadataType::PROTECTED_CONTENT>{});
dump(StandardMetadata<StandardMetadataType::COMPRESSION>{});
dump(StandardMetadata<StandardMetadataType::INTERLACED>{});
dump(StandardMetadata<StandardMetadataType::CHROMA_SITING>{});
dump(StandardMetadata<StandardMetadataType::PLANE_LAYOUTS>{});
dump(StandardMetadata<StandardMetadataType::DATASPACE>{});
dump(StandardMetadata<StandardMetadataType::BLEND_MODE>{});
}
AIMapper_Error CrosGrallocMapperV5::dumpBuffer(
buffer_handle_t _Nonnull bufferHandle,
AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback, void* _Null_unspecified context) {
VALIDATE_DRIVER_AND_BUFFER_HANDLE(bufferHandle)
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle);
if (!crosHandle) {
ALOGE("Failed to get. Invalid handle.");
return AIMAPPER_ERROR_BAD_BUFFER;
}
auto callback = [&](AIMapper_MetadataType type, const std::vector<uint8_t>& buffer) {
dumpBufferCallback(context, type, buffer.data(), buffer.size());
};
mDriver->with_buffer(
crosHandle, [&](cros_gralloc_buffer* crosBuffer) { dumpBuffer(crosBuffer, callback); });
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::dumpAllBuffers(
AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback, void* _Null_unspecified context) {
REQUIRE_DRIVER()
auto callback = [&](AIMapper_MetadataType type, const std::vector<uint8_t>& buffer) {
dumpBufferCallback(context, type, buffer.data(), buffer.size());
};
mDriver->with_each_buffer([&](cros_gralloc_buffer* crosBuffer) {
beginDumpBufferCallback(context);
dumpBuffer(crosBuffer, callback);
});
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::getReservedRegion(buffer_handle_t _Nonnull buffer,
void* _Nullable* _Nonnull outReservedRegion,
uint64_t* _Nonnull outReservedSize) {
VALIDATE_DRIVER_AND_BUFFER_HANDLE(buffer)
cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(buffer);
if (!crosHandle) {
ALOGE("Failed to getReservedRegion. Invalid handle.");
return AIMAPPER_ERROR_BAD_BUFFER;
}
void* reservedRegionAddr = nullptr;
uint64_t reservedRegionSize = 0;
AIMapper_Error error = AIMAPPER_ERROR_NONE;
mDriver->with_buffer(crosHandle, [&, this](cros_gralloc_buffer* crosBuffer) {
error = getReservedRegionArea(crosBuffer, ReservedRegionArea::USER_METADATA,
&reservedRegionAddr, &reservedRegionSize);
});
if (error != AIMAPPER_ERROR_NONE) {
ALOGE("Failed to getReservedRegion. Failed to getReservedRegionArea.");
return AIMAPPER_ERROR_BAD_BUFFER;
}
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::getReservedRegionArea(const cros_gralloc_buffer* crosBuffer,
ReservedRegionArea area, void** outAddr,
uint64_t* outSize) {
int ret = crosBuffer->get_reserved_region(outAddr, outSize);
if (ret) {
ALOGE("Failed to getReservedRegionArea.");
*outAddr = nullptr;
*outSize = 0;
return AIMAPPER_ERROR_NO_RESOURCES;
}
switch (area) {
case ReservedRegionArea::MAPPER4_METADATA: {
// CrosGralloc4Metadata resides at the beginning reserved region.
*outSize = sizeof(CrosGralloc4Metadata);
break;
}
case ReservedRegionArea::USER_METADATA: {
// User metadata resides after the CrosGralloc4Metadata.
*outAddr = reinterpret_cast<void*>(reinterpret_cast<char*>(*outAddr) +
sizeof(CrosGralloc4Metadata));
*outSize = *outSize - sizeof(CrosGralloc4Metadata);
break;
}
}
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::getCrosMetadata(const cros_gralloc_buffer* crosBuffer,
const CrosGralloc4Metadata** outMetadata) {
void* addr = nullptr;
uint64_t size;
auto error =
getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
if (error != AIMAPPER_ERROR_NONE) {
return error;
}
*outMetadata = reinterpret_cast<const CrosGralloc4Metadata*>(addr);
return AIMAPPER_ERROR_NONE;
}
AIMapper_Error CrosGrallocMapperV5::getMutableCrosMetadata(cros_gralloc_buffer* crosBuffer,
CrosGralloc4Metadata** outMetadata) {
void* addr = nullptr;
uint64_t size;
auto error =
getReservedRegionArea(crosBuffer, ReservedRegionArea::MAPPER4_METADATA, &addr, &size);
if (error != AIMAPPER_ERROR_NONE) {
return error;
}
*outMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr);
return AIMAPPER_ERROR_NONE;
}
extern "C" uint32_t ANDROID_HAL_MAPPER_VERSION = AIMAPPER_VERSION_5;
extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
static vendor::mapper::IMapperProvider<CrosGrallocMapperV5> provider;
return provider.load(outImplementation);
}

View file

@ -0,0 +1,9 @@
<manifest version="1.0" type="device">
<hal format="native">
<name>mapper</name>
<version>5.0</version>
<interface>
<instance>minigbm</instance>
</interface>
</hal>
</manifest>

View file

@ -0,0 +1,3 @@
# Suppress warnings for minigbm trying to read vendor.minigbm.debug
# property for the devices which do not use this property.
dontaudit cameraserver vendor_default_prop:file read;

View file

@ -0,0 +1,3 @@
# Suppress warnings for minigbm trying to read vendor.minigbm.debug
# property for the devices which do not use this property.
dontaudit mediaswcodec vendor_default_prop:file read;

View file

@ -0,0 +1,3 @@
# Suppress warnings for minigbm trying to read vendor.minigbm.debug
# property for the devices which do not use this property.
dontaudit system_server vendor_default_prop:file read;