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:
parent
bb30e85631
commit
fe5c2c0171
14 changed files with 1256 additions and 0 deletions
19
cros_gralloc/aidl/.clang-format
Normal file
19
cros_gralloc/aidl/.clang-format
Normal 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
|
||||
242
cros_gralloc/aidl/Allocator.cpp
Normal file
242
cros_gralloc/aidl/Allocator.cpp
Normal 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
|
||||
57
cros_gralloc/aidl/Allocator.h
Normal file
57
cros_gralloc/aidl/Allocator.h
Normal 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
|
||||
51
cros_gralloc/aidl/Android.bp
Normal file
51
cros_gralloc/aidl/Android.bp
Normal 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",
|
||||
],
|
||||
}
|
||||
44
cros_gralloc/aidl/Main.cpp
Normal file
44
cros_gralloc/aidl/Main.cpp
Normal 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, ¶m) != 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;
|
||||
}
|
||||
7
cros_gralloc/aidl/allocator.rc
Normal file
7
cros_gralloc/aidl/allocator.rc
Normal 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
|
||||
10
cros_gralloc/aidl/allocator.xml
Normal file
10
cros_gralloc/aidl/allocator.xml
Normal 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>
|
||||
19
cros_gralloc/mapper_stablec/.clang-format
Normal file
19
cros_gralloc/mapper_stablec/.clang-format
Normal 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
|
||||
44
cros_gralloc/mapper_stablec/Android.bp
Normal file
44
cros_gralloc/mapper_stablec/Android.bp
Normal 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",
|
||||
}
|
||||
745
cros_gralloc/mapper_stablec/Mapper.cpp
Normal file
745
cros_gralloc/mapper_stablec/Mapper.cpp
Normal 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);
|
||||
}
|
||||
9
cros_gralloc/mapper_stablec/mapper.minigbm.xml
Normal file
9
cros_gralloc/mapper_stablec/mapper.minigbm.xml
Normal 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>
|
||||
3
cros_gralloc/sepolicy/cameraserver.te
Normal file
3
cros_gralloc/sepolicy/cameraserver.te
Normal 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;
|
||||
3
cros_gralloc/sepolicy/mediaswcodec.te
Normal file
3
cros_gralloc/sepolicy/mediaswcodec.te
Normal 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;
|
||||
3
cros_gralloc/sepolicy/system_server.te
Normal file
3
cros_gralloc/sepolicy/system_server.te
Normal 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;
|
||||
Loading…
Add table
Add a link
Reference in a new issue