diff options
author | Xin Li <delphij@google.com> | 2022-08-15 22:03:47 -0700 |
---|---|---|
committer | Xin Li <delphij@google.com> | 2022-08-15 22:03:47 -0700 |
commit | a4d9d03f47690498b6ca31c973788c32facde90b (patch) | |
tree | 254d1dcda02a29ac2103fd54ea71ab40902c7419 | |
parent | 69202d597a6a5ccfffff7224f6a4394773839272 (diff) | |
parent | 64cc7f0eea2aabc12f8fc5d2dfeda70384e3f16a (diff) | |
download | gchips-android13-platform-release.tar.gz |
DO NOT MERGE - Merge Android 13android-platform-13.0.0_r1main-16kandroid13-platform-release
Bug: 242648940
Merged-In: I546ac3bad491e4950d192f8b3f4a20bc3ff5534f
Change-Id: Ia40e0147df18a7ea1efba8630d48cfd917442652
140 files changed, 10733 insertions, 12728 deletions
@@ -1,5 +1,9 @@ soong_namespace { - imports: ["hardware/google/graphics/common"] + imports: [ + "hardware/google/graphics/common", + "hardware/google/gchips/gralloc4", + "hardware/google/gchips/GrallocHAL", + ] } package { @@ -14,7 +14,7 @@ # limitations under the License. # -ifneq ($(filter gs101,$(TARGET_BOARD_PLATFORM)),) +ifeq (google,$(TARGET_SOC_NAME)) common_hal_dirs := \ libexynosutils \ diff --git a/GrallocHAL/.clang-format b/GrallocHAL/.clang-format new file mode 100644 index 0000000..03af56d --- /dev/null +++ b/GrallocHAL/.clang-format @@ -0,0 +1,13 @@ +BasedOnStyle: Google + +AccessModifierOffset: -4 +AlignOperands: false +AllowShortFunctionsOnASingleLine: Inline +AlwaysBreakBeforeMultilineStrings: false +ColumnLimit: 100 +CommentPragmas: NOLINT:.* +ConstructorInitializerIndentWidth: 6 +ContinuationIndentWidth: 8 +IndentWidth: 4 +PenaltyBreakBeforeFirstCallParameter: 100000 +SpacesBeforeTrailingComments: 1 diff --git a/GrallocHAL/Android.bp b/GrallocHAL/Android.bp new file mode 100644 index 0000000..bbac925 --- /dev/null +++ b/GrallocHAL/Android.bp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + */ + +soong_namespace { + imports: [ + "hardware/google/graphics/common", + "hardware/google/gchips", + ] +} + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +soong_config_module_type { + name: "arm_gralloc_cc_defaults", + module_type: "cc_defaults", + config_namespace: "arm_gralloc", + variables: [ + "mali_display_version", + "gralloc_hwc_force_bgra_8888", + "gralloc_hwc_fb_disable_afbc", + "gralloc_camera_write_raw16", + ], + properties: [ + "cflags", + ], +} + +soong_config_string_variable { + name: "mali_display_version", + values: [ + "v0", + "v500", + "v550", + "v650", + "v71", + ], +} + +soong_config_bool_variable { + name: "gralloc_hwc_force_bgra_8888", +} +soong_config_bool_variable { + name: "gralloc_hwc_fb_disable_afbc", +} +soong_config_bool_variable { + name: "gralloc_camera_write_raw16", +} + +arm_gralloc_cc_defaults { + name: "arm_gralloc_defaults", + owner: "arm", + vendor: true, + proprietary: true, + cflags: [ + "-Wundef", + "-Werror", + "-DGRALLOC_LIBRARY_BUILD=1", + "-DDISABLE_FRAMEBUFFER_HAL=1", + "-DGRALLOC_USE_LEGACY_CALCS=0", + "-DGRALLOC_USE_LEGACY_LOCK=0", + ], + product_variables: { + platform_sdk_version: { + cflags: ["-DPLATFORM_SDK_VERSION=%d"], + }, + }, + header_libs: [ + "libgralloc_headers", + ], + target: { + android: { + cflags: [ + "-DGRALLOC_HOST_BUILD=0", + ], + }, + host: { + cflags: [ + "-DGRALLOC_HOST_BUILD=1", + ], + }, + }, + soong_config_variables: { + mali_display_version: { + v0: { + cflags: [ + "-DMALI_DISPLAY_VERSION=0", + ], + }, + v500: { + cflags: [ + "-DMALI_DISPLAY_VERSION=500", + ], + }, + v550: { + cflags: [ + "-DMALI_DISPLAY_VERSION=550", + ], + }, + v650: { + cflags: [ + "-DMALI_DISPLAY_VERSION=650", + ], + }, + v71: { + cflags: [ + "-DMALI_DISPLAY_VERSION=71", + ], + }, + }, + gralloc_hwc_force_bgra_8888: { + cflags: [ + "-DGRALLOC_HWC_FORCE_BGRA_8888=1", + ], + }, + gralloc_hwc_fb_disable_afbc: { + cflags: [ + "-DGRALLOC_HWC_FB_DISABLE_AFBC=1", + ], + }, + gralloc_camera_write_raw16: { + cflags: [ + "-DGRALLOC_CAMERA_WRITE_RAW16=1", + ], + }, + }, +} diff --git a/GrallocHAL/interfaces/libs/drmutils/Android.bp b/GrallocHAL/interfaces/libs/drmutils/Android.bp new file mode 100644 index 0000000..69daf7b --- /dev/null +++ b/GrallocHAL/interfaces/libs/drmutils/Android.bp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library_static { + name: "libgralloc_drmutils", + cflags: [ + "-Wall", + "-Werror", + ], + srcs: [ + "src/drmutils.cpp", + ], + vendor: true, + shared_libs: [ + "liblog", + "libdrm", + "libcutils", + "android.hardware.graphics.common-V3-ndk", + ], + header_libs: [ + "libgralloc_headers", + ], + include_dirs: [ + ".", + "hardware/google/gchips/include", + ], + export_include_dirs: [ + ".", + ], + export_shared_lib_headers: [ + "libdrm", + ], + export_header_lib_headers: [ + "libgralloc_headers", + ], +} diff --git a/GrallocHAL/interfaces/libs/drmutils/drmutils.h b/GrallocHAL/interfaces/libs/drmutils/drmutils.h new file mode 100644 index 0000000..f0bbdc3 --- /dev/null +++ b/GrallocHAL/interfaces/libs/drmutils/drmutils.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_LIBS_DRMUTILS_H +#define GRALLOC_LIBS_DRMUTILS_H + +#include "mali_fourcc.h" +#include "mali_gralloc_buffer.h" + +/** + * @brief Obtain the FOURCC corresponding to the given Gralloc internal format. + * + * @param hnd Private handle where the format information is stored. + * + * @return The DRM FOURCC format or DRM_FORMAT_INVALID in case of errors. + */ +uint32_t drm_fourcc_from_handle(const private_handle_t *hnd); + +/** + * @brief Extract the part of the DRM modifier stored inside the given internal format and private handle. + * + * @param hnd Private handle where part of the modifier information is stored. + * @param internal_format The internal format, where part of the modifier information is stored. + * + * @return The information extracted from the argument, in the form of a DRM modifier. + */ +uint64_t drm_modifier_from_handle(const private_handle_t *hnd); + +#endif diff --git a/GrallocHAL/interfaces/libs/drmutils/src/drmutils.cpp b/GrallocHAL/interfaces/libs/drmutils/src/drmutils.cpp new file mode 100644 index 0000000..6e9e7e9 --- /dev/null +++ b/GrallocHAL/interfaces/libs/drmutils/src/drmutils.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "drmutils.h" +#include "mali_gralloc_formats.h" +#include <exynos_format.h> + +uint32_t drm_fourcc_from_handle(const private_handle_t *hnd) +{ + /* Clean the modifier bits in the internal format. */ + struct table_entry + { + uint64_t internal; + uint32_t fourcc; + }; + + static table_entry table[] = { + { MALI_GRALLOC_FORMAT_INTERNAL_RAW16, DRM_FORMAT_R16 }, + { MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888, DRM_FORMAT_ABGR8888 }, + { MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888, DRM_FORMAT_ARGB8888 }, + { MALI_GRALLOC_FORMAT_INTERNAL_RGB_565, DRM_FORMAT_RGB565 }, + { MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888, DRM_FORMAT_XBGR8888 }, + { MALI_GRALLOC_FORMAT_INTERNAL_RGB_888, DRM_FORMAT_BGR888 }, + { MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102, DRM_FORMAT_ABGR2101010 }, + { MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616, DRM_FORMAT_ABGR16161616F }, + { MALI_GRALLOC_FORMAT_INTERNAL_YV12, DRM_FORMAT_YVU420 }, + { MALI_GRALLOC_FORMAT_INTERNAL_NV12, DRM_FORMAT_NV12 }, + { MALI_GRALLOC_FORMAT_INTERNAL_NV16, DRM_FORMAT_NV16 }, + { MALI_GRALLOC_FORMAT_INTERNAL_NV21, DRM_FORMAT_NV21 }, + { MALI_GRALLOC_FORMAT_INTERNAL_Y0L2, DRM_FORMAT_Y0L2 }, + { MALI_GRALLOC_FORMAT_INTERNAL_Y210, DRM_FORMAT_Y210 }, + { MALI_GRALLOC_FORMAT_INTERNAL_P010, DRM_FORMAT_P010 }, + { MALI_GRALLOC_FORMAT_INTERNAL_P210, DRM_FORMAT_P210 }, + { MALI_GRALLOC_FORMAT_INTERNAL_Y410, DRM_FORMAT_Y410 }, + { MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT, DRM_FORMAT_YUYV }, + { MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I, DRM_FORMAT_YUV420_8BIT }, + { MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I, DRM_FORMAT_YUV420_10BIT }, + + /* Deprecated legacy formats, mapped to MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT. */ + { HAL_PIXEL_FORMAT_YCbCr_422_I, DRM_FORMAT_YUYV }, + /* Deprecated legacy formats, mapped to MALI_GRALLOC_FORMAT_INTERNAL_NV21. */ + { HAL_PIXEL_FORMAT_YCrCb_420_SP, DRM_FORMAT_NV21 }, + /* Format introduced in Android P, mapped to MALI_GRALLOC_FORMAT_INTERNAL_P010. */ + { HAL_PIXEL_FORMAT_YCBCR_P010, DRM_FORMAT_P010 }, + + /* Exynos Formats */ + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, DRM_FORMAT_NV21 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, DRM_FORMAT_NV21 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YV12_M, DRM_FORMAT_YVU420 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, DRM_FORMAT_NV21 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80, DRM_FORMAT_P010 }, + + /* Google Formats */ + { HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, DRM_FORMAT_NV12 }, + { HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, DRM_FORMAT_P010 }, + { HAL_PIXEL_FORMAT_GOOGLE_R_8, DRM_FORMAT_R8 }, + { HAL_PIXEL_FORMAT_GOOGLE_RG_88, DRM_FORMAT_RG88 }, + }; + + const uint64_t unmasked_format = hnd->alloc_format; + const uint64_t internal_format = (unmasked_format & MALI_GRALLOC_INTFMT_FMT_MASK); + for (size_t i = 0; i < sizeof(table) / sizeof(table[0]); i++) + { + if (table[i].internal == internal_format) + { + bool afbc = (unmasked_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK); + /* The internal RGB565 format describes two different component orderings depending on AFBC. */ + if (afbc && internal_format == MALI_GRALLOC_FORMAT_INTERNAL_RGB_565) + { + return DRM_FORMAT_BGR565; + } + return table[i].fourcc; + } + } + + return DRM_FORMAT_INVALID; +} + +uint64_t drm_modifier_from_handle(const private_handle_t *hnd) +{ + const uint64_t internal_format = hnd->alloc_format; + if ((internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) == 0) + { + return 0; + } + + uint64_t modifier = 0; + + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK) + { + modifier |= AFBC_FORMAT_MOD_SPLIT; + } + + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) + { + modifier |= AFBC_FORMAT_MOD_TILED; + } + + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY) + { + modifier |= AFBC_FORMAT_MOD_DB; + } + + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_BCH) + { + modifier |= AFBC_FORMAT_MOD_BCH; + } + + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM) + { + modifier |= AFBC_FORMAT_MOD_YTR; + } + + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_SPARSE) + { + modifier |= AFBC_FORMAT_MOD_SPARSE; + } + + /* Extract the block-size modifiers. */ + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) + { + modifier |= (hnd->is_multi_plane() ? AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4 : AFBC_FORMAT_MOD_BLOCK_SIZE_32x8); + } + else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) + { + modifier |= AFBC_FORMAT_MOD_BLOCK_SIZE_64x4; + } + else + { + modifier |= AFBC_FORMAT_MOD_BLOCK_SIZE_16x16; + } + + return DRM_FORMAT_MOD_ARM_AFBC(modifier); +} diff --git a/gralloc4/service/4.x/Android.bp b/GrallocHAL/service/4.x/Android.bp index 5bd81bc..dbdfbec 100644 --- a/gralloc4/service/4.x/Android.bp +++ b/GrallocHAL/service/4.x/Android.bp @@ -35,6 +35,7 @@ cc_binary { shared_libs: [ "android.hardware.graphics.allocator@4.0", "android.hardware.graphics.allocator@4.0-impl", + "android.hardware.graphics.common-V3-ndk", "libhidlbase", "liblog", "libutils", diff --git a/gralloc4/service/4.x/android.hardware.graphics.allocator@4.0-service.rc b/GrallocHAL/service/4.x/android.hardware.graphics.allocator@4.0-service.rc index 6523f4e..6523f4e 100644 --- a/gralloc4/service/4.x/android.hardware.graphics.allocator@4.0-service.rc +++ b/GrallocHAL/service/4.x/android.hardware.graphics.allocator@4.0-service.rc diff --git a/gralloc4/service/4.x/service.cpp b/GrallocHAL/service/4.x/service.cpp index d540086..d540086 100644 --- a/gralloc4/service/4.x/service.cpp +++ b/GrallocHAL/service/4.x/service.cpp diff --git a/GrallocHAL/service/aidl/Android.bp b/GrallocHAL/service/aidl/Android.bp new file mode 100644 index 0000000..a3d7a87 --- /dev/null +++ b/GrallocHAL/service/aidl/Android.bp @@ -0,0 +1,32 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_binary { + name: "android.hardware.graphics.allocator-V1-service", + proprietary: true, + relative_install_path: "hw", + srcs: [ + "service.cpp", + ], + init_rc: [ + "android.hardware.graphics.allocator-aidl-service.rc", + ], + vintf_fragments: ["manifest_gralloc_aidl.xml"], + header_libs: [ + "libgralloc_headers", + ], + shared_libs: [ + "android.hardware.graphics.allocator-V1-ndk", + "android.hardware.graphics.allocator-aidl-impl", + "libbinder_ndk", + "liblog", + "libutils", + ], + static_libs: [ + "libaidlcommonsupport", + ], + required: [ + "android.hardware.graphics.allocator-aidl-impl", + ], +} diff --git a/GrallocHAL/service/aidl/android.hardware.graphics.allocator-aidl-service.rc b/GrallocHAL/service/aidl/android.hardware.graphics.allocator-aidl-service.rc new file mode 100644 index 0000000..b069c5d --- /dev/null +++ b/GrallocHAL/service/aidl/android.hardware.graphics.allocator-aidl-service.rc @@ -0,0 +1,5 @@ +service vendor.graphics.allocator-default /vendor/bin/hw/android.hardware.graphics.allocator-V1-service + class hal animation + user system + group graphics drmrpc + capabilities SYS_NICE diff --git a/GrallocHAL/service/aidl/manifest_gralloc_aidl.xml b/GrallocHAL/service/aidl/manifest_gralloc_aidl.xml new file mode 100644 index 0000000..6848a99 --- /dev/null +++ b/GrallocHAL/service/aidl/manifest_gralloc_aidl.xml @@ -0,0 +1,7 @@ +<manifest version="1.0" type="device"> + <hal format="aidl"> + <name>android.hardware.graphics.allocator</name> + <fqname>IAllocator/default</fqname> + </hal> +</manifest> + diff --git a/GrallocHAL/service/aidl/service.cpp b/GrallocHAL/service/aidl/service.cpp new file mode 100644 index 0000000..26cf77e --- /dev/null +++ b/GrallocHAL/service/aidl/service.cpp @@ -0,0 +1,33 @@ +#define LOG_TAG "gralloc-V1-service" + +#include <android/binder_ibinder_platform.h> +#include <android/binder_manager.h> +#include <android/binder_process.h> +#include <android/binder_status.h> +#include <log/log.h> + +#include "aidl/GrallocAllocator.h" + +using namespace android; + +using pixel::allocator::GrallocAllocator; + +int main() { + auto service = ndk::SharedRefBase::make<GrallocAllocator>(); + auto binder = service->asBinder(); + + AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, -20); + + const auto instance = std::string() + GrallocAllocator::descriptor + "/default"; + auto status = AServiceManager_addService(binder.get(), instance.c_str()); + if (status != STATUS_OK) { + ALOGE("Failed to start AIDL gralloc allocator service"); + return -EINVAL; + } + + ABinderProcess_setThreadPoolMaxThreadCount(4); + ABinderProcess_startThreadPool(); + ABinderProcess_joinThreadPool(); + + return EXIT_FAILURE; // Unreachable +} diff --git a/GrallocHAL/src/4.x/Android.bp b/GrallocHAL/src/4.x/Android.bp new file mode 100644 index 0000000..905bfaa --- /dev/null +++ b/GrallocHAL/src/4.x/Android.bp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_defaults { + name: "arm_gralloc_version_defaults", + target: { + android: { + shared_libs: [ + "android.hardware.graphics.common@1.2", + ], + }, + }, + cflags: [ + "-DLOG_TAG=\"gralloc4\"", + "-DGRALLOC_VERSION_MAJOR=4", + "-DHIDL_ALLOCATOR_VERSION_SCALED=400", + "-DHIDL_MAPPER_VERSION_SCALED=400", + "-DHIDL_COMMON_VERSION_SCALED=120", + ], +} + +cc_defaults { + name: "arm_gralloc_api_4x_defaults", + defaults: [ + "arm_gralloc_defaults", + "arm_gralloc_version_defaults", + ], + compile_multilib: "both", + relative_install_path: "hw/", + shared_libs: [ + "libhardware", + "liblog", + "libcutils", + "libdmabufheap", + "libion_google", + "libsync", + "libutils", + "libnativewindow", + "libhidlbase", + "libgralloctypes", + ], + static_libs: [ + "libarect", + "libgralloc_core", + "libgralloc_allocator", + "libgralloc_capabilities", + "libdrm", + ], + header_libs: [ + "libnativebase_headers", + ], + export_shared_lib_headers: [ + "libhidlbase", + ], +} + +cc_library_shared { + name: "android.hardware.graphics.allocator@4.0-impl", + defaults: [ + "arm_gralloc_api_4x_defaults", + ], + shared_libs: [ + "android.hardware.graphics.allocator@4.0", + "android.hardware.graphics.mapper@4.0", + ], + srcs: [ + "GrallocAllocator.cpp", + ":libgralloc_hidl_common_allocator", + ":libgralloc_hidl_common_shared_metadata", + ], + include_dirs: [ + "hardware/google/gchips/include", + ], +} + +cc_library_shared { + name: "android.hardware.graphics.mapper@4.0-impl", + defaults: [ + "arm_gralloc_api_4x_defaults", + ], + static_libs: [ + "libgralloc_drmutils", + ], + shared_libs: [ + "android.hardware.graphics.mapper@4.0", + ], + srcs: [ + "GrallocMapper.cpp", + ":libgralloc_hidl_common_mapper", + ":libgralloc_hidl_common_mapper_metadata", + ":libgralloc_hidl_common_shared_metadata", + ], + include_dirs: [ + "hardware/google/gchips/include", + ], +} diff --git a/GrallocHAL/src/4.x/GrallocAllocator.cpp b/GrallocHAL/src/4.x/GrallocAllocator.cpp new file mode 100644 index 0000000..1a1e563 --- /dev/null +++ b/GrallocHAL/src/4.x/GrallocAllocator.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <hwbinder/IPCThreadState.h> + +#include "GrallocAllocator.h" +#include "hidl_common/BufferDescriptor.h" +#include "hidl_common/Allocator.h" +#include "allocator/mali_gralloc_ion.h" + +namespace arm +{ +namespace allocator +{ +using android::hardware::graphics::allocator::V4_0::IAllocator; +using android::hardware::graphics::mapper::V4_0::Error; +using android::hardware::Return; +using android::hardware::hidl_handle; +using android::hardware::hidl_vec; +using android::hardware::Void; +using android::hardware::hidl_string; + +unsigned long callingPid() { + android::hardware::IPCThreadState* ipc = android::hardware::IPCThreadState::self(); + return static_cast<unsigned long>(ipc->getCallingPid()); +} + +GrallocAllocator::GrallocAllocator() +{ + MALI_GRALLOC_LOGV("Arm Module IAllocator %d.%d, pid = %d ppid = %d", GRALLOC_VERSION_MAJOR, + (HIDL_ALLOCATOR_VERSION_SCALED - (GRALLOC_VERSION_MAJOR * 100)) / 10, getpid(), getppid()); +} + +GrallocAllocator::~GrallocAllocator() +{ + mali_gralloc_ion_close(); +} + +Return<void> GrallocAllocator::allocate(const BufferDescriptor &descriptor, uint32_t count, allocate_cb hidl_cb) +{ + MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid()); + + buffer_descriptor_t bufferDescriptor; + if (!mapper::common::grallocDecodeBufferDescriptor(descriptor, bufferDescriptor)) + { + hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>()); + return Void(); + } + common::allocate(bufferDescriptor, count, hidl_cb); + return Void(); +} + +} // namespace allocator +} // namespace arm diff --git a/GrallocHAL/src/4.x/GrallocAllocator.h b/GrallocHAL/src/4.x/GrallocAllocator.h new file mode 100644 index 0000000..64de2ac --- /dev/null +++ b/GrallocHAL/src/4.x/GrallocAllocator.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V4_x_GRALLOC_H +#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V4_x_GRALLOC_H + +#include "gralloc_allocator_hidl_header.h" +#include "core/mali_gralloc_bufferdescriptor.h" + +namespace arm +{ +namespace allocator +{ +using android::hardware::graphics::mapper::V4_0::BufferDescriptor; +using android::hardware::Return; +using android::hardware::hidl_handle; + +class GrallocAllocator : public IAllocator +{ +public: + /** + * IAllocator constructor. All the state information required for the Gralloc + * private module is populated in its default constructor. Gralloc 4.0 specific + * state information can be populated here. + */ + GrallocAllocator(); + + /** + * IAllocator destructor. All the resources acquired for Gralloc private module + * are released + */ + virtual ~GrallocAllocator(); + + /* Override IAllocator 4.0 interface */ + Return<void> allocate(const BufferDescriptor &descriptor, uint32_t count, allocate_cb hidl_cb) override; +}; + +} // namespace allocator +} // namespace arm + +#endif // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V4_x_GRALLOC_H diff --git a/GrallocHAL/src/4.x/GrallocMapper.cpp b/GrallocHAL/src/4.x/GrallocMapper.cpp new file mode 100644 index 0000000..e0ac1de --- /dev/null +++ b/GrallocHAL/src/4.x/GrallocMapper.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2020 Arm Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "GrallocMapper.h" +#include "hidl_common/BufferDescriptor.h" +#include "hidl_common/MapperMetadata.h" + +#include "allocator/mali_gralloc_ion.h" + +namespace arm +{ +namespace mapper +{ + +using android::hardware::graphics::mapper::V4_0::Error; +using android::hardware::graphics::mapper::V4_0::BufferDescriptor; +using android::hardware::graphics::mapper::V4_0::IMapper; +using android::hardware::Return; +using android::hardware::hidl_handle; +using android::hardware::hidl_vec; +using android::hardware::Void; + + +GrallocMapper::GrallocMapper() +{ +} + +GrallocMapper::~GrallocMapper() +{ + mali_gralloc_ion_close(); +} + +Return<void> GrallocMapper::createDescriptor(const BufferDescriptorInfo &descriptorInfo, createDescriptor_cb hidl_cb) +{ + if (common::validateDescriptorInfo(descriptorInfo)) + { + hidl_cb(Error::NONE, common::grallocEncodeBufferDescriptor<uint8_t>(descriptorInfo)); + } + else + { + MALI_GRALLOC_LOGE("Invalid attributes to create descriptor for Mapper 3.0"); + hidl_cb(Error::BAD_VALUE, BufferDescriptor()); + } + + return Void(); +} + +Return<void> GrallocMapper::importBuffer(const hidl_handle &rawHandle, importBuffer_cb hidl_cb) +{ + common::importBuffer(rawHandle, hidl_cb); + return Void(); +} + +Return<Error> GrallocMapper::freeBuffer(void *buffer) +{ + return common::freeBuffer(buffer); +} + +Return<Error> GrallocMapper::validateBufferSize(void *buffer, const BufferDescriptorInfo &descriptorInfo, + uint32_t in_stride) +{ + /* All Gralloc allocated buffers must be conform to local descriptor validation */ + if (!common::validateDescriptorInfo<BufferDescriptorInfo>(descriptorInfo)) + { + MALI_GRALLOC_LOGE("Invalid descriptor attributes for validating buffer size"); + return Error::BAD_VALUE; + } + return common::validateBufferSize(buffer, descriptorInfo, in_stride); +} + +Return<void> GrallocMapper::lock(void *buffer, uint64_t cpuUsage, const IMapper::Rect &accessRegion, + const hidl_handle &acquireFence, lock_cb hidl_cb) +{ + common::lock(buffer, cpuUsage, accessRegion, acquireFence, hidl_cb); + return Void(); +} + +Return<void> GrallocMapper::unlock(void *buffer, unlock_cb hidl_cb) +{ + common::unlock(buffer, hidl_cb); + return Void(); +} + +Return<void> GrallocMapper::flushLockedBuffer(void *buffer, flushLockedBuffer_cb hidl_cb) +{ + common::flushLockedBuffer(buffer, hidl_cb); + return Void(); +} + +Return<Error> GrallocMapper::rereadLockedBuffer(void *buffer) +{ + return common::rereadLockedBuffer(buffer); +} + +Return<void> GrallocMapper::get(void *buffer, const MetadataType &metadataType, IMapper::get_cb hidl_cb) +{ + common::get(buffer, metadataType, hidl_cb); + return Void(); +} + +Return<Error> GrallocMapper::set(void *buffer, const MetadataType &metadataType, const hidl_vec<uint8_t> &metadata) +{ + return common::set(buffer, metadataType, metadata); +} + +Return<void> GrallocMapper::getFromBufferDescriptorInfo(const BufferDescriptorInfo &description, + const MetadataType &metadataType, + getFromBufferDescriptorInfo_cb hidl_cb) +{ + common::getFromBufferDescriptorInfo(description, metadataType, hidl_cb); + return Void(); +} + +Return<void> GrallocMapper::getTransportSize(void *buffer, getTransportSize_cb hidl_cb) +{ + common::getTransportSize(buffer, hidl_cb); + return Void(); +} + +Return<void> GrallocMapper::isSupported(const IMapper::BufferDescriptorInfo &description, isSupported_cb hidl_cb) +{ + if (!common::validateDescriptorInfo<BufferDescriptorInfo>(description)) + { + MALI_GRALLOC_LOGE("Invalid descriptor attributes for validating buffer size"); + hidl_cb(Error::BAD_VALUE, false); + } + common::isSupported(description, hidl_cb); + return Void(); +} + +Return<void> GrallocMapper::listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidl_cb) +{ + common::listSupportedMetadataTypes(hidl_cb); + return Void(); +} + +Return<void> GrallocMapper::dumpBuffer(void *buffer, dumpBuffer_cb hidl_cb) +{ + common::dumpBuffer(buffer, hidl_cb); + return Void(); +} + +Return<void> GrallocMapper::dumpBuffers(dumpBuffers_cb hidl_cb) +{ + common::dumpBuffers(hidl_cb); + return Void(); +} + +Return<void> GrallocMapper::getReservedRegion(void *buffer, getReservedRegion_cb hidl_cb) +{ + common::getReservedRegion(buffer, hidl_cb); + return Void(); +} + +} // namespace mapper +} // namespace arm + +extern "C" IMapper *HIDL_FETCH_IMapper(const char * /* name */) +{ + MALI_GRALLOC_LOGV("Arm Module IMapper %d.%d , pid = %d", GRALLOC_VERSION_MAJOR, + (HIDL_MAPPER_VERSION_SCALED - (GRALLOC_VERSION_MAJOR * 100)) / 10, getpid()); + + return new arm::mapper::GrallocMapper(); +} diff --git a/GrallocHAL/src/4.x/GrallocMapper.h b/GrallocHAL/src/4.x/GrallocMapper.h new file mode 100644 index 0000000..959efa5 --- /dev/null +++ b/GrallocHAL/src/4.x/GrallocMapper.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 Arm Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V4_x_GRALLOC_MAPPER_H +#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V4_x_GRALLOC_MAPPER_H + +#include "hidl_common/Mapper.h" + +namespace arm +{ +namespace mapper +{ + +using android::hardware::Return; +using android::hardware::hidl_handle; +using android::hardware::hidl_vec; + +class GrallocMapper : public IMapper +{ +public: + /** + * IMapper constructor. All the state information required for the Gralloc + * private module is populated in its default constructor. Gralloc 4.x specific + * state information can be populated here. + */ + GrallocMapper(); + + /** + * IMapper destructor. All the resources aquired for Gralloc private module + * (in the IMapper context) are released + */ + ~GrallocMapper(); + + /* Override the public IMapper 4.0 interface */ + Return<void> createDescriptor(const BufferDescriptorInfo &descriptorInfo, createDescriptor_cb hidl_cb) override; + + Return<void> importBuffer(const hidl_handle &rawHandle, importBuffer_cb hidl_cb) override; + + Return<Error> freeBuffer(void *buffer) override; + + Return<Error> validateBufferSize(void *buffer, const IMapper::BufferDescriptorInfo &descriptorInfo, + uint32_t stride) override; + + Return<void> getTransportSize(void *buffer, getTransportSize_cb _hidl_cb) override; + + Return<void> lock(void *buffer, uint64_t cpuUsage, const IMapper::Rect &accessRegion, + const hidl_handle &acquireFence, lock_cb hidl_cb) override; + + Return<void> unlock(void *buffer, unlock_cb hidl_cb) override; + + Return<void> flushLockedBuffer(void *buffer, flushLockedBuffer_cb hidl_cb) override; + + Return<Error> rereadLockedBuffer(void *buffer) override; + + Return<void> isSupported(const IMapper::BufferDescriptorInfo &description, isSupported_cb hidl_cb) override; + + Return<void> get(void *buffer, const MetadataType &metadataType, IMapper::get_cb hidl_cb) override; + + Return<Error> set(void *buffer, const MetadataType &metadataType, const hidl_vec<uint8_t> &metadata) override; + + Return<void> getFromBufferDescriptorInfo(BufferDescriptorInfo const &description, MetadataType const &metadataType, + getFromBufferDescriptorInfo_cb hidl_cb) override; + + Return<void> listSupportedMetadataTypes(listSupportedMetadataTypes_cb _hidl_cb) override; + + Return<void> dumpBuffer(void *buffer, dumpBuffer_cb _hidl_cb) override; + + Return<void> dumpBuffers(dumpBuffers_cb _hidl_cb) override; + + Return<void> getReservedRegion(void *buffer, getReservedRegion_cb _hidl_cb) override; +}; + +} // namespace mapper +} // namespace arm + +#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V4_x_GRALLOC_MAPPER_H diff --git a/GrallocHAL/src/4.x/gralloc_allocator_hidl_header.h b/GrallocHAL/src/4.x/gralloc_allocator_hidl_header.h new file mode 100644 index 0000000..586b07a --- /dev/null +++ b/GrallocHAL/src/4.x/gralloc_allocator_hidl_header.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2020 Arm Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_ALLOCATOR_HIDL_HEADER_H +#define GRALLOC_ALLOCATOR_HIDL_HEADER_H + +#include <android/hardware/graphics/allocator/4.0/IAllocator.h> +using android::hardware::graphics::allocator::V4_0::IAllocator; +using android::hardware::graphics::mapper::V4_0::Error; + +#endif diff --git a/GrallocHAL/src/4.x/gralloc_mapper_hidl_header.h b/GrallocHAL/src/4.x/gralloc_mapper_hidl_header.h new file mode 100644 index 0000000..6d3d549 --- /dev/null +++ b/GrallocHAL/src/4.x/gralloc_mapper_hidl_header.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 Arm Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_MAPPER_HIDL_HEADER_H +#define GRALLOC_MAPPER_HIDL_HEADER_H + +#include <android/hardware/graphics/mapper/4.0/IMapper.h> +#include "mali_fourcc.h" +#include <gralloctypes/Gralloc4.h> + +using android::hardware::graphics::mapper::V4_0::Error; +using android::hardware::graphics::mapper::V4_0::BufferDescriptor; +using android::hardware::graphics::common::V1_2::PixelFormat; +using android::hardware::graphics::common::V1_2::BufferUsage; +using android::hardware::graphics::mapper::V4_0::IMapper; + +#endif diff --git a/GrallocHAL/src/Android.bp b/GrallocHAL/src/Android.bp new file mode 100644 index 0000000..a2c44c8 --- /dev/null +++ b/GrallocHAL/src/Android.bp @@ -0,0 +1,81 @@ + +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library_headers { + name: "libgralloc_headers", + vendor: true, + host_supported: true, + export_include_dirs: [ + ".", + ], + header_libs: [ + "libsystem_headers", + ], + export_header_lib_headers: [ + "libsystem_headers", + ], +} + +cc_library_shared { + name: "libGralloc4Wrapper", + vendor: true, + srcs: [ + "libGralloc4Wrapper/wrapper.cpp", + "allocator/mali_gralloc_ion.cpp", + "allocator/mali_gralloc_shared_memory.cpp", + "core/format_info.cpp", + "core/mali_gralloc_formats.cpp", + "core/mali_gralloc_bufferallocation.cpp", + "core/mali_gralloc_bufferdescriptor.cpp", + "core/mali_gralloc_reference.cpp", + "core/mali_gralloc_debug.cpp", + ":libgralloc_hidl_common_shared_metadata", + ], + cflags: [ + "-DGRALLOC_LIBRARY_BUILD=1", + ], + static_libs: [ + "libgralloc_capabilities", + ], + shared_libs: [ + "liblog", + "libcutils", + "libutils", + "libsync", + "libhardware", + "libhidlbase", + "libhidltransport", + "libnativewindow", + "libion_google", + "android.hardware.graphics.common@1.2", + "android.hardware.graphics.common-V3-ndk", + "android.hardware.graphics.mapper@4.0", + "libdmabufheap", + "libgralloctypes", + "libdrm", + ], + header_libs: [ + "google_hal_headers", + "device_kernel_headers", + ], + export_include_dirs: ["libGralloc4Wrapper/include"] +} diff --git a/GrallocHAL/src/aidl/Android.bp b/GrallocHAL/src/aidl/Android.bp new file mode 100644 index 0000000..e2d9d04 --- /dev/null +++ b/GrallocHAL/src/aidl/Android.bp @@ -0,0 +1,30 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library_shared { + name: "android.hardware.graphics.allocator-aidl-impl", + proprietary: true, + relative_install_path: "hw", + defaults: [ + "arm_gralloc_api_4x_defaults", + ], + shared_libs: [ + "android.hardware.graphics.allocator-V1-ndk", + "android.hardware.graphics.allocator@4.0", + "android.hardware.graphics.mapper@4.0", + "libbinder_ndk", + ], + static_libs: [ + "libaidlcommonsupport", + ], + srcs: [ + "GrallocAllocator.cpp", + ":libgralloc_hidl_common_allocator", + ":libgralloc_hidl_common_shared_metadata", + ], + include_dirs: [ + "hardware/google/gchips/include", + ], +} + diff --git a/GrallocHAL/src/aidl/GrallocAllocator.cpp b/GrallocHAL/src/aidl/GrallocAllocator.cpp new file mode 100644 index 0000000..d7addc5 --- /dev/null +++ b/GrallocHAL/src/aidl/GrallocAllocator.cpp @@ -0,0 +1,88 @@ +#include "GrallocAllocator.h" + +#include <aidl/android/hardware/graphics/allocator/AllocationError.h> +#include <aidlcommonsupport/NativeHandle.h> +#include <android/binder_ibinder.h> +#include <android/binder_status.h> +#include <hidl/HidlSupport.h> + +#include "allocator/mali_gralloc_ion.h" +#include "hidl_common/Allocator.h" + +namespace pixel::allocator { + +namespace AidlAllocator = aidl::android::hardware::graphics::allocator; +namespace HidlAllocator = android::hardware::graphics::allocator::V4_0; + +using android::hardware::hidl_handle; +using android::hardware::hidl_vec; +using HidlError = android::hardware::graphics::mapper::V4_0::Error; + +unsigned long callingPid() { + return static_cast<unsigned long>(AIBinder_getCallingPid()); +} + +GrallocAllocator::GrallocAllocator() {} + +GrallocAllocator::~GrallocAllocator() { + mali_gralloc_ion_close(); +} + +ndk::ScopedAStatus GrallocAllocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count, + AidlAllocator::AllocationResult* result) { + MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid()); + + buffer_descriptor_t bufferDescriptor; + if (!arm::mapper::common::grallocDecodeBufferDescriptor(hidl_vec(descriptor), + bufferDescriptor)) { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR)); + } + + // TODO(layog@): This dependency between AIDL and HIDL backends is not good. + // Ideally common::allocate should return the result and it should be encoded + // by this interface into HIDL or AIDL. + HidlError error = HidlError::NONE; + auto hidl_cb = [&](HidlError _error, int _stride, hidl_vec<hidl_handle> _buffers) { + if (_error != HidlError::NONE) { + error = _error; + return; + } + + const uint32_t size = _buffers.size(); + + result->stride = _stride; + result->buffers.resize(size); + for (uint32_t i = 0; i < size; i++) { + // Dup here is necessary. After this callback returns common::allocate + // will free the buffer which will destroy the older fd. + result->buffers[i] = android::dupToAidl(static_cast<const native_handle*>(_buffers[i])); + } + }; + + arm::allocator::common::allocate(bufferDescriptor, count, hidl_cb); + + switch (error) { + case HidlError::NONE: + break; + + case HidlError::BAD_DESCRIPTOR: + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR)); + + case HidlError::NO_RESOURCES: + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(AidlAllocator::AllocationError::NO_RESOURCES)); + + case HidlError::UNSUPPORTED: + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(AidlAllocator::AllocationError::UNSUPPORTED)); + + default: + return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR); + } + + return ndk::ScopedAStatus::ok(); +} + +} // namespace pixel::allocator diff --git a/GrallocHAL/src/aidl/GrallocAllocator.h b/GrallocHAL/src/aidl/GrallocAllocator.h new file mode 100644 index 0000000..82d4657 --- /dev/null +++ b/GrallocHAL/src/aidl/GrallocAllocator.h @@ -0,0 +1,26 @@ +#pragma once + +#include <aidl/android/hardware/graphics/allocator/AllocationResult.h> +#include <aidl/android/hardware/graphics/allocator/BnAllocator.h> +#include <aidlcommonsupport/NativeHandle.h> + +#include <cstdint> +#include <vector> + +namespace pixel { +namespace allocator { + +namespace AidlAllocator = aidl::android::hardware::graphics::allocator; + +class GrallocAllocator : public AidlAllocator::BnAllocator { +public: + GrallocAllocator(); + + ~GrallocAllocator(); + + virtual ndk::ScopedAStatus allocate(const std::vector<uint8_t>& descriptor, int32_t count, + AidlAllocator::AllocationResult* result) override; +}; + +} // namespace allocator +} // namespace pixel diff --git a/GrallocHAL/src/allocator/Android.bp b/GrallocHAL/src/allocator/Android.bp new file mode 100644 index 0000000..3051ced --- /dev/null +++ b/GrallocHAL/src/allocator/Android.bp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +soong_config_module_type { + name: "arm_gralloc_allocator_cc_defaults", + module_type: "cc_defaults", + config_namespace: "arm_gralloc", + variables: [ + "gralloc_use_ion_dma_heap", + "gralloc_use_ion_compound_page_heap", + "gralloc_init_afbc", + "gralloc_use_ion_dmabuf_sync", + ], + properties: [ + "cflags", + ], +} + +soong_config_bool_variable { + name: "gralloc_use_ion_dma_heap", +} +soong_config_bool_variable { + name: "gralloc_use_ion_compound_page_heap", +} +soong_config_bool_variable { + name: "gralloc_init_afbc", +} +soong_config_bool_variable { + name: "gralloc_use_ion_dmabuf_sync", +} + +arm_gralloc_allocator_cc_defaults { + name: "arm_gralloc_allocator_defaults", + defaults: [ + "arm_gralloc_defaults", + ], + soong_config_variables: { + gralloc_use_ion_dma_heap: { + cflags: [ + "-DGRALLOC_USE_ION_DMA_HEAP=1", + ], + }, + gralloc_use_ion_compound_page_heap: { + cflags: [ + "-DGRALLOC_USE_ION_COMPOUND_PAGE_HEAP=1", + ], + }, + gralloc_init_afbc: { + cflags: [ + "-DGRALLOC_INIT_AFBC=1", + ], + }, + gralloc_use_ion_dmabuf_sync: { + cflags: [ + "-DGRALLOC_USE_ION_DMABUF_SYNC=1", + ], + }, + }, + srcs: [ + "mali_gralloc_ion.cpp", + "mali_gralloc_shared_memory.cpp", + ], + static_libs: [ + "libarect", + ], + shared_libs: [ + "libhardware", + "liblog", + "libcutils", + "libdmabufheap", + "libion_google", + "libsync", + "libutils", + "libnativewindow", + "android.hardware.graphics.common-V3-ndk", + ], + header_libs: [ + "libnativebase_headers", + ], +} + +cc_library_static { + name: "libgralloc_allocator", + defaults: [ + "arm_gralloc_allocator_defaults", + "arm_gralloc_version_defaults", + ], +} diff --git a/GrallocHAL/src/allocator/mali_gralloc_ion.cpp b/GrallocHAL/src/allocator/mali_gralloc_ion.cpp new file mode 100644 index 0000000..e807651 --- /dev/null +++ b/GrallocHAL/src/allocator/mali_gralloc_ion.cpp @@ -0,0 +1,825 @@ +/* + * Copyright (C) 2016-2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <errno.h> +#include <inttypes.h> +#include <pthread.h> +#include <stdlib.h> +#include <limits.h> + +#include <log/log.h> +#include <cutils/atomic.h> + +#include <linux/dma-buf.h> +#include <vector> +#include <sys/ioctl.h> + +#include <hardware/hardware.h> +#include <hardware/gralloc1.h> + +#include <hardware/exynos/ion.h> +#include <hardware/exynos/dmabuf_container.h> + +#include <BufferAllocator/BufferAllocator.h> +#include "mali_gralloc_buffer.h" +#include "gralloc_helper.h" +#include "mali_gralloc_formats.h" +#include "mali_gralloc_usages.h" +#include "core/format_info.h" +#include "core/mali_gralloc_bufferdescriptor.h" +#include "core/mali_gralloc_bufferallocation.h" + +#include "mali_gralloc_ion.h" + +#include <array> + +#define INIT_ZERO(obj) (memset(&(obj), 0, sizeof((obj)))) + +#define HEAP_MASK_FROM_ID(id) (1 << id) +#define HEAP_MASK_FROM_TYPE(type) (1 << type) + +#if defined(ION_HEAP_SECURE_MASK) +#if (HEAP_MASK_FROM_TYPE(ION_HEAP_TYPE_SECURE) != ION_HEAP_SECURE_MASK) +#error "ION_HEAP_TYPE_SECURE value is not compatible with ION_HEAP_SECURE_MASK" +#endif +#endif + +static const char kDmabufSensorDirectHeapName[] = "sensor_direct_heap"; +static const char kDmabufFaceauthTpuHeapName[] = "faceauth_tpu-secure"; +static const char kDmabufFaceauthImgHeapName[] = "faimg-secure"; +static const char kDmabufFaceauthRawImgHeapName[] = "farawimg-secure"; +static const char kDmabufFaceauthPrevHeapName[] = "faprev-secure"; +static const char kDmabufFaceauthModelHeapName[] = "famodel-secure"; +static const char kDmabufVframeSecureHeapName[] = "vframe-secure"; +static const char kDmabufVstreamSecureHeapName[] = "vstream-secure"; + +struct ion_device +{ + int client() + { + return ion_client; + } + + static void close() + { + ion_device &dev = get_inst(); + if (dev.ion_client >= 0) + { + exynos_ion_close(dev.ion_client); + dev.ion_client = -1; + } + + dev.buffer_allocator.reset(); + } + + static ion_device *get() + { + ion_device &dev = get_inst(); + if (!dev.buffer_allocator) + { + dev.buffer_allocator = std::make_unique<BufferAllocator>(); + if (!dev.buffer_allocator) + ALOGE("Unable to create BufferAllocator object"); + } + + if (dev.ion_client < 0) + { + if (dev.open_and_query_ion() != 0) + { + close(); + } + } + + if (dev.ion_client < 0) + { + return nullptr; + } + return &dev; + } + + /* + * Identifies a heap and retrieves file descriptor from ION for allocation + * + * @param usage [in] Producer and consumer combined usage. + * @param size [in] Requested buffer size (in bytes). + * @param heap_type [in] Requested heap type. + * @param flags [in] ION allocation attributes defined by ION_FLAG_*. + * @param min_pgsz [out] Minimum page size (in bytes). + * + * @return File handle which can be used for allocation, on success + * -1, otherwise. + */ + int alloc_from_ion_heap(uint64_t usage, size_t size, unsigned int flags, int *min_pgsz); + + /* + * Signals the start or end of a region where the CPU is accessing a + * buffer, allowing appropriate cache synchronization. + * + * @param fd [in] fd for the buffer + * @param read [in] True if the CPU is reading from the buffer + * @param write [in] True if the CPU is writing to the buffer + * @param start [in] True if the CPU has not yet performed the + * operations; false if the operations are + * completed. + * + * @return 0 on success; an error code otherwise. + */ + int sync(int fd, bool read, bool write, bool start); + +private: + int ion_client; + std::unique_ptr<BufferAllocator> buffer_allocator; + + ion_device() + : ion_client(-1) + { + } + + static ion_device& get_inst() + { + static ion_device dev; + return dev; + } + + /* + * Opens the ION module. Queries heap information and stores it for later use + * + * @return 0 in case of success + * -1 for all error cases + */ + int open_and_query_ion(); + + /* + * Allocates in the DMA-BUF heap with name @heap_name. If allocation fails from + * the DMA-BUF heap or if it does not exist, falls back to an ION heap of the + * same name. + * + * @param heap_name [in] DMA-BUF heap name for allocation + * @param size [in] Requested buffer size (in bytes). + * @param flags [in] ION allocation attributes defined by ION_FLAG_* to + * be used for ION allocations. Will not be used with + * DMA-BUF heaps since the framework does not support + * allocation flags. + * + * @return fd of the allocated buffer on success, -1 otherwise; + */ + + int alloc_from_dmabuf_heap(const std::string& heap_name, size_t size, unsigned int flags); +}; + +static void set_ion_flags(uint64_t usage, unsigned int *ion_flags) +{ + if (ion_flags == nullptr) + return; + + if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) + { + *ion_flags |= ION_FLAG_CACHED; + } + + // DRM or Secure Camera + if (usage & (GRALLOC_USAGE_PROTECTED)) + { + *ion_flags |= ION_FLAG_PROTECTED; + } + + /* TODO: used for exynos3830. Add this as an option to Android.bp */ +#if defined(GRALLOC_SCALER_WFD) && GRALLOC_SCALER_WFD == 1 + if (usage & GRALLOC_USAGE_PRIVATE_NONSECURE && usage & GRALLOC_USAGE_HW_COMPOSER) + { + *ion_flags |= ION_FLAG_PROTECTED; + } +#endif + /* Sensor direct channels require uncached allocations. */ + if (usage & GRALLOC_USAGE_SENSOR_DIRECT_DATA) + { + *ion_flags &= ~ION_FLAG_CACHED; + } +} + +static unsigned int select_faceauth_heap_mask(uint64_t usage) +{ + struct HeapSpecifier + { + uint64_t usage_bits; // exact match required + unsigned int mask; + }; + + static constexpr std::array<HeapSpecifier, 5> faceauth_heaps = + {{ + { // isp_image_heap + GRALLOC_USAGE_PROTECTED | GRALLOC_USAGE_HW_CAMERA_WRITE | GS101_GRALLOC_USAGE_TPU_INPUT, + EXYNOS_ION_HEAP_FA_IMG_MASK + }, + { // isp_internal_heap + GRALLOC_USAGE_PROTECTED | GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_HW_CAMERA_READ, + EXYNOS_ION_HEAP_FA_RAWIMG_MASK + }, + { // isp_preview_heap + GRALLOC_USAGE_PROTECTED | GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_HW_COMPOSER | + GRALLOC_USAGE_HW_TEXTURE, + EXYNOS_ION_HEAP_FA_PREV_MASK + }, + { // ml_model_heap + GRALLOC_USAGE_PROTECTED | GS101_GRALLOC_USAGE_TPU_INPUT, + EXYNOS_ION_HEAP_FA_MODEL_MASK + }, + { // tpu_heap + GRALLOC_USAGE_PROTECTED | GS101_GRALLOC_USAGE_TPU_OUTPUT | GS101_GRALLOC_USAGE_TPU_INPUT, + EXYNOS_ION_HEAP_FA_TPU_MASK + } + }}; + + for (const HeapSpecifier &heap : faceauth_heaps) + { + if (usage == heap.usage_bits) + { + ALOGV("Using FaceAuth heap mask 0x%x for usage 0x%" PRIx64 "\n", + heap.mask, usage); + return heap.mask; + } + } + + return 0; +} + +static unsigned int select_heap_mask(uint64_t usage) +{ + if (unsigned int faceauth_heap_mask = select_faceauth_heap_mask(usage); + faceauth_heap_mask != 0) + { + return faceauth_heap_mask; + } + + unsigned int heap_mask; + + if (usage & GRALLOC_USAGE_PROTECTED) + { + if (usage & GRALLOC_USAGE_PRIVATE_NONSECURE) + { + heap_mask = EXYNOS_ION_HEAP_SYSTEM_MASK; + } + else if ((usage & GRALLOC_USAGE_HW_COMPOSER) && + !(usage & GRALLOC_USAGE_HW_TEXTURE) && + !(usage & GRALLOC_USAGE_HW_RENDER)) + { + heap_mask = EXYNOS_ION_HEAP_VIDEO_SCALER_MASK; + } + else + { + heap_mask = EXYNOS_ION_HEAP_VIDEO_FRAME_MASK; + } + } + /* TODO: used for exynos3830. Add this as a an option to Android.bp */ +#if defined(GRALLOC_SCALER_WFD) && GRALLOC_SCALER_WFD == 1 + else if (usage & GRALLOC_USAGE_PRIVATE_NONSECURE && usage & GRALLOC_USAGE_HW_COMPOSER) + { + heap_mask = EXYNOS_ION_HEAP_EXT_UI_MASK; + } +#endif + else if (usage & GRALLOC_USAGE_SENSOR_DIRECT_DATA) + { + heap_mask = EXYNOS_ION_HEAP_SENSOR_DIRECT_MASK; + } + else + { + heap_mask = EXYNOS_ION_HEAP_SYSTEM_MASK; + } + + return heap_mask; +} + +/* + * Selects a DMA-BUF heap name. + * + * @param heap_mask [in] heap_mask for which the equivalent DMA-BUF heap + * name must be found. + * + * @return the name of the DMA-BUF heap equivalent to the ION heap of mask + * @heap_mask. + * + */ +static std::string select_dmabuf_heap(unsigned int heap_mask) +{ + switch (heap_mask) { + case EXYNOS_ION_HEAP_SENSOR_DIRECT_MASK: + return kDmabufSensorDirectHeapName; + case EXYNOS_ION_HEAP_FA_TPU_MASK: + return kDmabufFaceauthTpuHeapName; + case EXYNOS_ION_HEAP_FA_IMG_MASK: + return kDmabufFaceauthImgHeapName; + case EXYNOS_ION_HEAP_FA_RAWIMG_MASK: + return kDmabufFaceauthRawImgHeapName; + case EXYNOS_ION_HEAP_FA_PREV_MASK: + return kDmabufFaceauthPrevHeapName; + case EXYNOS_ION_HEAP_FA_MODEL_MASK: + return kDmabufFaceauthModelHeapName; + case EXYNOS_ION_HEAP_VIDEO_FRAME_MASK: + return kDmabufVframeSecureHeapName; + case EXYNOS_ION_HEAP_VIDEO_STREAM_MASK: + return kDmabufVstreamSecureHeapName; + default: + return {}; + } +} + +int ion_device::alloc_from_dmabuf_heap(const std::string& heap_name, size_t size, + unsigned int flags) +{ + if (!buffer_allocator) + { + return -1; + } + + int shared_fd = buffer_allocator->Alloc(heap_name, size, flags); + if (shared_fd < 0) + { + ALOGE("Allocation failed for heap %s error: %d\n", heap_name.c_str(), shared_fd); + } + + return shared_fd; +} + +int ion_device::alloc_from_ion_heap(uint64_t usage, size_t size, unsigned int flags, int *min_pgsz) +{ + /* TODO: remove min_pgsz? I don't think this is useful on Exynos */ + if (size == 0 || min_pgsz == NULL) + { + return -1; + } + + unsigned int heap_mask = select_heap_mask(usage); + + int shared_fd; + auto dmabuf_heap_name = select_dmabuf_heap(heap_mask); + if (!dmabuf_heap_name.empty()) + { + shared_fd = alloc_from_dmabuf_heap(dmabuf_heap_name, size, flags); + } + else + { + if (ion_client < 0) + { + return -1; + } + + shared_fd = exynos_ion_alloc(ion_client, size, heap_mask, flags); + } + + *min_pgsz = SZ_4K; + + return shared_fd; +} + +int ion_device::open_and_query_ion() +{ + if (ion_client >= 0) + { + MALI_GRALLOC_LOGW("ION device already open"); + return 0; + } + + ion_client = exynos_ion_open(); + if (ion_client < 0) + { + MALI_GRALLOC_LOGE("ion_open failed with %s", strerror(errno)); + return -1; + } + + return 0; +} + +static SyncType sync_type_for_flags(const bool read, const bool write) +{ + if (read && !write) + { + return SyncType::kSyncRead; + } + else if (write && !read) + { + return SyncType::kSyncWrite; + } + else + { + // Deliberately also allowing "not sure" to map to ReadWrite. + return SyncType::kSyncReadWrite; + } +} + +int ion_device::sync(const int fd, const bool read, const bool write, const bool start) +{ + if (!buffer_allocator) + { + return -1; + } + + if (start) + { + return buffer_allocator->CpuSyncStart(fd, sync_type_for_flags(read, write)); + } + else + { + return buffer_allocator->CpuSyncEnd(fd, sync_type_for_flags(read, write)); + } +} + +static int mali_gralloc_ion_sync(const private_handle_t * const hnd, + const bool read, + const bool write, + const bool start) +{ + if (hnd == NULL) + { + return -EINVAL; + } + + ion_device *dev = ion_device::get(); + if (!dev) + { + return -1; + } + + for (int i = 0; i < hnd->fd_count; i++) + { + const int fd = hnd->fds[i]; + if (const int ret = dev->sync(fd, read, write, start)) + { + return ret; + } + } + + return 0; +} + + +/* + * Signal start of CPU access to the DMABUF exported from ION. + * + * @param hnd [in] Buffer handle + * @param read [in] Flag indicating CPU read access to memory + * @param write [in] Flag indicating CPU write access to memory + * + * @return 0 in case of success + * errno for all error cases + */ +int mali_gralloc_ion_sync_start(const private_handle_t * const hnd, + const bool read, + const bool write) +{ + return mali_gralloc_ion_sync(hnd, read, write, true); +} + + +/* + * Signal end of CPU access to the DMABUF exported from ION. + * + * @param hnd [in] Buffer handle + * @param read [in] Flag indicating CPU read access to memory + * @param write [in] Flag indicating CPU write access to memory + * + * @return 0 in case of success + * errno for all error cases + */ +int mali_gralloc_ion_sync_end(const private_handle_t * const hnd, + const bool read, + const bool write) +{ + return mali_gralloc_ion_sync(hnd, read, write, false); +} + + +void mali_gralloc_ion_free(private_handle_t * const hnd) +{ + for (int i = 0; i < hnd->fd_count; i++) + { + void* mapped_addr = reinterpret_cast<void*>(hnd->bases[i]); + + /* Buffer might be unregistered already so we need to assure we have a valid handle */ + if (mapped_addr != nullptr) + { + if (munmap(mapped_addr, hnd->alloc_sizes[i]) != 0) + { + /* TODO: more detailed error logs */ + MALI_GRALLOC_LOGE("Failed to munmap handle %p", hnd); + } + } + close(hnd->fds[i]); + hnd->fds[i] = -1; + hnd->bases[i] = 0; + } + delete hnd; +} + +static void mali_gralloc_ion_free_internal(buffer_handle_t * const pHandle, + const uint32_t num_hnds) +{ + for (uint32_t i = 0; i < num_hnds; i++) + { + if (pHandle[i] != NULL) + { + private_handle_t * const hnd = (private_handle_t * const)pHandle[i]; + mali_gralloc_ion_free(hnd); + } + } +} + +int mali_gralloc_ion_allocate_attr(private_handle_t *hnd) +{ + ion_device *dev = ion_device::get(); + if (!dev) + { + return -1; + } + + int idx = hnd->get_share_attr_fd_index(); + int ion_flags = 0; + int min_pgsz; + uint64_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; + + ion_flags = ION_FLAG_CACHED; + + hnd->fds[idx] = dev->alloc_from_ion_heap(usage, hnd->attr_size, ion_flags, &min_pgsz); + if (hnd->fds[idx] < 0) + { + MALI_GRALLOC_LOGE("ion_alloc failed from client ( %d )", dev->client()); + return -1; + } + + hnd->incr_numfds(1); + + return 0; +} + +/* + * Allocates ION buffers + * + * @param descriptors [in] Buffer request descriptors + * @param numDescriptors [in] Number of descriptors + * @param pHandle [out] Handle for each allocated buffer + * @param shared_backend [out] Shared buffers flag + * + * @return File handle which can be used for allocation, on success + * -1, otherwise. + */ +int mali_gralloc_ion_allocate(const gralloc_buffer_descriptor_t *descriptors, + uint32_t numDescriptors, buffer_handle_t *pHandle, + bool *shared_backend, int ion_fd) +{ + GRALLOC_UNUSED(shared_backend); + + unsigned int priv_heap_flag = 0; + uint64_t usage; + uint32_t i; + unsigned int ion_flags = 0; + int min_pgsz = 0; + int fds[5] = {-1, -1, -1, -1, -1}; + + ion_device *dev = ion_device::get(); + if (!dev) + { + return -1; + } + + for (i = 0; i < numDescriptors; i++) + { + buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]); + usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage; + + ion_flags = 0; + set_ion_flags(usage, &ion_flags); + + for (int fidx = 0; fidx < bufDescriptor->fd_count; fidx++) + { + if (ion_fd >= 0 && fidx == 0) { + fds[fidx] = ion_fd; + } else { + fds[fidx] = dev->alloc_from_ion_heap(usage, bufDescriptor->alloc_sizes[fidx], ion_flags, &min_pgsz); + } + if (fds[fidx] < 0) + { + MALI_GRALLOC_LOGE("ion_alloc failed from client ( %d )", dev->client()); + + for (int cidx = 0; cidx < fidx; cidx++) + { + close(fds[cidx]); + } + + /* need to free already allocated memory. not just this one */ + mali_gralloc_ion_free_internal(pHandle, numDescriptors); + + return -1; + } + } + + private_handle_t *hnd = new private_handle_t( + priv_heap_flag, + bufDescriptor->alloc_sizes, + bufDescriptor->consumer_usage, bufDescriptor->producer_usage, + fds, bufDescriptor->fd_count, + bufDescriptor->hal_format, bufDescriptor->alloc_format, + bufDescriptor->width, bufDescriptor->height, bufDescriptor->pixel_stride, + bufDescriptor->layer_count, bufDescriptor->plane_info); + + if (NULL == hnd) + { + MALI_GRALLOC_LOGE("Private handle could not be created for descriptor:%d in non-shared usecase", i); + + /* Close the obtained shared file descriptor for the current handle */ + for (int j = 0; j < bufDescriptor->fd_count; j++) + { + close(fds[j]); + } + + mali_gralloc_ion_free_internal(pHandle, numDescriptors); + return -1; + } + + pHandle[i] = hnd; + } + +#if defined(GRALLOC_INIT_AFBC) && (GRALLOC_INIT_AFBC == 1) + unsigned char *cpu_ptr = NULL; + for (i = 0; i < numDescriptors; i++) + { + buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]); + private_handle_t *hnd = (private_handle_t *)(pHandle[i]); + + usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage; + + if ((bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) + && !(usage & GRALLOC_USAGE_PROTECTED)) + { + /* TODO: only map for AFBC buffers */ + cpu_ptr = + (unsigned char *)mmap(NULL, bufDescriptor->alloc_sizes[0], PROT_READ | PROT_WRITE, MAP_SHARED, hnd->fds[0], 0); + + if (MAP_FAILED == cpu_ptr) + { + MALI_GRALLOC_LOGE("mmap failed from client ( %d ), fd ( %d )", dev->client(), hnd->fds[0]); + mali_gralloc_ion_free_internal(pHandle, numDescriptors); + return -1; + } + + mali_gralloc_ion_sync_start(hnd, true, true); + + /* For separated plane YUV, there is a header to initialise per plane. */ + const plane_info_t *plane_info = bufDescriptor->plane_info; + const bool is_multi_plane = hnd->is_multi_plane(); + for (int i = 0; i < MAX_PLANES && (i == 0 || plane_info[i].byte_stride != 0); i++) + { + init_afbc(cpu_ptr + plane_info[i].offset, + bufDescriptor->alloc_format, + is_multi_plane, + plane_info[i].alloc_width, + plane_info[i].alloc_height); + } + + mali_gralloc_ion_sync_end(hnd, true, true); + + munmap(cpu_ptr, bufDescriptor->alloc_sizes[0]); + } + } +#endif + + return 0; +} + + +int mali_gralloc_ion_map(private_handle_t *hnd) +{ + uint64_t usage = hnd->producer_usage | hnd->consumer_usage; + + /* Do not allow cpu access to secure buffers */ + if (usage & (GRALLOC_USAGE_PROTECTED | GRALLOC_USAGE_NOZEROED) + && !(usage & GRALLOC_USAGE_PRIVATE_NONSECURE)) + { + return 0; + } + + for (int fidx = 0; fidx < hnd->fd_count; fidx++) { + unsigned char *mappedAddress = + (unsigned char *)mmap(NULL, hnd->alloc_sizes[fidx], PROT_READ | PROT_WRITE, + MAP_SHARED, hnd->fds[fidx], 0); + + if (MAP_FAILED == mappedAddress) + { + int err = errno; + MALI_GRALLOC_LOGE("mmap( fds[%d]:%d size:%" PRIu64 " ) failed with %s", + fidx, hnd->fds[fidx], hnd->alloc_sizes[fidx], strerror(err)); + hnd->dump("map fail"); + + for (int cidx = 0; cidx < fidx; fidx++) + { + munmap((void*)hnd->bases[cidx], hnd->alloc_sizes[cidx]); + hnd->bases[cidx] = 0; + } + + return -err; + } + + hnd->bases[fidx] = uintptr_t(mappedAddress); + } + + return 0; +} + +int import_exynos_ion_handles(private_handle_t *hnd) +{ + int retval = -1; + + ion_device *dev = ion_device::get(); + + for (int idx = 0; idx < hnd->fd_count; idx++) + { + if (hnd->fds[idx] >= 0) + { + retval = exynos_ion_import_handle(dev->client(), hnd->fds[idx], &hnd->ion_handles[idx]); + if (retval) + { + MALI_GRALLOC_LOGE("error importing ion_handle. ion_client(%d), ion_handle[%d](%d) format(%s %#" PRIx64 ")", + dev->client(), idx, hnd->ion_handles[idx], format_name(hnd->alloc_format), hnd->alloc_format); + goto error; + } + } + } + + return retval; + +error: + for (int idx = 0; idx < hnd->fd_count; idx++) + { + if (hnd->ion_handles[idx]) + { + exynos_ion_free_handle(dev->client(), hnd->ion_handles[idx]); + } + } + + return retval; +} + +void free_exynos_ion_handles(private_handle_t *hnd) +{ + ion_device *dev = ion_device::get(); + + for (int idx = 0; idx < hnd->fd_count; idx++) + { + if (hnd->ion_handles[idx]) + { + if (hnd->ion_handles[idx] && + exynos_ion_free_handle(dev->client(), hnd->ion_handles[idx])) + { + MALI_GRALLOC_LOGE("error freeing ion_handle. ion_client(%d), ion_handle[%d](%d) format(%s %#" PRIx64 ")", + dev->client(), idx, hnd->ion_handles[idx], format_name(hnd->alloc_format), hnd->alloc_format); + } + } + } +} + + +void mali_gralloc_ion_unmap(private_handle_t *hnd) +{ + for (int i = 0; i < hnd->fd_count; i++) + { + int err = 0; + + if (hnd->bases[i]) + { + err = munmap((void*)hnd->bases[i], hnd->alloc_sizes[i]); + } + + if (err) + { + MALI_GRALLOC_LOGE("Could not munmap base:%p size:%" PRIu64 " '%s'", + (void*)hnd->bases[i], hnd->alloc_sizes[i], strerror(errno)); + } + else + { + hnd->bases[i] = 0; + } + } + + hnd->cpu_read = 0; + hnd->cpu_write = 0; +} + +void mali_gralloc_ion_close(void) +{ + ion_device::close(); +} + diff --git a/gralloc3/src/mali_gralloc_ion.h b/GrallocHAL/src/allocator/mali_gralloc_ion.h index d31e2f0..3877c5e 100644 --- a/gralloc3/src/mali_gralloc_ion.h +++ b/GrallocHAL/src/allocator/mali_gralloc_ion.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016, 2018-2019 ARM Limited. All rights reserved. + * Copyright (C) 2016, 2018-2020 ARM Limited. All rights reserved. * * Copyright (C) 2008 The Android Open Source Project * @@ -19,27 +19,12 @@ #ifndef MALI_GRALLOC_ION_H_ #define MALI_GRALLOC_ION_H_ -#include "mali_gralloc_module.h" -#include "mali_gralloc_bufferdescriptor.h" +#include "core/mali_gralloc_bufferdescriptor.h" -/* - * Allocates ION buffers - * - * @param descriptors [in] Buffer request descriptors - * @param numDescriptors [in] Number of descriptors - * @param pHandle [out] Handle for each allocated buffer - * @param shared_backend [out] Shared buffers flag - * @param ion_fd [in] Optional fd of an allocated ION buffer - * - * @return File handle which can be used for allocation, on success - * -1, otherwise. - * - * In the case ion_fd != -1, this functions wraps ion_fd in a buffer_handle_t - * instead. - */ +int mali_gralloc_ion_allocate_attr(private_handle_t *hnd); int mali_gralloc_ion_allocate(const gralloc_buffer_descriptor_t *descriptors, - uint32_t numDescriptors, buffer_handle_t *pHandle, - bool *alloc_from_backing_store, int ion_fd = -1); + uint32_t numDescriptors, buffer_handle_t *pHandle, bool *alloc_from_backing_store, + int ion_fd = -1); void mali_gralloc_ion_free(private_handle_t * const hnd); int mali_gralloc_ion_sync_start(const private_handle_t * const hnd, const bool read, const bool write); @@ -48,14 +33,8 @@ int mali_gralloc_ion_sync_end(const private_handle_t * const hnd, int mali_gralloc_ion_map(private_handle_t *hnd); void mali_gralloc_ion_unmap(private_handle_t *hnd); void mali_gralloc_ion_close(void); - +int mali_gralloc_attr_allocate(void); int import_exynos_ion_handles(private_handle_t *hnd); void free_exynos_ion_handles(private_handle_t *hnd); -int mali_gralloc_ion_open(void); - -#if GRALLOC_USE_ASHMEM_METADATA != 1 -int alloc_metadata(void); -#endif - #endif /* MALI_GRALLOC_ION_H_ */ diff --git a/gralloc3/src/gralloc_vsync_report.h b/GrallocHAL/src/allocator/mali_gralloc_shared_memory.cpp index 49baabf..b681cd9 100644 --- a/gralloc3/src/gralloc_vsync_report.h +++ b/GrallocHAL/src/allocator/mali_gralloc_shared_memory.cpp @@ -1,5 +1,7 @@ /* - * Copyright (C) 2011 ARM Limited. All rights reserved. + * Copyright (C) 2020 Arm Limited. All rights reserved. + * + * Copyright (C) 2008 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. @@ -14,33 +16,22 @@ * limitations under the License. */ -#ifndef GRALLOC_VSYNC_REPORT_H_ -#define GRALLOC_VSYNC_REPORT_H_ - +#include "mali_gralloc_shared_memory.h" +#include "mali_gralloc_log.h" +#include "mali_gralloc_buffer.h" +#include "mali_gralloc_ion.h" #include "gralloc_helper.h" -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum mali_vsync_event -{ - MALI_VSYNC_EVENT_BEGIN_WAIT = 0, - MALI_VSYNC_EVENT_END_WAIT -} mali_vsync_event; - -extern void _mali_base_arch_vsync_event_report(mali_vsync_event); +/* TODO: move shared attr memory allocation function here */ -inline void gralloc_mali_vsync_report(mali_vsync_event event) +void gralloc_shared_memory_free(private_handle_t *hnd) { -#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE - _mali_base_arch_vsync_event_report(event); -#else - GRALLOC_UNUSED(event); -#endif -} + if (hnd->attr_base) + { + munmap(hnd->attr_base, hnd->attr_size); + hnd->attr_base = nullptr; + } -#ifdef __cplusplus + hnd->close_share_attr_fd(); + hnd->set_share_attr_fd(-1); } -#endif -#endif /* GRALLOC_VSYNC_REPORT_H_ */ diff --git a/gralloc3/src/mali_gralloc_public_interface.h b/GrallocHAL/src/allocator/mali_gralloc_shared_memory.h index b35d11c..28e0a62 100644 --- a/gralloc3/src/mali_gralloc_public_interface.h +++ b/GrallocHAL/src/allocator/mali_gralloc_shared_memory.h @@ -1,10 +1,10 @@ /* - * Copyright (C) 2016 ARM Limited. All rights reserved. + * Copyright (C) 2020 Arm Limited. All rights reserved. * * Copyright (C) 2008 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 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 @@ -15,11 +15,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef MALI_GRALLOC_PUBLIC_INTERFACE_H_ -#define MALI_GRALLOC_PUBLIC_INTERFACE_H_ -#include <hardware/hardware.h> +#ifndef GRALLOC_SHARED_MEMORY_H_ +#define GRALLOC_SHARED_MEMORY_H_ -int mali_gralloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device); +#include <stdint.h> +#include <utility> +#include "mali_gralloc_buffer.h" -#endif /* MALI_GRALLOC_PUBLIC_INTERFACE_H_ */ +/* + * Frees resources acquired from gralloc_shared_memory_allocate. + */ +void gralloc_shared_memory_free(private_handle_t *hnd); + +#endif /* GRALLOC_SHARED_MEMORY_H_ */ diff --git a/GrallocHAL/src/capabilities/Android.bp b/GrallocHAL/src/capabilities/Android.bp new file mode 100644 index 0000000..dcc0ba1 --- /dev/null +++ b/GrallocHAL/src/capabilities/Android.bp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +soong_config_module_type { + name: "arm_gralloc_capabilities_cc_defaults", + module_type: "cc_defaults", + config_namespace: "arm_gralloc", + variables: [ + "mali_gpu_support_afbc_basic", + "mali_gpu_support_afbc_splitblk", + "mali_gpu_support_afbc_wideblk", + "mali_gpu_support_afbc_tiled_headers", + "mali_gpu_support_afbc_yuv_write", + "gralloc_arm_no_external_afbc", + "dpu_support_1010102_afbc", + "mali_gralloc_api_tests", + ], + properties: [ + "cflags", + ], +} + +soong_config_bool_variable { + name: "mali_gpu_support_afbc_basic", +} +soong_config_bool_variable { + name: "mali_gpu_support_afbc_splitblk", +} +soong_config_bool_variable { + name: "mali_gpu_support_afbc_wideblk", +} +soong_config_bool_variable { + name: "mali_gpu_support_afbc_tiled_headers", +} +soong_config_bool_variable { + name: "mali_gpu_support_afbc_yuv_write", +} +soong_config_bool_variable { + name: "gralloc_arm_no_external_afbc", +} +soong_config_bool_variable { + name: "dpu_support_1010102_afbc", +} +soong_config_bool_variable { + name: "mali_gralloc_api_tests", +} + +arm_gralloc_capabilities_cc_defaults { + name: "arm_gralloc_capabilities_defaults", + defaults: [ + "arm_gralloc_defaults", + ], + soong_config_variables: { + mali_gpu_support_afbc_basic: { + cflags: [ + "-DMALI_GPU_SUPPORT_AFBC_BASIC=1", + ], + }, + mali_gpu_support_afbc_splitblk: { + cflags: [ + "-DMALI_GPU_SUPPORT_AFBC_SPLITBLK=1", + ], + }, + mali_gpu_support_afbc_wideblk: { + cflags: [ + "-DMALI_GPU_SUPPORT_AFBC_WIDEBLK=1", + ], + }, + mali_gpu_support_afbc_tiled_headers: { + cflags: [ + "-DMALI_GPU_SUPPORT_AFBC_TILED_HEADERS=1", + ], + }, + mali_gpu_support_afbc_yuv_write: { + cflags: [ + "-DMALI_GPU_SUPPORT_AFBC_YUV_WRITE=1", + ], + }, + gralloc_arm_no_external_afbc: { + cflags: [ + "-DGRALLOC_ARM_NO_EXTERNAL_AFBC=1", + ], + }, + dpu_support_1010102_afbc: { + cflags: [ + "-DGRALLOC_DPU_SUPPORT_1010102_AFBC=1", + ], + }, + mali_gralloc_api_tests: { + cflags: [ + "-DMALI_GRALLOC_VENDOR_VPU=1", + ], + }, + }, + srcs: [ + "src/gralloc_capabilities.cpp", + ], + shared_libs: [ + "libhardware", + "liblog", + "libcutils", + "libsync", + "libutils", + "android.hardware.graphics.common-V3-ndk", + ], +} + +cc_library_static { + name: "libgralloc_capabilities", + defaults: [ + "arm_gralloc_capabilities_defaults", + "arm_gralloc_version_defaults", + ], +} diff --git a/GrallocHAL/src/capabilities/gralloc_capabilities.h b/GrallocHAL/src/capabilities/gralloc_capabilities.h new file mode 100644 index 0000000..4dfe08b --- /dev/null +++ b/GrallocHAL/src/capabilities/gralloc_capabilities.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "mali_gralloc_formats.h" + +extern mali_gralloc_format_caps cpu_runtime_caps; +extern mali_gralloc_format_caps dpu_runtime_caps; +extern mali_gralloc_format_caps vpu_runtime_caps; +extern mali_gralloc_format_caps gpu_runtime_caps; +extern mali_gralloc_format_caps cam_runtime_caps; +extern mali_gralloc_format_caps bo_runtime_caps; +extern mali_gralloc_format_caps mfc_runtime_caps; + +/* + * Obtains the capabilities of each media system IP that form the producers + * and consumers. Default capabilities are assigned (within this function) for + * each IP, based on CFLAGS which specify the version of each IP (or, for GPU, + * explicit features): + * - GPU: MALI_GPU_SUPPORT_* + * - DPU: MALI_DISPLAY_VERSION + * - VPU: MALI_VIDEO_VERSION + * + * See src/Android.mk for default values. + * + * These defaults can be overridden by runtime capabilities defined in the + * userspace drivers (*.so) loaded for each IP. The drivers should define a + * symbol named MALI_GRALLOC_FORMATCAPS_SYM_NAME, which contains all + * capabilities from set MALI_GRALLOC_FORMAT_CAPABILITY_* + * + * @return none. + * + * NOTE: although no capabilities are returned, global variables global variables + * named '*_runtime_caps' are updated. + */ +void get_ip_capabilities(void); + +#ifdef __cplusplus +extern "C" { +#endif + +void mali_gralloc_get_caps(struct mali_gralloc_format_caps *gpu_caps, + struct mali_gralloc_format_caps *vpu_caps, + struct mali_gralloc_format_caps *dpu_caps, + struct mali_gralloc_format_caps *cam_caps); +#ifdef __cplusplus +} +#endif diff --git a/GrallocHAL/src/capabilities/src/gralloc_capabilities.cpp b/GrallocHAL/src/capabilities/src/gralloc_capabilities.cpp new file mode 100644 index 0000000..92f2b7c --- /dev/null +++ b/GrallocHAL/src/capabilities/src/gralloc_capabilities.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gralloc_capabilities.h" + +#include <string.h> +#include <dlfcn.h> +#include <inttypes.h> +#include <assert.h> +#include <pthread.h> + +#include "core/format_info.h" + +/* Writing to runtime_caps_read is guarded by mutex caps_init_mutex. */ +static pthread_mutex_t caps_init_mutex = PTHREAD_MUTEX_INITIALIZER; +static bool runtime_caps_read = false; + +mali_gralloc_format_caps cpu_runtime_caps; +mali_gralloc_format_caps dpu_runtime_caps; +mali_gralloc_format_caps vpu_runtime_caps; +mali_gralloc_format_caps gpu_runtime_caps; +mali_gralloc_format_caps cam_runtime_caps; +mali_gralloc_format_caps bo_runtime_caps; +mali_gralloc_format_caps mfc_runtime_caps; + +void get_ip_capabilities(void) +{ + /* Ensure capability setting is not interrupted by other + * allocations during start-up. + */ + pthread_mutex_lock(&caps_init_mutex); + + if (runtime_caps_read) + { + goto already_init; + } + + sanitize_formats(); + + /* Determine CPU IP capabilities */ + cpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; + cpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102; + cpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616; + + /* Determine DPU IP capabilities */ + dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; + dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; + dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_READ; +#if defined(GRALLOC_DPU_SUPPORT_1010102_AFBC) && (GRALLOC_DPU_SUPPORT_1010102_AFBC == 1) + dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102; +#endif + +#if defined(MALI_GPU_SUPPORT_AFBC_BASIC) && (MALI_GPU_SUPPORT_AFBC_BASIC == 1) + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_READ; + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102; + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616; + +#if defined(MALI_GPU_SUPPORT_AFBC_YUV_WRITE) && (MALI_GPU_SUPPORT_AFBC_YUV_WRITE == 1) + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE; +#endif + +#if defined(MALI_GPU_SUPPORT_AFBC_SPLITBLK) && (MALI_GPU_SUPPORT_AFBC_SPLITBLK == 1) + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; +#endif + +#if defined(MALI_GPU_SUPPORT_AFBC_WIDEBLK) && (MALI_GPU_SUPPORT_AFBC_WIDEBLK == 1) + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK; +#endif + +#if defined(MALI_GPU_SUPPORT_AFBC_TILED_HEADERS) && (MALI_GPU_SUPPORT_AFBC_TILED_HEADERS == 1) + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK; + gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS; +#endif +#endif /* defined(MALI_GPU_SUPPORT_AFBC_BASIC) && (MALI_GPU_SUPPORT_AFBC_BASIC == 1) */ + + /* Determine BIGOCEAN IP capabilities */ + bo_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; + bo_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; + bo_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE; + + /* Determine MFC IP capabilities */ + mfc_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; + + /* Determine VPU IP capabilities */ + vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; + vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; + vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE; + +/* Build specific capability changes */ +#if defined(GRALLOC_ARM_NO_EXTERNAL_AFBC) && (GRALLOC_ARM_NO_EXTERNAL_AFBC == 1) + dpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; + gpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; + vpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; + cam_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; +#endif + + cam_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; + + runtime_caps_read = true; + +already_init: + pthread_mutex_unlock(&caps_init_mutex); + + MALI_GRALLOC_LOGV("GPU format capabilities 0x%" PRIx64, gpu_runtime_caps.caps_mask); + MALI_GRALLOC_LOGV("DPU format capabilities 0x%" PRIx64, dpu_runtime_caps.caps_mask); + MALI_GRALLOC_LOGV("VPU format capabilities 0x%" PRIx64, vpu_runtime_caps.caps_mask); + MALI_GRALLOC_LOGV("CAM format capabilities 0x%" PRIx64, cam_runtime_caps.caps_mask); + MALI_GRALLOC_LOGV("BO format capabilities 0x%" PRIx64, bo_runtime_caps.caps_mask); + MALI_GRALLOC_LOGV("MFC format capabilities 0x%" PRIx64, mfc_runtime_caps.caps_mask); +} + + +/* This is used by the unit tests to get the capabilities for each IP. */ +extern "C" { + void mali_gralloc_get_caps(struct mali_gralloc_format_caps *gpu_caps, + struct mali_gralloc_format_caps *vpu_caps, + struct mali_gralloc_format_caps *dpu_caps, + struct mali_gralloc_format_caps *cam_caps) + { + get_ip_capabilities(); + + memcpy(gpu_caps, (void *)&gpu_runtime_caps, sizeof(*gpu_caps)); + memcpy(vpu_caps, (void *)&vpu_runtime_caps, sizeof(*vpu_caps)); + memcpy(dpu_caps, (void *)&dpu_runtime_caps, sizeof(*dpu_caps)); + memcpy(cam_caps, (void *)&cam_runtime_caps, sizeof(*cam_caps)); + } +} diff --git a/GrallocHAL/src/core/Android.bp b/GrallocHAL/src/core/Android.bp new file mode 100644 index 0000000..b2e1a7a --- /dev/null +++ b/GrallocHAL/src/core/Android.bp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +soong_config_module_type { + name: "arm_gralloc_core_cc_defaults", + module_type: "cc_defaults", + config_namespace: "arm_gralloc", + variables: [ + "gralloc_ion_sync_on_lock", + ], + properties: [ + "cflags", + ], +} + +soong_config_bool_variable { + name: "gralloc_ion_sync_on_lock", +} + +arm_gralloc_core_cc_defaults { + name: "arm_gralloc_core_defaults", + defaults: [ + "arm_gralloc_defaults", + ], + cflags: [ + /* Minimum buffer dimensions in pixels when buffer will use AFBC */ + /* TODO: set this via BoardConfig */ + "-DGRALLOC_DISP_W=0", + "-DGRALLOC_DISP_H=0", + ], + soong_config_variables: { + gralloc_ion_sync_on_lock: { + cflags: [ + "-DGRALLOC_ION_SYNC_ON_LOCK=1", + ], + }, + }, + srcs: [ + "mali_gralloc_bufferaccess.cpp", + "mali_gralloc_bufferallocation.cpp", + "mali_gralloc_bufferdescriptor.cpp", + "mali_gralloc_formats.cpp", + "mali_gralloc_reference.cpp", + "mali_gralloc_debug.cpp", + "format_info.cpp", + ], + include_dirs: [ + "hardware/google/gchips/include", + ], + header_libs: [ + "device_kernel_headers", + ], + static_libs: [ + "libarect", + ], + shared_libs: [ + "liblog", + "libcutils", + "libutils", + "android.hardware.graphics.common@1.2", + "android.hardware.graphics.common-V3-ndk", + ], + target: { + android: { + shared_libs: [ + "libhardware", + ], + }, + }, +} + +cc_library_static { + name: "libgralloc_core", + defaults: [ + "arm_gralloc_core_defaults", + "arm_gralloc_version_defaults", + ], +} diff --git a/GrallocHAL/src/core/align_structs.py b/GrallocHAL/src/core/align_structs.py new file mode 100755 index 0000000..6c9fafd --- /dev/null +++ b/GrallocHAL/src/core/align_structs.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python3 + +import argparse +import sys + +def parse_args(): + parser = argparse.ArgumentParser(description="Align structs on single lines in BEGIN...END ALIGNED SECTION blocks") + parser.add_argument('file', metavar="FILE", nargs='?', help="If provided, a file to process. Otherwise stdin") + return parser.parse_args() + +def braces_match(line): + open_braces = 0 + for c in line: + if c == '{': + open_braces = open_braces + 1 + elif c == '}': + if open_braces == 0: + sys.exit("Too many close braces on line:\n{}", line) + open_braces = open_braces - 1 + return (open_braces == 0) + +assert(braces_match("{{{}}}")) +assert(not braces_match("{{}{}")) + +def is_partial_comment(line): + stripped = line.strip() + return stripped.startswith("/*") and not stripped.endswith("*/") + +assert(not is_partial_comment("/* */")) +assert(not is_partial_comment("/* /* */")) +assert(is_partial_comment("/* */ /")) +assert(is_partial_comment("/* */ /*")) + +def collineate(lines): + ret = [] + current_line = "" + for line in lines: + current_line = current_line + line + if braces_match(current_line) and not is_partial_comment(current_line): + ret.append(current_line) + current_line = "" + if current_line != "": + ret.append(current_line) + return ret + +assert(collineate(["/*", "...", "*/"]) == ["/*...*/"]) +assert(collineate(["{", "/*", "*/", "}"]) == ["{/**/}"]) +assert(collineate(["{", "{", "}", "}"]) == ["{{}}"]) +assert(collineate(["{", "}", "{", "}"]) == ["{}", "{}"]) + +def is_line_ignored(line): + stripped = line.lstrip() + return (stripped == "") or stripped.startswith("/*") or stripped.startswith("//") + +def pack(line): + if is_line_ignored(line): + return line + + ret = "" + in_leading_whitespace = True + for c in line: + if (c == " ") or (c == "\t"): + if in_leading_whitespace: + ret = ret + c + else: + in_leading_whitespace = False + ret = ret + c + return ret + +def prettify(line): + if is_line_ignored(line): + return line + + ret = "" + for c in line: + if (c == ","): + ret = ret + ", " + elif (c == "="): + ret = ret + " = " + elif (c == "{"): + ret = ret + "{ " + elif (c == "}"): + ret = ret + " }" + else: + ret = ret + c + return ret + +def has_an_offset(c): + return (c == "{") or (c == ",") + +def get_offsets(line): + if is_line_ignored(line): + return None + ret = [] + offset = -1 + for c in line: + offset = offset + 1 + if has_an_offset(c): + ret.append(offset) + offset = 0 + return ret + +def check_offsets(lines, offsets_list): + reference_index = -1 + for line in lines: + reference_index = reference_index + 1 + if not is_line_ignored(line): + break + if reference_index == len(lines): + return # no lines to check + index = -1 + for offsets in offsets_list: + index = index + 1 + if offsets == None: + continue + if len(offsets) != len(offsets_list[reference_index]): + sys.exit("Lines have differing numbers of offsets:\n" + lines[index] + "\n" + lines[reference_index]) + +def collect_max_offsets(offsets_list): + max_offsets = None + for offsets in offsets_list: + if offsets == None: + continue + if max_offsets == None: + max_offsets = offsets + continue + for index in range(len(max_offsets)): + if max_offsets[index] < offsets[index]: + max_offsets[index] = offsets[index] + return max_offsets + +def fix_offsets(line, target_offsets): + ret = "" + offset_index = 0 + offset = -1 + for c in line: + offset = offset + 1 + ret = ret + c + if has_an_offset(c): + ret = ret + " " * (target_offsets[offset_index] - offset) + offset_index = offset_index + 1 + offset = 0 + return ret + +def align_section(lines, args): + lines = collineate(lines) + lines = [pack(l) for l in lines] + lines = [prettify(l) for l in lines] + lines = [l.rstrip() for l in lines] + offsets_list = [get_offsets(l) for l in lines] + target_offsets = collect_max_offsets(offsets_list) + lines = [fix_offsets(l, target_offsets) for l in lines] + return lines + +def align_file(lines, args): + ret = [] + lines_to_align = None + + for line in lines: + if lines_to_align is None: + if "BEGIN ALIGNED SECTION" in line: + lines_to_align = [] + ret.append(line) + else: + if "END ALIGNED SECTION" in line: + ret = ret + align_section(lines_to_align, args) + lines_to_align = None + ret.append(line) + else: + lines_to_align.append(line) + + if lines_to_align is not None: + sys.exit("Incomplete aligned section") + + return ret + +if __name__ == '__main__': + args = parse_args() + lines = [] + + if args.file: + with open(args.file) as fd: + lines = [l.rstrip() for l in fd.readlines()] + else: + lines = [l.rstrip() for l in sys.stdin.readlines()] + + for line in align_file(lines, args): + print(line) diff --git a/GrallocHAL/src/core/exynos_format_allocation.h b/GrallocHAL/src/core/exynos_format_allocation.h new file mode 100644 index 0000000..30b2c15 --- /dev/null +++ b/GrallocHAL/src/core/exynos_format_allocation.h @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2020 Samsung Electronics Co. Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#if __has_include(<video/mfc_macros.h>) +#include <video/mfc_macros.h> +#else +#include "mfc_macros_local.h" +#endif + +#define PLANE_SIZE(w, h) ((w) * (h)) +#define S2B_PLANE_SIZE(w, h) (GRALLOC_ALIGN((w) / 4, 16) * (GRALLOC_ALIGN(h, 16))) + +/* + * Compute SBWC buffer geometry for a buffer containing packed SBWC YUV data + * with bits per pixel bpp, width w, and height h. + * Returns a pair of { luma size, chroma size }. + */ +template <int bpp> +static std::pair<size_t, size_t> sbwc_sizes(int w, int h) { + static_assert(bpp == 8 || bpp == 10, "Unexpected bit width"); + + const size_t luma_body_size = (bpp == 8) ? + SBWC_8B_Y_SIZE(w, h) : SBWC_10B_Y_SIZE(w, h); + const size_t luma_header_size = (bpp == 8) ? + SBWC_8B_Y_HEADER_SIZE(w, h) : SBWC_10B_Y_HEADER_SIZE(w, h); + + const size_t chroma_body_size = (bpp == 8) ? + SBWC_8B_CBCR_SIZE(w, h) : SBWC_10B_CBCR_SIZE(w, h); + const size_t chroma_header_size = (bpp == 8) ? + SBWC_8B_CBCR_HEADER_SIZE(w, h) : SBWC_10B_CBCR_HEADER_SIZE(w, h); + + MALI_GRALLOC_LOGV("SBWC luma body size 0x%zx, header size 0x%zx", luma_body_size, luma_header_size); + MALI_GRALLOC_LOGV("SBWC chroma body size 0x%zx, header size 0x%zx", chroma_body_size, chroma_header_size); + + return { luma_body_size + luma_header_size, + chroma_body_size + chroma_header_size }; +} + +/* + * All setup_<format> function will returns the plane_count + */ + +/* Sets up 8-bit SBWC semi planar and returns the plane count */ +int setup_sbwc_420_sp(int w, int h, int fd_count, plane_info_t *plane) +{ + std::tie(plane[0].size, plane[1].size) = sbwc_sizes<8>(w, h); + + plane[0].alloc_width = GRALLOC_ALIGN(w, 32); + plane[0].alloc_height = __ALIGN_UP(h, 16); + plane[0].byte_stride = SBWC_8B_STRIDE(w); + plane[0].fd_idx = 0; + + plane[1].alloc_width = GRALLOC_ALIGN(w, 32); + plane[1].alloc_height = __ALIGN_UP(h, 16) / 2; + plane[1].byte_stride = SBWC_8B_STRIDE(w); + + if (fd_count > 1) + { + plane[1].fd_idx = 1; + } + else + { + plane[1].fd_idx = 0; + plane[1].offset = plane[0].size; + } + + return 2; +} + +/* Sets up 10-bit SBWC semi planar and returns the plane count */ +int setup_sbwc_420_sp_10bit(int w, int h, int fd_count, plane_info_t *plane) +{ + std::tie(plane[0].size, plane[1].size) = sbwc_sizes<10>(w, h); + + plane[0].alloc_width = GRALLOC_ALIGN(w, 32); + plane[0].alloc_height = __ALIGN_UP(h, 16); + plane[0].byte_stride = SBWC_10B_STRIDE(w); + plane[0].fd_idx = 0; + + plane[1].alloc_width = GRALLOC_ALIGN(w, 32); + plane[1].alloc_height = __ALIGN_UP(h, 16) / 2; + plane[1].byte_stride = SBWC_10B_STRIDE(w); + + if (fd_count > 1) + { + plane[1].fd_idx = 1; + } + else + { + plane[1].fd_idx = 0; + plane[1].offset = plane[0].size; + } + + return 2; +} + +/* Sets up 8-bit Lossy SBWC semi planar and returns the plane count */ +int setup_sbwc_420_sp_lossy(int width, int height, int rate, int fd_count, plane_info_t *plane) +{ + plane[0].size = SBWCL_8B_Y_SIZE(width, height, rate); + plane[0].alloc_width = GRALLOC_ALIGN(width, 32); + plane[0].alloc_height = __ALIGN_UP(height, 8); + plane[0].byte_stride = SBWCL_8B_STRIDE(width, rate); + plane[0].fd_idx = 0; + + plane[1].size = SBWCL_8B_CBCR_SIZE(width, height, rate); + plane[1].alloc_width = GRALLOC_ALIGN(width, 32); + plane[1].alloc_height = __ALIGN_UP(height, 8) / 2; + plane[1].byte_stride = SBWCL_8B_STRIDE(width, rate); + + if (fd_count > 1) + { + plane[1].fd_idx = 1; + } + else + { + plane[1].fd_idx = 0; + plane[1].offset = plane[0].size; + } + + return 2; +} + + +/* Sets up 10-bit Lossy SBWC semi planar and returns the plane count */ +int setup_sbwc_420_sp_10bit_lossy(int width, int height, int rate, int fd_count, plane_info_t *plane) +{ + plane[0].size = SBWCL_10B_Y_SIZE(width, height, rate); + plane[0].alloc_width = GRALLOC_ALIGN(width, 32); + plane[0].alloc_height = __ALIGN_UP(height, 8); + plane[0].byte_stride = SBWCL_10B_STRIDE(width, rate); + plane[0].fd_idx = 0; + + plane[1].size = SBWCL_10B_CBCR_SIZE(width, height, rate); + plane[1].alloc_width = GRALLOC_ALIGN(width, 32); + plane[1].alloc_height = __ALIGN_UP(height, 8) / 2; + plane[1].byte_stride = SBWCL_10B_STRIDE(width, rate); + + if (fd_count > 1) + { + plane[1].fd_idx = 1; + } + else + { + plane[1].fd_idx = 0; + plane[1].offset = plane[0].size; + } + + return 2; +} + +int setup_420_sp(int width, int height, int fd_count, plane_info_t *plane) +{ + /* TODO: make this into an assert instead ? */ + height = GRALLOC_ALIGN(height, 2); + + plane[0].size = PLANE_SIZE(width, height); + plane[0].alloc_width = width; + plane[0].alloc_height = height; + plane[0].byte_stride = width; + plane[0].fd_idx = 0; + + int chroma_width = width; + int chroma_height = height / 2; + + plane[1].size = PLANE_SIZE(chroma_width, chroma_height); + plane[1].alloc_width = chroma_width; + plane[1].alloc_height = chroma_height; + plane[1].byte_stride = chroma_width; + + if (fd_count > 1) + { + plane[1].fd_idx = 1; + } + else + { + plane[1].fd_idx = 0; + plane[1].offset = plane[0].size; + } + + return 2; +} + +int setup_420_sp_s10b(int width, int height, int fd_count, plane_info_t *plane) +{ + /* TODO: make this into an assert instead ? */ + /* TODO: assert height aligned to 16 ? */ + height = GRALLOC_ALIGN(height, 2); + + int mscl_ext = 256; + + /* HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B have special padding requirement */ + if (fd_count == 1) + { + mscl_ext = 64; + } + + plane[0].size = PLANE_SIZE(width, height) + S2B_PLANE_SIZE(width, height) + mscl_ext; + plane[0].alloc_width = width; + plane[0].alloc_height = height; + plane[0].byte_stride = width; + plane[0].fd_idx = 0; + + int chroma_width = width; + int chroma_height = height / 2; + + plane[1].size = PLANE_SIZE(chroma_width, chroma_height) + + S2B_PLANE_SIZE(chroma_width, chroma_height) + mscl_ext; + plane[1].alloc_width = chroma_width; + plane[1].alloc_height = chroma_height; + plane[1].byte_stride = chroma_width; + + if (fd_count > 1) + { + plane[1].fd_idx = 1; + } + else + { + plane[1].fd_idx = 0; + plane[1].offset = plane[0].size; + } + + return 2; +} + +int setup_p010_sp(int width, int height, int fd_count, plane_info_t *plane) +{ + /* TODO: make this into an assert instead ? */ + height = GRALLOC_ALIGN(height, 2); + + plane[0].size = PLANE_SIZE(width * 2, height); + plane[0].alloc_width = width; + plane[0].alloc_height = height; + plane[0].byte_stride = width * 2; + plane[0].fd_idx = 0; + + int chroma_width = width; + int chroma_height = height / 2; + + plane[1].size = PLANE_SIZE(chroma_width * 2, chroma_height); + plane[1].alloc_width = chroma_width; + plane[1].alloc_height = chroma_height; + plane[1].byte_stride = chroma_width * 2; + + if (fd_count > 1) + { + plane[1].fd_idx = 1; + } + else + { + plane[1].fd_idx = 0; + plane[1].offset = plane[0].size; + } + + return 2; +} + +int setup_420_p(int width, int height, int fd_count, plane_info_t *plane) +{ + /* TODO: make this into an assert instead ? */ + width = GRALLOC_ALIGN(width, 2); + height = GRALLOC_ALIGN(height, 2); + + plane[0].size = PLANE_SIZE(width, height); + plane[0].alloc_width = width; + plane[0].alloc_height = height; + plane[0].byte_stride = width; + plane[0].fd_idx = 0; + + int chroma_width = GRALLOC_ALIGN(width / 2, 16); + int chroma_height = height / 2; + + plane[1].size = PLANE_SIZE(chroma_width, chroma_height); + plane[1].alloc_width = chroma_width; + plane[1].alloc_height = chroma_height; + plane[1].byte_stride = chroma_width; + + plane[2].size = PLANE_SIZE(chroma_width, chroma_height); + plane[2].alloc_width = chroma_width; + plane[2].alloc_height = chroma_height; + plane[2].byte_stride = chroma_width; + + if (fd_count > 1) + { + plane[1].fd_idx = 1; + plane[2].fd_idx = 2; + } + else + { + plane[1].fd_idx = 0; + plane[2].fd_idx = 0; + plane[1].offset = plane[0].size; + plane[2].offset = plane[0].size + plane[1].size; + } + + return 3; +} + +int setup_420_sp_tiled(int width, int height, int fd_count, plane_info_t *plane) +{ + /* TODO: make this into an assert instead ? */ + width = GRALLOC_ALIGN(width, 2); + height = GRALLOC_ALIGN(height, 2); + + plane[0].size = PLANE_SIZE(width, height); + plane[0].alloc_width = width; + plane[0].alloc_height = height; + plane[0].byte_stride = width * 16; + plane[0].fd_idx = 0; + + int chroma_width = width; + int chroma_height = GRALLOC_ALIGN(height / 2, 32); + + plane[1].size = PLANE_SIZE(chroma_width, chroma_height); + plane[1].alloc_width = chroma_width; + plane[1].alloc_height = chroma_height; + plane[1].byte_stride = chroma_width * 16; + + if (fd_count > 1) + { + plane[1].fd_idx = 1; + } + else + { + plane[1].fd_idx = 0; + plane[1].offset = plane[0].size; + } + + return 3; +} diff --git a/GrallocHAL/src/core/format_info.cpp b/GrallocHAL/src/core/format_info.cpp new file mode 100644 index 0000000..c6f707c --- /dev/null +++ b/GrallocHAL/src/core/format_info.cpp @@ -0,0 +1,611 @@ +/* + * Copyright (C) 2018-2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <inttypes.h> +#include "gralloc_helper.h" +#include "mali_gralloc_formats.h" +#include "format_info.h" +#include "mali_gralloc_usages.h" +#include <exynos_format.h> + +#include <unordered_map> +#include <mutex> + +/* Default width aligned to whole pixel (CPU access). */ +#define ALIGN_W_CPU_DEFAULT .align_w_cpu = 1 + +#define ID(x) .id = x, .name = #x + +/* + * Format table, containing format properties. + * + * NOTE: This table should only be used within + * the gralloc library and not by clients directly. + */ +const format_info_t formats[] = { + /* BEGIN ALIGNED SECTION */ + { ID(MALI_GRALLOC_FORMAT_INTERNAL_RGB_565), .npln = 1, .ncmp = { 3, 0, 0 }, .bps = 6, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_RGB_888), .npln = 1, .ncmp = { 3, 0, 0 }, .bps = 8, .bpp_afbc = { 24, 0, 0 }, .bpp = { 24, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888), .npln = 1, .ncmp = { 4, 0, 0 }, .bps = 8, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = true, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888), .npln = 1, .ncmp = { 4, 0, 0 }, .bps = 8, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = true, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888), .npln = 1, .ncmp = { 3, 0, 0 }, .bps = 8, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102), .npln = 1, .ncmp = { 4, 0, 0 }, .bps = 10, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = true, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616), .npln = 1, .ncmp = { 4, 0, 0 }, .bps = 16, .bpp_afbc = { 64, 0, 0 }, .bpp = { 64, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = true, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_Y8), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 8, .bpp_afbc = { 8, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_Y16), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 16, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 1, .vsub = 1, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + /* 420 (8-bit) */ + { ID(MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I), .npln = 1, .ncmp = { 3, 0, 0 }, .bps = 8, .bpp_afbc = { 12, 0, 0 }, .bpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = false, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_NV12), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 8, 16, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_NV21), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 8, 16, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_YV12), .npln = 3, .ncmp = { 1, 1, 1 }, .bps = 8, .bpp_afbc = { 8, 8, 8 }, .bpp = { 8, 8, 8 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + /* 422 (8-bit) */ + { ID(MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT), .npln = 1, .ncmp = { 3, 0, 0 }, .bps = 8, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 2, .vsub = 1, .align_w = 2, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_NV16), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 8, 16, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 1, .align_w = 2, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + /* 420 (10-bit) */ + { ID(MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I), .npln = 1, .ncmp = { 3, 0, 0 }, .bps = 10, .bpp_afbc = { 15, 0, 0 }, .bpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = false, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_Y0L2), .npln = 1, .ncmp = { 4, 0, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 2, .has_alpha = true, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_P010), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 10, 20, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + /* 422 (10-bit) */ + { ID(MALI_GRALLOC_FORMAT_INTERNAL_Y210), .npln = 1, .ncmp = { 3, 0, 0 }, .bps = 10, .bpp_afbc = { 20, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 2, .vsub = 1, .align_w = 2, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_P210), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 10, 20, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 1, .align_w = 2, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + /* 444 (10-bit) */ + { ID(MALI_GRALLOC_FORMAT_INTERNAL_YUV444_10BIT_I), .npln = 1, .ncmp = { 3, 0, 0 }, .bps = 10, .bpp_afbc = { 30, 0, 0 }, .bpp = { 0, 0, 0 }, .hsub = 1, .vsub = 1, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = false, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_Y410), .npln = 1, .ncmp = { 4, 0, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 1, .vsub = 1, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = true, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + /* Other */ + { ID(MALI_GRALLOC_FORMAT_INTERNAL_RAW16), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 16, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_RAW12), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 12, .bpp_afbc = { 0, 0, 0 }, .bpp = { 12, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 4, .align_h = 2, .align_w_cpu = 4, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_RAW10), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 10, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 4, .align_h = 2, .align_w_cpu = 4, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_BLOB), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + /* Depth and Stencil */ + { ID(MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_16), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 16, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 24, .bpp_afbc = { 0, 0, 0 }, .bpp = { 24, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24_STENCIL_8), .npln = 1, .ncmp = { 2, 0, 0 }, .bps = 24, .bpp_afbc = { 0, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 32, .bpp_afbc = { 0, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F_STENCIL_8), .npln = 1, .ncmp = { 2, 0, 0 }, .bps = 32, .bpp_afbc = { 0, 0, 0 }, .bpp = { 40, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + { ID(MALI_GRALLOC_FORMAT_INTERNAL_STENCIL_8), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false }, + /* Exynos Formats */ + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 16, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YV12_M), .npln = 3, .ncmp = { 1, 1, 1 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 8, 8 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M), .npln = 3, .ncmp = { 1, 1, 1 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 8, 8 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P), .npln = 3, .ncmp = { 1, 1, 1 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 8, 8 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_YCrCb_420_SP), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + + /* SBWC Formats */ + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + + /* Google Formats */ + { ID(HAL_PIXEL_FORMAT_GOOGLE_NV12_SP), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 64, .align_h = 8, .align_w_cpu = 64, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = true }, + { ID(HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 64, .align_h = 8, .align_w_cpu = 64, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = true }, + { ID(HAL_PIXEL_FORMAT_GOOGLE_R_8), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 8, .bpp_afbc = { 8, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + { ID(HAL_PIXEL_FORMAT_GOOGLE_RG_88), .npln = 1, .ncmp = { 2, 0, 0 }, .bps = 8, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, + /* END ALIGNED SECTION */ +}; +const size_t num_formats = sizeof(formats)/sizeof(formats[0]); + +/* + * This table represents the superset of flags for each base format and producer/consumer. + * Where IP does not support a capability, it should be defined and not set. + */ +const format_ip_support_t formats_ip_support[] = { + /* BEGIN ALIGNED SECTION */ + /* TODO(b/189467474) AFBC disabled on the GPU for RGB_565 due to color swap in Vulkan */ + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGB_565, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_NONE, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGB_888, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_LIN, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_LIN, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_LIN, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_LIN, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_LIN, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y8, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y16, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + /* 420 (8-bit) */ + { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I, .cpu_rd = F_NONE, .cpu_wr = F_NONE, .gpu_rd = F_AFBC, .gpu_wr = F_NONE, .dpu_rd = F_AFBC, .dpu_wr = F_NONE, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_AFBC, .vpu_wr = F_AFBC, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV12, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV21, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_YV12, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_LIN, }, + /* 422 (8-bit) */ + { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_NONE, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV16, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + /* 420 (10-bit) */ + { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I, .cpu_rd = F_NONE, .cpu_wr = F_NONE, .gpu_rd = F_AFBC, .gpu_wr = F_AFBC, .dpu_rd = F_AFBC, .dpu_wr = F_NONE, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_AFBC, .vpu_wr = F_AFBC, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y0L2, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_P010, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_NONE, }, + /* 422 (10-bit) */ + { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y210, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_P210, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + /* 444 (10-bit) */ + { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV444_10BIT_I, .cpu_rd = F_NONE, .cpu_wr = F_NONE, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y410, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + /* Other */ + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW16, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW12, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW10, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_BLOB, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + /* Depth and Stencil */ + { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_16, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24_STENCIL_8, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F_STENCIL_8, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_STENCIL_8, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + /* END ALIGNED SECTION */ + + /* Exynos Formats */ + /* BEGIN ALIGNED SECTION */ + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YV12_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_YCrCb_420_SP, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + + /* SBWC Formats */ + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN }, + /* END ALIGNED SECTION */ + + /* Google formats */ + /* BEGIN ALIGNED SECTION */ + { .id = HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN, .cam_wr = F_LIN }, + { .id = HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN, .cam_wr = F_LIN }, + { .id = HAL_PIXEL_FORMAT_GOOGLE_R_8, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN|F_AFBC, .gpu_rd = F_LIN|F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_NONE, .vpu_rd = F_NONE, .cam_wr = F_LIN }, + { .id = HAL_PIXEL_FORMAT_GOOGLE_RG_88, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN|F_AFBC, .gpu_rd = F_LIN|F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_NONE, .vpu_rd = F_NONE, .cam_wr = F_LIN }, + /* END ALIGNED SECTION */ +}; + +const size_t num_ip_formats = sizeof(formats_ip_support)/sizeof(formats_ip_support[0]); + +typedef struct +{ + uint32_t hal_format; + bool is_flex; + uint32_t internal_format; +} hal_int_fmt; + + +static const hal_int_fmt hal_to_internal_format[] = +{ + { HAL_PIXEL_FORMAT_RGBA_8888, false, MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888 }, + { HAL_PIXEL_FORMAT_RGBX_8888, false, MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888 }, + { HAL_PIXEL_FORMAT_RGB_888, false, MALI_GRALLOC_FORMAT_INTERNAL_RGB_888 }, + { HAL_PIXEL_FORMAT_RGB_565, false, MALI_GRALLOC_FORMAT_INTERNAL_RGB_565 }, + { HAL_PIXEL_FORMAT_BGRA_8888, false, MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888 }, + { HAL_PIXEL_FORMAT_YCbCr_422_SP, false, MALI_GRALLOC_FORMAT_INTERNAL_NV16 }, + { HAL_PIXEL_FORMAT_YCrCb_420_SP, false, MALI_GRALLOC_FORMAT_INTERNAL_NV21 }, + { HAL_PIXEL_FORMAT_YCbCr_422_I, false, MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT }, + { HAL_PIXEL_FORMAT_RGBA_FP16, false, MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 }, + { HAL_PIXEL_FORMAT_RAW16, false, MALI_GRALLOC_FORMAT_INTERNAL_RAW16 }, + { HAL_PIXEL_FORMAT_BLOB, false, MALI_GRALLOC_FORMAT_INTERNAL_BLOB }, + { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, true, MALI_GRALLOC_FORMAT_INTERNAL_NV12 }, + { HAL_PIXEL_FORMAT_YCbCr_420_888, true, MALI_GRALLOC_FORMAT_INTERNAL_NV12 }, + { HAL_PIXEL_FORMAT_RAW_OPAQUE, false, MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED }, + { HAL_PIXEL_FORMAT_RAW10, false, MALI_GRALLOC_FORMAT_INTERNAL_RAW10 }, + { HAL_PIXEL_FORMAT_RAW12, false, MALI_GRALLOC_FORMAT_INTERNAL_RAW12 }, + { HAL_PIXEL_FORMAT_YCbCr_422_888, true, MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT }, + { HAL_PIXEL_FORMAT_YCbCr_444_888, true, MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED }, + { HAL_PIXEL_FORMAT_FLEX_RGB_888, true, MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED }, + { HAL_PIXEL_FORMAT_FLEX_RGBA_8888, true, MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED }, + { HAL_PIXEL_FORMAT_RGBA_1010102, false, MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 }, + { HAL_PIXEL_FORMAT_DEPTH_16, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_16 }, + { HAL_PIXEL_FORMAT_DEPTH_24, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24 }, + { HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24_STENCIL_8 }, + { HAL_PIXEL_FORMAT_DEPTH_32F, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F }, + { HAL_PIXEL_FORMAT_DEPTH_32F_STENCIL_8, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F_STENCIL_8 }, + { HAL_PIXEL_FORMAT_STENCIL_8, false, MALI_GRALLOC_FORMAT_INTERNAL_STENCIL_8 }, + { HAL_PIXEL_FORMAT_YCBCR_P010, false, MALI_GRALLOC_FORMAT_INTERNAL_P010 }, + { HAL_PIXEL_FORMAT_Y8, false, MALI_GRALLOC_FORMAT_INTERNAL_Y8 }, + { HAL_PIXEL_FORMAT_Y16, false, MALI_GRALLOC_FORMAT_INTERNAL_Y16 }, + { HAL_PIXEL_FORMAT_YV12, false, MALI_GRALLOC_FORMAT_INTERNAL_YV12 }, + /* Exynos Formats */ + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, true, MALI_GRALLOC_FORMAT_INTERNAL_NV12 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, false, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M }, + { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, false, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M }, + { HAL_PIXEL_FORMAT_EXYNOS_YV12_M, false, HAL_PIXEL_FORMAT_EXYNOS_YV12_M }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED}, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P }, + /* SBWC Formats */ + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC }, + { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC }, + { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC }, + + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60 }, + { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80 }, + + /* Google Formats */ + { HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, true, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP }, + { HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, true, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B }, + { HAL_PIXEL_FORMAT_GOOGLE_R_8, true, HAL_PIXEL_FORMAT_GOOGLE_R_8 }, + { HAL_PIXEL_FORMAT_GOOGLE_RG_88, true, HAL_PIXEL_FORMAT_GOOGLE_RG_88 }, + { MALI_GRALLOC_FORMAT_INTERNAL_R_8, false, HAL_PIXEL_FORMAT_GOOGLE_R_8 }, +}; + +const size_t num_hal_formats = sizeof(hal_to_internal_format)/sizeof(hal_to_internal_format[0]); + + +/* + * Finds "Look-up Table" index for the given format + * + * @param base_format [in] Format for which index is required. + * + * @return index, when the format is found in the look up table + * -1, otherwise + * + */ +int32_t get_format_index(const uint32_t base_format) +{ + int32_t format_idx; + for (format_idx = 0; format_idx < (int32_t)num_formats; format_idx++) + { + if (formats[format_idx].id == base_format) + { + break; + } + } + if (format_idx >= (int32_t)num_formats) + { + MALI_GRALLOC_LOGE("ERROR: Format allocation info not found for format: %" PRIx32, base_format); + return -1; + } + + return format_idx; +} + + +int32_t get_ip_format_index(const uint32_t base_format) +{ + int32_t format_idx; + for (format_idx = 0; format_idx < (int32_t)num_ip_formats; format_idx++) + { + if (formats_ip_support[format_idx].id == base_format) + { + break; + } + } + if (format_idx >= (int32_t)num_ip_formats) + { + MALI_GRALLOC_LOGE("ERROR: IP support not found for format: %" PRIx32, base_format); + return -1; + } + + return format_idx; +} + + +/* + * Attempt to map base HAL format to an internal format and + * validate format is supported for allocation. + * + * @param map_to_internal [in] 1: Forces mapping to (and validation of) internal format + * 0: Only maps flex HAL formats to internal + * + * @return internal_format, where internal format is found + * HAL format, where map_to_internal == 0 and base_format is not flex + * MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED, otherwise + * + * NOTE: Base format might be either a HAL format or (already) an internal format. + * + */ +uint32_t get_internal_format(const uint32_t base_format, const bool map_to_internal) +{ + uint32_t internal_format = base_format; + + for (int idx = 0; idx < (int)num_hal_formats; idx++) + { + if (hal_to_internal_format[idx].hal_format == base_format) + { + if (hal_to_internal_format[idx].is_flex || map_to_internal) + { + internal_format = hal_to_internal_format[idx].internal_format; + } + break; + } + } + + /* Ensure internal format is valid when expected. */ + if (map_to_internal && get_format_index(internal_format) < 0) + { + internal_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED; + } + + return internal_format; +} + + +/* Get the dataspace to use based on private usage and format. */ +void get_format_dataspace(uint32_t base_format, + uint64_t usage, + int width, + int height, + android_dataspace_t *dataspace) +{ + GRALLOC_UNUSED(usage); + + uint64_t color_space = HAL_DATASPACE_STANDARD_UNSPECIFIED; + uint64_t range = HAL_DATASPACE_RANGE_UNSPECIFIED; + *dataspace = HAL_DATASPACE_UNKNOWN; + + const int32_t format_idx = get_format_index(base_format); + if (format_idx < 0) + { + return; + } + + /* This resolution is the cut-off point at which BT709 is used (as default) + * instead of BT601 for YUV formats < 10 bits. + */ + constexpr int yuv_bt601_max_width = 1280; + constexpr int yuv_bt601_max_height = 720; + + if (formats[format_idx].is_yuv) + { + /* Default YUV dataspace. */ + color_space = HAL_DATASPACE_STANDARD_BT709; + range = HAL_DATASPACE_RANGE_LIMITED; + + /* 10-bit YUV is assumed to be wide BT2020. + */ + if (formats[format_idx].bps >= 10) + { + color_space = HAL_DATASPACE_STANDARD_BT2020; + range = HAL_DATASPACE_RANGE_FULL; + } + else if (width < yuv_bt601_max_width || height < yuv_bt601_max_height) + { + color_space = HAL_DATASPACE_STANDARD_BT601_625; + range = HAL_DATASPACE_RANGE_LIMITED; + } + + *dataspace = static_cast<android_dataspace_t>(color_space | range); + } + else if (formats[format_idx].is_rgb) + { + /* Default RGB dataspace. Expected by Mapper VTS. */ + *dataspace = static_cast<android_dataspace_t>(HAL_DATASPACE_UNKNOWN); + } +} + + +bool sanitize_formats(void) +{ + bool fail = false; + + for (int i = 0; i < (int)num_formats; i++) + { + const format_info_t * format = &formats[i]; + + /* Identify invalid values. */ + if (format->id == 0 || + format->npln == 0 || format->npln > 3 || + format->total_components() == 0 || + format->bps == 0 || + format->align_w == 0 || + format->align_h == 0 || + format->align_w_cpu == 0 || + format->tile_size == 0) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] property zero/out of range (unexpected)", format->id); + fail = true; + } + + if (format->is_rgb && format->is_yuv) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] cannot be both RGB and YUV", format->id); + fail = true; + } + + if (format->npln > format->total_components()) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] planes cannot exceed components", format->id); + fail = true; + } + + if (format->linear && (format->bps > format->bpp[0])) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] bpp should be greater than/equal to bps", format->id); + fail = true; + } + + if (format->afbc && (format->bps > format->bpp_afbc[0])) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] bpp_afbc should be greater than/equal to bps", format->id); + fail = true; + } + + if (!format->linear && format->tile_size > 1) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] tile_size must be set to 1 for formats without linear support", format->id); + fail = true; + } + + for (int pln = 0; pln < 3; pln++) + { + if (format->linear && (pln < format->npln) && (format->bpp[pln] == 0)) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] does not have bpp defined for plane: %d", format->id, pln); + fail = true; + } + else if (format->linear && (pln >= format->npln) && (format->bpp[pln] != 0)) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] should not have bpp defined for plane: %d", format->id, pln); + fail = true; + } + else if (!format->linear && (format->bpp[pln] != 0)) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] which doesn't support linear should not have bpp defined", format->id); + fail = true; + } + + if (format->afbc && (pln < format->npln) && (format->bpp_afbc[pln] == 0)) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] does not have bpp_afbc defined for plane: %d", format->id, pln); + fail = true; + } + else if (format->afbc && (pln >= format->npln) && (format->bpp_afbc[pln] != 0)) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] should not have bpp_afbc defined for plane: %d", format->id, pln); + fail = true; + } + else if (!format->afbc && (format->bpp_afbc[pln] != 0)) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] which doesn't support afbc should not have bpp defined", format->id); + fail = true; + } + } + + if (format->is_yuv) + { + if (format->hsub == 0 || format->vsub == 0) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] hsub and vsub should be non-zero (YUV)", format->id); + fail = true; + } + + if (!is_power2(format->hsub) || !is_power2(format->vsub)) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] hsub and vsub should be powers of 2", format->id); + fail = true; + } + + if ((format->align_w % format->hsub) != 0) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] align_w should be a multiple of hsub", format->id); + fail = true; + } + + if ((format->align_h % format->vsub) != 0) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] align_h should be a multiple of vsub", format->id); + fail = true; + } + } + else + { + if (format->hsub != 0 || format->vsub != 0) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] hsub and vsub should be zero (non-YUV)", format->id); + fail = true; + } + } + + if (format->align_w == 0 || format->align_h == 0) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] align_w and align_h should be non-zero", format->id); + fail = true; + } + else + { + if (!is_power2(format->align_w) || !is_power2(format->align_h)) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] align_w and align_h should be powers of 2", format->id); + fail = true; + } + + if (!is_power2(format->align_w_cpu)) + { + MALI_GRALLOC_LOGE("Format [id:0x%" PRIx32 "] align_w_cpu should be a power of 2", format->id); + fail = true; + } + } + } + + return fail; +} + +const char *format_name(uint32_t base_format) { + static std::once_flag name_map_flag; + using NameMap = std::unordered_map<uint32_t, const char*>; + static NameMap name_map; + + std::call_once(name_map_flag, []() { + for (size_t i = 0; i < num_formats; ++i) { + const format_info_t &format = formats[i]; + if (name_map.count(format.id)) { + ALOGE("Format id 0x%" PRIx32 " mapped to %s and to %s", + format.id, name_map[format.id], format.name); + } else { + name_map[format.id] = format.name; + } + } + }); + + NameMap::const_iterator i = name_map.find(base_format); + if (i == name_map.end()) { + return "<unrecognized format>"; + } + return i->second; +} diff --git a/gralloc3/src/format_info.h b/GrallocHAL/src/core/format_info.h index 023ac58..ad2db6d 100644 --- a/gralloc3/src/format_info.h +++ b/GrallocHAL/src/core/format_info.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019 ARM Limited. All rights reserved. + * Copyright (C) 2018-2020 ARM Limited. All rights reserved. * * Copyright (C) 2008 The Android Open Source Project * @@ -19,9 +19,10 @@ #ifndef FORMAT_INFO_H_ #define FORMAT_INFO_H_ -#include "exynos_format.h" #include "mali_gralloc_buffer.h" +typedef uint8_t format_support_flags; + /* Base format unsupported */ #define F_NONE 0 /* Base format supports uncompressed */ @@ -31,12 +32,17 @@ /* Base format supports AFBC with different swizzle */ #define F_AFBC_SWIZ ((uint8_t)1 << 2) + typedef struct { uint16_t width; uint16_t height; } rect_t; +constexpr bool is_power2(uint8_t n) +{ + return ((n & (n-1)) == 0); +} /* * Pixel format information. @@ -48,7 +54,7 @@ typedef struct { uint32_t id; /* Format ID. */ uint8_t npln; /* Number of planes. */ - uint8_t ncmp; /* Number of components. */ + uint8_t ncmp[MAX_PLANES]; /* Number of components in each plane. */ uint8_t bps; /* Bits per sample (primary/largest). */ uint8_t bpp_afbc[MAX_PLANES]; /* Bits per pixel (AFBC), without implicit padding. 'X' in RGBX is still included. */ uint8_t bpp[MAX_PLANES]; /* Bits per pixel (linear/uncompressed), including any implicit sample padding defined by format (e.g. 10-bit Y210 padded to 16-bits). @@ -66,22 +72,33 @@ typedef struct bool linear; /* Linear/uncompressed supported. */ bool yuv_transform; /* Supports AFBC YUV transform: 3+ channel RGB (strict R-G-B-? order) with less than 12-bit per sample. */ bool flex; /* Linear version of format can be represented as flex. */ - bool planes_contiguous; /* True if all planes in format are contiguous in memory. Has no effect on non-planar formats */ + bool planes_contiguous; /* True if all planes in format are contiguous in memory. Has no effect on non-planar formats. */ const char *name; /* Human-readable name. */ + /* Computes the total number of components in the format. */ + int total_components() const + { + int sum = 0; + for (auto n: ncmp) + { + sum += n; + } + return sum; + } } format_info_t; typedef struct { - uint32_t id; /* Format ID. */ - uint8_t cpu_wr; /* CPU producer. */ - uint8_t cpu_rd; /* CPU consumer. */ - uint8_t gpu_wr; /* GPU producer. */ - uint8_t gpu_rd; /* GPU consumer. */ - uint8_t dpu_wr; /* DPU producer. */ - uint8_t dpu_rd; /* DPU consumer. */ - uint8_t dpu_aeu_wr; /* DPU AEU producer. */ - uint8_t vpu_wr; /* VPU producer. */ - uint8_t vpu_rd; /* VPU consumer. */ + uint32_t id; /* Format ID. */ + format_support_flags cpu_wr; /* CPU producer. */ + format_support_flags cpu_rd; /* CPU consumer. */ + format_support_flags gpu_wr; /* GPU producer. */ + format_support_flags gpu_rd; /* GPU consumer. */ + format_support_flags dpu_wr; /* DPU producer. */ + format_support_flags dpu_rd; /* DPU consumer. */ + format_support_flags dpu_aeu_wr; /* DPU AEU producer. (UNUSED IN EXYNOS) */ + format_support_flags vpu_wr; /* VPU producer. */ + format_support_flags vpu_rd; /* VPU consumer. */ + format_support_flags cam_wr; /* Camera producer. */ } format_ip_support_t; @@ -94,6 +111,11 @@ extern const size_t num_ip_formats; extern int32_t get_format_index(const uint32_t base_format); extern int32_t get_ip_format_index(const uint32_t base_format); extern uint32_t get_internal_format(const uint32_t base_format, const bool map_to_internal); +void get_format_dataspace(uint32_t base_format, + uint64_t usage, + int width, + int height, + android_dataspace_t *dataspace); extern bool sanitize_formats(void); extern const char *format_name(const uint32_t base_format); diff --git a/GrallocHAL/src/core/mali_gralloc_bufferaccess.cpp b/GrallocHAL/src/core/mali_gralloc_bufferaccess.cpp new file mode 100644 index 0000000..6740556 --- /dev/null +++ b/GrallocHAL/src/core/mali_gralloc_bufferaccess.cpp @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2016-2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <errno.h> +#include <inttypes.h> +#include <inttypes.h> +/* For error codes. */ +#include <hardware/gralloc1.h> + +#include "mali_gralloc_buffer.h" +#include "mali_gralloc_formats.h" +#include "mali_gralloc_usages.h" +#include "mali_gralloc_reference.h" +#include "allocator/mali_gralloc_ion.h" +#include "gralloc_helper.h" +#include "format_info.h" + + +enum tx_direction +{ + TX_NONE = 0, + TX_TO_DEVICE, + TX_FROM_DEVICE, + TX_BOTH, +}; + + +static enum tx_direction get_tx_direction(const uint64_t usage) +{ + const bool read = (usage & GRALLOC_USAGE_SW_READ_MASK) ? true : false; + const bool write = (usage & GRALLOC_USAGE_SW_WRITE_MASK) ? true : false; + enum tx_direction dir = TX_NONE; + + if (read && write) + { + dir = TX_BOTH; + } + else if (write) + { + dir = TX_TO_DEVICE; + } + else if (read) + { + dir = TX_FROM_DEVICE; + } + + return dir; +} + +static void buffer_sync(private_handle_t * const hnd, + const enum tx_direction direction) +{ + if (direction != TX_NONE) + { + hnd->cpu_read = (direction == TX_FROM_DEVICE || direction == TX_BOTH) ? 1 : 0; + hnd->cpu_write = (direction == TX_TO_DEVICE || direction == TX_BOTH) ? 1 : 0; + +#if defined(GRALLOC_ION_SYNC_ON_LOCK) && GRALLOC_ION_SYNC_ON_LOCK == 1 + const int status = mali_gralloc_ion_sync_start(hnd, + hnd->cpu_read ? true : false, + hnd->cpu_write ? true : false); + if (status < 0) + { + return; + } +#endif + } + else if (hnd->cpu_read || hnd->cpu_write) + { +#if defined(GRALLOC_ION_SYNC_ON_LOCK) && GRALLOC_ION_SYNC_ON_LOCK == 1 + const int status = mali_gralloc_ion_sync_end(hnd, + hnd->cpu_read ? true : false, + hnd->cpu_write ? true : false); + if (status < 0) + { + return; + } +#endif + hnd->cpu_read = 0; + hnd->cpu_write = 0; + } +} + + +/* + * Validates input parameters of lock request. + * + * @param buffer [in] The buffer to lock. + * @param l [in] Access region left offset (in pixels). + * @param t [in] Access region top offset (in pixels). + * @param w [in] Access region requested width (in pixels). + * @param h [in] Access region requested height (in pixels). + * @param usage [in] Lock request (producer and consumer combined) usage. + * + * @return 0,for valid input parameters; + * -EINVAL, for erroneous input parameters + */ +int validate_lock_input_parameters(const buffer_handle_t buffer, const int l, + const int t, const int w, const int h, + uint64_t usage) +{ + bool is_registered_process = false; + const int lock_pid = getpid(); + const private_handle_t * const hnd = (private_handle_t *)buffer; + + /* TODO: do not check access region for blob formats. + * This is because codec2 attempts to lock with wrong access region. + * Ask Google to fix codec2 + */ + if (hnd->get_alloc_format() != HAL_PIXEL_FORMAT_BLOB) + { + if ((l < 0) || (t < 0) || (w < 0) || (h < 0)) + { + MALI_GRALLOC_LOGW("Negative values for access region (l = %d t = %d w = %d and " + "h = %d) in buffer lock request are invalid. Locking PID:%d", + l, t, w, h, lock_pid); + return -EINVAL; + } + + /* Test overflow conditions on access region parameters */ + if (((l + w) < 0) || ((t + h) < 0)) + { + MALI_GRALLOC_LOGW("Encountered overflow with access region (l = %d t = %d w = %d and" + " h = %d) in buffer lock request. Locking PID:%d", + l, t, w, h, lock_pid); + return -EINVAL; + } + + /* Region of interest shall be inside the allocated buffer */ + if (((t + h) > hnd->height) || ((l + w) > hnd->width)) + { + MALI_GRALLOC_LOGW("Buffer lock access region (l = %d t = %d w = %d " + "and h = %d) is outside allocated buffer (width = %d and height = %d)" + " Locking PID:%d", l, t, w, h, hnd->width, hnd->height, lock_pid); + return -EINVAL; + } + } + + /* Locking process should have a valid buffer virtual address. A process + * will have a valid buffer virtual address if it is the allocating + * process or it retained / registered a cloned buffer handle + */ + if ((hnd->allocating_pid == lock_pid) || (hnd->remote_pid == lock_pid)) + { + is_registered_process = true; + } + + /* TODO: differentiate between mappable and unmappable(secure, hfr etc) buffers */ + if (is_registered_process == false) + { + MALI_GRALLOC_LOGE("The buffer must be retained before lock request"); + return -EINVAL; + } + + /* Reject lock requests for AFBC (compressed format) enabled buffers */ + if ((hnd->alloc_format & MALI_GRALLOC_INTFMT_EXT_MASK) != 0) + { + MALI_GRALLOC_LOGE("Lock is not supported for AFBC enabled buffers." + "Internal Format:0x%" PRIx64, hnd->alloc_format); + + return GRALLOC1_ERROR_UNSUPPORTED; + } + + /* Producer and consumer usage is verified in gralloc1 specific code. */ + GRALLOC_UNUSED(usage); + + return 0; +} + + +/* + * Locks the given buffer for the specified CPU usage. + * + * @param m [in] Gralloc module. + * @param buffer [in] The buffer to lock. + * @param usage [in] Producer and consumer combined usage. + * @param l [in] Access region left offset (in pixels). + * @param t [in] Access region top offset (in pixels). + * @param w [in] Access region requested width (in pixels). + * @param h [in] Access region requested height (in pixels). + * @param vaddr [out] To be filled with a CPU-accessible pointer to + * the buffer data for CPU usage. + * + * @return 0, when the locking is successful; + * Appropriate error, otherwise + * + * @Note: There is no way to ascertain whether buffer data is valid or not (for + * example, establishing if the h/w needs to finish rendering or if CPU + * caches need to be synchronized). + * + * @Note: Locking a buffer simultaneously for write or read/write leaves the + * buffer's content in an indeterminate state. + */ +int mali_gralloc_lock(buffer_handle_t buffer, + uint64_t usage, int l, int t, int w, int h, void **vaddr) +{ + int status; + + if (private_handle_t::validate(buffer) < 0) + { + MALI_GRALLOC_LOGE("Locking invalid buffer %p, returning error", buffer); + return -EINVAL; + } + + /* Validate input parameters for lock request */ + status = validate_lock_input_parameters(buffer, l, t, w, h, usage); + if (status != 0) + { + return status; + } + + private_handle_t *hnd = (private_handle_t *)buffer; + + const int32_t format_idx = get_format_index(hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); + if (format_idx == -1) + { + MALI_GRALLOC_LOGE("Corrupted buffer format (%s 0x%" PRIx64 ") of buffer %p", + format_name(hnd->alloc_format), hnd->alloc_format, hnd); + return -EINVAL; + } + + /* Populate CPU-accessible pointer when requested for CPU usage */ + if ((usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) != 0) + { + if (vaddr == NULL) + { + return -EINVAL; + } + + mali_gralloc_reference_map(buffer); + + *vaddr = (void *)hnd->bases[0]; + + buffer_sync(hnd, get_tx_direction(usage)); + } + + return 0; +} + + +/* + * Unlocks the given buffer. + * + * @param m [in] Gralloc module. + * @param buffer [in] The buffer to unlock. + * + * @return 0, when the locking is successful; + * Appropriate error, otherwise + * + * Note: unlocking a buffer which is not locked results in an unexpected behaviour. + * Though it is possible to create a state machine to track the buffer state to + * recognize erroneous conditions, it is expected of client to adhere to API + * call sequence + */ +int mali_gralloc_unlock(buffer_handle_t buffer) +{ + if (private_handle_t::validate(buffer) < 0) + { + MALI_GRALLOC_LOGE("Unlocking invalid buffer %p, returning error", buffer); + return -EINVAL; + } + + private_handle_t *hnd = (private_handle_t *)buffer; + buffer_sync(hnd, TX_NONE); + + return 0; +} diff --git a/GrallocHAL/src/core/mali_gralloc_bufferaccess.h b/GrallocHAL/src/core/mali_gralloc_bufferaccess.h new file mode 100644 index 0000000..a6f9f0c --- /dev/null +++ b/GrallocHAL/src/core/mali_gralloc_bufferaccess.h @@ -0,0 +1,34 @@ + +/* + * Copyright (C) 2016-2017, 2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MALI_GRALLOC_BUFFERACCESS_H_ +#define MALI_GRALLOC_BUFFERACCESS_H_ + +#include "gralloc_priv.h" + +int mali_gralloc_lock(buffer_handle_t buffer, uint64_t usage, int l, int t, int w, int h, + void **vaddr); +int mali_gralloc_lock_ycbcr(buffer_handle_t buffer, uint64_t usage, int l, int t, int w, + int h, android_ycbcr *ycbcr); +int mali_gralloc_unlock(buffer_handle_t buffer); + +int mali_gralloc_get_num_flex_planes(buffer_handle_t buffer, uint32_t *num_planes); +int mali_gralloc_lock_flex(buffer_handle_t buffer, uint64_t usage, int l, int t, + int w, int h, struct android_flex_layout *flex_layout); + +#endif /* MALI_GRALLOC_BUFFERACCESS_H_ */ diff --git a/GrallocHAL/src/core/mali_gralloc_bufferallocation.cpp b/GrallocHAL/src/core/mali_gralloc_bufferallocation.cpp new file mode 100644 index 0000000..a570723 --- /dev/null +++ b/GrallocHAL/src/core/mali_gralloc_bufferallocation.cpp @@ -0,0 +1,1179 @@ +/* + * Copyright (C) 2016-2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <inttypes.h> +#include <assert.h> +#include <atomic> +#include <algorithm> + +#include <hardware/hardware.h> +#include <hardware/gralloc1.h> + +#include "mali_gralloc_bufferallocation.h" +#include "allocator/mali_gralloc_ion.h" +#include "allocator/mali_gralloc_shared_memory.h" +#include "mali_gralloc_buffer.h" +#include "mali_gralloc_bufferdescriptor.h" +#include "mali_gralloc_debug.h" +#include "mali_gralloc_log.h" +#include "format_info.h" +#include <exynos_format.h> +#include "exynos_format_allocation.h" + +#define EXT_SIZE 256 + +/* Default align values for Exynos */ +#define YUV_BYTE_ALIGN_DEFAULT 16 +#define RGB_BYTE_ALIGN_DEFAULT 64 + +/* IP-specific align values */ +#define GPU_BYTE_ALIGN_DEFAULT 64 + +/* Always CPU align for Exynos */ +#define CAN_SKIP_CPU_ALIGN 0 + +/* Realign YV12 format so that chroma stride is half of luma stride */ +#define REALIGN_YV12 1 + +/* TODO: set S10B format align in BoardConfig.mk */ +#define BOARD_EXYNOS_S10B_FORMAT_ALIGN 64 +#if 0 +ifeq ($(BOARD_EXYNOS_S10B_FORMAT_ALIGN), 64) +LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=$(BOARD_EXYNOS_S10B_FORMAT_ALIGN) +else +LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=16 +endif +#endif + +#define AFBC_PIXELS_PER_BLOCK 256 +#define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY 16 + +bool afbc_format_fallback(uint32_t * const format_idx, const uint64_t usage, bool force); + + +/* + * Get a global unique ID + */ +static uint64_t getUniqueId() +{ + static std::atomic<uint32_t> counter(0); + uint64_t id = static_cast<uint64_t>(getpid()) << 32; + return id | counter++; +} + +static void afbc_buffer_align(const bool is_tiled, int *size) +{ + const uint16_t AFBC_BODY_BUFFER_BYTE_ALIGNMENT = 1024; + + int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + + if (is_tiled) + { + buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + } + + *size = GRALLOC_ALIGN(*size, buffer_byte_alignment); +} + +/* + * Obtain AFBC superblock dimensions from type. + */ +static rect_t get_afbc_sb_size(AllocBaseType alloc_base_type) +{ + const uint16_t AFBC_BASIC_BLOCK_WIDTH = 16; + const uint16_t AFBC_BASIC_BLOCK_HEIGHT = 16; + const uint16_t AFBC_WIDE_BLOCK_WIDTH = 32; + const uint16_t AFBC_WIDE_BLOCK_HEIGHT = 8; + const uint16_t AFBC_EXTRAWIDE_BLOCK_WIDTH = 64; + const uint16_t AFBC_EXTRAWIDE_BLOCK_HEIGHT = 4; + + rect_t sb = {0, 0}; + + switch(alloc_base_type) + { + case AllocBaseType::AFBC: + sb.width = AFBC_BASIC_BLOCK_WIDTH; + sb.height = AFBC_BASIC_BLOCK_HEIGHT; + break; + case AllocBaseType::AFBC_WIDEBLK: + sb.width = AFBC_WIDE_BLOCK_WIDTH; + sb.height = AFBC_WIDE_BLOCK_HEIGHT; + break; + case AllocBaseType::AFBC_EXTRAWIDEBLK: + sb.width = AFBC_EXTRAWIDE_BLOCK_WIDTH; + sb.height = AFBC_EXTRAWIDE_BLOCK_HEIGHT; + break; + default: + break; + } + return sb; +} + +/* + * Obtain AFBC superblock dimensions for specific plane. + * + * See alloc_type_t for more information. + */ +static rect_t get_afbc_sb_size(alloc_type_t alloc_type, const uint8_t plane) +{ + if (plane > 0 && alloc_type.is_afbc() && alloc_type.is_multi_plane) + { + return get_afbc_sb_size(AllocBaseType::AFBC_EXTRAWIDEBLK); + } + else + { + return get_afbc_sb_size(alloc_type.primary_type); + } +} + +bool get_alloc_type(const uint64_t format_ext, + const uint32_t format_idx, + const uint64_t usage, + alloc_type_t * const alloc_type) +{ + alloc_type->primary_type = AllocBaseType::UNCOMPRESSED; + alloc_type->is_multi_plane = formats[format_idx].npln > 1; + alloc_type->is_tiled = false; + alloc_type->is_padded = false; + alloc_type->is_frontbuffer_safe = false; + + /* Determine AFBC type for this format. This is used to decide alignment. + Split block does not affect alignment, and therefore doesn't affect the allocation type. */ + if (format_ext & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) + { + /* YUV transform shall not be enabled for a YUV format */ + if ((formats[format_idx].is_yuv == true) && (format_ext & MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM)) + { + MALI_GRALLOC_LOGW("YUV Transform is incorrectly enabled for format = (%s 0x%x). Extended internal format = (%s 0x%" PRIx64 ")\n", + format_name(formats[format_idx].id), formats[format_idx].id, format_name(format_ext), format_ext); + } + + /* Determine primary AFBC (superblock) type. */ + alloc_type->primary_type = AllocBaseType::AFBC; + if (format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) + { + alloc_type->primary_type = AllocBaseType::AFBC_WIDEBLK; + } + else if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) + { + alloc_type->primary_type = AllocBaseType::AFBC_EXTRAWIDEBLK; + } + + if (format_ext & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) + { + alloc_type->is_tiled = true; + + if (formats[format_idx].npln > 1 && + (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) == 0) + { + MALI_GRALLOC_LOGW("Extra-wide AFBC must be signalled for multi-plane formats. " + "Falling back to single plane AFBC."); + alloc_type->is_multi_plane = false; + } + + if (format_ext & MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY) + { + alloc_type->is_frontbuffer_safe = true; + } + } + else + { + if (formats[format_idx].npln > 1) + { + MALI_GRALLOC_LOGW("Multi-plane AFBC is not supported without tiling. " + "Falling back to single plane AFBC."); + } + alloc_type->is_multi_plane = false; + } + + if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK && + !alloc_type->is_tiled) + { + /* Headers must be tiled for extra-wide. */ + MALI_GRALLOC_LOGE("ERROR: Invalid to specify extra-wide block without tiled headers."); + return false; + } + + if (alloc_type->is_frontbuffer_safe && + (format_ext & (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK | MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK))) + { + MALI_GRALLOC_LOGE("ERROR: Front-buffer safe not supported with wide/extra-wide block."); + } + + if (formats[format_idx].npln == 1 && + format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK && + format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) + { + /* "Wide + Extra-wide" implicitly means "multi-plane". */ + MALI_GRALLOC_LOGE("ERROR: Invalid to specify multiplane AFBC with single plane format."); + return false; + } + + if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING) + { + alloc_type->is_padded = true; + } + } + return true; +} + +/* + * Initialise AFBC header based on superblock layout. + * Width and height should already be AFBC aligned. + */ +void init_afbc(uint8_t *buf, const uint64_t alloc_format, + const bool is_multi_plane, + const int w, const int h) +{ + const bool is_tiled = ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) + == MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS); + const uint32_t n_headers = (w * h) / AFBC_PIXELS_PER_BLOCK; + int body_offset = n_headers * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + + afbc_buffer_align(is_tiled, &body_offset); + + /* + * Declare the AFBC header initialisation values for each superblock layout. + * Tiled headers (AFBC 1.2) can be initialised to zero for non-subsampled formats + * (SB layouts: 0, 3, 4, 7). + */ + uint32_t headers[][4] = { + { (uint32_t)body_offset, 0x1, 0x10000, 0x0 }, /* Layouts 0, 3, 4, 7 */ + { ((uint32_t)body_offset + (1 << 28)), 0x80200040, 0x1004000, 0x20080 } /* Layouts 1, 5 */ + }; + if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)) + { + /* Zero out body_offset for non-subsampled formats. */ + memset(headers[0], 0, sizeof(uint32_t) * 4); + } + + /* Map base format to AFBC header layout */ + const uint32_t base_format = alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK; + + /* Sub-sampled formats use layouts 1 and 5 which is index 1 in the headers array. + * 1 = 4:2:0 16x16, 5 = 4:2:0 32x8. + * + * Non-subsampled use layouts 0, 3, 4 and 7, which is index 0. + * 0 = 16x16, 3 = 32x8 + split, 4 = 32x8, 7 = 64x4. + * + * When using separated planes for YUV formats, the header layout is the non-subsampled one + * as there is a header per-plane and there is no sub-sampling within the plane. + * Separated plane only supports 32x8 or 64x4 for the luma plane, so the first plane must be 4 or 7. + * Seperated plane only supports 64x4 for subsequent planes, so these must be header layout 7. + */ + const uint32_t layout = is_subsampled_yuv(base_format) && !is_multi_plane ? 1 : 0; + + MALI_GRALLOC_LOGV("Writing AFBC header layout %d for format (%s %" PRIx32 ")", + layout, format_name(base_format), base_format); + + for (uint32_t i = 0; i < n_headers; i++) + { + memcpy(buf, headers[layout], sizeof(headers[layout])); + buf += sizeof(headers[layout]); + } +} + +static int max(int a, int b) +{ + return a > b ? a : b; +} + +static int max(int a, int b, int c) +{ + return c > max(a, b) ? c : max(a, b); +} + +/* + * Obtain plane allocation dimensions (in pixels). + * + * NOTE: pixel stride, where defined for format, is + * incorporated into allocation dimensions. + */ +static void get_pixel_w_h(uint32_t * const width, + uint32_t * const height, + const format_info_t format, + const alloc_type_t alloc_type, + const uint8_t plane, + bool has_cpu_usage) +{ + const rect_t sb = get_afbc_sb_size(alloc_type, plane); + const bool is_primary_plane = (plane == 0 || !format.planes_contiguous); + + /* + * Round-up plane dimensions, to multiple of: + * - Samples for all channels (sub-sampled formats) + * - Memory bytes/words (some packed formats) + */ + if (is_primary_plane) + { + *width = GRALLOC_ALIGN(*width, format.align_w); + *height = GRALLOC_ALIGN(*height, format.align_h); + } + + /* + * Sub-sample (sub-sampled) planes. + */ + if (plane > 0) + { + *width /= format.hsub; + *height /= format.vsub; + } + + /* + * Pixel alignment (width), + * where format stride is stated in pixels. + */ + int pixel_align_w = 1, pixel_align_h = 1; + if (has_cpu_usage && is_primary_plane) + { + pixel_align_w = format.align_w_cpu; + } + else if (alloc_type.is_afbc()) + { +#define HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS (0) + uint32_t num_sb_align = 0; + if (alloc_type.is_padded && !format.is_yuv) + { + /* Align to 4 superblocks in width --> 64-byte, + * assuming 16-byte header per superblock. + */ + num_sb_align = 4; + } + pixel_align_w = max(HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS, num_sb_align) * sb.width; + + /* + * Determine AFBC tile size when allocating tiled headers. + */ + rect_t afbc_tile = sb; + if (alloc_type.is_tiled) + { + afbc_tile.width = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.width : 8 * afbc_tile.width; + afbc_tile.height = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.height : 8 * afbc_tile.height; + } + + MALI_GRALLOC_LOGV("Plane[%hhu]: [SUB-SAMPLE] w:%d, h:%d\n", plane, *width, *height); + MALI_GRALLOC_LOGV("Plane[%hhu]: [PIXEL_ALIGN] w:%d\n", plane, pixel_align_w); + MALI_GRALLOC_LOGV("Plane[%hhu]: [LINEAR_TILE] w:%" PRIu16 "\n", plane, format.tile_size); + MALI_GRALLOC_LOGV("Plane[%hhu]: [AFBC_TILE] w:%" PRIu16 ", h:%" PRIu16 "\n", plane, afbc_tile.width, afbc_tile.height); + + pixel_align_w = max(pixel_align_w, afbc_tile.width); + pixel_align_h = max(pixel_align_h, afbc_tile.height); + + if (AllocBaseType::AFBC_WIDEBLK == alloc_type.primary_type && !alloc_type.is_tiled) + { + /* + * Special case for wide block (32x8) AFBC with linear (non-tiled) + * headers: hardware reads and writes 32x16 blocks so we need to + * pad the body buffer accordingly. + * + * Note that this branch will not be taken for multi-plane AFBC + * since that requires tiled headers. + */ + pixel_align_h = max(pixel_align_h, 16); + } + } + *width = GRALLOC_ALIGN(*width, max(1, pixel_align_w, format.tile_size)); + *height = GRALLOC_ALIGN(*height, max(1, pixel_align_h, format.tile_size)); +} + + + +static uint32_t gcd(uint32_t a, uint32_t b) +{ + uint32_t r, t; + + if (a == b) + { + return a; + } + else if (a < b) + { + t = a; + a = b; + b = t; + } + + while (b != 0) + { + r = a % b; + a = b; + b = r; + } + + return a; +} + +uint32_t lcm(uint32_t a, uint32_t b) +{ + if (a != 0 && b != 0) + { + return (a * b) / gcd(a, b); + } + + return max(a, b); +} + + +#if REALIGN_YV12 == 1 +/* + * YV12 stride has additional complexity since chroma stride + * must conform to the following: + * + * c_stride = ALIGN(stride/2, 16) + * + * Since the stride alignment must satisfy both CPU and HW + * constraints, the luma stride must be doubled. + */ +static void update_yv12_stride(int8_t plane, + uint32_t luma_stride, + uint32_t stride_align, + uint32_t * byte_stride) +{ + if (plane == 0) + { + *byte_stride = GRALLOC_ALIGN(luma_stride, GRALLOC_ALIGN(stride_align, 32)); + } + else + { + /* + * Derive chroma stride from luma and verify it is: + * 1. Aligned to "1/2*lcm(hw_align, cpu_align)" + * 2. Multiple of 16px (16 bytes) + */ + *byte_stride = luma_stride / 2; + assert(*byte_stride == GRALLOC_ALIGN(*byte_stride, GRALLOC_ALIGN(stride_align / 2, 16))); + assert(*byte_stride & 15 == 0); + } +} +#endif + +/* + * Logs and returns true if deprecated usage bits are found + * + * At times, framework introduces new usage flags which are identical to what + * vendor has been using internally. This method logs those bits and returns + * true if there is any deprecated usage bit. + * + * TODO(layog@): This check is also performed again during format deduction. At + * that point, the allocation is not aborted, just a log is printed to ALOGE + * (matched against `VALID_USAGE`). These should be aligned. + */ +static bool log_deprecated_usage_flags(uint64_t usage) { + if (usage & MALI_GRALLOC_USAGE_FRONTBUFFER) { + MALI_GRALLOC_LOGW("Using deprecated FRONTBUFFER usage bit, please upgrade to BufferUsage::FRONT_BUFFER"); + return true; + } + + return false; +} + +/* + * Modify usage flag when BO is the producer + * + * BO cannot use the flags CPU_READ_RARELY as Codec layer redefines those flags + * for some internal usage. So, when BO is sending CPU_READ_OFTEN, it still + * expects to allocate an uncached buffer and this procedure convers the OFTEN + * flag to RARELY. + */ +static uint64_t update_usage_for_BO(uint64_t usage) { + MALI_GRALLOC_LOGV("Hacking CPU RW flags for BO"); + if (usage & hidl_common::BufferUsage::CPU_READ_OFTEN) { + usage &= ~(static_cast<uint64_t>(hidl_common::BufferUsage::CPU_READ_OFTEN)); + usage |= hidl_common::BufferUsage::CPU_READ_RARELY; + } + + if (usage & hidl_common::BufferUsage::CPU_WRITE_OFTEN) { + usage &= ~(static_cast<uint64_t>(hidl_common::BufferUsage::CPU_WRITE_OFTEN)); + usage |= hidl_common::BufferUsage::CPU_WRITE_RARELY; + } + return usage; +} + +static void align_plane_stride(plane_info_t *plane_info, int plane, const format_info_t format, uint32_t stride_align) +{ + plane_info[plane].byte_stride = GRALLOC_ALIGN(plane_info[plane].byte_stride * format.tile_size, stride_align) / format.tile_size; + plane_info[plane].alloc_width = plane_info[plane].byte_stride * 8 / format.bpp[plane]; +} + +/* + * Calculate allocation size. + * + * Determine the width and height of each plane based on pixel alignment for + * both uncompressed and AFBC allocations. + * + * @param width [in] Buffer width. + * @param height [in] Buffer height. + * @param alloc_type [in] Allocation type inc. whether tiled and/or multi-plane. + * @param format [in] Pixel format. + * @param has_cpu_usage [in] CPU usage requested (in addition to any other). + * @param pixel_stride [out] Calculated pixel stride. + * @param size [out] Total calculated buffer size including all planes. + * @param plane_info [out] Array of calculated information for each plane. Includes + * offset, byte stride and allocation width and height. + */ +static void calc_allocation_size(const int width, + const int height, + const alloc_type_t alloc_type, + const format_info_t format, + const bool has_cpu_usage, + const bool has_hw_usage, + const bool has_gpu_usage, + int * const pixel_stride, + uint64_t * const size, + plane_info_t plane_info[MAX_PLANES]) +{ + /* pixel_stride is set outside this function after this function is called */ + GRALLOC_UNUSED(pixel_stride); + + plane_info[0].offset = 0; + + *size = 0; + for (uint8_t plane = 0; plane < format.npln; plane++) + { + plane_info[plane].alloc_width = width; + plane_info[plane].alloc_height = height; + get_pixel_w_h(&plane_info[plane].alloc_width, + &plane_info[plane].alloc_height, + format, + alloc_type, + plane, + has_cpu_usage); + MALI_GRALLOC_LOGV("Aligned w=%d, h=%d (in pixels)", + plane_info[plane].alloc_width, plane_info[plane].alloc_height); + + /* + * Calculate byte stride (per plane). + */ + if (alloc_type.is_afbc()) + { + assert((plane_info[plane].alloc_width * format.bpp_afbc[plane]) % 8 == 0); + plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp_afbc[plane]) / 8; + } + else + { + assert((plane_info[plane].alloc_width * format.bpp[plane]) % 8 == 0); + plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp[plane]) / 8; + + /* + * Align byte stride (uncompressed allocations only). + * + * Find the lowest-common-multiple of: + * 1. hw_align: Minimum byte stride alignment for HW IP (has_hw_usage == true) + * 2. cpu_align: Byte equivalent of 'align_w_cpu' (has_cpu_usage == true) + * + * NOTE: Pixel stride is defined as multiple of 'align_w_cpu'. + */ + uint16_t hw_align = 0; + if (has_hw_usage) + { + static_assert(is_power2(YUV_BYTE_ALIGN_DEFAULT), + "YUV_BYTE_ALIGN_DEFAULT is not a power of 2"); + static_assert(is_power2(RGB_BYTE_ALIGN_DEFAULT), + "RGB_BYTE_ALIGN_DEFAULT is not a power of 2"); + + hw_align = format.is_yuv ? + YUV_BYTE_ALIGN_DEFAULT : + (format.is_rgb ? RGB_BYTE_ALIGN_DEFAULT : 0); + } + + if (has_gpu_usage) + { + static_assert(is_power2(GPU_BYTE_ALIGN_DEFAULT), + "RGB_BYTE_ALIGN_DEFAULT is not a power of 2"); + + /* + * The GPU requires stricter alignment on YUV and raw formats. + */ + hw_align = std::max(hw_align, static_cast<uint16_t>(GPU_BYTE_ALIGN_DEFAULT)); + } + + uint32_t cpu_align = 0; + +#if CAN_SKIP_CPU_ALIGN == 1 + if (has_cpu_usage) +#endif + { + assert((format.bpp[plane] * format.align_w_cpu) % 8 == 0); + const bool is_primary_plane = (plane == 0 || !format.planes_contiguous); + if (is_primary_plane) + { + cpu_align = (format.bpp[plane] * format.align_w_cpu) / 8; + } + } + + uint32_t stride_align = lcm(hw_align, cpu_align); + if (stride_align) + { + align_plane_stride(plane_info, plane, format, stride_align); + } + +#if REALIGN_YV12 == 1 + /* + * Update YV12 stride with both CPU & HW usage due to constraint of chroma stride. + * Width is anyway aligned to 16px for luma and chroma (has_cpu_usage). + * + * Note: To prevent luma stride misalignment with GPU stride alignment. + * The luma plane will maintain the same `stride` size, and the chroma plane + * will align to `stride/2`. + */ + if (format.id == MALI_GRALLOC_FORMAT_INTERNAL_YV12 && has_hw_usage && has_cpu_usage) + { + update_yv12_stride(plane, + plane_info[0].byte_stride, + stride_align, + &plane_info[plane].byte_stride); + } +#endif + } + MALI_GRALLOC_LOGV("Byte stride: %d", plane_info[plane].byte_stride); + + const uint32_t sb_num = (plane_info[plane].alloc_width * plane_info[plane].alloc_height) + / AFBC_PIXELS_PER_BLOCK; + + /* + * Calculate body size (per plane). + */ + int body_size = 0; + if (alloc_type.is_afbc()) + { + const rect_t sb = get_afbc_sb_size(alloc_type, plane); + const int sb_bytes = GRALLOC_ALIGN((format.bpp_afbc[plane] * sb.width * sb.height) / 8, 128); + body_size = sb_num * sb_bytes; + + /* When AFBC planes are stored in separate buffers and this is not the last plane, + also align the body buffer to make the subsequent header aligned. */ + if (format.npln > 1 && plane < 2) + { + afbc_buffer_align(alloc_type.is_tiled, &body_size); + } + + if (alloc_type.is_frontbuffer_safe) + { + int back_buffer_size = body_size; + afbc_buffer_align(alloc_type.is_tiled, &back_buffer_size); + body_size += back_buffer_size; + } + } + else + { + body_size = plane_info[plane].byte_stride * plane_info[plane].alloc_height; + } + MALI_GRALLOC_LOGV("Body size: %d", body_size); + + + /* + * Calculate header size (per plane). + */ + int header_size = 0; + if (alloc_type.is_afbc()) + { + /* As this is AFBC, calculate header size for this plane. + * Always align the header, which will make the body buffer aligned. + */ + header_size = sb_num * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(alloc_type.is_tiled, &header_size); + } + MALI_GRALLOC_LOGV("AFBC Header size: %d", header_size); + + /* + * Set offset for separate chroma planes. + */ + if (plane > 0) + { + plane_info[plane].offset = *size; + } + + /* + * Set overall size. + * Size must be updated after offset. + */ + *size += body_size + header_size; + MALI_GRALLOC_LOGV("size=%" PRIu64, *size); + } +} + + + +/* + * Validate selected format against requested. + * Return true if valid, false otherwise. + */ +static bool validate_format(const format_info_t * const format, + const alloc_type_t alloc_type, + const buffer_descriptor_t * const bufDescriptor) +{ + if (alloc_type.is_afbc()) + { + /* + * Validate format is supported by AFBC specification and gralloc. + */ + if (format->afbc == false) + { + MALI_GRALLOC_LOGE("ERROR: AFBC selected but not supported for base format: (%s 0x%" PRIx32")", + format_name(format->id), format->id); + return false; + } + + /* + * Enforce consistency between number of format planes and + * request for single/multi-plane AFBC. + */ + if (((format->npln == 1 && alloc_type.is_multi_plane) || + (format->npln > 1 && !alloc_type.is_multi_plane))) + { + MALI_GRALLOC_LOGE("ERROR: Format ((%s %" PRIx32 "), num planes: %u) is incompatible with %s-plane AFBC request", + format_name(format->id), format->id, format->npln, (alloc_type.is_multi_plane) ? "multi" : "single"); + return false; + } + } + else + { + if (format->linear == false) + { + MALI_GRALLOC_LOGE("ERROR: Uncompressed format requested but not supported for base format: (%s %" PRIx32 ")", + format_name(format->id), format->id); + return false; + } + } + + if (format->id == MALI_GRALLOC_FORMAT_INTERNAL_BLOB && + bufDescriptor->height != 1) + { + MALI_GRALLOC_LOGE("ERROR: Height for format BLOB must be 1."); + return false; + } + + return true; +} + +static int prepare_descriptor_exynos_formats( + buffer_descriptor_t *bufDescriptor, + format_info_t format_info) +{ + int fd_count = 1; + int w = bufDescriptor->width; + int h = bufDescriptor->height; + uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage; + int plane_count = 2; + int format = MALI_GRALLOC_INTFMT_FMT_MASK & bufDescriptor->alloc_format; + + if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_HW_VIDEO_DECODER)) + { + usage |= GRALLOC_USAGE_VIDEO_PRIVATE_DATA; + bufDescriptor->producer_usage |= GRALLOC_USAGE_VIDEO_PRIVATE_DATA; + bufDescriptor->consumer_usage |= GRALLOC_USAGE_VIDEO_PRIVATE_DATA; + } + + /* set SBWC format fd_count */ + fd_count = 1; + switch (format) + { + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: + fd_count = 2; + break; + } + + /* SWBC Formats have special size requirements */ + switch (format) + { + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC: + plane_count = setup_sbwc_420_sp(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: + plane_count = setup_sbwc_420_sp_10bit(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: + plane_count = setup_sbwc_420_sp_lossy(w, h, 50, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: + plane_count = setup_sbwc_420_sp_lossy(w, h, 75, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: + plane_count = setup_sbwc_420_sp_10bit_lossy(w, h, 40, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: + plane_count = setup_sbwc_420_sp_10bit_lossy(w, h, 60, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: + plane_count = setup_sbwc_420_sp_10bit_lossy(w, h, 80, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + fd_count = 1; + h = GRALLOC_ALIGN(h, 2); + plane_count = setup_420_sp(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YV12_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M: + w = GRALLOC_ALIGN(w, 32); + h = GRALLOC_ALIGN(h, 16); + fd_count = 3; + plane_count = setup_420_p(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED: + w = GRALLOC_ALIGN(w, 16); + h = GRALLOC_ALIGN(h, 32); + fd_count = 2; + plane_count = setup_420_sp_tiled(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P: + w = GRALLOC_ALIGN(w, 16); + fd_count = 1; + plane_count = setup_420_p(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M: + w = GRALLOC_ALIGN(w, 16); + h = GRALLOC_ALIGN(h, 32); + fd_count = 2; + plane_count = setup_420_sp(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN: + w = GRALLOC_ALIGN(w, 16); + h = GRALLOC_ALIGN(h, 16); + fd_count = 1; + plane_count = setup_420_sp(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B: + /* This is 64 pixel align for now */ + w = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN); + h = GRALLOC_ALIGN(h, 16); + fd_count = 2; + plane_count = setup_420_sp_s10b(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B: + w = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN); + h = GRALLOC_ALIGN(h, 16); + fd_count = 1; + plane_count = setup_420_sp_s10b(w, h, fd_count, bufDescriptor->plane_info); + break; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M: + w = GRALLOC_ALIGN(w, 16); + h = GRALLOC_ALIGN(h, 16); + fd_count = 2; + plane_count = setup_p010_sp(w, h, fd_count, bufDescriptor->plane_info); + break; + + default: + MALI_GRALLOC_LOGE("invalid yuv format (%s %" PRIx64 ")", format_name(bufDescriptor->alloc_format), + bufDescriptor->alloc_format); + return -1; + } + + plane_info_t *plane = bufDescriptor->plane_info; + + if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER)) + { + if (is_sbwc_format(format)) + { + MALI_GRALLOC_LOGE("using SBWC format (%s %" PRIx64 ") with GPU is invalid", + format_name(bufDescriptor->alloc_format), + bufDescriptor->alloc_format); + return -1; + } + else + { + /* + * The GPU requires stricter alignment on YUV formats. + */ + for (int pidx = 0; pidx < plane_count; ++pidx) + { + if (plane[pidx].size == plane[pidx].byte_stride * plane[pidx].alloc_height) + { + align_plane_stride(plane, pidx, format_info, GPU_BYTE_ALIGN_DEFAULT); + plane[pidx].size = plane[pidx].byte_stride * plane[pidx].alloc_height; + } + else + { + MALI_GRALLOC_LOGE("buffer with format (%s %" PRIx64 + ") has size %" PRIu64 + " != byte_stride %" PRIu32 " * alloc_height %" PRIu32, + format_name(bufDescriptor->alloc_format), + bufDescriptor->alloc_format, + plane[pidx].size, plane[pidx].byte_stride, plane[pidx].alloc_height); + } + } + } + } + + for (int fidx = 0; fidx < fd_count; fidx++) + { + uint64_t size = 0; + + for (int pidx = 0; pidx < plane_count; pidx++) + { + if (plane[pidx].fd_idx == fidx) + { + size += plane[pidx].size; + } + } + + /* TODO(b/183073089): Removing the following size hacks make video playback + * fail. Need to investigate more for the root cause. Copying the original + * comment from upstream below */ + /* is there a need to check the condition for padding like in older gralloc? */ + /* Add MSCL_EXT_SIZE */ + /* MSCL_EXT_SIZE + MSCL_EXT_SIZE/2 + ext_size */ + size += 1024; + + size = size < SZ_4K ? SZ_4K : size; + + bufDescriptor->alloc_sizes[fidx] = size; + } + + + bufDescriptor->fd_count = fd_count; + bufDescriptor->plane_count = plane_count; + + return 0; +} + +int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescriptor) +{ + alloc_type_t alloc_type{}; + + int alloc_width = bufDescriptor->width; + int alloc_height = bufDescriptor->height; + uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage; + + /* + * Select optimal internal pixel format based upon + * usage and requested format. + */ + bufDescriptor->alloc_format = mali_gralloc_select_format(bufDescriptor->hal_format, + bufDescriptor->format_type, + usage, + bufDescriptor->width * bufDescriptor->height); + if (bufDescriptor->alloc_format == MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED) + { + MALI_GRALLOC_LOGE("ERROR: Unrecognized and/or unsupported format (%s 0x%" PRIx64 ") and usage (%s 0x%" PRIx64 ")", + format_name(bufDescriptor->hal_format), bufDescriptor->hal_format, + describe_usage(usage).c_str(), usage); + return -EINVAL; + } + + int32_t format_idx = get_format_index(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); + if (format_idx == -1) + { + return -EINVAL; + } + MALI_GRALLOC_LOGV("alloc_format: (%s 0x%" PRIx64 ") format_idx: %d", + format_name(bufDescriptor->alloc_format), bufDescriptor->alloc_format, format_idx); + + /* + * Obtain allocation type (uncompressed, AFBC basic, etc...) + */ + if (!get_alloc_type(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_EXT_MASK, + format_idx, usage, &alloc_type)) + { + return -EINVAL; + } + + if (!validate_format(&formats[format_idx], alloc_type, bufDescriptor)) + { + return -EINVAL; + } + + if (is_exynos_format(bufDescriptor->alloc_format)) + { + prepare_descriptor_exynos_formats(bufDescriptor, formats[format_idx]); + } + else + { + /* + * Resolution of frame (allocation width and height) might require adjustment. + * This adjustment is only based upon specific usage and pixel format. + * If using AFBC, further adjustments to the allocation width and height will be made later + * based on AFBC alignment requirements and, for YUV, the plane properties. + */ + mali_gralloc_adjust_dimensions(bufDescriptor->alloc_format, + usage, + &alloc_width, + &alloc_height); + + /* Obtain buffer size and plane information. */ + calc_allocation_size(alloc_width, + alloc_height, + alloc_type, + formats[format_idx], + usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), + usage & ~(GRALLOC_USAGE_PRIVATE_MASK | GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), + usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER), + &bufDescriptor->pixel_stride, + &bufDescriptor->alloc_sizes[0], + bufDescriptor->plane_info); + } + + /* Set pixel stride differently for RAW formats */ + switch (MALI_GRALLOC_INTFMT_FMT_MASK & bufDescriptor->alloc_format) + { + case MALI_GRALLOC_FORMAT_INTERNAL_RAW12: + case MALI_GRALLOC_FORMAT_INTERNAL_RAW10: + bufDescriptor->pixel_stride = bufDescriptor->plane_info[0].byte_stride; + break; + default: + bufDescriptor->pixel_stride = bufDescriptor->plane_info[0].alloc_width; + } + + /* + * Each layer of a multi-layer buffer must be aligned so that + * it is accessible by both producer and consumer. In most cases, + * the stride alignment is also sufficient for each layer, however + * for AFBC the header buffer alignment is more constrained (see + * AFBC specification v3.4, section 2.15: "Alignment requirements"). + * Also update the buffer size to accommodate all layers. + */ + if (bufDescriptor->layer_count > 1) + { + if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) + { + if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) + { + bufDescriptor->alloc_sizes[0] = GRALLOC_ALIGN(bufDescriptor->alloc_sizes[0], 4096); + } + else + { + bufDescriptor->alloc_sizes[0] = GRALLOC_ALIGN(bufDescriptor->alloc_sizes[0], 128); + } + } + + bufDescriptor->alloc_sizes[0] *= bufDescriptor->layer_count; + } + + /* MFC requires EXT_SIZE padding */ + bufDescriptor->alloc_sizes[0] += EXT_SIZE; + + return 0; +} + + +int mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t *descriptors, + uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend, + int fd) +{ + bool shared = false; + uint64_t backing_store_id = 0x0; + int err; + + for (uint32_t i = 0; i < numDescriptors; i++) + { + buffer_descriptor_t * const bufDescriptor = (buffer_descriptor_t *)(descriptors[i]); + + assert(bufDescriptor->producer_usage == bufDescriptor->consumer_usage); + uint64_t usage = bufDescriptor->producer_usage; + if ((usage & hidl_common::BufferUsage::VIDEO_DECODER) && (usage & GRALLOC_USAGE_GOOGLE_IP_BO)) { + usage = update_usage_for_BO(usage); + bufDescriptor->producer_usage = usage; + bufDescriptor->consumer_usage = usage; + } + + if (log_deprecated_usage_flags(usage)) { + return -EINVAL; + } + + /* Derive the buffer size from descriptor parameters */ + err = mali_gralloc_derive_format_and_size(bufDescriptor); + if (err != 0) + { + return err; + } + } + + /* Allocate ION backing store memory */ + err = mali_gralloc_ion_allocate(descriptors, numDescriptors, pHandle, &shared, fd); + if (err < 0) + { + return err; + } + + if (shared) + { + backing_store_id = getUniqueId(); + } + + for (uint32_t i = 0; i < numDescriptors; i++) + { + private_handle_t *hnd = (private_handle_t *)pHandle[i]; + + if (shared) + { + /*each buffer will share the same backing store id.*/ + hnd->backing_store_id = backing_store_id; + } + else + { + /* each buffer will have an unique backing store id.*/ + hnd->backing_store_id = getUniqueId(); + } + } + + if (NULL != shared_backend) + { + *shared_backend = shared; + } + + return 0; +} + +int mali_gralloc_buffer_free(buffer_handle_t pHandle) +{ + auto *hnd = const_cast<private_handle_t *>( + reinterpret_cast<const private_handle_t *>(pHandle)); + + if (hnd == nullptr) + { + return -1; + } + + gralloc_shared_memory_free(hnd); + mali_gralloc_ion_free(hnd); + + return 0; +} diff --git a/gralloc3/src/mali_gralloc_bufferallocation.h b/GrallocHAL/src/core/mali_gralloc_bufferallocation.h index 207230e..3d759de 100644 --- a/gralloc3/src/mali_gralloc_bufferallocation.h +++ b/GrallocHAL/src/core/mali_gralloc_bufferallocation.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2019 ARM Limited. All rights reserved. + * Copyright (C) 2016-2020 ARM Limited. All rights reserved. * * Copyright (C) 2008 The Android Open Source Project * @@ -19,74 +19,88 @@ #define MALI_GRALLOC_BUFFERALLOCATION_H_ #include <hardware/hardware.h> -#include "mali_gralloc_module.h" -#include "mali_gralloc_private_interface_types.h" #include "mali_gralloc_buffer.h" -#include "mali_gralloc_bufferdescriptor.h" +#include "core/mali_gralloc_bufferdescriptor.h" -/* - * AFBC superblock type. - */ -enum AllocBaseType +/* Compression scheme */ +enum class AllocBaseType { - UNCOMPRESSED, /* No compression. */ - AFBC, /* AFBC basic (16x16). */ - AFBC_WIDEBLK, /* AFBC wide-block (32x8). */ - AFBC_EXTRAWIDEBLK, /* AFBC extra-wide-block (64x4). */ + /* + * No compression scheme + */ + UNCOMPRESSED, + + /* + * Arm Framebuffer Compression + */ + AFBC, /* 16 x 16 block size */ + AFBC_WIDEBLK, /* 32 x 8 block size */ + AFBC_EXTRAWIDEBLK, /* 64 x 4 block size */ + }; /* * Allocation type. * - * Allocation-specific properties of the AFBC format modifiers + * Allocation-specific properties of format modifiers * described by MALI_GRALLOC_INTFMT_*. - * */ -typedef struct { - +struct AllocType +{ /* - * AFBC superblock type for either: - * - single plane AFBC format or - * - first/luma plane of multi-plane AFBC format. + * The compression scheme in use + * + * For AFBC formats, this describes: + * - the block size for single plane base formats, or + * - the block size of the first/luma plane for multi-plane base formats. */ - AllocBaseType primary_type; + AllocBaseType primary_type{AllocBaseType::UNCOMPRESSED}; /* * Multi-plane AFBC format. AFBC chroma-only plane(s) are * always compressed with superblock type 'AFBC_EXTRAWIDEBLK'. */ - bool is_multi_plane; + bool is_multi_plane{}; /* * Allocate tiled AFBC headers. */ - bool is_tiled; + bool is_tiled{}; /* * Pad AFBC header stride to 64-byte alignment * (multiple of 4x16B headers). */ - bool is_padded; + bool is_padded{}; /* * Front-buffer rendering safe AFBC allocations include an * additional 4kB-aligned body buffer. */ - bool is_frontbuffer_safe; + bool is_frontbuffer_safe{}; bool is_afbc() const { - return primary_type != UNCOMPRESSED; + switch (primary_type) + { + case AllocBaseType::AFBC: + case AllocBaseType::AFBC_WIDEBLK: + case AllocBaseType::AFBC_EXTRAWIDEBLK: + return true; + default: + return false; + } } -} alloc_type_t; +}; +using alloc_type_t = AllocType; -int mali_gralloc_derive_format_and_size(mali_gralloc_module *m, - buffer_descriptor_t * const bufDescriptor); +int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescriptor); -int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors, - uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend); +int mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t *descriptors, + uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend, + int fd = -1); int mali_gralloc_buffer_free(buffer_handle_t pHandle); diff --git a/GrallocHAL/src/core/mali_gralloc_bufferdescriptor.cpp b/GrallocHAL/src/core/mali_gralloc_bufferdescriptor.cpp new file mode 100644 index 0000000..46ce17b --- /dev/null +++ b/GrallocHAL/src/core/mali_gralloc_bufferdescriptor.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2020 Google Inc. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mali_gralloc_bufferdescriptor.h" +#include "mali_gralloc_usages.h" + +#include <sstream> + +using android::hardware::graphics::common::V1_2::BufferUsage; + +#define BUFFERUSAGE(n) { static_cast<uint64_t>(BufferUsage::n), #n } +#define USAGE(prefix, n) { prefix ## n, #n } +static struct usage_name { + uint64_t usage; + const char *name; +} usage_names[] = { +// graphics common v1.0 usages + BUFFERUSAGE(GPU_TEXTURE), + BUFFERUSAGE(GPU_RENDER_TARGET), + BUFFERUSAGE(COMPOSER_OVERLAY), + BUFFERUSAGE(COMPOSER_CLIENT_TARGET), + BUFFERUSAGE(PROTECTED), + BUFFERUSAGE(COMPOSER_CURSOR), + BUFFERUSAGE(VIDEO_ENCODER), + BUFFERUSAGE(CAMERA_OUTPUT), + BUFFERUSAGE(CAMERA_INPUT), + BUFFERUSAGE(RENDERSCRIPT), + BUFFERUSAGE(VIDEO_DECODER), + BUFFERUSAGE(SENSOR_DIRECT_DATA), + BUFFERUSAGE(GPU_DATA_BUFFER), +// graphics common v1.1 usages + BUFFERUSAGE(GPU_CUBE_MAP), + BUFFERUSAGE(GPU_MIPMAP_COMPLETE), +// graphics common v1.2 usages + BUFFERUSAGE(HW_IMAGE_ENCODER), +// Google usages + USAGE(GRALLOC_USAGE_, GOOGLE_IP_BO), + USAGE(GRALLOC_USAGE_, GOOGLE_IP_MFC), + USAGE(GS101_GRALLOC_USAGE_, TPU_INPUT), + USAGE(GS101_GRALLOC_USAGE_, TPU_OUTPUT), + USAGE(GS101_GRALLOC_USAGE_, CAMERA_STATS), +// Exynos specific usages + USAGE(GRALLOC_USAGE_, PRIVATE_NONSECURE), + USAGE(GRALLOC_USAGE_, NOZEROED), + USAGE(GRALLOC_USAGE_, VIDEO_PRIVATE_DATA), +}; + +std::string describe_usage(uint64_t usage) +{ + std::ostringstream stream; + switch (static_cast<BufferUsage>(usage & BufferUsage::CPU_READ_MASK)) { + case BufferUsage::CPU_READ_NEVER: + stream << "CPU_READ_NEVER"; + break; + case BufferUsage::CPU_READ_RARELY: + stream << "CPU_READ_RARELY"; + break; + case BufferUsage::CPU_READ_OFTEN: + stream << "CPU_READ_OFTEN"; + break; + default: + stream << "<unknown CPU read value 0x" << std::hex << (usage & 0x0full) << ">"; + break; + } + stream << "|"; + switch (static_cast<BufferUsage>(usage & BufferUsage::CPU_WRITE_MASK)) { + case BufferUsage::CPU_WRITE_NEVER: + stream << "CPU_WRITE_NEVER"; + break; + case BufferUsage::CPU_WRITE_RARELY: + stream << "CPU_WRITE_RARELY"; + break; + case BufferUsage::CPU_WRITE_OFTEN: + stream << "CPU_WRITE_OFTEN"; + break; + default: + stream << "<unknown CPU write value 0x" << std::hex << (usage & 0xf0ull) << ">"; + break; + } + usage &= ~(0xffull); + for (uint64_t i = 0; + i < (sizeof(usage_names) / sizeof(usage_name)) && usage; + ++i) + { + if ((usage & usage_names[i].usage) == usage_names[i].usage) + { + usage = usage & (~usage_names[i].usage); + stream << "|"; + stream << usage_names[i].name; + } + } + if (usage) { + stream << std::dec; + for (uint64_t i = 0; (i < 64) && usage; ++i) + { + if (usage & (1 << i)) + { + stream << "|(1<<" << i << ")"; + usage &= ~(1 << i); + } + } + } + return stream.str(); +} diff --git a/GrallocHAL/src/core/mali_gralloc_bufferdescriptor.h b/GrallocHAL/src/core/mali_gralloc_bufferdescriptor.h new file mode 100644 index 0000000..3c7c45f --- /dev/null +++ b/GrallocHAL/src/core/mali_gralloc_bufferdescriptor.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2016-2020 Arm Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MALI_GRALLOC_BUFFERDESCRIPTOR_H_ +#define MALI_GRALLOC_BUFFERDESCRIPTOR_H_ + +#include "mali_gralloc_buffer.h" +#include "mali_gralloc_formats.h" +#include <string> + +typedef uint64_t gralloc_buffer_descriptor_t; + +std::string describe_usage(uint64_t usage); + +/* A buffer_descriptor contains the requested parameters for the buffer + * as well as the calculated parameters that are passed to the allocator. + */ +struct buffer_descriptor_t +{ + /* For validation. */ + uint32_t signature; + + /* Requested parameters from IAllocator. */ + uint32_t width; + uint32_t height; + uint64_t producer_usage; + uint64_t consumer_usage; + uint64_t hal_format; + uint32_t layer_count; + mali_gralloc_format_type format_type; + std::string name; + uint64_t reserved_size; + + /* + * Calculated values that will be passed to the allocator in order to + * allocate the buffer. + */ + uint64_t alloc_sizes[MAX_PLANES]; + int pixel_stride; + uint64_t alloc_format; + uint32_t fd_count; + uint32_t plane_count; + plane_info_t plane_info[MAX_PLANES]; + + buffer_descriptor_t() : + signature(0), + width(0), + height(0), + producer_usage(0), + consumer_usage(0), + hal_format(0), + layer_count(0), + format_type(MALI_GRALLOC_FORMAT_TYPE_USAGE), + name("Unnamed"), + reserved_size(0), + pixel_stride(0), + alloc_format(0), + fd_count(1), + plane_count(1) + { + memset(plane_info, 0, sizeof(plane_info_t) * MAX_PLANES); + memset(alloc_sizes, 0, sizeof(alloc_sizes)); + } + + void dump(const std::string &str) const { + ALOGI("buffer_descriptor: %s " + "wh(%u %u) " + "usage_pc(%s 0x%" PRIx64 " %s 0x%" PRIx64 ") " + "hal_format(0x%" PRIx64 ") " + "layer_count(%u) " + "format_type(%u) " + "name(%s)" + "reserved_size(%" PRIu64 ") " + "alloc_sizes(%" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" + "pixel_stride(%d) alloc_format(0x%" PRIx64 ") fd_count(%d) " + "plane_count(%u) " + "plane[0](offset %" PRId64 ", idx %u, size %" PRIu64 " byte_stride %u, wh %u %u)" + "plane[1](offset %" PRId64 ", idx %u, size %" PRIu64 " byte_stride %u, wh %u %u)" + "plane[2](offset %" PRId64 ", idx %u, size %" PRIu64 " byte_stride %u, wh %u %u)" + "\n", + str.c_str(), + width, height, + describe_usage(producer_usage).c_str(), producer_usage, + describe_usage(consumer_usage).c_str(), consumer_usage, + hal_format, + layer_count, + format_type, + name.c_str(), + reserved_size, + alloc_sizes[0], alloc_sizes[1], alloc_sizes[2], + pixel_stride, alloc_format, fd_count, + plane_count, + plane_info[0].offset, plane_info[0].fd_idx, plane_info[0].size, plane_info[0].byte_stride, plane_info[0].alloc_width, plane_info[0].alloc_height, + plane_info[1].offset, plane_info[1].fd_idx, plane_info[1].size, plane_info[1].byte_stride, plane_info[1].alloc_width, plane_info[1].alloc_height, + plane_info[2].offset, plane_info[2].fd_idx, plane_info[2].size, plane_info[2].byte_stride, plane_info[2].alloc_width, plane_info[2].alloc_height + ); + } +}; + +#endif /* MALI_GRALLOC_BUFFERDESCRIPTOR_H_ */ diff --git a/gralloc3/src/mali_gralloc_debug.cpp b/GrallocHAL/src/core/mali_gralloc_debug.cpp index 099ff2f..cc3bc7f 100644 --- a/gralloc3/src/mali_gralloc_debug.cpp +++ b/GrallocHAL/src/core/mali_gralloc_debug.cpp @@ -22,14 +22,7 @@ #include <algorithm> #include <hardware/hardware.h> -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include "mali_gralloc_module.h" -#include "gralloc_priv.h" + #include "mali_gralloc_debug.h" static pthread_mutex_t dump_lock = PTHREAD_MUTEX_INITIALIZER; @@ -40,7 +33,7 @@ void mali_gralloc_dump_buffer_add(private_handle_t *handle) { if (NULL == handle) { - ALOGE("Invalid handle %p and return", handle); + MALI_GRALLOC_LOGE("Invalid handle %p and return", handle); return; } @@ -53,7 +46,7 @@ void mali_gralloc_dump_buffer_erase(private_handle_t *handle) { if (NULL == handle) { - ALOGE("Invalid handle %p and return", handle); + MALI_GRALLOC_LOGE("Invalid handle %p and return", handle); return; } @@ -74,7 +67,7 @@ void mali_gralloc_dump_buffers(android::String8 &dumpStrings, uint32_t *outSize) { if (NULL == outSize) { - ALOGE("Invalid pointer to dump buffer size and return"); + MALI_GRALLOC_LOGE("Invalid pointer to dump buffer size and return"); return; } @@ -84,8 +77,8 @@ void mali_gralloc_dump_buffers(android::String8 &dumpStrings, uint32_t *outSize) private_handle_t *hnd; size_t num; - mali_gralloc_dump_string(dumpStrings, " handle | width | height | stride | req format |internal " - "format|consumer usage|producer usage| fd | fd1 | fd2 | AFBC " + mali_gralloc_dump_string(dumpStrings, " handle | width | height | stride | req format |alloc " + "format|consumer usage|producer usage| shared fd | AFBC " "|\n"); mali_gralloc_dump_string(dumpStrings, "------------+-------+--------+--------+----------------+---------------+----" "----------+--------------+-----------+------+\n"); @@ -95,10 +88,10 @@ void mali_gralloc_dump_buffers(android::String8 &dumpStrings, uint32_t *outSize) { hnd = dump_buffers[num]; mali_gralloc_dump_string(dumpStrings, " %08" PRIxPTR " | %5d | %5d | %5d | %08x | %09" PRIx64 - " | %09" PRIx64 " | %09" PRIx64 " | %08x | %08x | %08x | %4d |\n", - hnd, hnd->width, hnd->height, hnd->stride, hnd->req_format, hnd->internal_format, - hnd->consumer_usage, hnd->producer_usage, hnd->fds[0], hnd->fds[1], hnd->fds[2], - (hnd->internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) ? true : false); + " | %09" PRIx64 " | %09" PRIx64 " | %08x | %4d |\n", + hnd, hnd->width, hnd->height, hnd->stride, hnd->req_format, hnd->alloc_format, + hnd->consumer_usage, hnd->producer_usage, hnd->fds[0], + (hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) ? true : false); } pthread_mutex_unlock(&dump_lock); @@ -114,7 +107,7 @@ void mali_gralloc_dump_internal(uint32_t *outSize, char *outBuffer) if (NULL == outSize) { - ALOGE("Invalid pointer to dump buffer size and return"); + MALI_GRALLOC_LOGE("Invalid pointer to dump buffer size and return"); return; } diff --git a/gralloc3/src/mali_gralloc_debug.h b/GrallocHAL/src/core/mali_gralloc_debug.h index 8713c83..9f99f0e 100644 --- a/gralloc3/src/mali_gralloc_debug.h +++ b/GrallocHAL/src/core/mali_gralloc_debug.h @@ -21,13 +21,8 @@ #include <utils/String8.h> #include "gralloc_priv.h" -#include "mali_gralloc_module.h" -#if GRALLOC_VERSION_MAJOR == 1 #include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif void mali_gralloc_dump_buffer_add(private_handle_t *handle); void mali_gralloc_dump_buffer_erase(private_handle_t *handle); diff --git a/gralloc3/src/mali_gralloc_formats.cpp b/GrallocHAL/src/core/mali_gralloc_formats.cpp index dbac7ed..528b1d3 100644 --- a/gralloc3/src/mali_gralloc_formats.cpp +++ b/GrallocHAL/src/core/mali_gralloc_formats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2019 ARM Limited. All rights reserved. + * Copyright (C) 2016-2020 ARM Limited. All rights reserved. * * Copyright (C) 2008 The Android Open Source Project * @@ -24,253 +24,77 @@ #include <vector> #include <cutils/properties.h> -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include "mali_gralloc_module.h" #include "gralloc_priv.h" #include "mali_gralloc_bufferallocation.h" +#include "mali_gralloc_usages.h" #include "format_info.h" - -static mali_gralloc_format_caps cpu_runtime_caps; -static mali_gralloc_format_caps dpu_runtime_caps; -static mali_gralloc_format_caps dpu_aeu_runtime_caps; -static mali_gralloc_format_caps vpu_runtime_caps; -static mali_gralloc_format_caps gpu_runtime_caps; -static mali_gralloc_format_caps cam_runtime_caps; -/* Writing to runtime_caps_read is guarded by mutex caps_init_mutex. */ -static pthread_mutex_t caps_init_mutex = PTHREAD_MUTEX_INITIALIZER; -static bool runtime_caps_read = false; - -#define MALI_GRALLOC_GPU_LIB_NAME "libGLES_mali.so" -#define MALI_GRALLOC_VPU_LIB_NAME "libstagefrighthw.so" -#define MALI_GRALLOC_DPU_LIB_NAME "hwcomposer.default.so" +#include "capabilities/gralloc_capabilities.h" +#include "exynos_format.h" /* Producer/consumer definitions. * CPU: Software access * GPU: Graphics processor * DPU: Display processor - * DPU_AEU: AFBC encoder (input to DPU) * VPU: Video processor * CAM: Camera ISP + * TPU: ML accelerator */ -#define MALI_GRALLOC_PRODUCER_CPU ((uint16_t)1 << 0) -#define MALI_GRALLOC_PRODUCER_GPU ((uint16_t)1 << 1) -#define MALI_GRALLOC_PRODUCER_DPU ((uint16_t)1 << 2) -#define MALI_GRALLOC_PRODUCER_DPU_AEU ((uint16_t)1 << 3) -#define MALI_GRALLOC_PRODUCER_VPU ((uint16_t)1 << 4) -#define MALI_GRALLOC_PRODUCER_CAM ((uint16_t)1 << 5) -#define MALI_GRALLOC_PRODUCER_TPU ((uint16_t)1 << 6) - -#define MALI_GRALLOC_CONSUMER_CPU ((uint16_t)1 << 0) -#define MALI_GRALLOC_CONSUMER_GPU ((uint16_t)1 << 1) -#define MALI_GRALLOC_CONSUMER_DPU ((uint16_t)1 << 2) -#define MALI_GRALLOC_CONSUMER_VPU ((uint16_t)1 << 3) -#define MALI_GRALLOC_CONSUMER_CAM ((uint16_t)1 << 5) -#define MALI_GRALLOC_CONSUMER_TPU ((uint16_t)1 << 6) +#define MALI_GRALLOC_PRODUCER_CPU ((uint16_t)1 << 0) +#define MALI_GRALLOC_PRODUCER_GPU ((uint16_t)1 << 1) +#define MALI_GRALLOC_PRODUCER_DPU ((uint16_t)1 << 2) +#define MALI_GRALLOC_PRODUCER_VPU ((uint16_t)1 << 4) +#define MALI_GRALLOC_PRODUCER_CAM ((uint16_t)1 << 5) +#define GOOGLE_GRALLOC_PRODUCER_BO ((uint16_t)1 << 6) +#define GOOGLE_GRALLOC_PRODUCER_MFC ((uint16_t)1 << 7) +#define GOOGLE_GRALLOC_PRODUCER_VPUS_MASK (MALI_GRALLOC_PRODUCER_VPU | GOOGLE_GRALLOC_PRODUCER_BO | GOOGLE_GRALLOC_PRODUCER_MFC) +#define GOOGLE_GRALLOC_PRODUCER_TPU ((uint16_t)1 << 8) + +#define MALI_GRALLOC_CONSUMER_CPU ((uint16_t)1 << 0) +#define MALI_GRALLOC_CONSUMER_GPU ((uint16_t)1 << 1) +#define MALI_GRALLOC_CONSUMER_DPU ((uint16_t)1 << 2) +#define MALI_GRALLOC_CONSUMER_VPU ((uint16_t)1 << 3) +#define GOOGLE_GRALLOC_CONSUMER_BO ((uint16_t)1 << 4) +#define GOOGLE_GRALLOC_CONSUMER_MFC ((uint16_t)1 << 5) +#define GOOGLE_GRALLOC_CONSUMER_VPUS_MASK (MALI_GRALLOC_CONSUMER_VPU | GOOGLE_GRALLOC_CONSUMER_BO | GOOGLE_GRALLOC_CONSUMER_MFC) +#define GOOGLE_GRALLOC_CONSUMER_TPU ((uint16_t)1 << 6) typedef struct { uint32_t base_format; uint64_t format_ext; - uint16_t f_flags; + format_support_flags f_flags; } fmt_props; - - -static bool get_block_capabilities(const char *name, mali_gralloc_format_caps *block_caps) -{ - /* Exynos IPs do not provide AFBC capability info during runtime */ -#if 1 - GRALLOC_UNUSED(name); - GRALLOC_UNUSED(block_caps); - return false; -#else - void *dso_handle = NULL; - bool rval = false; - - /* Clear any error conditions */ - dlerror(); - - /* Look for MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR symbol in user-space drivers - * to determine hw format capabilities. - */ - dso_handle = dlopen(name, RTLD_LAZY); - - if (dso_handle) - { - void *sym = dlsym(dso_handle, MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR); - - if (sym) - { - memcpy((void *)block_caps, sym, sizeof(mali_gralloc_format_caps)); - rval = true; - } - else - { - AERR("Symbol %s is not found in %s shared object", - MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR, name); - } - dlclose(dso_handle); - } - else - { - AWAR("Unable to dlopen %s shared object, error = %s", name, dlerror()); - } - - return rval; -#endif -} - - /* - * Obtains the capabilities of each media system IP that form the producers - * and consumers. Default capabilities are assigned (within this function) for - * each IP, based on CFLAGS which specify the version of each IP (or, for GPU, - * explicit features): - * - GPU: MALI_GPU_SUPPORT_* - * - * See src/Android.mk for default values. - * - * These defaults can be overridden by runtime capabilities defined in the - * userspace drivers (*.so) loaded for each IP. The drivers should define a - * symbol named MALI_GRALLOC_FORMATCAPS_SYM_NAME, which contains all - * capabilities from set MALI_GRALLOC_FORMAT_CAPABILITY_* + * Video encoder consumer can be signalled by a combination of usage flags + * Besides VIDEO_ENCODER, clients can specify the specific IP block they belong + * to, for fine-grained control over capabilities. * - * @return none. + * @param usage [in] Buffer usage. * - * NOTE: although no capabilities are returned, global variables global variables - * named '*_runtime_caps' are updated. + * @return The corresponding consumer flag, or 0 if the consumer is not a VPU. */ -static void get_ip_capabilities(void) +static uint16_t get_vpu_consumer(uint64_t usage) { - /* Ensure capability setting is not interrupted by other - * allocations during start-up. - */ - pthread_mutex_lock(&caps_init_mutex); - - if (runtime_caps_read) - { - goto already_init; - } + if (!(usage & hidl_common::BufferUsage::VIDEO_ENCODER)) + return 0; - sanitize_formats(); + /* When both the BO and MFC flags are present, the assumption is BO is the + producer and MFC is the consumer. There is no use case as of now in which + MFC is the producer and BO is the consumer. */ + if (usage & GRALLOC_USAGE_GOOGLE_IP_MFC) + return GOOGLE_GRALLOC_CONSUMER_MFC; - memset((void *)&cpu_runtime_caps, 0, sizeof(cpu_runtime_caps)); - memset((void *)&dpu_runtime_caps, 0, sizeof(dpu_runtime_caps)); - memset((void *)&dpu_aeu_runtime_caps, 0, sizeof(dpu_aeu_runtime_caps)); - memset((void *)&vpu_runtime_caps, 0, sizeof(vpu_runtime_caps)); - memset((void *)&gpu_runtime_caps, 0, sizeof(gpu_runtime_caps)); - memset((void *)&cam_runtime_caps, 0, sizeof(cam_runtime_caps)); + if (usage & GRALLOC_USAGE_GOOGLE_IP_BO) + return GOOGLE_GRALLOC_CONSUMER_BO; - /* Determine CPU IP capabilities */ - cpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; - cpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102; - cpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616; - - /* Determine DPU IP capabilities */ - dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; - dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; - dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_READ; - dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102; - - /* Determine GPU IP capabilities */ - if (access(MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, R_OK) == 0) - { - get_block_capabilities(MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps); - } - else if (access(MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, R_OK) == 0) - { - get_block_capabilities(MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps); - } - - if ((gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) == 0) - { - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102; - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616; -#if MALI_GPU_SUPPORT_AFBC_BASIC == 1 - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_READ; - -#if MALI_GPU_SUPPORT_AFBC_YUV_WRITE == 1 - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE; -#endif - -#if MALI_GPU_SUPPORT_AFBC_SPLITBLK == 1 - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; -#endif - -#if MALI_GPU_SUPPORT_AFBC_WIDEBLK == 1 - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK; -#endif - -#if MALI_GPU_SUPPORT_AFBC_TILED_HEADERS == 1 - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK; - gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS; -#endif -#endif /* MALI_GPU_SUPPORT_AFBC_BASIC == 1 */ - } - - /* Determine VPU IP capabilities */ - vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; - vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; - vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE; - - cam_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; - -/* Build specific capability changes */ -#if GRALLOC_ARM_NO_EXTERNAL_AFBC == 1 - { - dpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; - gpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; - vpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; - cam_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; - } -#endif - - runtime_caps_read = true; - -already_init: - pthread_mutex_unlock(&caps_init_mutex); - - ALOGV("format capabilities GPU(0x%" PRIx64 ") DPU(0x%" PRIx64 ") VPU(0x%" PRIx64 ") CAM(0x%" PRIx64 ")", - gpu_runtime_caps.caps_mask, - dpu_runtime_caps.caps_mask, - vpu_runtime_caps.caps_mask, - cam_runtime_caps.caps_mask); -} - - -/* This is used by the unit tests to get the capabilities for each IP. */ -extern "C" { - void mali_gralloc_get_caps(struct mali_gralloc_format_caps *gpu_caps, - struct mali_gralloc_format_caps *vpu_caps, - struct mali_gralloc_format_caps *dpu_caps, - struct mali_gralloc_format_caps *dpu_aeu_caps, - struct mali_gralloc_format_caps *cam_caps) - { - get_ip_capabilities(); - - memcpy(gpu_caps, (void *)&gpu_runtime_caps, sizeof(*gpu_caps)); - memcpy(vpu_caps, (void *)&vpu_runtime_caps, sizeof(*vpu_caps)); - memcpy(dpu_caps, (void *)&dpu_runtime_caps, sizeof(*dpu_caps)); - memcpy(dpu_aeu_caps, (void *)&dpu_aeu_runtime_caps, sizeof(*dpu_aeu_caps)); - memcpy(cam_caps, (void *)&cam_runtime_caps, sizeof(*cam_caps)); - } + // TODO(b/185896428): Support 64-bits usage version for GraphicBufferSource + return GOOGLE_GRALLOC_CONSUMER_MFC; } - /* * Determines all IP consumers included by the requested buffer usage. - * Capabilities must be defined (OPTIONS_PRESENT) to indicate that an IP is part - * of the media system (otherwise it will be ignored). Private usage flags are - * excluded from this process. + * Private usage flags are excluded from this process. * * @param usage [in] Buffer usage. * @@ -283,23 +107,21 @@ static uint16_t get_consumers(uint64_t usage) if (usage & GS101_GRALLOC_USAGE_TPU_INPUT) { - consumers |= MALI_GRALLOC_CONSUMER_TPU; + consumers |= GOOGLE_GRALLOC_CONSUMER_TPU; } - /* Other private usages are not applicable to consumer derivation */ - usage &= ~GRALLOC_USAGE_PRIVATE_MASK; + /* Exclude usages also not applicable to consumer derivation */ + usage &= ~GRALLOC_USAGE_PROTECTED; get_ip_capabilities(); - if (usage == GRALLOC_USAGE_HW_COMPOSER && - dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + if ((usage & GRALLOC_USAGE_PUBLIC_MASK) == GRALLOC_USAGE_HW_COMPOSER) { consumers = MALI_GRALLOC_CONSUMER_DPU; } else { - if (usage & GRALLOC_USAGE_SW_READ_MASK && - cpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + if (usage & GRALLOC_USAGE_SW_READ_MASK) { consumers |= MALI_GRALLOC_CONSUMER_CPU; } @@ -309,17 +131,12 @@ static uint16_t get_consumers(uint64_t usage) * can be consumed by even the most basic display processor which does * not support multi-layer composition. */ - if (usage & GRALLOC_USAGE_HW_FB && - dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + if (usage & GRALLOC_USAGE_HW_FB) { consumers |= MALI_GRALLOC_CONSUMER_DPU; } - if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER && - vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) - { - consumers |= MALI_GRALLOC_CONSUMER_VPU; - } + consumers |= get_vpu_consumer(usage); /* GRALLOC_USAGE_HW_COMPOSER does not explicitly define whether the * display processor is producer or consumer. When used in combination @@ -327,27 +144,15 @@ static uint16_t get_consumers(uint64_t usage) * GPU and DPU both act as compositors. */ if ((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER)) == - (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER) && - dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER)) { consumers |= MALI_GRALLOC_CONSUMER_DPU; } - if (usage & GRALLOC_USAGE_HW_TEXTURE && - gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_GPU_DATA_BUFFER)) { consumers |= MALI_GRALLOC_CONSUMER_GPU; } - - if (usage & GRALLOC_USAGE_HW_CAMERA_READ) - { - consumers |= MALI_GRALLOC_CONSUMER_CAM; - } - - if (usage & GRALLOC_USAGE_HW_COMPOSER) - { - consumers |= MALI_GRALLOC_CONSUMER_DPU; - } } return consumers; @@ -355,9 +160,8 @@ static uint16_t get_consumers(uint64_t usage) /* * Video decoder producer can be signalled by a combination of usage flags - * (see definition of GRALLOC_USAGE_DECODER). - * However, individual HAL usage bits may also signal it. - * This function handles both cases. + * Besides VIDEO_DECODER, clients can specify the specific IP block they belong + * to, for fine-grained control over capabilities. * * @param usage [in] Buffer usage. * @@ -365,22 +169,25 @@ static uint16_t get_consumers(uint64_t usage) */ static uint16_t get_vpu_producer(uint64_t usage) { - if ((usage & GRALLOC_USAGE_DECODER) == GRALLOC_USAGE_DECODER) - { - return MALI_GRALLOC_PRODUCER_VPU; - } - if (usage & GRALLOC_USAGE_VIDEO_DECODER) - { - return MALI_GRALLOC_PRODUCER_VPU; - } - return 0; + if (!(usage & hidl_common::BufferUsage::VIDEO_DECODER)) + return 0; + + /* When both the BO and MFC flags are present, the assumption is BO is the + producer and MFC is the consumer. There is no use case as of now in which + MFC is the producer and BO is the consumer. */ + if (usage & GRALLOC_USAGE_GOOGLE_IP_BO) + return GOOGLE_GRALLOC_PRODUCER_BO; + + if (usage & GRALLOC_USAGE_GOOGLE_IP_MFC) + return GOOGLE_GRALLOC_PRODUCER_MFC; + + MALI_GRALLOC_LOGV("Video producer IP not specified, falling back to default VPU producer"); + return MALI_GRALLOC_PRODUCER_VPU; } /* * Determines all IP producers included by the requested buffer usage. - * Capabilities must be defined (OPTIONS_PRESENT) to indicate that an IP is part - * of the media system (otherwise it will be ignored). Private usage flags are - * excluded from this process. + * Private usage flags are excluded from this process. * * @param usage [in] Buffer usage. * @@ -393,59 +200,53 @@ static uint16_t get_producers(uint64_t usage) if (usage & GS101_GRALLOC_USAGE_TPU_OUTPUT) { - producers |= MALI_GRALLOC_PRODUCER_TPU; + producers |= GOOGLE_GRALLOC_PRODUCER_TPU; } - /* Other private usages are not applicable to producer derivation */ - usage &= ~GRALLOC_USAGE_PRIVATE_MASK; + /* Exclude usages also not applicable to producer derivation */ + usage &= ~GRALLOC_USAGE_PROTECTED; get_ip_capabilities(); - if (usage == GRALLOC_USAGE_HW_COMPOSER && - dpu_aeu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + if (usage & GRALLOC_USAGE_SW_WRITE_MASK) { - producers = MALI_GRALLOC_PRODUCER_DPU_AEU; + producers |= MALI_GRALLOC_PRODUCER_CPU; } - else - { - if (usage & GRALLOC_USAGE_SW_WRITE_MASK && - cpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) - { - producers |= MALI_GRALLOC_PRODUCER_CPU; - } - /* DPU is normally consumer however, when there is an alternative - * consumer (VPU) and no other producer (e.g. VPU), it acts as a producer. - */ - if ((usage & GRALLOC_USAGE_DECODER) != GRALLOC_USAGE_DECODER && - (usage & (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) == - (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER) && - dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) - { - producers |= MALI_GRALLOC_PRODUCER_DPU; - } - - if (usage & GRALLOC_USAGE_HW_RENDER && - gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) - { - producers |= MALI_GRALLOC_PRODUCER_GPU; - } - - if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) - { - producers |= MALI_GRALLOC_PRODUCER_CAM; - } + /* DPU is normally consumer however, when there is an alternative + * consumer (VPU) and no other producer (e.g. VPU), it acts as a producer. + */ + if ((usage & GRALLOC_USAGE_DECODER) != GRALLOC_USAGE_DECODER && + (usage & (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) == + (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) + { + producers |= MALI_GRALLOC_PRODUCER_DPU; + } + if (usage & (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER)) + { + producers |= MALI_GRALLOC_PRODUCER_GPU; + } - if ((vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)) - { - producers |= get_vpu_producer(usage); - } + if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) + { + producers |= MALI_GRALLOC_PRODUCER_CAM; } + producers |= get_vpu_producer(usage); + return producers; } +static inline bool consumers_use_cpu_caps(uint16_t consumers) +{ + return consumers & (MALI_GRALLOC_CONSUMER_CPU | GOOGLE_GRALLOC_CONSUMER_TPU); +} + +static inline bool producers_use_cpu_caps(uint16_t producers) +{ + return producers & (MALI_GRALLOC_PRODUCER_CPU | GOOGLE_GRALLOC_PRODUCER_TPU); +} /* * Determines the intersection of all IP consumers capability sets. Since all @@ -468,8 +269,7 @@ static uint64_t get_consumer_caps(const uint16_t consumers) /* Consumers can't write */ consumer_caps &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE; - if ((consumers & MALI_GRALLOC_CONSUMER_CPU) || - (consumers & MALI_GRALLOC_CONSUMER_TPU)) + if (consumers_use_cpu_caps(consumers)) { consumer_caps &= cpu_runtime_caps.caps_mask; } @@ -492,6 +292,20 @@ static uint64_t get_consumer_caps(const uint16_t consumers) consumer_caps &= vpu_runtime_caps.caps_mask; } + if (consumers & GOOGLE_GRALLOC_CONSUMER_BO && + bo_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + { + consumer_caps &= bo_runtime_caps.caps_mask; + } + + if (consumers & GOOGLE_GRALLOC_CONSUMER_MFC && + mfc_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + { + consumer_caps &= mfc_runtime_caps.caps_mask; + } + + /* TODO: if consumers is 0, set consumer_caps to 0 as well */ + return consumer_caps; } @@ -512,13 +326,18 @@ static uint64_t get_producer_caps(const uint16_t producers) { uint64_t producer_caps = ~0; + if (producers == 0) + { + /* When no producer is specified assume no capabilities. */ + return 0; + } + get_ip_capabilities(); /* Producers can't read */ producer_caps &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_READ; - if ((producers & MALI_GRALLOC_PRODUCER_CPU) || - (producers & MALI_GRALLOC_PRODUCER_TPU)) + if (producers_use_cpu_caps(producers)) { producer_caps &= cpu_runtime_caps.caps_mask; } @@ -535,12 +354,6 @@ static uint64_t get_producer_caps(const uint16_t producers) producer_caps &= dpu_runtime_caps.caps_mask; } - if (producers & MALI_GRALLOC_PRODUCER_DPU_AEU && - dpu_aeu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) - { - producer_caps &= dpu_aeu_runtime_caps.caps_mask; - } - if (producers & MALI_GRALLOC_PRODUCER_CAM && cam_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) { @@ -553,6 +366,18 @@ static uint64_t get_producer_caps(const uint16_t producers) producer_caps &= vpu_runtime_caps.caps_mask; } + if (producers & GOOGLE_GRALLOC_PRODUCER_BO && + bo_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + { + producer_caps &= bo_runtime_caps.caps_mask; + } + + if (producers & GOOGLE_GRALLOC_PRODUCER_MFC && + mfc_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + { + producer_caps &= mfc_runtime_caps.caps_mask; + } + return producer_caps; } @@ -575,7 +400,7 @@ void mali_gralloc_adjust_dimensions(const uint64_t alloc_format, int* const width, int* const height) { - /* Determine producers and consumers. */ + /* Determine producers. */ const uint16_t producers = get_producers(usage); /* @@ -583,7 +408,7 @@ void mali_gralloc_adjust_dimensions(const uint64_t alloc_format, * rows of 16x16 superblocks). Cropping will be applied to internal * dimensions to fit the public size. */ - if ((producers & MALI_GRALLOC_PRODUCER_VPU) && + if ((producers & GOOGLE_GRALLOC_PRODUCER_VPUS_MASK) && (alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)) { const int32_t idx = get_format_index(alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); @@ -607,10 +432,10 @@ void mali_gralloc_adjust_dimensions(const uint64_t alloc_format, } } - ALOGV("%s: alloc_format=(%s 0x%" PRIx64 ") usage=0x%" PRIx64 - " alloc_width=%u, alloc_height=%u", - __FUNCTION__, format_name(alloc_format), alloc_format, - usage, *width, *height); + MALI_GRALLOC_LOGV("%s: alloc_format=(%s 0x%" PRIx64 ") usage=(%s 0x%" PRIx64 + ") alloc_width=%u, alloc_height=%u", + __FUNCTION__, format_name(alloc_format), alloc_format, describe_usage(usage).c_str(), + usage, *width, *height); } @@ -623,20 +448,16 @@ void mali_gralloc_adjust_dimensions(const uint64_t alloc_format, * @param consumers [in] Consumers (flags). * @param format [in] Format entry in IP support table. * - * @return format support (flags) comprising: - * F_NONE: None - * F_LIN: Uncompressed/linear - * F_AFBC: AFBC (via modifiers) + * @return format support flags. */ -static uint16_t ip_supports_base_format(const uint16_t producers, - const uint16_t consumers, - const format_ip_support_t * const format) +static format_support_flags ip_supports_base_format(const uint16_t producers, + const uint16_t consumers, + const format_ip_support_t * const format) { - uint32_t support = ~0; + format_support_flags support = ~0; /* Determine producer support for base format. */ - if ((producers & MALI_GRALLOC_PRODUCER_CPU) || - (producers & MALI_GRALLOC_PRODUCER_TPU)) + if (producers_use_cpu_caps(producers)) { support &= format->cpu_wr; } @@ -648,23 +469,17 @@ static uint16_t ip_supports_base_format(const uint16_t producers, { support &= format->dpu_wr; } - if (producers & MALI_GRALLOC_PRODUCER_DPU_AEU) - { - support &= format->dpu_aeu_wr; - } if (producers & MALI_GRALLOC_PRODUCER_CAM) { - /* There is no implementation for camera */ - //support &= format->cam_wr; + support &= format->cam_wr; } - if (producers & MALI_GRALLOC_PRODUCER_VPU) + if (producers & GOOGLE_GRALLOC_PRODUCER_VPUS_MASK) { support &= format->vpu_wr; } - /* Determine producer support for base format. */ - if ((consumers & MALI_GRALLOC_CONSUMER_CPU) || - (producers & MALI_GRALLOC_PRODUCER_TPU)) + /* Determine consumer support for base format. */ + if (consumers_use_cpu_caps(consumers)) { support &= format->cpu_rd; } @@ -676,7 +491,7 @@ static uint16_t ip_supports_base_format(const uint16_t producers, { support &= format->dpu_rd; } - if (consumers & MALI_GRALLOC_CONSUMER_VPU) + if (consumers & GOOGLE_GRALLOC_CONSUMER_VPUS_MASK) { support &= format->vpu_rd; } @@ -755,22 +570,19 @@ static inline bool is_afbc_multiplane_supported(const uint16_t producers, * @param producer_caps [in] Producer capabilities (flags). * @param consumer_caps [in] Consumer capabilities (flags). * - * @return format support (flags) comprising: - * F_NONE: None - * F_LIN: Uncompressed/linear - * F_AFBC: AFBC (via modifiers) + * @return format support flags. */ -static uint8_t is_format_supported(const int32_t fmt_idx, - const int32_t ip_fmt_idx, - const uint64_t usage, - const uint16_t producers, - const uint16_t consumers, - const uint64_t producer_caps, - const uint64_t consumer_caps) +static format_support_flags is_format_supported(const int32_t fmt_idx, + const int32_t ip_fmt_idx, + const uint64_t usage, + const uint16_t producers, + const uint16_t consumers, + const uint64_t producer_caps, + const uint64_t consumer_caps) { /* Determine format support from table. */ - uint8_t f_flags = ip_supports_base_format(producers, consumers, - &formats_ip_support[ip_fmt_idx]); + format_support_flags f_flags = ip_supports_base_format(producers, consumers, + &formats_ip_support[ip_fmt_idx]); /* Determine whether producers/consumers support required AFBC features. */ if (f_flags & F_AFBC) @@ -803,35 +615,36 @@ static uint8_t is_format_supported(const int32_t fmt_idx, } } - if (usage & MALI_GRALLOC_USAGE_FRONTBUFFER) + if (usage & GRALLOC_USAGE_FRONT_BUFFER) { if ((producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_DOUBLE_BODY) == 0) { f_flags &= ~F_AFBC; } } - - if (usage & GRALLOC_USAGE_PROTECTED) - { - f_flags &= ~F_AFBC; - } } - if (f_flags != F_NONE) { -#if PLATFORM_SDK_VERSION >= 26 if (formats[fmt_idx].id == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 && (producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0) { + /* TODO: forcing F_LIN is a W/A. Make a proper solution */ f_flags = F_NONE; + f_flags = F_LIN; } - - if (formats[fmt_idx].id == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 && - (producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0) + else if (formats[fmt_idx].id == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616) { - f_flags = F_NONE; + if ((producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0) + { + /* TODO: forcing F_LIN is a W/A. Make a proper solution */ + //f_flags = F_NONE; + f_flags = F_LIN; + } + else if ((producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_RGBA16161616) == 0) + { + f_flags = F_LIN; + } } -#endif } return f_flags; @@ -917,7 +730,7 @@ static uint64_t validate_afbc_format(uint64_t alloc_format, if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) && (producer_active_caps & consumer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) == 0) { - ALOGE("AFBC basic selected but not supported by producer/consumer. Disabling " + MALI_GRALLOC_LOGE("AFBC basic selected but not supported by producer/consumer. Disabling " "MALI_GRALLOC_INTFMT_AFBC_BASIC"); alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_BASIC; } @@ -925,7 +738,7 @@ static uint64_t validate_afbc_format(uint64_t alloc_format, if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK) && (producer_active_caps & consumer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK) == 0) { - ALOGE("AFBC split-block selected but not supported by producer/consumer. Disabling " + MALI_GRALLOC_LOGE("AFBC split-block selected but not supported by producer/consumer. Disabling " "MALI_GRALLOC_INTFMT_AFBC_SPLITBLK"); alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_SPLITBLK; } @@ -933,7 +746,7 @@ static uint64_t validate_afbc_format(uint64_t alloc_format, if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) && (producer_active_caps & consumer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK) == 0) { - ALOGE("AFBC wide-block selected but not supported by producer/consumer. Disabling " + MALI_GRALLOC_LOGE("AFBC wide-block selected but not supported by producer/consumer. Disabling " "MALI_GRALLOC_INTFMT_AFBC_WIDEBLK"); alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_WIDEBLK; } @@ -941,11 +754,19 @@ static uint64_t validate_afbc_format(uint64_t alloc_format, if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) && (producer_active_caps & consumer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) == 0) { - ALOGE("AFBC tiled-headers selected but not supported by producer/consumer. Disabling " + MALI_GRALLOC_LOGE("AFBC tiled-headers selected but not supported by producer/consumer. Disabling " "MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS"); alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; } + if (!((alloc_format & MALI_GRALLOC_INTFMT_AFBC_SPARSE) || + (producer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WRITE_NON_SPARSE))) + { + MALI_GRALLOC_LOGE("AFBC sparse not selected while producer cannot write non-sparse. Enabling " + "MALI_GRALLOC_INTFMT_AFBC_SPARSE"); + alloc_format |= MALI_GRALLOC_INTFMT_AFBC_SPARSE; + } + return alloc_format; } @@ -980,14 +801,17 @@ static uint64_t get_afbc_format(const uint32_t base_format, * and consumers. NOTE: AFBC is not supported for video transcode (VPU --> VPU). */ if (producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT && - ((producer & MALI_GRALLOC_PRODUCER_VPU) == 0 || (consumer & MALI_GRALLOC_CONSUMER_VPU) == 0)) + ((producer & GOOGLE_GRALLOC_PRODUCER_VPUS_MASK) == 0 || (consumer & GOOGLE_GRALLOC_CONSUMER_VPUS_MASK) == 0)) { if (producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC && consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) { alloc_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC; +#if 0 const int format_idx = get_format_index(base_format); + + /* TODO: AFBC YUV TRANSFORM corrupts screen when enabled. find out why */ if (format_idx != -1) { if (formats[format_idx].yuv_transform == true) @@ -995,13 +819,19 @@ static uint64_t get_afbc_format(const uint32_t base_format, alloc_format |= MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM; } } +#endif + + if (!(producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WRITE_NON_SPARSE)) + { + alloc_format |= MALI_GRALLOC_INTFMT_AFBC_SPARSE; + } if (producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS && consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) { alloc_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; - if (usage & MALI_GRALLOC_USAGE_FRONTBUFFER && + if (usage & GRALLOC_USAGE_FRONT_BUFFER && producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_DOUBLE_BODY) { alloc_format |= MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY; @@ -1103,16 +933,31 @@ static void get_active_caps(const format_info_t format, MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK); } + if (consumers & MALI_GRALLOC_CONSUMER_DPU) + { + /* DPU does not support split-block other than RGB(A) 24/32-bit */ + if (!format.is_rgb || format.bpp[0] < 24) + { + if (consumers & MALI_GRALLOC_CONSUMER_DPU) + { + consumer_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; + } + } + } + bool afbc_allowed = false; afbc_allowed = buffer_size > (192 * 192); -#if GRALLOC_DISP_W != 0 && GRALLOC_DISP_H != 0 if (consumers & MALI_GRALLOC_CONSUMER_DPU) { + /* TODO: make this into an option in BoardConfig */ +#if GRALLOC_DISP_W != 0 && GRALLOC_DISP_H != 0 +#define GRALLOC_AFBC_MIN_SIZE 40 /* Disable AFBC based on buffer dimensions */ - afbc_allowed = afbc_allowed && ((buffer_size * 100) / (GRALLOC_DISP_W * GRALLOC_DISP_H)) >= GRALLOC_AFBC_MIN_SIZE; - } + afbc_allowed = ((buffer_size * 100) / (GRALLOC_DISP_W * GRALLOC_DISP_H)) >= GRALLOC_AFBC_MIN_SIZE; #endif + } + if (!afbc_allowed) { consumer_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; @@ -1130,10 +975,7 @@ static void get_active_caps(const format_info_t format, /* - * Obtains support flags and modifiers for base format. Support flags are: - * - F_NONE: None - * - F_LIN: Uncompressed/linear - * - F_AFBC: AFBC (via modifiers) + * Obtains support flags and modifiers for base format. * * @param base_format [in] Base format for which to deduce support. * @param usage [in] Buffer usage. @@ -1160,7 +1002,7 @@ bool get_supported_format(const uint32_t base_format, if (ip_fmt_idx == -1) { /* Return undefined base format. */ - AERR("Failed to find IP support info for format id: 0x%" PRIx32, + MALI_GRALLOC_LOGE("Failed to find IP support info for format id: 0x%" PRIx32, base_format); return false; } @@ -1172,7 +1014,7 @@ bool get_supported_format(const uint32_t base_format, consumers, producer_active_caps, consumer_active_caps); - ALOGV("IP support: 0x%" PRIx16, fmt_supported->f_flags); + MALI_GRALLOC_LOGV("IP support: 0x%" PRIx16, fmt_supported->f_flags); if (fmt_supported->f_flags == F_NONE && consumers & MALI_GRALLOC_CONSUMER_GPU && consumers & MALI_GRALLOC_CONSUMER_DPU) @@ -1203,17 +1045,17 @@ bool get_supported_format(const uint32_t base_format, } fmt_supported->base_format = base_format; - if (fmt_supported->f_flags & F_AFBC) { const uint64_t afbc_format = get_afbc_format(base_format, - usage, - producers, - consumers, - producer_active_caps, - consumer_active_caps); + usage, + producers, + consumers, + producer_active_caps, + consumer_active_caps); - ALOGV("AFBC format: (%s 0x%" PRIx64 ")", format_name(afbc_format), afbc_format); + MALI_GRALLOC_LOGV("AFBC format: (%s 0x%" PRIx64 ")", + format_name(afbc_format), afbc_format); /* Disable AFBC when forced by usage or no format modifiers selected. */ if ((usage & MALI_GRALLOC_USAGE_NO_AFBC) == MALI_GRALLOC_USAGE_NO_AFBC || @@ -1223,7 +1065,7 @@ bool get_supported_format(const uint32_t base_format, } /* Check that AFBC features are correct for multiplane format. */ - alloc_type_t alloc_type; + alloc_type_t alloc_type{}; get_alloc_type(afbc_format & MALI_GRALLOC_INTFMT_EXT_MASK, fmt_idx, usage, @@ -1236,13 +1078,13 @@ bool get_supported_format(const uint32_t base_format, /* Store any format modifiers */ fmt_supported->format_ext = afbc_format & MALI_GRALLOC_INTFMT_EXT_MASK; } - if ((fmt_supported->f_flags & F_AFBC) == 0) { fmt_supported->format_ext = 0; } - ALOGV("AFBC ext format: 0x%" PRIx64, fmt_supported->format_ext); + MALI_GRALLOC_LOGV("Ext format: (%s 0x%" PRIx64 ")", format_name(fmt_supported->format_ext), + fmt_supported->format_ext); return (fmt_supported->f_flags == F_NONE) ? false : true; } @@ -1261,10 +1103,10 @@ bool get_supported_format(const uint32_t base_format, static bool comparable_components(const format_info_t * const f_old, const format_info_t * const f_new) { - if (f_old->is_yuv) + if (f_old->is_yuv && f_new->bps == f_old->bps) { /* Formats have the same number of components. */ - if (f_new->ncmp == f_old->ncmp) + if (f_new->total_components() == f_old->total_components()) { return true; } @@ -1275,7 +1117,7 @@ static bool comparable_components(const format_info_t * const f_old, */ if (f_old->has_alpha) { - if (f_new->ncmp == 3 && + if (f_new->total_components() == 3 && f_new->is_yuv && !f_new->has_alpha) { @@ -1285,10 +1127,12 @@ static bool comparable_components(const format_info_t * const f_old, } else if (f_old->is_rgb) { - if (f_new->ncmp == f_old->ncmp && - f_new->bpp[0] == f_old->bpp[0]) + if (f_new->total_components() == f_old->total_components()) { - return true; + if (f_new->bpp[0] == f_old->bpp[0] && f_new->bps == f_old->bps) + { + return true; + } } } else @@ -1316,8 +1160,7 @@ static bool comparable_components(const format_info_t * const f_old, static bool is_format_compatible(const format_info_t * const f_old, const format_info_t * const f_new) { - if (f_new->bps == f_old->bps && - f_new->hsub == f_old->hsub && + if (f_new->hsub == f_old->hsub && f_new->vsub == f_old->vsub && f_new->is_rgb == f_old->is_rgb && f_new->is_yuv == f_old->is_yuv && @@ -1331,6 +1174,46 @@ static bool is_format_compatible(const format_info_t * const f_old, } } +/** + * Provide a grade for the compatible format with respect to the requested format. Used to find the best compatible + * format. + * + * @param fmt[in] Compatible format properties. + * @param req_format Requested base format. + * + * @return The grade of the compatible format. Higher is better. Returns 0 if format extensions are incompatible with + * requested format. + */ +uint64_t grade_format(const fmt_props &fmt, uint32_t req_format) +{ + uint64_t grade = 1; + + GRALLOC_UNUSED(req_format); + + static const struct { + uint64_t fmt_ext; + uint64_t value; + } fmt_ext_values[] { + { MALI_GRALLOC_INTFMT_AFBC_BASIC, 1 }, + { MALI_GRALLOC_INTFMT_AFBC_SPLITBLK, 1 }, + { MALI_GRALLOC_INTFMT_AFBC_WIDEBLK, 1 }, + { MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS, 1 }, + { MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK, 1 }, + { MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY, 1 }, + { MALI_GRALLOC_INTFMT_AFBC_BCH, 1 }, + { MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM, 1 }, + { MALI_GRALLOC_INTFMT_AFBC_SPARSE, 1 }, + }; + for (auto& ext : fmt_ext_values) + { + if (fmt.format_ext & ext.fmt_ext) + { + grade += ext.value; + } + } + + return grade; +} /* * Obtains the 'best' allocation format for requested format and usage: @@ -1363,8 +1246,9 @@ static uint64_t get_best_format(const uint32_t req_base_format, assert(req_base_format != MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED); const int32_t req_fmt_idx = get_format_index(req_base_format); - ALOGV("req_base_format: (%s 0x%" PRIx32 ")", - format_name(req_base_format), req_base_format); + MALI_GRALLOC_LOGV("req_base_format: (%s 0x%" PRIx32 ")", + format_name(req_base_format), req_base_format); + MALI_GRALLOC_LOGV("req_fmt_idx: %d", req_fmt_idx); assert(req_fmt_idx >= 0); /* 1. Find compatible base formats. */ @@ -1375,8 +1259,8 @@ static uint64_t get_best_format(const uint32_t req_base_format, { fmt_props fmt = {0, 0, 0}; fmt.base_format = formats[i].id; - ALOGV("Compatible: Base-format: (%s 0x%" PRIx32 ")", - format_name(fmt.base_format), fmt.base_format); + MALI_GRALLOC_LOGV("Compatible: Base-format: (%s 0x%" PRIx32 ")", + format_name(fmt.base_format), fmt.base_format); f_compat.push_back(fmt); } } @@ -1387,13 +1271,14 @@ static uint64_t get_best_format(const uint32_t req_base_format, */ int32_t num_supported_formats = 0; - int32_t req_format_num_extn_bits = -1; - int32_t best_fmt_num_extn_bits = -1; + uint64_t req_format_grade = 0; + uint64_t best_fmt_grade = 0; uint64_t first_of_best_formats = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED; uint64_t req_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED; for (uint16_t i = 0; i < f_compat.size(); i++) { + MALI_GRALLOC_LOGV("Compatible: Base-format: 0x%" PRIx32, f_compat[i].base_format); fmt_props fmt = {0, 0, 0}; bool supported = get_supported_format(f_compat[i].base_format, usage, @@ -1404,32 +1289,26 @@ static uint64_t get_best_format(const uint32_t req_base_format, &fmt); if (supported) { - num_supported_formats++; - ALOGV("Supported: Base-format: (%s 0x%" PRIx32 "), Modifiers: 0x%" PRIx64 ", Flags: 0x%" PRIx16, - format_name(fmt.base_format), fmt.base_format, fmt.format_ext, fmt.f_flags); - - /* Calculate the number of modifier bits enabled for a supported format - * so as to identify best (highest modifier bits enabled) format among them - */ - int32_t sup_fmt_num_extn_bits = 0; - uint64_t format_ext = fmt.format_ext; - for (; format_ext; ++sup_fmt_num_extn_bits) + const uint64_t sup_fmt_grade = grade_format(fmt, req_base_format); + if (sup_fmt_grade) { - format_ext &= format_ext - 1; - } + num_supported_formats++; + MALI_GRALLOC_LOGV("Supported: Base-format: (%s 0x%" PRIx32 "), Modifiers: 0x%" PRIx64 ", Flags: 0x%" PRIx16, + format_name(fmt.base_format), fmt.base_format, fmt.format_ext, fmt.f_flags); - /* 3. Find best modifiers from supported base formats */ - if (sup_fmt_num_extn_bits > best_fmt_num_extn_bits) - { - best_fmt_num_extn_bits = sup_fmt_num_extn_bits; - first_of_best_formats = fmt.base_format | fmt.format_ext; - } + /* 3. Find best modifiers from supported base formats */ + if (sup_fmt_grade > best_fmt_grade) + { + best_fmt_grade = sup_fmt_grade; + first_of_best_formats = fmt.base_format | fmt.format_ext; + } - /* Check if current supported format is same as requested format */ - if (fmt.base_format == req_base_format) - { - req_format_num_extn_bits = sup_fmt_num_extn_bits; - req_format = fmt.base_format | fmt.format_ext; + /* Check if current supported format is same as requested format */ + if (fmt.base_format == req_base_format) + { + req_format_grade = sup_fmt_grade; + req_format = fmt.base_format | fmt.format_ext; + } } } } @@ -1440,74 +1319,23 @@ static uint64_t get_best_format(const uint32_t req_base_format, /* Select first/one of best format when requested format is either not * supported or requested format is not the best format. */ - if ((req_format_num_extn_bits != best_fmt_num_extn_bits) && + if ((req_format_grade != best_fmt_grade) && (((producers & MALI_GRALLOC_PRODUCER_CPU) == 0) && ((consumers & MALI_GRALLOC_CONSUMER_CPU) == 0))) { alloc_format = first_of_best_formats; } - else if (req_format_num_extn_bits != -1) + else if (req_format_grade != 0) { alloc_format = req_format; } } - ALOGV("Selected format: (%s 0x%" PRIx64 ")", - format_name(alloc_format), alloc_format); + MALI_GRALLOC_LOGV("Selected format: (%s 0x%" PRIx64 ")", + format_name(alloc_format), alloc_format); return alloc_format; } -/* - * Determines whether multi-plane AFBC is supported with a set of format - * modifiers. This function does not consider producers and consumers. - * - * @param format_ext [in] Format modifiers (extension bits). - * - * @return 1, multiplane AFBC is supported - * 0, otherwise - */ -static inline bool is_multiplane_enabled(const uint64_t format_ext) -{ - const uint64_t modifiers = format_ext & MALI_GRALLOC_INTFMT_EXT_MASK; - - return ((modifiers & MALI_GRALLOC_INTFMT_AFBC_BASIC) && - (modifiers & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) && - (modifiers & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)) ? true : false; -} - -/* - * Determines the base format suitable for requested allocation format (base + - * modifiers). Going forward, the base format requested MUST be compatible with - * the format modifiers. In legacy mode, more leeway is given such that fallback - * to a supported base format for multi-plane AFBC formats is handled here - * within the gralloc implementation. - * - * @param fmt_idx [in] Index into format properties table (base format). - * @param format_ext [in] Format modifiers (extension bits). - * - * @return base_format, suitable for modifiers; - * MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED, otherwise - */ -static uint32_t get_base_format_for_modifiers(const int32_t fmt_idx, - const uint64_t format_ext) -{ - uint32_t base_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED; - - if (format_ext == 0) - { - /* Uncompressed formats have no forced fallback. */ - base_format = formats[fmt_idx].id; - } - else if (formats[fmt_idx].afbc && - (formats[fmt_idx].npln == 1 || is_multiplane_enabled(format_ext))) - { - /* Requested format modifiers are suitable for base format. */ - base_format = formats[fmt_idx].id; - } - - return base_format; -} - /* * Obtain format modifiers from requested format. @@ -1520,18 +1348,9 @@ static uint32_t get_base_format_for_modifiers(const int32_t fmt_idx, */ uint64_t get_format_ext(const uint64_t req_format, const uint64_t usage) { - uint64_t format_ext = 0; - - if (usage & MALI_GRALLOC_USAGE_PRIVATE_FORMAT) - { - format_ext = (req_format & MALI_GRALLOC_INTFMT_EXT_WRAP_MASK) << MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT; - } - else - { - format_ext = req_format & MALI_GRALLOC_INTFMT_EXT_MASK; - } - - return format_ext; + /* TODO: clean up this function. Or remove it */ + GRALLOC_UNUSED(usage); + return req_format & MALI_GRALLOC_INTFMT_EXT_MASK; } @@ -1562,40 +1381,8 @@ uint32_t get_base_format(const uint64_t req_format, uint32_t base_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED; - if (usage & MALI_GRALLOC_USAGE_PRIVATE_FORMAT) - { - base_format = req_format & MALI_GRALLOC_INTFMT_FMT_WRAP_MASK; - - if (base_format == MALI_GRALLOC_FORMAT_INTERNAL_YV12_WRAP) - { - base_format = MALI_GRALLOC_FORMAT_INTERNAL_YV12; - } - else if (base_format == MALI_GRALLOC_FORMAT_INTERNAL_Y8_WRAP) - { - base_format = MALI_GRALLOC_FORMAT_INTERNAL_Y8; - } - else if (base_format == MALI_GRALLOC_FORMAT_INTERNAL_Y16_WRAP) - { - base_format = MALI_GRALLOC_FORMAT_INTERNAL_Y16; - } - } - else - { - /* - * Internal format (NV12) overlaps with HAL format (JPEG). To disambiguate, - * reject HAL_PIXEL_FORMAT_JPEG when provided through the public interface. - * All formats requested through private interface (type == - * MALI_GRALLOC_FORMAT_TYPE_INTERNAL) should be accepted, including - * MALI_GRALLOC_FORMAT_INTERNAL_NV12 (same value as HAL_PIXEL_FORMAT_JPEG). - */ -#if PLATFORM_SDK_VERSION >= 26 && PLATFORM_SDK_VERSION < 28 - if (type == MALI_GRALLOC_FORMAT_TYPE_INTERNAL || req_format != HAL_PIXEL_FORMAT_JPEG) -#endif - { - /* Mask out extension bits which could be present with type 'internal'. */ - base_format = req_format & MALI_GRALLOC_INTFMT_FMT_MASK; - } - } + /* Mask out extension bits which could be present with type 'internal'. */ + base_format = req_format & MALI_GRALLOC_INTFMT_FMT_MASK; /* Map Android flexible formats to internal base formats */ if (req_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) @@ -1603,33 +1390,35 @@ uint32_t get_base_format(const uint64_t req_format, auto consumers = get_consumers(usage); auto producers = get_producers(usage); - if ((usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) || (usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER)) + if ((usage & GRALLOC_USAGE_HW_TEXTURE) || (usage & GRALLOC_USAGE_HW_COMPOSER)) { base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; //NV21M narrow } - else if ((producers & MALI_GRALLOC_PRODUCER_CAM) && (consumers == MALI_GRALLOC_CONSUMER_VPU)) + else if ((producers & MALI_GRALLOC_PRODUCER_CAM) && + !(producers & MALI_GRALLOC_PRODUCER_GPU) && + (consumers == GOOGLE_GRALLOC_CONSUMER_MFC)) { - // Allocated buffer is SBWC compressed when MFC is the sole consumer for - // camera buffers. But, we cannot differentiate the type of video encoder - // on gralloc3. Since BO does not support encoding in P21, it is safe to - // enable SBWC for all camera buffers. + // Allocated camera buffer is SBWC compressed when + // 1. Camera is one of the producers + // 2. GPU is not one of the producers + // 3. MFC is the sole consumer if (property_get_bool("debug.vendor.gpu.record_sbwc", true)) { base_format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC; } else { base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; } } - else if (usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) + else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) { base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; //NV21M narrow } - else if (usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) + else if (usage & GRALLOC_USAGE_VIDEO_PRIVATE_DATA) { base_format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M; } - else if ((usage & GRALLOC1_CONSUMER_USAGE_CAMERA) && (usage & GRALLOC1_PRODUCER_USAGE_CAMERA)) + else if ((usage & GRALLOC_USAGE_HW_CAMERA_READ) && (usage & GRALLOC_USAGE_HW_CAMERA_WRITE)) { - // Camera IMPLEMENTATION_DEFINED format output maps to NV21M narrow. + // Camera IMPLEMENTATION_DEFINED format output maps to NV21M. base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; } else @@ -1639,7 +1428,16 @@ uint32_t get_base_format(const uint64_t req_format, } else if (req_format == HAL_PIXEL_FORMAT_YCbCr_420_888) { - if (usage & (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) + if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_HW_VIDEO_DECODER)) + { + base_format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M; + } + else if ((usage & GRALLOC_USAGE_HW_TEXTURE) && (usage & GRALLOC_USAGE_HW_CAMERA_WRITE)) + { + // Camera flexible YUV format output maps to NV21M. + base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; + } + else if (usage & (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE)) { base_format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M; } @@ -1650,9 +1448,6 @@ uint32_t get_base_format(const uint64_t req_format, } } - ALOGV("[%s] req_format(%s %#x) base_format(%s %#x) usage(%#" PRIx64 ")\n", - __FUNCTION__, format_name(req_format), (uint32_t)req_format, format_name(base_format), base_format, usage); - /* Obtain a valid base format, optionally mapped to internal. Flex formats * are always mapped to internal base format. * NOTE: Overlap between HAL_PIXEL_FORMAT_* and MALI_GRALLOC_FORMAT_INTERNAL_* @@ -1669,7 +1464,6 @@ uint32_t get_base_format(const uint64_t req_format, * @param type [in] Format type (public usage or internal). * @param usage [in] Buffer usage. * @param buffer_size [in] Buffer resolution (w x h, in pixels). - * @param internal_format [out] Legacy format (base format as requested). * * @return alloc_format, format to be used in allocation; * MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED, where no suitable @@ -1678,8 +1472,7 @@ uint32_t get_base_format(const uint64_t req_format, uint64_t mali_gralloc_select_format(const uint64_t req_format, const mali_gralloc_format_type type, const uint64_t usage, - const int buffer_size, - uint64_t * const internal_format) + const int buffer_size) { uint64_t alloc_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED; @@ -1691,39 +1484,27 @@ uint64_t mali_gralloc_select_format(const uint64_t req_format, if (req_base_format == MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED || req_fmt_idx == -1) { - ALOGE("Invalid base format! req_base_format = (%s 0x%" PRIx32 - "), req_format = (%s 0x%" PRIx64 "), type = 0x%" PRIx32, - format_name(req_base_format), req_base_format, format_name(req_format), req_format, type); + MALI_GRALLOC_LOGE("Invalid base format! req_base_format = (%s 0x%" PRIx32 + "), req_format = (%s 0x%" PRIx64 "), type = 0x%" PRIx32, + format_name(req_base_format), req_base_format, format_name(req_format), req_format, type); goto out; } - /* Warn if usage specified is outside white list of valid usages. */ + /* Reject if usage specified is outside white list of valid usages. */ if (type != MALI_GRALLOC_FORMAT_TYPE_INTERNAL && (usage & (~VALID_USAGE)) != 0) { - ALOGW("Unknown usage specified: 0x%" PRIx64, usage); + MALI_GRALLOC_LOGE("Invalid usage specified: %s 0x%" PRIx64, describe_usage(usage).c_str(), usage); } - /* - * Exynos only formats should be selected as-is instead of choosing - * the "best" format. - */ - if (is_exynos_format(req_base_format)) + /* TODO: Make a function for finding formats that should be allocated as the request format */ + if (is_exynos_format(req_base_format) || req_base_format == HAL_PIXEL_FORMAT_BLOB) { - alloc_format = (uint64_t)req_base_format; + alloc_format = req_base_format; } - /* - * Construct format as requested (using AFBC modifiers) ensuring that - * base format is compatible with modifiers. Otherwise, reject allocation with UNDEFINED. - * NOTE: IP support is not considered and modifiers are not adjusted. - */ - else if (usage & MALI_GRALLOC_USAGE_PRIVATE_FORMAT || type == MALI_GRALLOC_FORMAT_TYPE_INTERNAL) + else if (usage == 0) { - const uint64_t format_ext = get_format_ext(req_format, usage); - const uint32_t base_format = get_base_format_for_modifiers(req_fmt_idx, format_ext); - if (base_format != MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED) - { - alloc_format = format_ext | base_format; - } + /* Allocate format as-is when no usage is specified */ + alloc_format = req_base_format; } else { @@ -1731,30 +1512,42 @@ uint64_t mali_gralloc_select_format(const uint64_t req_format, const uint16_t producers = get_producers(usage); const uint16_t consumers = get_consumers(usage); - ALOGV("Producers: 0x%" PRIx16 ", Consumers: 0x%" PRIx16, + MALI_GRALLOC_LOGV("Producers: 0x%" PRIx16 ", Consumers: 0x%" PRIx16, producers, consumers); /* Obtain producer and consumer capabilities. */ const uint64_t producer_caps = get_producer_caps(producers); - const uint64_t consumer_caps = get_consumer_caps(consumers); - ALOGV("Producer caps: 0x%" PRIx64 ", Consumer caps: 0x%" PRIx64, + uint64_t consumer_caps = 0; +#ifdef GRALLOC_HWC_FB_DISABLE_AFBC + if (GRALLOC_HWC_FB_DISABLE_AFBC && DISABLE_FRAMEBUFFER_HAL && (usage & GRALLOC_USAGE_HW_FB)) + { + /* Override capabilities to disable AFBC for DRM HWC framebuffer surfaces. */ + consumer_caps = MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; + } + else +#endif + { + consumer_caps = get_consumer_caps(consumers); + } + + MALI_GRALLOC_LOGV("Producer caps: 0x%" PRIx64 ", Consumer caps: 0x%" PRIx64, producer_caps, consumer_caps); if (producers == 0 && consumers == 0) { - ALOGE("Producer and consumer not identified."); + MALI_GRALLOC_LOGE("Producer and consumer not identified."); goto out; } else if (producers == 0 || consumers == 0) { - ALOGV("Producer or consumer not identified."); + MALI_GRALLOC_LOGV("Producer or consumer not identified."); } if ((usage & MALI_GRALLOC_USAGE_NO_AFBC) == MALI_GRALLOC_USAGE_NO_AFBC && formats[req_fmt_idx].is_yuv) { - ALOGE("ERROR: Invalid usage 'MALI_GRALLOC_USAGE_NO_AFBC' when allocating YUV formats"); + MALI_GRALLOC_LOGE("ERROR: Invalid usage 'MALI_GRALLOC_USAGE_NO_AFBC' when allocating YUV formats"); goto out; } @@ -1766,9 +1559,10 @@ uint64_t mali_gralloc_select_format(const uint64_t req_format, &producer_active_caps, &consumer_active_caps, buffer_size); - ALOGV("Producer caps (active): 0x%" PRIx64 ", Consumer caps (active): 0x%" PRIx64, + MALI_GRALLOC_LOGV("Producer caps (active): 0x%" PRIx64 ", Consumer caps (active): 0x%" PRIx64, producer_active_caps, consumer_active_caps); + /* TODO: reimplment get_best_format */ alloc_format = get_best_format(formats[req_fmt_idx].id, usage, producers, @@ -1778,32 +1572,49 @@ uint64_t mali_gralloc_select_format(const uint64_t req_format, } out: - /* - * Reconstruct internal format (legacy). - * In order to retain backwards-compatiblity, private_handle_t member, - * 'internal_format' will *not* be updated with single-plane format. Clients with - * support for multi-plane AFBC should use a combination of 'internal_format' and - * 'is_multi_plane()'' to determine whether the allocated format is multi-plane. - */ - if (alloc_format == MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED) - { - *internal_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED; - } - else - { - *internal_format = get_base_format(req_format, usage, type, false); + MALI_GRALLOC_LOGV("%s: req_format=(%s 0x%08" PRIx64 "), usage=(%s 0x%" PRIx64 + "), req_base_format=(%s 0x%" PRIx32 "), alloc_format=(%s, 0x%" PRIx64 ")", __func__, + format_name(req_format), req_format, describe_usage(usage).c_str(), usage, + format_name(req_base_format), req_base_format, format_name(alloc_format), alloc_format); - if ((uint32_t)*internal_format >= MALI_GRALLOC_FORMAT_INTERNAL_RANGE_BASE) - *internal_format = req_format; + return alloc_format; +} - *internal_format |= (alloc_format & MALI_GRALLOC_INTFMT_EXT_MASK); +bool is_exynos_format(uint32_t base_format) +{ + switch (base_format) + { + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_EXYNOS_YV12_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: + return true; } - ALOGV("mali_gralloc_select_format: req_format=(%s 0x%08" PRIx64 "), usage=0x%" PRIx64 - ", req_base_format=(%s 0x%" PRIx32 "), alloc_format=(%s 0x%" PRIx64 - "), internal_format=(%s 0x%" PRIx64 ")", - format_name(req_format), req_format, usage, format_name(req_base_format), req_base_format, - format_name(alloc_format), alloc_format, format_name(*internal_format), *internal_format); - - return alloc_format; + return false; } + diff --git a/GrallocHAL/src/core/mali_gralloc_reference.cpp b/GrallocHAL/src/core/mali_gralloc_reference.cpp new file mode 100644 index 0000000..880f838 --- /dev/null +++ b/GrallocHAL/src/core/mali_gralloc_reference.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2016, 2018-2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <hardware/gralloc1.h> + +#include "mali_gralloc_buffer.h" +#include "allocator/mali_gralloc_ion.h" +#include "allocator/mali_gralloc_shared_memory.h" +#include "mali_gralloc_bufferallocation.h" +#include "mali_gralloc_debug.h" +#include "mali_gralloc_reference.h" +#include "mali_gralloc_usages.h" + +static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER; + +int mali_gralloc_reference_retain(buffer_handle_t handle) +{ + if (private_handle_t::validate(handle) < 0) + { + MALI_GRALLOC_LOGE("Registering/Retaining invalid buffer %p, returning error", handle); + return -EINVAL; + } + + private_handle_t *hnd = (private_handle_t *)handle; + pthread_mutex_lock(&s_map_lock); + int retval = 0; + + if (hnd->allocating_pid == getpid() || hnd->remote_pid == getpid()) + { + hnd->ref_count++; + } + else + { + hnd->remote_pid = getpid(); + hnd->ref_count = 1; + + // Reset the handle bases, this is used to check if a buffer is mapped + for (int fidx = 0; fidx < hnd->fd_count; fidx++) { + hnd->bases[fidx] = 0; + } + } + + pthread_mutex_unlock(&s_map_lock); + + // TODO(b/187145254): CPU_READ/WRITE buffer is not being properly locked from + // MFC. This is a WA for the time being. + constexpr auto cpu_access_usage = ( + GRALLOC_USAGE_SW_WRITE_OFTEN | + GRALLOC_USAGE_SW_READ_OFTEN | + GRALLOC_USAGE_SW_WRITE_RARELY | + GRALLOC_USAGE_SW_READ_RARELY + ); + + if (hnd->get_usage() & cpu_access_usage) + retval = mali_gralloc_reference_map(handle); + + return retval; +} + +int mali_gralloc_reference_map(buffer_handle_t handle) { + private_handle_t *hnd = (private_handle_t *)handle; + + pthread_mutex_lock(&s_map_lock); + + if (hnd->bases[0]) { + MALI_GRALLOC_LOGV("Buffer is already mapped"); + pthread_mutex_unlock(&s_map_lock); + return 0; + } + + int retval = mali_gralloc_ion_map(hnd); + + pthread_mutex_unlock(&s_map_lock); + + return retval; +} + +int mali_gralloc_reference_release(buffer_handle_t handle, bool canFree) +{ + if (private_handle_t::validate(handle) < 0) + { + MALI_GRALLOC_LOGE("unregistering/releasing invalid buffer %p, returning error", handle); + return -EINVAL; + } + + private_handle_t *hnd = (private_handle_t *)handle; + pthread_mutex_lock(&s_map_lock); + + if (hnd->ref_count == 0) + { + MALI_GRALLOC_LOGE("Buffer %p should have already been released", handle); + pthread_mutex_unlock(&s_map_lock); + return -EINVAL; + } + + if (hnd->allocating_pid == getpid()) + { + hnd->ref_count--; + + if (hnd->ref_count == 0 && canFree) + { + mali_gralloc_dump_buffer_erase(hnd); + mali_gralloc_buffer_free(handle); + } + } + else if (hnd->remote_pid == getpid()) // never unmap buffers that were not imported into this process + { + hnd->ref_count--; + + if (hnd->ref_count == 0) + { + mali_gralloc_ion_unmap(hnd); + + /* TODO: Make this unmapping of shared meta fd into a function? */ + if (hnd->attr_base) + { + munmap(hnd->attr_base, hnd->attr_size); + hnd->attr_base = nullptr; + } + } + } + else + { + MALI_GRALLOC_LOGE("Trying to unregister buffer %p from process %d that was not imported into current process: %d", hnd, + hnd->remote_pid, getpid()); + } + + pthread_mutex_unlock(&s_map_lock); + return 0; +} + +int mali_gralloc_reference_validate(buffer_handle_t handle) +{ + if (private_handle_t::validate(handle) < 0) + { + MALI_GRALLOC_LOGE("Reference invalid buffer %p, returning error", handle); + return -EINVAL; + } + + const auto *hnd = (private_handle_t *)handle; + pthread_mutex_lock(&s_map_lock); + + if (hnd->allocating_pid == getpid() || hnd->remote_pid == getpid()) { + pthread_mutex_unlock(&s_map_lock); + return 0; + } else { + pthread_mutex_unlock(&s_map_lock); + MALI_GRALLOC_LOGE("Reference unimported buffer %p, returning error", handle); + return -EINVAL; + } +} + diff --git a/gralloc3/src/mali_gralloc_reference.h b/GrallocHAL/src/core/mali_gralloc_reference.h index 5fa6809..85bc1c9 100644 --- a/gralloc3/src/mali_gralloc_reference.h +++ b/GrallocHAL/src/core/mali_gralloc_reference.h @@ -21,7 +21,9 @@ #include "gralloc_priv.h" -int mali_gralloc_reference_retain(mali_gralloc_module const *module, buffer_handle_t handle); -int mali_gralloc_reference_release(mali_gralloc_module const *module, buffer_handle_t handle, bool canFree); +int mali_gralloc_reference_retain(buffer_handle_t handle); +int mali_gralloc_reference_release(buffer_handle_t handle, bool canFree); +int mali_gralloc_reference_validate(buffer_handle_t handle); +int mali_gralloc_reference_map(buffer_handle_t handle); #endif /* MALI_GRALLOC_REFERENCE_H_ */ diff --git a/gralloc3/src/local_mfc_macros.h b/GrallocHAL/src/core/mfc_macros_local.h index 563bf48..ab66d17 100644 --- a/gralloc3/src/local_mfc_macros.h +++ b/GrallocHAL/src/core/mfc_macros_local.h @@ -1,7 +1,6 @@ /* - * Copyright (C) 2010-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2020 Samsung Electronics Co. Ltd. + * Copyright (C) 2021 Google LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +15,11 @@ * limitations under the License. */ -#ifndef LOCAL_MFC_MACROS_H_ -#define LOCAL_MFC_MACROS_H_ +#pragma once + +#if __has_include(<video/mfc_macros.h>) +#error "This header should not be included if mfc_macros is available in UAPI" +#endif /* helper macros */ #ifndef __ALIGN_UP @@ -55,4 +57,3 @@ #define SBWCL_8B_CBCR_BASE(base, w, h, r) ((base) + SBWCL_8B_Y_SIZE(w, h, r)) #define SBWCL_10B_CBCR_BASE(base, w, h, r) ((base) + SBWCL_10B_Y_SIZE(w, h, r)) -#endif /* LOCAL_MFC_MACROS_H_ */ diff --git a/GrallocHAL/src/gralloc_helper.h b/GrallocHAL/src/gralloc_helper.h new file mode 100644 index 0000000..ba31333 --- /dev/null +++ b/GrallocHAL/src/gralloc_helper.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2010-2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_HELPER_H_ +#define GRALLOC_HELPER_H_ + +#include <unistd.h> +#include <sys/mman.h> +#include <sys/user.h> + +#include "mali_gralloc_log.h" + +#define GRALLOC_ALIGN(value, base) ((((value) + (base) -1) / (base)) * (base)) + +#define GRALLOC_MAX(a, b) (((a)>(b))?(a):(b)) + +#define GRALLOC_UNUSED(x) ((void)x) + +static inline size_t round_up_to_page_size(size_t x) +{ + return (x + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); +} + +#endif /* GRALLOC_HELPER_H_ */ diff --git a/GrallocHAL/src/gralloc_priv.h b/GrallocHAL/src/gralloc_priv.h new file mode 100644 index 0000000..bbef1b6 --- /dev/null +++ b/GrallocHAL/src/gralloc_priv.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2017, 2019-2020 Arm Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_PRIV_H_ +#define GRALLOC_PRIV_H_ + +#include <stdint.h> +#include <pthread.h> +#include <errno.h> +#include <linux/fb.h> +#include <sys/types.h> +#include <unistd.h> +#include <sys/mman.h> +#include <cutils/native_handle.h> + +/* Allocator = 4.0, Mapper = 4.0 and Common = 1.2 */ +#define HIDL_ALLOCATOR_VERSION_SCALED 400 +#define HIDL_MAPPER_VERSION_SCALED 400 +#define HIDL_COMMON_VERSION_SCALED 120 + +#include "mali_gralloc_formats.h" +#include "mali_gralloc_usages.h" +#include "gralloc_helper.h" + +/* + * This header file contains the private buffer definition. For gralloc 0.3 it will + * always be exposed, but for gralloc 1.0 it will be removed at some point in the future. + * + * GRALLOC_DISABLE_PRIVATE_BUFFER_DEF is intended for DDKs to test while implementing + * the new private API. + */ +#include "mali_gralloc_buffer.h" + +#endif /* GRALLOC_PRIV_H_ */ diff --git a/GrallocHAL/src/hidl_common/Allocator.cpp b/GrallocHAL/src/hidl_common/Allocator.cpp new file mode 100644 index 0000000..8174f05 --- /dev/null +++ b/GrallocHAL/src/hidl_common/Allocator.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2020 ARM Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SharedMetadata.h" +#include "Allocator.h" +#include "core/mali_gralloc_bufferallocation.h" +#include "core/mali_gralloc_bufferdescriptor.h" +#include "core/format_info.h" +#include "allocator/mali_gralloc_ion.h" +#include "allocator/mali_gralloc_shared_memory.h" +#include "gralloc_priv.h" + +namespace arm +{ +namespace allocator +{ +namespace common +{ + +void allocate(const buffer_descriptor_t &bufferDescriptor, uint32_t count, IAllocator::allocate_cb hidl_cb, + std::function<int(const buffer_descriptor_t *, buffer_handle_t *)> fb_allocator) +{ +#if DISABLE_FRAMEBUFFER_HAL + GRALLOC_UNUSED(fb_allocator); +#endif + + Error error = Error::NONE; + int stride = 0; + std::vector<hidl_handle> grallocBuffers; + gralloc_buffer_descriptor_t grallocBufferDescriptor[1]; + + grallocBufferDescriptor[0] = (gralloc_buffer_descriptor_t)(&bufferDescriptor); + grallocBuffers.reserve(count); + + for (uint32_t i = 0; i < count; i++) + { + buffer_handle_t tmpBuffer = nullptr; + + int allocResult; +#if (DISABLE_FRAMEBUFFER_HAL != 1) + if (((bufferDescriptor.producer_usage & GRALLOC_USAGE_HW_FB) || + (bufferDescriptor.consumer_usage & GRALLOC_USAGE_HW_FB)) && + fb_allocator) + { + allocResult = fb_allocator(&bufferDescriptor, &tmpBuffer); + } + else +#endif + { + allocResult = mali_gralloc_buffer_allocate(grallocBufferDescriptor, 1, &tmpBuffer, nullptr); + if (allocResult != 0) + { + MALI_GRALLOC_LOGE("%s, buffer allocation failed with %d", __func__, allocResult); + error = Error::NO_RESOURCES; + break; + } + auto hnd = const_cast<private_handle_t *>(reinterpret_cast<const private_handle_t *>(tmpBuffer)); + hnd->imapper_version = HIDL_MAPPER_VERSION_SCALED; + + hnd->reserved_region_size = bufferDescriptor.reserved_size; + hnd->attr_size = mapper::common::shared_metadata_size() + hnd->reserved_region_size; + + if (hnd->get_usage() & GRALLOC_USAGE_ROIINFO) + { + hnd->attr_size += 32768; + } + + /* TODO: must do error checking */ + mali_gralloc_ion_allocate_attr(hnd); + + /* TODO: error check for failure */ + hnd->attr_base = mmap(nullptr, hnd->attr_size, PROT_READ | PROT_WRITE, + MAP_SHARED, hnd->get_share_attr_fd(), 0); + + memset(hnd->attr_base, 0, hnd->attr_size); + + mapper::common::shared_metadata_init(hnd->attr_base, bufferDescriptor.name); + + const uint32_t base_format = bufferDescriptor.alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK; + const uint64_t usage = bufferDescriptor.consumer_usage | bufferDescriptor.producer_usage; + android_dataspace_t dataspace; + get_format_dataspace(base_format, usage, hnd->width, hnd->height, &dataspace); + + mapper::common::set_dataspace(hnd, static_cast<mapper::common::Dataspace>(dataspace)); + + /* + * We need to set attr_base to MAP_FAILED before the HIDL callback + * to avoid sending an invalid pointer to the client process. + * + * hnd->attr_base = mmap(...); + * hidl_callback(hnd); // client receives hnd->attr_base = <dangling pointer> + */ + munmap(hnd->attr_base, hnd->attr_size); + hnd->attr_base = 0; + } + + int tmpStride = 0; + tmpStride = bufferDescriptor.pixel_stride; + + if (stride == 0) + { + stride = tmpStride; + } + else if (stride != tmpStride) + { + /* Stride must be the same for all allocations */ + mali_gralloc_buffer_free(tmpBuffer); + stride = 0; + error = Error::UNSUPPORTED; + break; + } + + grallocBuffers.emplace_back(hidl_handle(tmpBuffer)); + } + + /* Populate the array of buffers for application consumption */ + hidl_vec<hidl_handle> hidlBuffers; + if (error == Error::NONE) + { + hidlBuffers.setToExternal(grallocBuffers.data(), grallocBuffers.size()); + } + hidl_cb(error, stride, hidlBuffers); + + /* The application should import the Gralloc buffers using IMapper for + * further usage. Free the allocated buffers in IAllocator context + */ + for (const auto &buffer : grallocBuffers) + { + mali_gralloc_buffer_free(buffer.getNativeHandle()); + } +} + +} // namespace common +} // namespace allocator +} // namespace arm diff --git a/GrallocHAL/src/hidl_common/Allocator.h b/GrallocHAL/src/hidl_common/Allocator.h new file mode 100644 index 0000000..8fdd5ba --- /dev/null +++ b/GrallocHAL/src/hidl_common/Allocator.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 ARM Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GRALLOC_COMMON_ALLOCATOR_H +#define GRALLOC_COMMON_ALLOCATOR_H + +#include "4.x/gralloc_allocator_hidl_header.h" + +#include <functional> + +#include "core/mali_gralloc_bufferdescriptor.h" +#include "BufferDescriptor.h" + +namespace arm +{ +namespace allocator +{ +namespace common +{ + +using android::hardware::hidl_handle; +using android::hardware::hidl_vec; + +/* + * Allocates buffers with the properties specified by the descriptor + * + * @param bufferDescriptor: Specifies the properties of the buffers to allocate. + * @param count: Number of buffers to allocate. + * @param hidl_cb [in] HIDL callback function generating - + * error : NONE upon success. Otherwise, + * BAD_DESCRIPTOR when the descriptor is invalid. + * NO_RESOURCES when the allocation cannot be fulfilled + * UNSUPPORTED when any of the property encoded in the descriptor + * is not supported + * stride: Number of pixels between two consecutive rows of the + * buffers, when the concept of consecutive rows is defined. + * buffers: An array of raw handles to the newly allocated buffers + * @param fb_allocator [in] function to use for allocation of buffers with GRALLOC_USAGE_HW_FB + */ +void allocate(const buffer_descriptor_t &bufferDescriptor, uint32_t count, IAllocator::allocate_cb hidl_cb, + std::function<int(const buffer_descriptor_t *, buffer_handle_t *)> fb_allocator = nullptr); + +} // namespace common +} // namespace allocator +} // namespace arm + +#endif /* GRALLOC_COMMON_ALLOCATOR_H */ diff --git a/GrallocHAL/src/hidl_common/Android.bp b/GrallocHAL/src/hidl_common/Android.bp new file mode 100644 index 0000000..7476d0d --- /dev/null +++ b/GrallocHAL/src/hidl_common/Android.bp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 Arm Limited. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +filegroup { + name: "libgralloc_hidl_common_allocator", + srcs: [ + "Allocator.cpp", + ], +} + +filegroup { + name: "libgralloc_hidl_common_mapper", + srcs: [ + "Mapper.cpp", + "RegisteredHandlePool.cpp", + ], +} + +filegroup { + name: "libgralloc_hidl_common_mapper_metadata", + srcs: [ + "MapperMetadata.cpp", + ], +} + +filegroup { + name: "libgralloc_hidl_common_shared_metadata", + srcs: [ + "SharedMetadata.cpp", + ], +} diff --git a/GrallocHAL/src/hidl_common/BufferDescriptor.h b/GrallocHAL/src/hidl_common/BufferDescriptor.h new file mode 100644 index 0000000..abaac62 --- /dev/null +++ b/GrallocHAL/src/hidl_common/BufferDescriptor.h @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2020 ARM Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _GRALLOC_BUFFER_DESCRIPTOR_H_ +#define _GRALLOC_BUFFER_DESCRIPTOR_H_ + +#include "core/mali_gralloc_bufferdescriptor.h" + +#include "4.x/gralloc_mapper_hidl_header.h" + +#include <assert.h> +#include <inttypes.h> +#include <string.h> + +namespace arm { +namespace mapper { +namespace common { + +using android::hardware::hidl_vec; + +const size_t DESCRIPTOR_32BIT_FIELDS = 5; +const size_t DESCRIPTOR_64BIT_FIELDS = 2; + +const uint64_t validUsageBits = + BufferUsage::GPU_CUBE_MAP | + BufferUsage::GPU_MIPMAP_COMPLETE | + BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | + BufferUsage::GPU_TEXTURE | BufferUsage::GPU_RENDER_TARGET | + BufferUsage::COMPOSER_OVERLAY | BufferUsage::COMPOSER_CLIENT_TARGET | + BufferUsage::CAMERA_INPUT | BufferUsage::CAMERA_OUTPUT | + BufferUsage::PROTECTED | + BufferUsage::COMPOSER_CURSOR | + BufferUsage::VIDEO_ENCODER | + BufferUsage::RENDERSCRIPT | + BufferUsage::VIDEO_DECODER | + BufferUsage::SENSOR_DIRECT_DATA | + BufferUsage::GPU_DATA_BUFFER | + BufferUsage::VENDOR_MASK | + BufferUsage::VENDOR_MASK_HI; + +template<typename BufferDescriptorInfoT> +static bool validateDescriptorInfo(const BufferDescriptorInfoT &descriptorInfo) +{ + if (descriptorInfo.width == 0 || descriptorInfo.height == 0 || descriptorInfo.layerCount == 0) + { + return false; + } + + if (static_cast<int32_t>(descriptorInfo.format) == 0) + { + return false; + } + + return true; +} + +template <typename vecT> +static void push_descriptor_uint32(hidl_vec<vecT> *vec, size_t *pos, uint32_t val) +{ + static_assert(sizeof(val) % sizeof(vecT) == 0, "Unsupported vector type"); + memcpy(vec->data() + *pos, &val, sizeof(val)); + *pos += sizeof(val) / sizeof(vecT); +} + +template <typename vecT> +static uint32_t pop_descriptor_uint32(const hidl_vec<vecT> &vec, size_t *pos) +{ + uint32_t val; + static_assert(sizeof(val) % sizeof(vecT) == 0, "Unsupported vector type"); + memcpy(&val, vec.data() + *pos, sizeof(val)); + *pos += sizeof(val) / sizeof(vecT); + return val; +} + +template <typename vecT> +static void push_descriptor_uint64(hidl_vec<vecT> *vec, size_t *pos, uint64_t val) +{ + static_assert(sizeof(val) % sizeof(vecT) == 0, "Unsupported vector type"); + memcpy(vec->data() + *pos, &val, sizeof(val)); + *pos += sizeof(val) / sizeof(vecT); +} + +template <typename vecT> +static uint64_t pop_descriptor_uint64(const hidl_vec<vecT> &vec, size_t *pos) +{ + uint64_t val; + static_assert(sizeof(val) % sizeof(vecT) == 0, "Unsupported vector type"); + memcpy(&val, vec.data() + *pos, sizeof(val)); + *pos += sizeof(val) / sizeof(vecT); + return val; +} + +static void push_descriptor_string(hidl_vec<uint8_t> *vec, size_t *pos, const std::string &str) +{ + strcpy(reinterpret_cast<char *>(vec->data() + *pos), str.c_str()); + *pos += strlen(str.c_str()) + 1; +} + +static std::string pop_descriptor_string(const hidl_vec<uint8_t> &vec, size_t *pos) +{ + std::string str(reinterpret_cast<const char *>(vec.data() + *pos)); + *pos += str.size() + 1; + return str; +} + +template <typename vecT, typename BufferDescriptorInfoT> +static const hidl_vec<vecT> grallocEncodeBufferDescriptor(const BufferDescriptorInfoT &descriptorInfo) +{ + hidl_vec<vecT> descriptor; + + static_assert(sizeof(uint32_t) % sizeof(vecT) == 0, "Unsupported vector type"); + size_t dynamic_size = 0; + constexpr size_t static_size = (DESCRIPTOR_32BIT_FIELDS * sizeof(uint32_t) / sizeof(vecT)) + + (DESCRIPTOR_64BIT_FIELDS * sizeof(uint64_t) / sizeof(vecT)); + + /* Include the name and '\0' in the descriptor. */ + dynamic_size += strlen(descriptorInfo.name.c_str()) + 1; + + size_t pos = 0; + descriptor.resize(dynamic_size + static_size); + push_descriptor_uint32(&descriptor, &pos, HIDL_MAPPER_VERSION_SCALED / 10); + push_descriptor_uint32(&descriptor, &pos, descriptorInfo.width); + push_descriptor_uint32(&descriptor, &pos, descriptorInfo.height); + push_descriptor_uint32(&descriptor, &pos, descriptorInfo.layerCount); + push_descriptor_uint32(&descriptor, &pos, static_cast<uint32_t>(descriptorInfo.format)); + push_descriptor_uint64(&descriptor, &pos, static_cast<uint64_t>(descriptorInfo.usage)); + + push_descriptor_uint64(&descriptor, &pos, descriptorInfo.reservedSize); + + assert(pos == static_size); + + push_descriptor_string(&descriptor, &pos, descriptorInfo.name); + + return descriptor; +} + +template <typename vecT> +static bool grallocDecodeBufferDescriptor(const hidl_vec<vecT> &androidDescriptor, buffer_descriptor_t &grallocDescriptor) +{ + static_assert(sizeof(uint32_t) % sizeof(vecT) == 0, "Unsupported vector type"); + size_t pos = 0; + + if (((DESCRIPTOR_32BIT_FIELDS * sizeof(uint32_t) / sizeof(vecT)) + + (DESCRIPTOR_64BIT_FIELDS * sizeof(uint64_t) / sizeof(vecT))) > androidDescriptor.size()) + { + MALI_GRALLOC_LOGE("Descriptor is too small"); + return false; + } + + if (pop_descriptor_uint32(androidDescriptor, &pos) != HIDL_MAPPER_VERSION_SCALED / 10) + { + MALI_GRALLOC_LOGE("Corrupted buffer version in descriptor = %p, pid = %d ", &androidDescriptor, getpid()); + return false; + } + + grallocDescriptor.width = pop_descriptor_uint32(androidDescriptor, &pos); + grallocDescriptor.height = pop_descriptor_uint32(androidDescriptor, &pos); + grallocDescriptor.layer_count = pop_descriptor_uint32(androidDescriptor, &pos); + grallocDescriptor.hal_format = static_cast<uint64_t>(pop_descriptor_uint32(androidDescriptor, &pos)); + grallocDescriptor.producer_usage = pop_descriptor_uint64(androidDescriptor, &pos); + grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage; + grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; + grallocDescriptor.signature = sizeof(buffer_descriptor_t); + grallocDescriptor.reserved_size = pop_descriptor_uint64(androidDescriptor, &pos); + grallocDescriptor.name = pop_descriptor_string(androidDescriptor, &pos); + + return true; +} + +} // namespace common +} // namespace mapper +} // namespace arm +#endif diff --git a/GrallocHAL/src/hidl_common/Mapper.cpp b/GrallocHAL/src/hidl_common/Mapper.cpp new file mode 100644 index 0000000..8a5edaf --- /dev/null +++ b/GrallocHAL/src/hidl_common/Mapper.cpp @@ -0,0 +1,780 @@ +/* + * Copyright (C) 2020 ARM Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <inttypes.h> +#include <sync/sync.h> +#include "RegisteredHandlePool.h" +#include "Mapper.h" +#include "BufferDescriptor.h" +#include "mali_gralloc_log.h" +#include "core/mali_gralloc_bufferallocation.h" +#include "core/mali_gralloc_bufferdescriptor.h" +#include "core/mali_gralloc_bufferaccess.h" +#include "core/mali_gralloc_reference.h" +#include "core/format_info.h" +#include "allocator/mali_gralloc_ion.h" +#include "mali_gralloc_buffer.h" +#include "mali_gralloc_log.h" + +#include "MapperMetadata.h" +#include "SharedMetadata.h" + +/* GraphicBufferMapper is expected to be valid (and leaked) during process + * termination. IMapper, and in turn, gRegisteredHandles must be valid as + * well. Create the registered handle pool on the heap, and let + * it leak for simplicity. + * + * However, there is no way to make sure gralloc0/gralloc1 are valid. Any use + * of static/global object in gralloc0/gralloc1 that may have been destructed + * is potentially broken. + */ +RegisteredHandlePool* gRegisteredHandles = new RegisteredHandlePool; + +namespace arm { +namespace mapper { +namespace common { + +/* + * Translates the register buffer API into existing gralloc implementation + * + * @param bufferHandle [in] Private handle for the buffer to be imported + * + * @return Error::BAD_BUFFER for an invalid buffer + * Error::NO_RESOURCES when unable to import the given buffer + * Error::NONE on successful import + */ +static Error registerBuffer(buffer_handle_t bufferHandle) +{ + if (private_handle_t::validate(bufferHandle) < 0) + { + MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle); + return Error::BAD_BUFFER; + } + + if (mali_gralloc_reference_retain(bufferHandle) < 0) + { + return Error::NO_RESOURCES; + } + + return Error::NONE; +} + +/* + * Translates the unregister buffer API into existing gralloc implementation + * + * @param bufferHandle [in] Private handle for the buffer to be released + * + * @return Error::BAD_BUFFER for an invalid buffer / buffers which can't be released + * Error::NONE on successful release of the buffer + */ +static Error unregisterBuffer(buffer_handle_t bufferHandle) +{ + if (private_handle_t::validate(bufferHandle) < 0) + { + MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle); + return Error::BAD_BUFFER; + } + + const int status = mali_gralloc_reference_release(bufferHandle, true); + if (status != 0) + { + MALI_GRALLOC_LOGE("Unable to release buffer:%p", bufferHandle); + return Error::BAD_BUFFER; + } + + return Error::NONE; +} + +/* + * Retrieves the file descriptor referring to a sync fence object + * + * @param fenceHandle [in] HIDL fence handle + * @param outFenceFd [out] Fence file descriptor. '-1' indicates no fence + * + * @return false, for an invalid HIDL fence handle + * true, otherwise + */ +static bool getFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) +{ + auto const handle = fenceHandle.getNativeHandle(); + if (handle && handle->numFds > 1) + { + MALI_GRALLOC_LOGE("Invalid fence handle with %d fds", handle->numFds); + return false; + } + + *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1; + return true; +} + +/* + * Populates the HIDL fence handle for the given fence object + * + * @param fenceFd [in] Fence file descriptor + * @param handleStorage [in] HIDL handle storage for fence + * + * @return HIDL fence handle + */ +static hidl_handle getFenceHandle(int fenceFd, char* handleStorage) +{ + native_handle_t* handle = nullptr; + if (fenceFd >= 0) + { + handle = native_handle_init(handleStorage, 1, 0); + handle->data[0] = fenceFd; + } + + return hidl_handle(handle); +} + +/* + * Locks the given buffer for the specified CPU usage. + * + * @param bufferHandle [in] Buffer to lock. + * @param cpuUsage [in] Specifies one or more CPU usage flags to request + * @param accessRegion [in] Portion of the buffer that the client intends to access. + * @param fenceFd [in] Fence file descriptor + * @param outData [out] CPU accessible buffer address + * + * @return Error::BAD_BUFFER for an invalid buffer + * Error::NO_RESOURCES when unable to duplicate fence + * Error::BAD_VALUE when locking fails + * Error::NONE on successful buffer lock + */ +static Error lockBuffer(buffer_handle_t bufferHandle, + uint64_t cpuUsage, + const IMapper::Rect& accessRegion, int fenceFd, + void** outData) +{ + /* dup fenceFd as it is going to be owned by gralloc. Note that it is + * gralloc's responsibility to close it, even on locking errors. + */ + if (fenceFd >= 0) + { + fenceFd = dup(fenceFd); + if (fenceFd < 0) + { + MALI_GRALLOC_LOGE("Error encountered while duplicating fence file descriptor"); + return Error::NO_RESOURCES; + } + } + + if (private_handle_t::validate(bufferHandle) < 0) + { + if (fenceFd >= 0) + { + close(fenceFd); + } + MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle); + return Error::BAD_BUFFER; + } + + if (mali_gralloc_reference_validate(bufferHandle) < 0) + { + if (fenceFd >= 0) + { + close(fenceFd); + } + MALI_GRALLOC_LOGE("Buffer: %p is not imported", bufferHandle); + return Error::BAD_VALUE; + } + + auto private_handle = private_handle_t::dynamicCast(bufferHandle); + if (private_handle->cpu_write != 0 && (cpuUsage & BufferUsage::CPU_WRITE_MASK)) + { + if (fenceFd >= 0) + { + close(fenceFd); + } +#if 0 + MALI_GRALLOC_LOGW("Attempt to call lock*() for writing on an already locked buffer (%p)", bufferHandle); +#endif + + /* TODO: handle simulatneous locks differently. May be keep a global lock count per buffer? */ + } + else if (fenceFd >= 0) + { + sync_wait(fenceFd, -1); + close(fenceFd); + } + + void* data = nullptr; + if (mali_gralloc_lock(bufferHandle, cpuUsage, accessRegion.left, accessRegion.top, accessRegion.width, + accessRegion.height, &data) < 0) + { + return Error::BAD_VALUE; + } + + *outData = data; + + return Error::NONE; +} + +/* + * Unlocks a buffer to indicate all CPU accesses to the buffer have completed + * + * @param bufferHandle [in] Buffer to lock. + * @param outFenceFd [out] Fence file descriptor + * + * @return Error::BAD_BUFFER for an invalid buffer + * Error::BAD_VALUE when unlocking failed + * Error::NONE on successful buffer unlock + */ +static Error unlockBuffer(buffer_handle_t bufferHandle, + int* outFenceFd) +{ + if (private_handle_t::validate(bufferHandle) < 0) + { + MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle); + return Error::BAD_BUFFER; + } + + auto private_handle = private_handle_t::dynamicCast(bufferHandle); +#if 0 + if (!private_handle->cpu_write && !private_handle->cpu_read) + { + MALI_GRALLOC_LOGW("Attempt to call unlock*() on an unlocked buffer (%p)", bufferHandle); + + /* TODO: handle simulatneous locks differently. May be keep a global lock count per buffer? */ + } +#endif + + const int result = mali_gralloc_unlock(bufferHandle); + if (result) + { + MALI_GRALLOC_LOGE("Unlocking failed with error: %d", result); + return Error::BAD_VALUE; + } + + *outFenceFd = -1; + + return Error::NONE; +} + +void importBuffer(const hidl_handle& rawHandle, IMapper::importBuffer_cb hidl_cb) +{ + if (!rawHandle.getNativeHandle()) + { + MALI_GRALLOC_LOGE("Invalid buffer handle to import"); + hidl_cb(Error::BAD_BUFFER, nullptr); + return; + } + + native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle()); + if (!bufferHandle) + { + MALI_GRALLOC_LOGE("Failed to clone buffer handle"); + hidl_cb(Error::NO_RESOURCES, nullptr); + return; + } + + const Error error = registerBuffer(bufferHandle); + if (error != Error::NONE) + { + native_handle_close(bufferHandle); + native_handle_delete(bufferHandle); + + hidl_cb(error, nullptr); + return; + } + + auto *private_handle = static_cast<private_handle_t *>(bufferHandle); + private_handle->attr_base = mmap(nullptr, private_handle->attr_size, PROT_READ | PROT_WRITE, + MAP_SHARED, private_handle->get_share_attr_fd(), 0); + if (private_handle->attr_base == MAP_FAILED) + { + native_handle_close(bufferHandle); + native_handle_delete(bufferHandle); + hidl_cb(Error::NO_RESOURCES, nullptr); + return; + } + + if (gRegisteredHandles->add(bufferHandle) == false) + { + /* The newly cloned handle is already registered. This can only happen + * when a handle previously registered was native_handle_delete'd instead + * of freeBuffer'd. + */ + MALI_GRALLOC_LOGE("Handle %p has already been imported; potential fd leaking", + bufferHandle); + unregisterBuffer(bufferHandle); + native_handle_close(bufferHandle); + native_handle_delete(bufferHandle); + + hidl_cb(Error::NO_RESOURCES, nullptr); + return; + } + + hidl_cb(Error::NONE, bufferHandle); +} + +Error freeBuffer(void* buffer) +{ + native_handle_t * const bufferHandle = gRegisteredHandles->remove(buffer); + if (!bufferHandle) + { + MALI_GRALLOC_LOGE("Invalid buffer handle %p to freeBuffer", buffer); + return Error::BAD_BUFFER; + } + + { + auto *private_handle = static_cast<private_handle_t *>(bufferHandle); + int ret = munmap(private_handle->attr_base, private_handle->attr_size); + if (ret < 0) + { + MALI_GRALLOC_LOGW("munmap: %s", strerror(errno)); + } + private_handle->attr_base = MAP_FAILED; + } + + const Error status = unregisterBuffer(bufferHandle); + if (status != Error::NONE) + { + return status; + } + + native_handle_close(bufferHandle); + native_handle_delete(bufferHandle); + + return Error::NONE; +} + +void lock(void* buffer, uint64_t cpuUsage, const IMapper::Rect& accessRegion, + const hidl_handle& acquireFence, IMapper::lock_cb hidl_cb) +{ + buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); + if (!bufferHandle || private_handle_t::validate(bufferHandle) < 0) + { + MALI_GRALLOC_LOGE("Buffer to lock: %p is not valid", buffer); + hidl_cb(Error::BAD_BUFFER, nullptr); + return; + } + + int fenceFd; + if (!getFenceFd(acquireFence, &fenceFd)) + { + hidl_cb(Error::BAD_VALUE, nullptr); + return; + } + + void* data = nullptr; + const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data); + + hidl_cb(error, data); +} + +void unlock(void* buffer, IMapper::unlock_cb hidl_cb) +{ + buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); + if (!bufferHandle) + { + MALI_GRALLOC_LOGE("Buffer to unlock: %p has not been registered with Gralloc", buffer); + hidl_cb(Error::BAD_BUFFER, nullptr); + return; + } + + int fenceFd; + const Error error = unlockBuffer(bufferHandle, &fenceFd); + if (error == Error::NONE) + { + NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0); + hidl_cb(error, getFenceHandle(fenceFd, fenceStorage)); + + if (fenceFd >= 0) + { + close(fenceFd); + } + } + else + { + hidl_cb(error, nullptr); + } +} + +Error validateBufferSize(void* buffer, + const IMapper::BufferDescriptorInfo& descriptorInfo, + uint32_t in_stride) +{ + /* The buffer must have been allocated by Gralloc */ + buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); + if (!bufferHandle) + { + MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer); + return Error::BAD_BUFFER; + } + + if (private_handle_t::validate(bufferHandle) < 0) + { + MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle); + return Error::BAD_BUFFER; + } + + buffer_descriptor_t grallocDescriptor; + grallocDescriptor.width = descriptorInfo.width; + grallocDescriptor.height = descriptorInfo.height; + grallocDescriptor.layer_count = descriptorInfo.layerCount; + grallocDescriptor.hal_format = static_cast<uint64_t>(descriptorInfo.format); + grallocDescriptor.producer_usage = static_cast<uint64_t>(descriptorInfo.usage); + grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage; + grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; + + /* Derive the buffer size for the given descriptor */ + const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor); + if (result) + { + MALI_GRALLOC_LOGV("Unable to derive format and size for the given descriptor information. error: %d", result); + return Error::BAD_VALUE; + } + + /* Validate the buffer parameters against descriptor info */ + private_handle_t *gralloc_buffer = (private_handle_t *)bufferHandle; + + /* The buffer size must be greater than (or equal to) what would have been allocated with descriptor */ + for (int i = 0; i < gralloc_buffer->fd_count; i++) + { + if (gralloc_buffer->alloc_sizes[i] < grallocDescriptor.alloc_sizes[i]) + { + MALI_GRALLOC_LOGW("Buf size mismatch. fd_idx(%d) Buffer size = %" PRIu64 ", Descriptor (derived) size = %" PRIu64, + i, gralloc_buffer->alloc_sizes[i], grallocDescriptor.alloc_sizes[i]); + return Error::BAD_VALUE; + } + } + + if (in_stride != 0 && (uint32_t)gralloc_buffer->stride != in_stride) + { + MALI_GRALLOC_LOGE("Stride mismatch. Expected stride = %d, Buffer stride = %d", + in_stride, gralloc_buffer->stride); + return Error::BAD_VALUE; + } + + if (gralloc_buffer->alloc_format != grallocDescriptor.alloc_format) + { + MALI_GRALLOC_LOGE("Buffer alloc format: (%s, 0x%" PRIx64") does not match descriptor (derived) alloc format: (%s 0x%" + PRIx64 ")", format_name(gralloc_buffer->alloc_format), gralloc_buffer->alloc_format, + format_name(grallocDescriptor.alloc_format), grallocDescriptor.alloc_format); + return Error::BAD_VALUE; + } + + const int format_idx = get_format_index(gralloc_buffer->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); + if (format_idx == -1) + { + MALI_GRALLOC_LOGE("Invalid format to validate buffer descriptor"); + return Error::BAD_VALUE; + } + else + { + for (int i = 0; i < formats[format_idx].npln; i++) + { + if (gralloc_buffer->plane_info[i].byte_stride != grallocDescriptor.plane_info[i].byte_stride) + { + MALI_GRALLOC_LOGE("Buffer byte stride 0x%x mismatch with desc byte stride 0x%x in plane %d ", + gralloc_buffer->plane_info[i].byte_stride, grallocDescriptor.plane_info[i].byte_stride, i); + return Error::BAD_VALUE; + } + + if (gralloc_buffer->plane_info[i].alloc_width != grallocDescriptor.plane_info[i].alloc_width) + { + MALI_GRALLOC_LOGE("Buffer alloc width 0x%x mismatch with desc alloc width 0x%x in plane %d ", + gralloc_buffer->plane_info[i].alloc_width, grallocDescriptor.plane_info[i].alloc_width, i); + return Error::BAD_VALUE; + } + + if (gralloc_buffer->plane_info[i].alloc_height != grallocDescriptor.plane_info[i].alloc_height) + { + MALI_GRALLOC_LOGE("Buffer alloc height 0x%x mismatch with desc alloc height 0x%x in plane %d ", + gralloc_buffer->plane_info[i].alloc_height, grallocDescriptor.plane_info[i].alloc_height, i); + return Error::BAD_VALUE; + } + } + } + + if ((uint32_t)gralloc_buffer->width != grallocDescriptor.width) + { + MALI_GRALLOC_LOGE("Width mismatch. Buffer width = %u, Descriptor width = %u", + gralloc_buffer->width, grallocDescriptor.width); + return Error::BAD_VALUE; + } + + if ((uint32_t)gralloc_buffer->height != grallocDescriptor.height) + { + MALI_GRALLOC_LOGE("Height mismatch. Buffer height = %u, Descriptor height = %u", + gralloc_buffer->height, grallocDescriptor.height); + return Error::BAD_VALUE; + } + + if (gralloc_buffer->layer_count != grallocDescriptor.layer_count) + { + MALI_GRALLOC_LOGE("Layer Count mismatch. Buffer layer_count = %u, Descriptor layer_count width = %u", + gralloc_buffer->layer_count, grallocDescriptor.layer_count); + return Error::BAD_VALUE; + } + + return Error::NONE; +} + +void getTransportSize(void* buffer, IMapper::getTransportSize_cb hidl_cb) +{ + /* The buffer must have been allocated by Gralloc */ + buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); + if (!bufferHandle) + { + MALI_GRALLOC_LOGE("Buffer %p is not registered with Gralloc", bufferHandle); + hidl_cb(Error::BAD_BUFFER, -1, -1); + return; + } + + if (private_handle_t::validate(bufferHandle) < 0) + { + MALI_GRALLOC_LOGE("Buffer %p is corrupted", buffer); + hidl_cb(Error::BAD_BUFFER, -1, -1); + return; + } + hidl_cb(Error::NONE, bufferHandle->numFds, bufferHandle->numInts); +} + +void isSupported(const IMapper::BufferDescriptorInfo& description, IMapper::isSupported_cb hidl_cb) +{ + buffer_descriptor_t grallocDescriptor; + grallocDescriptor.width = description.width; + grallocDescriptor.height = description.height; + grallocDescriptor.layer_count = description.layerCount; + grallocDescriptor.hal_format = static_cast<uint64_t>(description.format); + grallocDescriptor.producer_usage = static_cast<uint64_t>(description.usage); + grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage; + grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; + + /* Check if it is possible to allocate a buffer for the given description */ + const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor); + if (result != 0) + { + MALI_GRALLOC_LOGV("Allocation for the given description will not succeed. error: %d", result); + hidl_cb(Error::NO_RESOURCES, false); + } + else + { + hidl_cb(Error::NONE, true); + } +} + +void flushLockedBuffer(void *buffer, IMapper::flushLockedBuffer_cb hidl_cb) +{ + buffer_handle_t handle = gRegisteredHandles->get(buffer); + if (private_handle_t::validate(handle) < 0) + { + MALI_GRALLOC_LOGE("Bandle: %p is corrupted", handle); + hidl_cb(Error::BAD_BUFFER, hidl_handle{}); + return; + } + + auto private_handle = static_cast<const private_handle_t *>(handle); + if (!private_handle->cpu_write && !private_handle->cpu_read) + { + MALI_GRALLOC_LOGE("Attempt to call flushLockedBuffer() on an unlocked buffer (%p)", handle); + hidl_cb(Error::BAD_BUFFER, hidl_handle{}); + return; + } + + mali_gralloc_ion_sync_end(private_handle, false, true); + hidl_cb(Error::NONE, hidl_handle{}); +} + +Error rereadLockedBuffer(void *buffer) +{ + buffer_handle_t handle = gRegisteredHandles->get(buffer); + if (private_handle_t::validate(handle) < 0) + { + MALI_GRALLOC_LOGE("Buffer: %p is corrupted", handle); + return Error::BAD_BUFFER; + } + + auto private_handle = static_cast<const private_handle_t *>(handle); + if (!private_handle->cpu_write && !private_handle->cpu_read) + { + MALI_GRALLOC_LOGE("Attempt to call rereadLockedBuffer() on an unlocked buffer (%p)", handle); + return Error::BAD_BUFFER; + } + + mali_gralloc_ion_sync_start(private_handle, true, false); + return Error::NONE; +} + +void get(void *buffer, const IMapper::MetadataType &metadataType, IMapper::get_cb hidl_cb) +{ + /* The buffer must have been allocated by Gralloc */ + const private_handle_t *handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer)); + if (handle == nullptr) + { + MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer); + hidl_cb(Error::BAD_BUFFER, hidl_vec<uint8_t>()); + return; + } + + if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0) + { + MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle); + hidl_cb(Error::BAD_VALUE, hidl_vec<uint8_t>()); + return; + } + + get_metadata(handle, metadataType, hidl_cb); +} + +Error set(void *buffer, const IMapper::MetadataType &metadataType, const hidl_vec<uint8_t> &metadata) +{ + /* The buffer must have been allocated by Gralloc */ + const private_handle_t *handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer)); + if (handle == nullptr) + { + MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer); + return Error::BAD_BUFFER; + } + + if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0) + { + MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle); + return Error::BAD_VALUE; + } + + return set_metadata(handle, metadataType, metadata); +} + +void listSupportedMetadataTypes(IMapper::listSupportedMetadataTypes_cb hidl_cb) +{ + /* Returns a vector of {metadata type, description, isGettable, isSettable} + * Only non-standardMetadataTypes require a description. + */ + hidl_vec<IMapper::MetadataTypeDescription> descriptions = { + { android::gralloc4::MetadataType_BufferId, "", true, false }, + { android::gralloc4::MetadataType_Name, "", true, false }, + { android::gralloc4::MetadataType_Width, "", true, false }, + { android::gralloc4::MetadataType_Height, "", true, false }, + { android::gralloc4::MetadataType_LayerCount, "", true, false }, + { android::gralloc4::MetadataType_PixelFormatRequested, "", true, false }, + { android::gralloc4::MetadataType_PixelFormatFourCC, "", true, false }, + { android::gralloc4::MetadataType_PixelFormatModifier, "", true, false }, + { android::gralloc4::MetadataType_Usage, "", true, false }, + { android::gralloc4::MetadataType_AllocationSize, "", true, false }, + { android::gralloc4::MetadataType_ProtectedContent, "", true, false }, + { android::gralloc4::MetadataType_Compression, "", true, false }, + { android::gralloc4::MetadataType_Interlaced, "", true, false }, + { android::gralloc4::MetadataType_ChromaSiting, "", true, false }, + { android::gralloc4::MetadataType_PlaneLayouts, "", true, false }, + { android::gralloc4::MetadataType_Dataspace, "", true, true }, + { android::gralloc4::MetadataType_BlendMode, "", true, true }, + { android::gralloc4::MetadataType_Smpte2086, "", true, true }, + { android::gralloc4::MetadataType_Cta861_3, "", true, true }, + { android::gralloc4::MetadataType_Smpte2094_40, "", true, true }, + { android::gralloc4::MetadataType_Crop, "", true, true }, + }; + hidl_cb(Error::NONE, descriptions); + return; +} + + +static hidl_vec<IMapper::MetadataDump> dumpBufferHelper(const private_handle_t* handle) +{ + hidl_vec<IMapper::MetadataType> standardMetadataTypes = { + android::gralloc4::MetadataType_BufferId, + android::gralloc4::MetadataType_Name, + android::gralloc4::MetadataType_Width, + android::gralloc4::MetadataType_Height, + android::gralloc4::MetadataType_LayerCount, + android::gralloc4::MetadataType_PixelFormatRequested, + android::gralloc4::MetadataType_PixelFormatFourCC, + android::gralloc4::MetadataType_PixelFormatModifier, + android::gralloc4::MetadataType_Usage, + android::gralloc4::MetadataType_AllocationSize, + android::gralloc4::MetadataType_ProtectedContent, + android::gralloc4::MetadataType_Compression, + android::gralloc4::MetadataType_Interlaced, + android::gralloc4::MetadataType_ChromaSiting, + android::gralloc4::MetadataType_PlaneLayouts, + android::gralloc4::MetadataType_Dataspace, + android::gralloc4::MetadataType_BlendMode, + android::gralloc4::MetadataType_Smpte2086, + android::gralloc4::MetadataType_Cta861_3, + android::gralloc4::MetadataType_Smpte2094_40, + android::gralloc4::MetadataType_Crop, + }; + + std::vector<IMapper::MetadataDump> metadataDumps; + for (const auto& metadataType: standardMetadataTypes) + { + get_metadata(handle, metadataType, [&metadataDumps, &metadataType](Error error, hidl_vec<uint8_t> metadata) { + switch(error) + { + case Error::NONE: + metadataDumps.push_back({metadataType, metadata}); + break; + case Error::UNSUPPORTED: + default: + return; + } + }); + } + return hidl_vec<IMapper::MetadataDump>(metadataDumps); +} + +void dumpBuffer(void *buffer, IMapper::dumpBuffer_cb hidl_cb) +{ + IMapper::BufferDump bufferDump{}; + auto handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer)); + if (handle == nullptr) + { + MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer); + hidl_cb(Error::BAD_BUFFER, bufferDump); + return; + } + + bufferDump.metadataDump = dumpBufferHelper(handle); + hidl_cb(Error::NONE, bufferDump); +} + +void dumpBuffers(IMapper::dumpBuffers_cb hidl_cb) +{ + std::vector<IMapper::BufferDump> bufferDumps; + gRegisteredHandles->for_each([&bufferDumps](buffer_handle_t buffer) { + IMapper::BufferDump bufferDump { dumpBufferHelper(static_cast<const private_handle_t *>(buffer)) }; + bufferDumps.push_back(bufferDump); + }); + hidl_cb(Error::NONE, hidl_vec<IMapper::BufferDump>(bufferDumps)); +} + +void getReservedRegion(void *buffer, IMapper::getReservedRegion_cb hidl_cb) +{ + auto handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer)); + if (handle == nullptr) + { + MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer); + hidl_cb(Error::BAD_BUFFER, 0, 0); + return; + } + else if (handle->reserved_region_size == 0) + { + MALI_GRALLOC_LOGE("Buffer: %p has no reserved region", buffer); + hidl_cb(Error::BAD_BUFFER, 0, 0); + return; + } + void *reserved_region = static_cast<std::byte *>(handle->attr_base) + + mapper::common::shared_metadata_size(); + hidl_cb(Error::NONE, reserved_region, handle->reserved_region_size); +} + +} // namespace common +} // namespace mapper +} // namespace arm diff --git a/GrallocHAL/src/hidl_common/Mapper.h b/GrallocHAL/src/hidl_common/Mapper.h new file mode 100644 index 0000000..6d114cc --- /dev/null +++ b/GrallocHAL/src/hidl_common/Mapper.h @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2020 ARM Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_COMMON_MAPPER_H +#define GRALLOC_COMMON_MAPPER_H + +#include <inttypes.h> +#include "mali_gralloc_log.h" +#include "core/mali_gralloc_bufferdescriptor.h" + +#include "4.x/gralloc_mapper_hidl_header.h" + +namespace arm +{ +namespace mapper +{ +namespace common +{ + +using android::hardware::hidl_handle; +using android::hardware::hidl_vec; +using android::hardware::Void; + +/** + * Imports a raw buffer handle to create an imported buffer handle for use with + * the rest of the mapper or with other in-process libraries. + * + * @param rawHandle [in] Raw buffer handle to import. + * @param hidl_cb [in] HIDL Callback function to export output information + * @param hidl_cb [in] HIDL callback function generating - + * error : NONE upon success. Otherwise, + * BAD_BUFFER for an invalid buffer + * NO_RESOURCES when the raw handle cannot be imported + * BAD_VALUE when any of the specified attributes are invalid + * buffer : Imported buffer handle + */ +void importBuffer(const hidl_handle &rawHandle, IMapper::importBuffer_cb hidl_cb); + +/** + * Frees a buffer handle and releases all the resources associated with it + * + * @param buffer [in] Imported buffer to free + * + * @return Error::BAD_BUFFER for an invalid buffer / when failed to free the buffer + * Error::NONE on successful free + */ +Error freeBuffer(void *buffer); + +/** + * Locks the given buffer for the specified CPU usage. + * + * @param buffer [in] Buffer to lock + * @param cpuUsage [in] Specifies one or more CPU usage flags to request + * @param accessRegion [in] Portion of the buffer that the client intends to access + * @param acquireFence [in] Handle for aquire fence object + * @param hidl_cb [in] HIDL callback function generating - + * error: NONE upon success. Otherwise, + * BAD_BUFFER for an invalid buffer + * BAD_VALUE for an invalid input parameters + * data: CPU-accessible pointer to the buffer data + * bytesPerPixel: v3.X Only. Number of bytes per pixel in the buffer + * bytesPerStride: v3.X Only. Bytes per stride of the buffer + */ +void lock(void *buffer, uint64_t cpuUsage, const IMapper::Rect &accessRegion, const hidl_handle &acquireFence, + IMapper::lock_cb hidl_cb); + +/** + * Unlocks a buffer to indicate all CPU accesses to the buffer have completed + * + * @param buffer [in] Buffer to lock. + * @param hidl_cb [in] HIDL callback function generating - + * error: NONE upon success. Otherwise, + * BAD_BUFFER for an invalid buffer + * releaseFence: Referrs to a sync fence object + */ +void unlock(void *buffer, IMapper::unlock_cb hidl_cb); + +/** + * Validates the buffer against specified descriptor attributes + * + * @param buffer [in] Buffer which needs to be validated. + * @param descriptorInfo [in] Required attributes of the buffer + * @param in_stride [in] Buffer stride returned by IAllocator::allocate, + * or zero if unknown. + * + * @return Error::NONE upon success. Otherwise, + * Error::BAD_BUFFER upon bad buffer input + * Error::BAD_VALUE when any of the specified attributes are invalid + */ +Error validateBufferSize(void *buffer, const IMapper::BufferDescriptorInfo &descriptorInfo, uint32_t stride); + +/** + * Get the transport size of a buffer + * + * @param buffer [in] Buffer for computing transport size + * @param hidl_cb [in] HIDL callback function generating - + * error: NONE upon success. Otherwise, + * BAD_BUFFER for an invalid buffer + * numFds: Number of file descriptors needed for transport + * numInts: Number of integers needed for transport + */ +void getTransportSize(void *buffer, IMapper::getTransportSize_cb hidl_cb); + +/** + * Test whether the given BufferDescriptorInfo is allocatable. + * + * @param description [in] Description for the buffer + * @param hidl_cb [in] HIDL callback function generating - + * error: NONE, for supported description + * BAD_VALUE, Otherwise, + * supported: Whether the description can be allocated + */ +void isSupported(const IMapper::BufferDescriptorInfo &description, IMapper::isSupported_cb hidl_cb); + +/* TODO: implement this feature for exynos */ +/** + * Flushes the CPU caches of a mapped buffer. + * + * @param buffer [in] Locked buffer which needs to have CPU caches flushed. + * @param hidl_cb [in] HIDL callback function generating - + * error: NONE upon success. Otherwise, BAD_BUFFER for an invalid buffer or a buffer that + * has not been locked. + * releaseFence: Empty fence signaling completion as all work is completed within the call. + */ +void flushLockedBuffer(void *buffer, IMapper::flushLockedBuffer_cb hidl_cb); + +/* TODO: implement this feature for exynos */ +/** + * Invalidates the CPU caches of a mapped buffer. + * + * @param buffer [in] Locked buffer which needs to have CPU caches invalidated. + * + * @return Error::NONE upon success. + * Error::BAD_BUFFER for an invalid buffer or a buffer that has not been locked. + */ +Error rereadLockedBuffer(void *buffer); + +/** + * Retrieves a Buffer's metadata value. + * + * @param buffer [in] The buffer to query for metadata. + * @param metadataType [in] The type of metadata queried. + * @param hidl_cb [in] HIDL callback function generating - + * error: NONE on success. + * BAD_BUFFER on invalid buffer argument. + * UNSUPPORTED on error when reading or unsupported metadata type. + * metadata: Vector of bytes representing the metadata value. + */ +void get(void *buffer, const IMapper::MetadataType &metadataType, IMapper::get_cb hidl_cb); + +/** + * Sets a Buffer's metadata value. + * + * @param buffer [in] The buffer for which to modify metadata. + * @param metadataType [in] The type of metadata to modify. + * @param metadata [in] Vector of bytes representing the new value for the metadata associated with the buffer. + * + * @return Error::NONE on success. + * Error::BAD_BUFFER on invalid buffer argument. + * Error::UNSUPPORTED on error when writing or unsupported metadata type. + */ +Error set(void *buffer, const IMapper::MetadataType &metadataType, const hidl_vec<uint8_t> &metadata); + +/** + * Lists all the MetadataTypes supported by IMapper as well as a description + * of each supported MetadataType. For StandardMetadataTypes, the description + * string can be left empty. + * + * @param hidl_cb [in] HIDL callback function generating - + * error: Error status of the call, which may be + * - NONE upon success. + * - NO_RESOURCES if the get cannot be fullfilled due to unavailability of + * resources. + * descriptions: vector of MetadataTypeDescriptions that represent the + * MetadataTypes supported by the device. + */ +void listSupportedMetadataTypes(IMapper::listSupportedMetadataTypes_cb hidl_cb); + +/** + * Dumps a buffer's metadata. + * + * @param buffer [in] Buffer that is being dumped + * @param hidl_cb [in] HIDL callback function generating - + * error: Error status of the call, which may be + * - NONE upon success. + * - BAD_BUFFER if the raw handle is invalid. + * - NO_RESOURCES if the get cannot be fullfilled due to unavailability of + * resources. + * bufferDump: Struct representing the metadata being dumped + */ +void dumpBuffer(void *buffer, IMapper::dumpBuffer_cb hidl_cb); + +/** + * Dumps the metadata for all the buffers in the current process. + * + * @param hidl_cb [in] HIDL callback function generating - + * error: Error status of the call, which may be + * - NONE upon success. + * - NO_RESOURCES if the get cannot be fullfilled due to unavailability of + * resources. + * bufferDumps: Vector of structs representing the buffers being dumped + */ +void dumpBuffers(IMapper::dumpBuffers_cb hidl_cb); + +/** + * Returns the region of shared memory associated with the buffer that is + * reserved for client use. + * + * The shared memory may be allocated from any shared memory allocator. + * The shared memory must be CPU-accessible and virtually contiguous. The + * starting address must be word-aligned. + * + * This function may only be called after importBuffer() has been called by the + * client. The reserved region must remain accessible until freeBuffer() has + * been called. After freeBuffer() has been called, the client must not access + * the reserved region. + * + * This reserved memory may be used in future versions of Android to + * help clients implement backwards compatible features without requiring + * IAllocator/IMapper updates. + * + * @param buffer Imported buffer handle. + * @param hidl_cb [in] HIDL callback function generating - + * error: Error status of the call, which may be + * - NONE upon success. + * - BAD_BUFFER if the buffer is invalid. + * reservedRegion: CPU-accessible pointer to the reserved region + * reservedSize: the size of the reservedRegion that was requested + * in the BufferDescriptorInfo. + */ +void getReservedRegion(void *buffer, IMapper::getReservedRegion_cb _hidl_cb); + +} // namespace common +} // namespace mapper +} // namespace arm + +#endif /* GRALLOC_COMMON_MAPPER_H */ diff --git a/GrallocHAL/src/hidl_common/MapperMetadata.cpp b/GrallocHAL/src/hidl_common/MapperMetadata.cpp new file mode 100644 index 0000000..413aedf --- /dev/null +++ b/GrallocHAL/src/hidl_common/MapperMetadata.cpp @@ -0,0 +1,847 @@ +/* + * Copyright (C) 2020 Arm Limited. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MapperMetadata.h" +#include "SharedMetadata.h" +#include "core/format_info.h" +#include "core/mali_gralloc_bufferallocation.h" +#include "mali_gralloc_buffer.h" +#include "mali_gralloc_log.h" +#include "drmutils.h" +#include "gralloctypes/Gralloc4.h" + +#include "exynos_format.h" +#include "mali_gralloc_formats.h" + +#include <vector> + +namespace arm +{ +namespace mapper +{ +namespace common +{ + +using aidl::android::hardware::graphics::common::PlaneLayout; +using aidl::android::hardware::graphics::common::PlaneLayoutComponent; +using aidl::android::hardware::graphics::common::Rect; +using aidl::android::hardware::graphics::common::Dataspace; +using aidl::android::hardware::graphics::common::BlendMode; +using aidl::android::hardware::graphics::common::StandardMetadataType; +using aidl::android::hardware::graphics::common::XyColor; +using aidl::android::hardware::graphics::common::Smpte2086; +using aidl::android::hardware::graphics::common::Cta861_3; + +using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType; + +static int get_num_planes(const private_handle_t *hnd) +{ + if (is_exynos_format(hnd->get_alloc_format())) + { + switch (hnd->get_alloc_format()) + { + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_EXYNOS_YV12_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M: + return 3; + + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: + case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: + return 2; + } + } + + return hnd->is_multi_plane() ? (hnd->plane_info[2].offset == 0 ? 2 : 3) : 1; +} + +static std::vector<std::vector<PlaneLayoutComponent>> plane_layout_components_from_handle(const private_handle_t *hnd) +{ + /* Re-define the component constants to make the table easier to read. */ + const ExtendableType R = android::gralloc4::PlaneLayoutComponentType_R; + const ExtendableType G = android::gralloc4::PlaneLayoutComponentType_G; + const ExtendableType B = android::gralloc4::PlaneLayoutComponentType_B; + const ExtendableType A = android::gralloc4::PlaneLayoutComponentType_A; + const ExtendableType CB = android::gralloc4::PlaneLayoutComponentType_CB; + const ExtendableType CR = android::gralloc4::PlaneLayoutComponentType_CR; + const ExtendableType Y = android::gralloc4::PlaneLayoutComponentType_Y; + const ExtendableType RAW = android::gralloc4::PlaneLayoutComponentType_RAW; + + struct table_entry + { + uint32_t drm_fourcc; + std::vector<std::vector<PlaneLayoutComponent>> components; + }; + + /* clang-format off */ + static table_entry table[] = { + /* 16 bit RGB(A) */ + { + .drm_fourcc = DRM_FORMAT_RGB565, + .components = { { { B, 0, 5 }, { G, 5, 6 }, { R, 11, 5 } } } + }, + { + .drm_fourcc = DRM_FORMAT_BGR565, + .components = { { { R, 0, 5 }, { G, 5, 6 }, { B, 11, 5 } } } + }, + /* 24 bit RGB(A) */ + { + .drm_fourcc = DRM_FORMAT_BGR888, + .components = { { { R, 0, 8 }, { G, 8, 8 }, { B, 16, 8 } } } + }, + /* 32 bit RGB(A) */ + { + .drm_fourcc = DRM_FORMAT_ARGB8888, + .components = { { { B, 0, 8 }, { G, 8, 8 }, { R, 16, 8 }, { A, 24, 8 } } } + }, + { + .drm_fourcc = DRM_FORMAT_ABGR8888, + .components = { { { R, 0, 8 }, { G, 8, 8 }, { B, 16, 8 }, { A, 24, 8 } } } + }, + { + .drm_fourcc = DRM_FORMAT_XBGR8888, + .components = { { { R, 0, 8 }, { G, 8, 8 }, { B, 16, 8 } } } + }, + { + .drm_fourcc = DRM_FORMAT_ABGR2101010, + .components = { { { R, 0, 10 }, { G, 10, 10 }, { B, 20, 10 }, { A, 30, 2 } } } + }, + /* 64 bit RGB(A) */ + { + .drm_fourcc = DRM_FORMAT_ABGR16161616F, + .components = { { { R, 0, 16 }, { G, 16, 16 }, { B, 32, 16 }, { A, 48, 16 } } } + }, + /* Single plane 8 bit YUV 4:2:2 */ + { + .drm_fourcc = DRM_FORMAT_YUYV, + .components = { { { Y, 0, 8 }, { CB, 8, 8 }, { Y, 16, 8 }, { CR, 24, 8 } } } + }, + /* Single plane 10 bit YUV 4:4:4 */ + { + .drm_fourcc = DRM_FORMAT_Y410, + .components = { { { CB, 0, 10 }, { Y, 10, 10 }, { CR, 20, 10 }, { A, 30, 2 } } } + }, + /* Single plane 10 bit YUV 4:2:2 */ + { + .drm_fourcc = DRM_FORMAT_Y210, + .components = { { { Y, 6, 10 }, { CB, 22, 10 }, { Y, 38, 10 }, { CR, 54, 10 } } } + }, + /* Single plane 10 bit YUV 4:2:0 */ + { + .drm_fourcc = DRM_FORMAT_Y0L2, + .components = { { + { Y, 0, 10 }, { CB, 10, 10 }, { Y, 20, 10 }, { A, 30, 1 }, { A, 31, 1 }, + { Y, 32, 10 }, { CR, 42, 10 }, { Y, 52, 10 }, { A, 62, 1 }, { A, 63, 1 } + } } + }, + /* Semi-planar 8 bit YUV 4:2:2 */ + { + .drm_fourcc = DRM_FORMAT_NV16, + .components = { + { { Y, 0, 8 } }, + { { CB, 0, 8 }, { CR, 8, 8 } } + } + }, + /* Semi-planar 8 bit YUV 4:2:0 */ + { + .drm_fourcc = DRM_FORMAT_NV12, + .components = { + { { Y, 0, 8 } }, + { { CB, 0, 8 }, { CR, 8, 8 } } + } + }, + { + .drm_fourcc = DRM_FORMAT_NV21, + .components = { + { { Y, 0, 8 } }, + { { CR, 0, 8 }, { CB, 8, 8 } } + } + }, + /* Semi-planar 10 bit YUV 4:2:2 */ + { + .drm_fourcc = DRM_FORMAT_P210, + .components = { + { { Y, 6, 10 } }, + { { CB, 6, 10 }, { CB, 22, 10 } } + } + }, + /* Semi-planar 10 bit YUV 4:2:0 */ + { + .drm_fourcc = DRM_FORMAT_P010, + .components = { + { { Y, 6, 10 } }, + { { CB, 6, 10 }, { CR, 22, 10 } } + } + }, + /* Planar 8 bit YUV 4:2:0 */ + { + .drm_fourcc = DRM_FORMAT_YVU420, + .components = { + { { Y, 0, 8 } }, + { { CR, 0, 8 } }, + { { CB, 0, 8 } } + } + }, + /* Planar 8 bit YUV 4:4:4 */ + { + .drm_fourcc = DRM_FORMAT_YUV444, + .components = { + { { Y, 0, 8 } }, + { { CB, 0, 8 } }, + { { CR, 0, 8 } } + } + }, + + /* AFBC Only FourCC */ + {.drm_fourcc = DRM_FORMAT_YUV420_8BIT, .components = { {} } }, + {.drm_fourcc = DRM_FORMAT_YUV420_10BIT, .components = { {} } }, + + /* Google specific formats */ + { + .drm_fourcc = DRM_FORMAT_R8, + .components = { + { { R, 0, 8 } } + } + }, + { + .drm_fourcc = DRM_FORMAT_RG88, + .components = { + { { R, 0, 8 }, { G, 8, 8 } } + } + }, + }; + /* clang-format on */ + + const uint32_t drm_fourcc = drm_fourcc_from_handle(hnd); + if (drm_fourcc != DRM_FORMAT_INVALID) + { + for (const auto& entry : table) + { + if (entry.drm_fourcc == drm_fourcc) + { + return entry.components; + } + } + } + + switch (hnd->get_alloc_format()) + { + case HAL_PIXEL_FORMAT_RAW10: + return {{{RAW, 0, -1}}}; + case HAL_PIXEL_FORMAT_RAW12: + return {{{RAW, 0, -1}}}; + case HAL_PIXEL_FORMAT_BLOB: + break; + default: + MALI_GRALLOC_LOGW("Could not find component description for Format(%#x) FourCC value(%#x)", + hnd->get_alloc_format(), drm_fourcc); + } + + return std::vector<std::vector<PlaneLayoutComponent>>(0); +} + +static android::status_t get_plane_layouts(const private_handle_t *handle, std::vector<PlaneLayout> *layouts) +{ + const int num_planes = get_num_planes(handle); + int32_t format_index = get_format_index(handle->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); + if (format_index < 0) + { + MALI_GRALLOC_LOGE("Negative format index in get_plane_layouts"); + return android::BAD_VALUE; + } + const format_info_t format_info = formats[format_index]; + layouts->reserve(num_planes); + + if (is_exynos_format(handle->get_alloc_format())) + { + std::vector<std::vector<PlaneLayoutComponent>> components = plane_layout_components_from_handle(handle); + for (size_t plane_index = 0; plane_index < num_planes; ++plane_index) + { + int64_t plane_size = handle->plane_info[plane_index].size; + int64_t sample_increment_in_bits = format_info.bpp[plane_index]; + int64_t offset = handle->plane_info[plane_index].offset; + + // TODO(b/182885532): Allocate the complete buffer contiguously + if (handle->plane_info[plane_index].fd_idx == plane_index) + { + offset = (int64_t)handle->bases[plane_index] - handle->bases[0]; + } + + /* sample increments in bits must be 8 for y plane for lock */ + if (plane_index == 0) + { + sample_increment_in_bits = 8; + } + /* sample increments in bits must be 8 or 16 for cb/cr plane for lock */ + else if (sample_increment_in_bits > 16) + { + sample_increment_in_bits = 16; + } + + PlaneLayout layout = {.offsetInBytes = offset, + .sampleIncrementInBits = sample_increment_in_bits, + .strideInBytes = handle->plane_info[plane_index].byte_stride, + .widthInSamples = handle->plane_info[plane_index].alloc_width, + .heightInSamples = handle->plane_info[plane_index].alloc_height, + .totalSizeInBytes = plane_size, + .horizontalSubsampling = (plane_index == 0 ? 1 : format_info.hsub), + .verticalSubsampling = (plane_index == 0 ? 1 : format_info.vsub), + .components = components.size() > plane_index ? components[plane_index] : + std::vector<PlaneLayoutComponent>(0) }; + layouts->push_back(layout); + } + } + else + { + std::vector<std::vector<PlaneLayoutComponent>> components = plane_layout_components_from_handle(handle); + for (size_t plane_index = 0; plane_index < num_planes; ++plane_index) + { + int64_t plane_size; + if (plane_index < num_planes - 1) + { + plane_size = handle->plane_info[plane_index + 1].offset; + } + else + { + int64_t layer_size = handle->alloc_sizes[0] / handle->layer_count; + plane_size = layer_size - handle->plane_info[plane_index].offset; + } + + if (handle->fd_count > 1 && handle->plane_info[plane_index].fd_idx == plane_index) + { + plane_size = handle->plane_info[plane_index].size; + } + + int64_t sample_increment_in_bits = 0; + if (handle->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) + { + sample_increment_in_bits = format_info.bpp_afbc[plane_index]; + } + else + { + sample_increment_in_bits = format_info.bpp[plane_index]; + } + + switch (handle->get_alloc_format()) + { + case HAL_PIXEL_FORMAT_RAW10: + case HAL_PIXEL_FORMAT_RAW12: + sample_increment_in_bits = 0; + break; + default: + break; + } + + PlaneLayout layout = {.offsetInBytes = handle->plane_info[plane_index].offset, + .sampleIncrementInBits = sample_increment_in_bits, + .strideInBytes = handle->plane_info[plane_index].byte_stride, + .widthInSamples = handle->plane_info[plane_index].alloc_width, + .heightInSamples = handle->plane_info[plane_index].alloc_height, + .totalSizeInBytes = plane_size, + .horizontalSubsampling = (plane_index == 0 ? 1 : format_info.hsub), + .verticalSubsampling = (plane_index == 0 ? 1 : format_info.vsub), + .components = components.size() > plane_index ? components[plane_index] : + std::vector<PlaneLayoutComponent>(0) }; + layouts->push_back(layout); + } + } + + return android::OK; +} + +void get_metadata(const private_handle_t *handle, const IMapper::MetadataType &metadataType, IMapper::get_cb hidl_cb) +{ + /* This will hold the metadata that is returned. */ + hidl_vec<uint8_t> vec; + + if (android::gralloc4::isStandardMetadataType(metadataType)) + { + android::status_t err = android::OK; + + switch (android::gralloc4::getStandardMetadataTypeValue(metadataType)) + { + case StandardMetadataType::BUFFER_ID: + err = android::gralloc4::encodeBufferId(handle->backing_store_id, &vec); + break; + case StandardMetadataType::NAME: + { + std::string name; + get_name(handle, &name); + err = android::gralloc4::encodeName(name, &vec); + break; + } + case StandardMetadataType::WIDTH: + err = android::gralloc4::encodeWidth(handle->width, &vec); + break; + case StandardMetadataType::HEIGHT: + err = android::gralloc4::encodeHeight(handle->height, &vec); + break; + case StandardMetadataType::LAYER_COUNT: + err = android::gralloc4::encodeLayerCount(handle->layer_count, &vec); + break; + case StandardMetadataType::PIXEL_FORMAT_REQUESTED: + err = android::gralloc4::encodePixelFormatRequested(static_cast<PixelFormat>(handle->req_format), &vec); + break; + case StandardMetadataType::PIXEL_FORMAT_FOURCC: + err = android::gralloc4::encodePixelFormatFourCC(drm_fourcc_from_handle(handle), &vec); + break; + case StandardMetadataType::PIXEL_FORMAT_MODIFIER: + err = android::gralloc4::encodePixelFormatModifier(drm_modifier_from_handle(handle), &vec); + break; + case StandardMetadataType::USAGE: + err = android::gralloc4::encodeUsage(handle->consumer_usage | handle->producer_usage, &vec); + break; + case StandardMetadataType::ALLOCATION_SIZE: + { + uint64_t total_size = 0; + for (int fidx = 0; fidx < handle->fd_count; fidx++) + { + total_size += handle->alloc_sizes[fidx]; + } + err = android::gralloc4::encodeAllocationSize(total_size, &vec); + break; + } + case StandardMetadataType::PROTECTED_CONTENT: + { + /* This is set to 1 if the buffer has protected content. */ + const int is_protected = + (((handle->consumer_usage | handle->producer_usage) & BufferUsage::PROTECTED) == 0) ? 0 : 1; + err = android::gralloc4::encodeProtectedContent(is_protected, &vec); + break; + } + case StandardMetadataType::COMPRESSION: + { + ExtendableType compression = android::gralloc4::Compression_None; + err = android::gralloc4::encodeCompression(compression, &vec); + break; + } + case StandardMetadataType::INTERLACED: + err = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None, &vec); + break; + case StandardMetadataType::CHROMA_SITING: + { + int format_index = get_format_index(handle->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); + if (format_index < 0) + { + err = android::BAD_VALUE; + break; + } + ExtendableType siting = android::gralloc4::ChromaSiting_None; + if (formats[format_index].is_yuv) + { + siting = android::gralloc4::ChromaSiting_Unknown; + } + err = android::gralloc4::encodeChromaSiting(siting, &vec); + break; + } + case StandardMetadataType::PLANE_LAYOUTS: + { + std::vector<PlaneLayout> layouts; + err = get_plane_layouts(handle, &layouts); + if (!err) + { + err = android::gralloc4::encodePlaneLayouts(layouts, &vec); + } + break; + } + case StandardMetadataType::DATASPACE: + { + std::optional<Dataspace> dataspace; + get_dataspace(handle, &dataspace); + err = android::gralloc4::encodeDataspace(dataspace.value_or(Dataspace::UNKNOWN), &vec); + break; + } + case StandardMetadataType::BLEND_MODE: + { + std::optional<BlendMode> blend_mode; + get_blend_mode(handle, &blend_mode); + err = android::gralloc4::encodeBlendMode(blend_mode.value_or(BlendMode::INVALID), &vec); + break; + } + case StandardMetadataType::CROP: + { + const int num_planes = get_num_planes(handle); + std::vector<Rect> crops(num_planes); + for (size_t plane_index = 0; plane_index < num_planes; ++plane_index) + { + /* Set the default crop rectangle. Android mandates that it must fit [0, 0, widthInSamples, heightInSamples] + * We always require using the requested width and height for the crop rectangle size. + * For planes > 0 the size might need to be scaled, but since we only use plane[0] for crop set it to the + * Android default of [0, 0, widthInSamples, heightInSamples] for other planes. + */ + Rect rect = {.top = 0, + .left = 0, + .right = static_cast<int32_t>(handle->plane_info[plane_index].alloc_width), + .bottom = static_cast<int32_t>(handle->plane_info[plane_index].alloc_height) }; + if (plane_index == 0) + { + std::optional<Rect> crop_rect; + get_crop_rect(handle, &crop_rect); + if (crop_rect.has_value()) + { + rect = crop_rect.value(); + } + else + { + rect = {.top = 0, .left = 0, .right = handle->width, .bottom = handle->height }; + } + } + crops[plane_index] = rect; + } + err = android::gralloc4::encodeCrop(crops, &vec); + break; + } + case StandardMetadataType::SMPTE2086: + { + std::optional<Smpte2086> smpte2086; + get_smpte2086(handle, &smpte2086); + err = android::gralloc4::encodeSmpte2086(smpte2086, &vec); + break; + } + case StandardMetadataType::CTA861_3: + { + std::optional<Cta861_3> cta861_3; + get_cta861_3(handle, &cta861_3); + err = android::gralloc4::encodeCta861_3(cta861_3, &vec); + break; + } + case StandardMetadataType::SMPTE2094_40: + { + std::optional<std::vector<uint8_t>> smpte2094_40; + get_smpte2094_40(handle, &smpte2094_40); + err = android::gralloc4::encodeSmpte2094_40(smpte2094_40, &vec); + break; + } + case StandardMetadataType::INVALID: + default: + err = android::BAD_VALUE; + } + hidl_cb((err) ? Error::UNSUPPORTED : Error::NONE, vec); + } + else + { + /* If known vendor type, return it */ + hidl_cb(Error::UNSUPPORTED, vec); + } +} + +Error set_metadata(const private_handle_t *handle, const IMapper::MetadataType &metadataType, + const hidl_vec<uint8_t> &metadata) +{ + if (android::gralloc4::isStandardMetadataType(metadataType)) + { + android::status_t err = android::OK; + switch (android::gralloc4::getStandardMetadataTypeValue(metadataType)) + { + case StandardMetadataType::DATASPACE: + { + Dataspace dataspace; + err = android::gralloc4::decodeDataspace(metadata, &dataspace); + if (!err) + { + set_dataspace(handle, dataspace); + } + break; + } + case StandardMetadataType::BLEND_MODE: + { + BlendMode blend_mode; + err = android::gralloc4::decodeBlendMode(metadata, &blend_mode); + if (!err) + { + set_blend_mode(handle, blend_mode); + } + break; + } + case StandardMetadataType::SMPTE2086: + { + std::optional<Smpte2086> smpte2086; + err = android::gralloc4::decodeSmpte2086(metadata, &smpte2086); + if (!err) + { + err = set_smpte2086(handle, smpte2086); + } + break; + } + case StandardMetadataType::CTA861_3: + { + std::optional<Cta861_3> cta861_3; + err = android::gralloc4::decodeCta861_3(metadata, &cta861_3); + if (!err) + { + err = set_cta861_3(handle, cta861_3); + } + break; + } + case StandardMetadataType::SMPTE2094_40: + { + std::optional<std::vector<uint8_t>> smpte2094_40; + err = android::gralloc4::decodeSmpte2094_40(metadata, &smpte2094_40); + if (!err) + { + err = set_smpte2094_40(handle, smpte2094_40); + } + break; + } + case StandardMetadataType::CROP: + { + std::vector<Rect> crops; + err = android::gralloc4::decodeCrop(metadata, &crops); + if (!err) + { + err = set_crop_rect(handle, crops[0]); + } + break; + } + /* The following meta data types cannot be changed after allocation. */ + 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 Error::BAD_VALUE; + /* Changing other metadata types is unsupported. */ + case StandardMetadataType::PLANE_LAYOUTS: + case StandardMetadataType::PIXEL_FORMAT_FOURCC: + case StandardMetadataType::PIXEL_FORMAT_MODIFIER: + case StandardMetadataType::ALLOCATION_SIZE: + case StandardMetadataType::PROTECTED_CONTENT: + case StandardMetadataType::COMPRESSION: + case StandardMetadataType::INTERLACED: + case StandardMetadataType::CHROMA_SITING: + case StandardMetadataType::INVALID: + default: + return Error::UNSUPPORTED; + } + return ((err) ? Error::UNSUPPORTED : Error::NONE); + } + else + { + /* None of the vendor types support set. */ + return Error::UNSUPPORTED; + } +} + +void getFromBufferDescriptorInfo(IMapper::BufferDescriptorInfo const &description, + IMapper::MetadataType const &metadataType, + IMapper::getFromBufferDescriptorInfo_cb hidl_cb) +{ + /* This will hold the metadata that is returned. */ + hidl_vec<uint8_t> vec; + + buffer_descriptor_t descriptor; + descriptor.width = description.width; + descriptor.height = description.height; + descriptor.layer_count = description.layerCount; + descriptor.hal_format = static_cast<uint64_t>(description.format); + descriptor.producer_usage = static_cast<uint64_t>(description.usage); + descriptor.consumer_usage = descriptor.producer_usage; + descriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; + + /* Check if it is possible to allocate a buffer for the given description */ + const int alloc_result = mali_gralloc_derive_format_and_size(&descriptor); + if (alloc_result != 0) + { + MALI_GRALLOC_LOGV("Allocation for the given description will not succeed. error: %d", alloc_result); + hidl_cb(Error::BAD_VALUE, vec); + return; + } + /* Create buffer handle from the initialized descriptor without a backing store or shared metadata region. + * Used to share functionality with the normal metadata get function that can only use the allocated buffer handle + * and does not have the buffer descriptor available. */ + private_handle_t partial_handle(0, descriptor.alloc_sizes, descriptor.consumer_usage, descriptor.producer_usage, + nullptr, descriptor.fd_count, + descriptor.hal_format, descriptor.alloc_format, + descriptor.width, descriptor.height, descriptor.pixel_stride, + descriptor.layer_count, descriptor.plane_info); + if (android::gralloc4::isStandardMetadataType(metadataType)) + { + android::status_t err = android::OK; + + switch (android::gralloc4::getStandardMetadataTypeValue(metadataType)) + { + case StandardMetadataType::NAME: + err = android::gralloc4::encodeName(description.name, &vec); + break; + case StandardMetadataType::WIDTH: + err = android::gralloc4::encodeWidth(description.width, &vec); + break; + case StandardMetadataType::HEIGHT: + err = android::gralloc4::encodeHeight(description.height, &vec); + break; + case StandardMetadataType::LAYER_COUNT: + err = android::gralloc4::encodeLayerCount(description.layerCount, &vec); + break; + case StandardMetadataType::PIXEL_FORMAT_REQUESTED: + err = android::gralloc4::encodePixelFormatRequested(static_cast<PixelFormat>(description.format), &vec); + break; + case StandardMetadataType::USAGE: + err = android::gralloc4::encodeUsage(description.usage, &vec); + break; + case StandardMetadataType::PIXEL_FORMAT_FOURCC: + err = android::gralloc4::encodePixelFormatFourCC(drm_fourcc_from_handle(&partial_handle), &vec); + break; + case StandardMetadataType::PIXEL_FORMAT_MODIFIER: + err = android::gralloc4::encodePixelFormatModifier(drm_modifier_from_handle(&partial_handle), &vec); + break; + case StandardMetadataType::ALLOCATION_SIZE: + { + /* TODO: Returns expetected size if the buffer was actually allocated. + * Is this the right behavior? + */ + uint64_t total_size = 0; + for (int fidx = 0; fidx < descriptor.fd_count; fidx++) + { + total_size += descriptor.alloc_sizes[fidx]; + } + err = android::gralloc4::encodeAllocationSize(total_size, &vec); + break; + } + case StandardMetadataType::PROTECTED_CONTENT: + { + /* This is set to 1 if the buffer has protected content. */ + const int is_protected = + (((partial_handle.consumer_usage | partial_handle.producer_usage) & BufferUsage::PROTECTED)) ? 1 : 0; + err = android::gralloc4::encodeProtectedContent(is_protected, &vec); + break; + } + case StandardMetadataType::COMPRESSION: + { + ExtendableType compression = android::gralloc4::Compression_None; + err = android::gralloc4::encodeCompression(compression, &vec); + break; + } + case StandardMetadataType::INTERLACED: + err = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None, &vec); + break; + case StandardMetadataType::CHROMA_SITING: + { + int format_index = get_format_index(partial_handle.alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); + if (format_index < 0) + { + err = android::BAD_VALUE; + break; + } + ExtendableType siting = android::gralloc4::ChromaSiting_None; + if (formats[format_index].is_yuv) + { + siting = android::gralloc4::ChromaSiting_Unknown; + } + err = android::gralloc4::encodeChromaSiting(siting, &vec); + break; + } + case StandardMetadataType::PLANE_LAYOUTS: + { + std::vector<PlaneLayout> layouts; + err = get_plane_layouts(&partial_handle, &layouts); + if (!err) + { + err = android::gralloc4::encodePlaneLayouts(layouts, &vec); + } + break; + } + case StandardMetadataType::DATASPACE: + { + android_dataspace_t dataspace; + get_format_dataspace(partial_handle.alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK, + partial_handle.consumer_usage | partial_handle.producer_usage, partial_handle.width, + partial_handle.height, &dataspace); + err = android::gralloc4::encodeDataspace(static_cast<Dataspace>(dataspace), &vec); + break; + } + case StandardMetadataType::BLEND_MODE: + err = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &vec); + break; + case StandardMetadataType::CROP: + { + const int num_planes = get_num_planes(&partial_handle); + std::vector<Rect> crops(num_planes); + for (size_t plane_index = 0; plane_index < num_planes; ++plane_index) + { + Rect rect = {.top = 0, + .left = 0, + .right = static_cast<int32_t>(partial_handle.plane_info[plane_index].alloc_width), + .bottom = static_cast<int32_t>(partial_handle.plane_info[plane_index].alloc_height) }; + if (plane_index == 0) + { + rect = {.top = 0, .left = 0, .right = partial_handle.width, .bottom = partial_handle.height }; + } + crops[plane_index] = rect; + } + err = android::gralloc4::encodeCrop(crops, &vec); + break; + } + case StandardMetadataType::SMPTE2086: + { + std::optional<Smpte2086> smpte2086{}; + err = android::gralloc4::encodeSmpte2086(smpte2086, &vec); + break; + } + case StandardMetadataType::CTA861_3: + { + std::optional<Cta861_3> cta861_3{}; + err = android::gralloc4::encodeCta861_3(cta861_3, &vec); + break; + } + case StandardMetadataType::SMPTE2094_40: + { + std::optional<std::vector<uint8_t>> smpte2094_40{}; + err = android::gralloc4::encodeSmpte2094_40(smpte2094_40, &vec); + break; + } + + case StandardMetadataType::BUFFER_ID: + case StandardMetadataType::INVALID: + default: + err = android::BAD_VALUE; + } + hidl_cb((err) ? Error::UNSUPPORTED : Error::NONE, vec); + } + else + { + hidl_cb(Error::UNSUPPORTED, vec); + } +} + +} // namespace common +} // namespace mapper +} // namespace arm diff --git a/GrallocHAL/src/hidl_common/MapperMetadata.h b/GrallocHAL/src/hidl_common/MapperMetadata.h new file mode 100644 index 0000000..aca3156 --- /dev/null +++ b/GrallocHAL/src/hidl_common/MapperMetadata.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 Arm Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_COMMON_MAPPER_METADATA_H +#define GRALLOC_COMMON_MAPPER_METADATA_H + +#include <inttypes.h> +#include "mali_gralloc_log.h" +#include "core/mali_gralloc_bufferdescriptor.h" +#include "mali_gralloc_buffer.h" + +#include "4.x/gralloc_mapper_hidl_header.h" + +namespace arm +{ +namespace mapper +{ +namespace common +{ +using android::hardware::hidl_vec; +using aidl::android::hardware::graphics::common::ExtendableType; + + +/** + * Retrieves a Buffer's metadata value. + * + * @param handle [in] The private handle of the buffer to query for metadata. + * @param metadataType [in] The type of metadata queried. + * @param hidl_cb [in] HIDL callback function generating - + * error: NONE on success. + * UNSUPPORTED on error when reading or unsupported metadata type. + * metadata: Vector of bytes representing the metadata value. + */ +void get_metadata(const private_handle_t *handle, const IMapper::MetadataType &metadataType, IMapper::get_cb hidl_cb); + +/** + * Sets a Buffer's metadata value. + * + * @param handle [in] The private handle of the buffer for which to modify metadata. + * @param metadataType [in] The type of metadata to modify. + * @param metadata [in] Vector of bytes representing the new value for the metadata associated with the buffer. + * + * @return Error::NONE on success. + * Error::UNSUPPORTED on error when writing or unsupported metadata type. + */ +Error set_metadata(const private_handle_t *handle, const IMapper::MetadataType &metadataType, + const hidl_vec<uint8_t> &metadata); + +/** + * Query basic metadata information about a buffer form its descriptor before allocation. + * + * @param description [in] The buffer descriptor. + * @param metadataType [in] The type of metadata to query + * @param hidl_cb [in] HIDL callback function generating - + * error: NONE on success. + * UNSUPPORTED on unsupported metadata type. + * metadata: Vector of bytes representing the metadata value. + */ +void getFromBufferDescriptorInfo(IMapper::BufferDescriptorInfo const &description, + IMapper::MetadataType const &metadataType, + IMapper::getFromBufferDescriptorInfo_cb hidl_cb); + +} // namespace common +} // namespace mapper +} // namespace arm + +#endif diff --git a/GrallocHAL/src/hidl_common/RegisteredHandlePool.cpp b/GrallocHAL/src/hidl_common/RegisteredHandlePool.cpp new file mode 100644 index 0000000..b598d8a --- /dev/null +++ b/GrallocHAL/src/hidl_common/RegisteredHandlePool.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 ARM Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "RegisteredHandlePool.h" + +bool RegisteredHandlePool::add(buffer_handle_t bufferHandle) +{ + std::lock_guard<std::mutex> lock(mutex); + return bufPool.insert(bufferHandle).second; +} + +native_handle_t* RegisteredHandlePool::remove(void* buffer) +{ + auto bufferHandle = static_cast<native_handle_t*>(buffer); + + std::lock_guard<std::mutex> lock(mutex); + return bufPool.erase(bufferHandle) == 1 ? bufferHandle : nullptr; +} + +buffer_handle_t RegisteredHandlePool::get(const void* buffer) +{ + auto bufferHandle = static_cast<buffer_handle_t>(buffer); + + std::lock_guard<std::mutex> lock(mutex); + return bufPool.count(bufferHandle) == 1 ? bufferHandle : nullptr; +} + +void RegisteredHandlePool::for_each(std::function<void(const buffer_handle_t &)> fn) +{ + std::lock_guard<std::mutex> lock(mutex); + std::for_each(bufPool.begin(), bufPool.end(), fn); +}
\ No newline at end of file diff --git a/GrallocHAL/src/hidl_common/RegisteredHandlePool.h b/GrallocHAL/src/hidl_common/RegisteredHandlePool.h new file mode 100644 index 0000000..d3fb9b0 --- /dev/null +++ b/GrallocHAL/src/hidl_common/RegisteredHandlePool.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 ARM Limited. All rights reserved. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef GRALLOC_COMMON_REGISTERED_HANDLE_POOL_H + #define GRALLOC_COMMON_REGISTERED_HANDLE_POOL_H + +#include <cutils/native_handle.h> +#include <mutex> +#include <unordered_set> +#include <algorithm> +#include <functional> + +/* An unordered set to internally store / retrieve imported buffer handles */ +class RegisteredHandlePool +{ +public: + /* Stores the buffer handle in the internal list */ + bool add(buffer_handle_t bufferHandle); + + /* Retrieves and removes the buffer handle from internal list */ + native_handle_t* remove(void* buffer); + + /* Retrieves the buffer handle from internal list */ + buffer_handle_t get(const void* buffer); + + /* Applies a function to each buffer handle */ + void for_each(std::function<void(const buffer_handle_t &)> fn); + +private: + std::mutex mutex; + std::unordered_set<buffer_handle_t> bufPool; +}; + +#endif /* GRALLOC_COMMON_REGISTERED_HANDLE_POOL_H */ diff --git a/GrallocHAL/src/hidl_common/SharedMetadata.cpp b/GrallocHAL/src/hidl_common/SharedMetadata.cpp new file mode 100644 index 0000000..4247bd8 --- /dev/null +++ b/GrallocHAL/src/hidl_common/SharedMetadata.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2020 Arm Limited. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SharedMetadata.h" +#include "mali_gralloc_log.h" +//#include <VendorVideoAPI.h> + +namespace arm +{ +namespace mapper +{ +namespace common +{ + +void shared_metadata_init(void *memory, std::string_view name) +{ + new(memory) shared_metadata(name); +} + +size_t shared_metadata_size() +{ + return sizeof(shared_metadata); +} + +void get_name(const private_handle_t *hnd, std::string *name) +{ + auto *metadata = reinterpret_cast<const shared_metadata *>(hnd->attr_base); + *name = metadata->get_name(); +} + +void get_crop_rect(const private_handle_t *hnd, std::optional<Rect> *crop) +{ + auto *metadata = reinterpret_cast<const shared_metadata *>(hnd->attr_base); + *crop = metadata->crop.to_std_optional(); +} + +android::status_t set_crop_rect(const private_handle_t *hnd, const Rect &crop) +{ + auto *metadata = reinterpret_cast<shared_metadata *>(hnd->attr_base); + + if (crop.top < 0 || crop.left < 0 || + crop.left > crop.right || crop.right > hnd->plane_info[0].alloc_width || + crop.top > crop.bottom || crop.bottom > hnd->plane_info[0].alloc_height || + (crop.right - crop.left) != hnd->width || + (crop.bottom - crop.top) != hnd->height) + { + MALI_GRALLOC_LOGE("Attempt to set invalid crop rectangle"); + return android::BAD_VALUE; + } + + metadata->crop = aligned_optional(crop); + return android::OK; +} + +void get_dataspace(const private_handle_t *hnd, std::optional<Dataspace> *dataspace) +{ + auto *metadata = reinterpret_cast<const shared_metadata *>(hnd->attr_base); + *dataspace = metadata->dataspace.to_std_optional(); +} + +void set_dataspace(const private_handle_t *hnd, const Dataspace &dataspace) +{ + auto *metadata = reinterpret_cast<shared_metadata *>(hnd->attr_base); + metadata->dataspace = aligned_optional(dataspace); +} + +void get_blend_mode(const private_handle_t *hnd, std::optional<BlendMode> *blend_mode) +{ + auto *metadata = reinterpret_cast<const shared_metadata *>(hnd->attr_base); + *blend_mode = metadata->blend_mode.to_std_optional(); +} + +void set_blend_mode(const private_handle_t *hnd, const BlendMode &blend_mode) +{ + auto *metadata = reinterpret_cast<shared_metadata *>(hnd->attr_base); + metadata->blend_mode = aligned_optional(blend_mode); +} + +void get_smpte2086(const private_handle_t *hnd, std::optional<Smpte2086> *smpte2086) +{ + auto *metadata = reinterpret_cast<const shared_metadata *>(hnd->attr_base); + *smpte2086 = metadata->smpte2086.to_std_optional(); +} + +android::status_t set_smpte2086(const private_handle_t *hnd, const std::optional<Smpte2086> &smpte2086) +{ + if (!smpte2086.has_value()) + { + return android::BAD_VALUE; + } + + auto *metadata = reinterpret_cast<shared_metadata *>(hnd->attr_base); + metadata->smpte2086 = aligned_optional(smpte2086); + + return android::OK; +} + +void get_cta861_3(const private_handle_t *hnd, std::optional<Cta861_3> *cta861_3) +{ + auto *metadata = reinterpret_cast<const shared_metadata *>(hnd->attr_base); + *cta861_3 = metadata->cta861_3.to_std_optional(); +} + +android::status_t set_cta861_3(const private_handle_t *hnd, const std::optional<Cta861_3> &cta861_3) +{ + if (!cta861_3.has_value()) + { + return android::BAD_VALUE; + } + + auto *metadata = reinterpret_cast<shared_metadata *>(hnd->attr_base); + metadata->cta861_3 = aligned_optional(cta861_3); + + return android::OK; +} + +void get_smpte2094_40(const private_handle_t *hnd, std::optional<std::vector<uint8_t>> *smpte2094_40) +{ + auto *metadata = reinterpret_cast<const shared_metadata *>(hnd->attr_base); + if (metadata->smpte2094_40.size > 0) + { + const uint8_t *begin = metadata->smpte2094_40.data(); + const uint8_t *end = begin + metadata->smpte2094_40.size; + smpte2094_40->emplace(begin, end); + } + else + { + smpte2094_40->reset(); + } +} + +android::status_t set_smpte2094_40(const private_handle_t *hnd, const std::optional<std::vector<uint8_t>> &smpte2094_40) +{ + if (!smpte2094_40.has_value() || smpte2094_40->size() == 0) + { + MALI_GRALLOC_LOGE("Empty SMPTE 2094-40 data"); + return android::BAD_VALUE; + } + + auto *metadata = reinterpret_cast<shared_metadata *>(hnd->attr_base); + const size_t size = smpte2094_40.has_value() ? smpte2094_40->size() : 0; + if (size > metadata->smpte2094_40.capacity()) + { + MALI_GRALLOC_LOGE("SMPTE 2094-40 metadata too large to fit in shared metadata region"); + return android::BAD_VALUE; + } + + metadata->smpte2094_40.size = size; + std::memcpy(metadata->smpte2094_40.data(), smpte2094_40->data(), size); + + return android::OK; +} + +} // namespace common +} // namespace mapper +} // namespace arm diff --git a/GrallocHAL/src/hidl_common/SharedMetadata.h b/GrallocHAL/src/hidl_common/SharedMetadata.h new file mode 100644 index 0000000..e1f6d0b --- /dev/null +++ b/GrallocHAL/src/hidl_common/SharedMetadata.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 Arm Limited. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRALLOC_COMMON_SHARED_METADATA_H +#define GRALLOC_COMMON_SHARED_METADATA_H + +#include <optional> +#include <vector> +#include "gralloctypes/Gralloc4.h" +#include "mali_gralloc_buffer.h" +#include "allocator/mali_gralloc_shared_memory.h" +#include "core/mali_gralloc_bufferdescriptor.h" +#include "gralloc_helper.h" + +#include "4.x/gralloc_mapper_hidl_header.h" + +#include "SharedMetadata_struct.h" + +namespace arm +{ +namespace mapper +{ +namespace common +{ + +using android::hardware::hidl_vec; +using aidl::android::hardware::graphics::common::Rect; +using aidl::android::hardware::graphics::common::Smpte2086; +using aidl::android::hardware::graphics::common::Cta861_3; +using aidl::android::hardware::graphics::common::BlendMode; +using aidl::android::hardware::graphics::common::Dataspace; + +void shared_metadata_init(void *memory, std::string_view name); +size_t shared_metadata_size(); + +void get_name(const private_handle_t *hnd, std::string *name); + +void get_crop_rect(const private_handle_t *hnd, std::optional<Rect> *crop); +android::status_t set_crop_rect(const private_handle_t *hnd, const Rect &crop_rectangle); + +void get_dataspace(const private_handle_t *hnd, std::optional<Dataspace> *dataspace); +void set_dataspace(const private_handle_t *hnd, const Dataspace &dataspace); + +void get_blend_mode(const private_handle_t *hnd, std::optional<BlendMode> *blend_mode); +void set_blend_mode(const private_handle_t *hnd, const BlendMode &blend_mode); + +void get_smpte2086(const private_handle_t *hnd, std::optional<Smpte2086> *smpte2086); +android::status_t set_smpte2086(const private_handle_t *hnd, const std::optional<Smpte2086> &smpte2086); + +void get_cta861_3(const private_handle_t *hnd, std::optional<Cta861_3> *cta861_3); +android::status_t set_cta861_3(const private_handle_t *hnd, const std::optional<Cta861_3> &cta861_3); + +void get_smpte2094_40(const private_handle_t *hnd, std::optional<std::vector<uint8_t>> *smpte2094_40); +android::status_t set_smpte2094_40(const private_handle_t *hnd, const std::optional<std::vector<uint8_t>> &smpte2094_40); + +} // namespace common +} // namespace mapper +} // namespace arm + +#endif diff --git a/GrallocHAL/src/hidl_common/SharedMetadata_struct.h b/GrallocHAL/src/hidl_common/SharedMetadata_struct.h new file mode 100644 index 0000000..60df44c --- /dev/null +++ b/GrallocHAL/src/hidl_common/SharedMetadata_struct.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2020 Arm Limited. + * + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <optional> +#include <vector> +#include <VendorVideoAPI.h> +#include "gralloctypes/Gralloc4.h" + +namespace arm +{ +namespace mapper +{ +namespace common +{ + +using aidl::android::hardware::graphics::common::Rect; +using aidl::android::hardware::graphics::common::Smpte2086; +using aidl::android::hardware::graphics::common::Cta861_3; +using aidl::android::hardware::graphics::common::BlendMode; +using aidl::android::hardware::graphics::common::Dataspace; + +template <typename T> +struct aligned_optional +{ + enum class state : uint32_t + { + vacant, + occupied, + }; + + state item_state { state::vacant }; + T item {}; + + aligned_optional() = default; + + aligned_optional(T initial_value) + : item_state(state::occupied) + , item(initial_value) + { + } + + aligned_optional(std::optional<T> std_optional) + : item_state(std_optional ? state::occupied : state::vacant) + { + if (std_optional) + { + item = *std_optional; + } + } + + std::optional<T> to_std_optional() const + { + switch (item_state) + { + case state::vacant: return std::nullopt; + case state::occupied: return std::make_optional(item); + } + } +}; + +template <typename T, size_t N> +struct aligned_inline_vector +{ + uint32_t size; + T contents[N]; + + constexpr uint32_t capacity() const + { + return N; + } + + const T *data() const + { + return &contents[0]; + } + + T *data() + { + return &contents[0]; + } +}; + +struct shared_metadata +{ + ExynosVideoMeta video_private_data; + + aligned_optional<BlendMode> blend_mode {}; + aligned_optional<Rect> crop {}; + aligned_optional<Cta861_3> cta861_3 {}; + aligned_optional<Dataspace> dataspace {}; + aligned_optional<Smpte2086> smpte2086 {}; + aligned_inline_vector<uint8_t, 2048> smpte2094_40 {}; + aligned_inline_vector<char, 256> name {}; + + shared_metadata() = default; + + shared_metadata(std::string_view in_name) + { + name.size = std::min(name.capacity(), static_cast<uint32_t>(in_name.size())); + std::memcpy(name.data(), in_name.data(), name.size); + } + + std::string_view get_name() const + { + return name.size > 0 + ? std::string_view(name.data(), name.size) + : std::string_view(); + } +}; + +/* TODO: convert alignment assert taking video metadata into account */ +#if 0 +static_assert(offsetof(shared_metadata, blend_mode) == 0, "bad alignment"); +static_assert(sizeof(shared_metadata::blend_mode) == 8, "bad size"); + +static_assert(offsetof(shared_metadata, crop) == 8, "bad alignment"); +static_assert(sizeof(shared_metadata::crop) == 20, "bad size"); + +static_assert(offsetof(shared_metadata, cta861_3) == 28, "bad alignment"); +static_assert(sizeof(shared_metadata::cta861_3) == 12, "bad size"); + +static_assert(offsetof(shared_metadata, dataspace) == 40, "bad alignment"); +static_assert(sizeof(shared_metadata::dataspace) == 8, "bad size"); + +static_assert(offsetof(shared_metadata, smpte2086) == 48, "bad alignment"); +static_assert(sizeof(shared_metadata::smpte2086) == 44, "bad size"); + +static_assert(offsetof(shared_metadata, smpte2094_40) == 92, "bad alignment"); +static_assert(sizeof(shared_metadata::smpte2094_40) == 2052, "bad size"); + +static_assert(offsetof(shared_metadata, name) == 2144, "bad alignment"); +static_assert(sizeof(shared_metadata::name) == 260, "bad size"); + +static_assert(alignof(shared_metadata) == 4, "bad alignment"); +static_assert(sizeof(shared_metadata) == 2404, "bad size"); +#endif + +} // namespace common +} // namespace mapper +} // namespace arm + diff --git a/gralloc3/include/gralloc3/gralloc_vendor_interface.h b/GrallocHAL/src/libGralloc4Wrapper/include/gralloc4/gralloc_vendor_interface.h index 6387845..cbd98d9 100644 --- a/gralloc3/include/gralloc3/gralloc_vendor_interface.h +++ b/GrallocHAL/src/libGralloc4Wrapper/include/gralloc4/gralloc_vendor_interface.h @@ -23,6 +23,7 @@ #include <sys/types.h> #include <cstdint> #include <system/graphics-base-v1.0.h> +#include <android/hardware/graphics/mapper/4.0/IMapper.h> namespace android::hardware::graphics::allocator::priv { @@ -42,6 +43,8 @@ void setFormat(Descriptor &descriptor, int format); buffer_handle_t createNativeHandle(const Descriptor &descriptor); +int freeImportedHandle(void *handle); + } // namespace android::hardware::graphics::allocator::priv #endif diff --git a/GrallocHAL/src/libGralloc4Wrapper/wrapper.cpp b/GrallocHAL/src/libGralloc4Wrapper/wrapper.cpp new file mode 100644 index 0000000..c9d3381 --- /dev/null +++ b/GrallocHAL/src/libGralloc4Wrapper/wrapper.cpp @@ -0,0 +1,237 @@ +#include "gralloc4/gralloc_vendor_interface.h" +#include <vector> +#include <sys/stat.h> + +#include "core/format_info.h" +#include "core/mali_gralloc_bufferdescriptor.h" +#include "core/mali_gralloc_bufferallocation.h" +#include "core/mali_gralloc_reference.h" +#include "allocator/mali_gralloc_ion.h" +#include "hidl_common/SharedMetadata.h" +#include "gralloc_priv.h" + +namespace android::hardware::graphics::allocator::priv { + +struct Descriptor { + unsigned int size = 0; + uint64_t producer_usage = 0; + uint64_t consumer_usage = 0; + + struct PlaneDescriptor { + int fd = -1; + size_t size = 0; + off_t offset = 0; + int stride_byte = 0; + }; + std::vector<PlaneDescriptor> planes; + + int width = 0; + int height = 0; + int stride_pixel = 0; + int format = 0; +}; + +Descriptor *createDescriptor() { return new Descriptor(); } +void deleteDescriptor(Descriptor *descriptor) { delete descriptor; } + +void setProducerUsage(Descriptor &descriptor, uint64_t usage) { + descriptor.producer_usage = usage; +} + +void setConsumerUsage(Descriptor &descriptor, uint64_t usage) { + descriptor.consumer_usage = usage; +} + +void setPlaneCount(Descriptor &descriptor, int count) { + descriptor.planes.resize(count); +} + +void setPlane(Descriptor &descriptor, int index, int fd, size_t size, off_t offset, int stride_byte) { + descriptor.planes[index].fd = fd; + descriptor.planes[index].size = size; + descriptor.planes[index].offset = offset; + descriptor.planes[index].stride_byte = stride_byte; +} + +void setWidth(Descriptor &descriptor, int width) { + descriptor.width = width; +} + +void setHeight(Descriptor &descriptor, int height) { + descriptor.height = height; +} + +void setStridePixel(Descriptor &descriptor, int stride_pixel) { + descriptor.stride_pixel = stride_pixel; +} + +void setFormat(Descriptor &descriptor, int format) { + descriptor.format = format; +} + +buffer_handle_t createNativeHandle(const Descriptor &descriptor) { + for (int i = 0; i < descriptor.planes.size(); ++i) { + struct stat st; + fstat(descriptor.planes[i].fd, &st); + off64_t fd_size = st.st_size; + if (fd_size < descriptor.planes[i].size) { + ALOGE("libGralloc4Wrapper: createNativeHandle failed: plane[%d] requested size greater than fd size.", + i); + return nullptr; + } + } + + buffer_descriptor_t buffer_descriptor; + + buffer_descriptor.pixel_stride = descriptor.stride_pixel; + buffer_descriptor.width = descriptor.width; + buffer_descriptor.height = descriptor.height; + buffer_descriptor.layer_count = 1; + buffer_descriptor.hal_format = buffer_descriptor.alloc_format + = descriptor.format; + buffer_descriptor.producer_usage = descriptor.producer_usage; + buffer_descriptor.consumer_usage = descriptor.consumer_usage; + buffer_descriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; + buffer_descriptor.signature = sizeof(buffer_descriptor_t); + + buffer_descriptor.fd_count = buffer_descriptor.plane_count + = descriptor.planes.size(); + for (int i = 0; i < descriptor.planes.size(); ++i) { + buffer_descriptor.alloc_sizes[i] = descriptor.planes[i].size; + } + + auto format_index = get_format_index(descriptor.format); + if (format_index == -1) { + ALOGE("libGralloc4Wrapper: invalid format 0x%x", + descriptor.format); + return 0; + } + for (int i = 0; i < descriptor.planes.size(); ++i) { + uint8_t bpp = formats[format_index].bpp[i]; + if (bpp == 0) { + ALOGE("libGralloc4Wrapper: format 0x%x has bpp[%d]=0", + descriptor.format, i); + return nullptr; + } + buffer_descriptor.plane_info[i] = { + .byte_stride = static_cast<uint32_t>((descriptor.planes[i].stride_byte * bpp) / 8), + .alloc_width = buffer_descriptor.width, + .alloc_height = buffer_descriptor.height, + }; + } + + if (mali_gralloc_derive_format_and_size(&buffer_descriptor)) { + ALOGE("libGralloc4Wrapper: mali_gralloc_derive_format_and_size failed"); + return nullptr; + } + + const gralloc_buffer_descriptor_t gralloc_buffer_descriptor = + reinterpret_cast<const gralloc_buffer_descriptor_t>(&buffer_descriptor); + + buffer_handle_t tmp_buffer; + bool shared_backend; + // TODO(modan@, make mali_gralloc_ion_allocate accept multiple fds) + { + int result = mali_gralloc_buffer_allocate(&gralloc_buffer_descriptor, 1, &tmp_buffer, + &shared_backend, descriptor.planes[0].fd); + if (result < 0) { + ALOGE("mali_gralloc_buffer_allocate failed"); + return nullptr; + } + } + + private_handle_t *hnd = const_cast<private_handle_t *>( + static_cast<const private_handle_t *>(tmp_buffer)); + + hnd->imapper_version = HIDL_MAPPER_VERSION_SCALED; + + hnd->reserved_region_size = buffer_descriptor.reserved_size; + hnd->attr_size = arm::mapper::common::shared_metadata_size() + hnd->reserved_region_size; + + { + int result = mali_gralloc_ion_allocate_attr(hnd); + if (result < 0) { + ALOGE("mali_gralloc_ion_allocate_attr failed"); + mali_gralloc_buffer_free(tmp_buffer); + return nullptr; + } + } + + { + hnd->attr_base = mmap(nullptr, hnd->attr_size, PROT_READ | PROT_WRITE, + MAP_SHARED, hnd->get_share_attr_fd(), 0); + if (hnd->attr_base == MAP_FAILED) { + ALOGE("mmap hnd->get_share_attr_fd() failed"); + mali_gralloc_buffer_free(tmp_buffer); + return nullptr; + } + + memset(hnd->attr_base, 0, hnd->attr_size); + + arm::mapper::common::shared_metadata_init(hnd->attr_base, buffer_descriptor.name); + + const uint32_t base_format = buffer_descriptor.alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK; + const uint64_t usage = buffer_descriptor.consumer_usage | buffer_descriptor.producer_usage; + android_dataspace_t dataspace; + get_format_dataspace(base_format, usage, hnd->width, hnd->height, &dataspace); + + arm::mapper::common::set_dataspace(hnd, static_cast<arm::mapper::common::Dataspace>(dataspace)); + + munmap(hnd->attr_base, hnd->attr_size); + hnd->attr_base = 0; + } + + // TODO(modan@, handle all plane offsets) + hnd->offset = hnd->plane_info[0].offset = descriptor.planes[0].offset; + hnd->layer_count = 1; + + return tmp_buffer; +} + +int freeImportedHandle(void *handle) +{ + using android::hardware::graphics::mapper::V4_0::IMapper; + using android::hardware::graphics::mapper::V4_0::Error; + + const private_handle_t *hnd = static_cast<private_handle_t *>(handle); + + struct UnmapWork { void *base; size_t alloc_size; }; + std::vector<UnmapWork> work(hnd->fd_count); + + for (size_t i = 0; i < hnd->fd_count; ++i) + { + work[i].base = reinterpret_cast<void*>(hnd->bases[i]); + work[i].alloc_size = hnd->alloc_sizes[i]; + } + + static android::sp<IMapper> mapper = IMapper::getService(); + if (!mapper) + { + ALOGE("libGralloc4Wrapper: %s failed to get a mapper", __func__); + return -1; + } + + if (mapper->freeBuffer(handle) != Error::NONE) + { + ALOGE("libGralloc4Wrapper: %s couldn't freeBuffer(%p\n", __func__, handle); + return -1; + } + + { + bool unmapFailed = false; + for (const UnmapWork &w : work) + { + if (!w.base) { continue; } + if (int ret = munmap(w.base, w.alloc_size); ret) + { + ALOGE("libGralloc4Wrapper: %s couldn't unmap address %p (size %zu): %s", __func__, w.base, w.alloc_size, strerror(ret)); + unmapFailed = true; + } + } + if (unmapFailed) { return -1; } + } + + return 0; +} + +} // namespace android::hardware::graphics::allocator::priv diff --git a/GrallocHAL/src/mali_fourcc.h b/GrallocHAL/src/mali_fourcc.h new file mode 100644 index 0000000..9dcec0c --- /dev/null +++ b/GrallocHAL/src/mali_fourcc.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2019-2020 ARM Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MALI_FOURCC_H_ +#define MALI_FOURCC_H_ + +extern "C" +{ + +#include <drm_fourcc.h> +#include <stdint.h> + +/* FOURCCs for formats that exist upstream, but may not be in the drm_fourcc.h header included above. + * + * Below we define DRM FOURCC formats that are upstreamed, but may not be in the drm_fourcc.h header that we include + * above, merely because that header is too old. As drm_fourcc.h is an external header that we cannot control, the best + * we can do is to define here the missing formats. + */ +#ifndef DRM_FORMAT_INVALID +#define DRM_FORMAT_INVALID 0 +#endif + +#ifndef DRM_FORMAT_P010 +#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') +#endif + +#ifndef DRM_FORMAT_Y0L2 +#define DRM_FORMAT_Y0L2 fourcc_code('Y', '0', 'L', '2') +#endif + +#ifndef DRM_FORMAT_P210 +#define DRM_FORMAT_P210 fourcc_code('P', '2', '1', '0') +#endif + +#ifndef DRM_FORMAT_Y210 +#define DRM_FORMAT_Y210 fourcc_code('Y', '2', '1', '0') +#endif + +#ifndef DRM_FORMAT_Y410 +#define DRM_FORMAT_Y410 fourcc_code('Y', '4', '1', '0') +#endif + +#ifndef DRM_FORMAT_YUV420_8BIT +#define DRM_FORMAT_YUV420_8BIT fourcc_code('Y', 'U', '0', '8') +#endif + +#ifndef DRM_FORMAT_YUV420_10BIT +#define DRM_FORMAT_YUV420_10BIT fourcc_code('Y', 'U', '1', '0') +#endif + +#ifndef DRM_FORMAT_ABGR16161616F +#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H') +#endif + +#ifndef DRM_FORMAT_R16 +#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ') +#endif + +/* ARM specific modifiers. */ +#ifndef DRM_FORMAT_MOD_VENDOR_ARM +#define DRM_FORMAT_MOD_VENDOR_ARM 0x08 +#endif + +#ifndef fourcc_mod_code +#define fourcc_mod_code(vendor, val) \ + ((((uint64_t)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | ((val) & 0x00ffffffffffffffULL)) +#endif + +#ifndef DRM_FORMAT_MOD_ARM_AFBC +/* AFBC modifiers. */ + +#define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode) fourcc_mod_code(ARM, (__afbc_mode)) +/* AFBC superblock size. */ +#ifndef AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 +#define AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 ((uint64_t)0x1) +#endif + +#ifndef AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 +#define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ((uint64_t)0x2) +#endif + +#ifndef AFBC_FORMAT_MOD_BLOCK_SIZE_MASK +#define AFBC_FORMAT_MOD_BLOCK_SIZE_MASK ((uint64_t)0xf) +#endif + +/* AFBC lossless transform. */ +#ifndef AFBC_FORMAT_MOD_YTR +#define AFBC_FORMAT_MOD_YTR (((uint64_t)1) << 4) +#endif + +/* AFBC block-split. */ +#ifndef AFBC_FORMAT_MOD_SPLIT +#define AFBC_FORMAT_MOD_SPLIT (((uint64_t)1) << 5) +#endif + +/* AFBC sparse layout. */ +#ifndef AFBC_FORMAT_MOD_SPARSE +#define AFBC_FORMAT_MOD_SPARSE (((uint64_t)1) << 6) +#endif + +/* AFBC tiled layout. */ +#ifndef AFBC_FORMAT_MOD_TILED +#define AFBC_FORMAT_MOD_TILED (((uint64_t)1) << 8) +#endif + +#endif /* DRM_FORMAT_MOD_ARM_AFBC */ + +/* AFBC 1.3 block sizes. */ +#ifndef AFBC_FORMAT_MOD_BLOCK_SIZE_64x4 +#define AFBC_FORMAT_MOD_BLOCK_SIZE_64x4 ((uint64_t)0x3) +#endif + +#ifndef AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4 +#define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4 ((uint64_t)0x4) +#endif + +/* AFBC double-buffer. */ +#ifndef AFBC_FORMAT_MOD_DB +#define AFBC_FORMAT_MOD_DB (((uint64_t)1) << 10) +#endif + +/* AFBC buffer content hints. */ +#ifndef AFBC_FORMAT_MOD_BCH +#define AFBC_FORMAT_MOD_BCH (((uint64_t)1) << 11) +#endif + +} + +#endif /* MALI_FOURCC_H_ */ diff --git a/GrallocHAL/src/mali_gralloc_buffer.h b/GrallocHAL/src/mali_gralloc_buffer.h new file mode 100644 index 0000000..a163d1a --- /dev/null +++ b/GrallocHAL/src/mali_gralloc_buffer.h @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2017-2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MALI_GRALLOC_BUFFER_H_ +#define MALI_GRALLOC_BUFFER_H_ + +#include <stdint.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <sys/mman.h> +#include <cutils/native_handle.h> +#include <string.h> +#include <log/log.h> +#include <inttypes.h> + +/* the max string size of GRALLOC_HARDWARE_GPU0 & GRALLOC_HARDWARE_FB0 + * 8 is big enough for "gpu0" & "fb0" currently + */ +#define MALI_GRALLOC_HARDWARE_MAX_STR_LEN 8 + +/* Define number of shared file descriptors. Not guaranteed to be constant for a private_handle_t object + * as fds that do not get initialized may instead be treated as integers. + */ + +#define NUM_INTS_IN_PRIVATE_HANDLE ((sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int)) + +#define SZ_4K 0x00001000 +#define SZ_2M 0x00200000 + +/* + * Maximum number of pixel format planes. + * Plane [0]: Single plane formats (inc. RGB, YUV) and Y + * Plane [1]: U/V, UV + * Plane [2]: V/U + */ +#define MAX_PLANES 3 + +#ifdef __cplusplus +#define DEFAULT_INITIALIZER(x) = x +#else +#define DEFAULT_INITIALIZER(x) +#endif + +typedef struct plane_info { + + /* + * Offset to plane (in bytes), + * from the start of the allocation. + */ + int64_t offset; + + uint32_t fd_idx; + uint64_t size; + + /* + * Byte Stride: number of bytes between two vertically adjacent + * pixels in given plane. This can be mathematically described by: + * + * byte_stride = ALIGN((alloc_width * bpp)/8, alignment) + * + * where, + * + * alloc_width: width of plane in pixels (c.f. pixel_stride) + * bpp: average bits per pixel + * alignment (in bytes): dependent upon pixel format and usage + * + * For uncompressed allocations, byte_stride might contain additional + * padding beyond the alloc_width. For AFBC, alignment is zero. + */ + uint32_t byte_stride; + + /* + * Dimensions of plane (in pixels). + * + * For single plane formats, pixels equates to luma samples. + * For multi-plane formats, pixels equates to the number of sample sites + * for the corresponding plane, even if subsampled. + * + * AFBC compressed formats: requested width/height are rounded-up + * to a whole AFBC superblock/tile (next superblock at minimum). + * Uncompressed formats: dimensions typically match width and height + * but might require pixel stride alignment. + * + * See 'byte_stride' for relationship between byte_stride and alloc_width. + * + * Any crop rectangle defined by GRALLOC_ARM_BUFFER_ATTR_CROP_RECT must + * be wholly within the allocation dimensions. The crop region top-left + * will be relative to the start of allocation. + */ + uint32_t alloc_width; + uint32_t alloc_height; +} plane_info_t; + +struct private_handle_t; + +#ifndef __cplusplus +/* C99 with pedantic don't allow anonymous unions which is used in below struct + * Disable pedantic for C for this struct only. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +#ifdef __cplusplus +struct private_handle_t : public native_handle +{ +private: + /* Having a default constructor makes sure that we zero out the padding + * which prevents data leak. */ + private_handle_t() = default; + +public: + +#else +struct private_handle_t +{ + struct native_handle nativeHandle; +#endif + +#ifdef __cplusplus + /* Never intended to be used from C code */ + enum + { + PRIV_FLAGS_USES_2PRIVATE_DATA = 1U << 4, + PRIV_FLAGS_USES_3PRIVATE_DATA = 1U << 5, + }; + + enum + { + LOCK_STATE_WRITE = 1 << 31, + LOCK_STATE_MAPPED = 1 << 30, + LOCK_STATE_READ_MASK = 0x3FFFFFFF + }; +#endif + + /* + * Shared file descriptor for dma_buf sharing. This must be the first element in the + * structure so that binder knows where it is and can properly share it between + * processes. + * DO NOT MOVE THIS ELEMENT! + */ + union { + int fds[5]; + }; + + // ints + int magic DEFAULT_INITIALIZER(sMagic); + int flags DEFAULT_INITIALIZER(0); + + int fd_count DEFAULT_INITIALIZER(1); + + /* + * Input properties. + * + * req_format: Pixel format, base + private modifiers. + * width/height: Buffer dimensions. + * producer/consumer_usage: Buffer usage (indicates IP) + */ + int width DEFAULT_INITIALIZER(0); + int height DEFAULT_INITIALIZER(0); + int req_format DEFAULT_INITIALIZER(0); + uint64_t producer_usage DEFAULT_INITIALIZER(0); + uint64_t consumer_usage DEFAULT_INITIALIZER(0); + + /* + * DEPRECATED members. + * Equivalent information can be obtained from other fields: + * + * - 'internal_format' --> alloc_format + * - 'stride' (pixel stride) ~= plane_info[0].alloc_width + * - 'byte_stride' ~= plane_info[0].byte_stride + * - 'internalWidth' ~= plane_info[0].alloc_width + * - 'internalHeight' ~= plane_info[0].alloc_height + * + * '~=' (approximately equal) is used because the fields were either previously + * incorrectly populated by gralloc or the meaning has slightly changed. + * + * NOTE: 'stride' values sometimes vary significantly from plane_info[0].alloc_width. + */ + int stride DEFAULT_INITIALIZER(0); + + /* + * Allocation properties. + * + * alloc_format: Pixel format (base + modifiers). NOTE: base might differ from requested + * format (req_format) where fallback to single-plane format was required. + * plane_info: Per plane allocation information. + * size: Total bytes allocated for buffer (inc. all planes, layers. etc.). + * layer_count: Number of layers allocated to buffer. + * All layers are the same size (in bytes). + * Multi-layers supported in v1.0, where GRALLOC1_CAPABILITY_LAYERED_BUFFERS is enabled. + * Layer size: 'size' / 'layer_count'. + * Layer (n) offset: n * ('size' / 'layer_count'), n=0 for the first layer. + * + */ + uint64_t alloc_format DEFAULT_INITIALIZER(0); + plane_info_t plane_info[MAX_PLANES] DEFAULT_INITIALIZER({}); + uint32_t layer_count DEFAULT_INITIALIZER(0); + + uint64_t backing_store_id DEFAULT_INITIALIZER(0x0); + int cpu_read DEFAULT_INITIALIZER(0); /**< Buffer is locked for CPU read when non-zero. */ + int cpu_write DEFAULT_INITIALIZER(0); /**< Buffer is locked for CPU write when non-zero. */ + int allocating_pid DEFAULT_INITIALIZER(0); + int remote_pid DEFAULT_INITIALIZER(-1); + int ref_count DEFAULT_INITIALIZER(0); + // locally mapped shared attribute area + + int ion_handles[3]; + uint64_t bases[3]; + uint64_t alloc_sizes[3]; + + void *attr_base __attribute__((aligned (8))) DEFAULT_INITIALIZER(nullptr); + off_t offset __attribute__((aligned (8))) DEFAULT_INITIALIZER(0); + + /* Size of the attribute shared region in bytes. */ + uint64_t attr_size __attribute__((aligned (8))) DEFAULT_INITIALIZER(0); + + uint64_t reserved_region_size DEFAULT_INITIALIZER(0); + + uint64_t imapper_version DEFAULT_INITIALIZER(0); + +#ifdef __cplusplus + /* + * We track the number of integers in the structure. There are 16 unconditional + * integers (magic - pid, yuv_info, fd and offset). Note that the fd element is + * considered an int not an fd because it is not intended to be used outside the + * surface flinger process. The GRALLOC_ARM_NUM_INTS variable is used to track the + * number of integers that are conditionally included. Similar considerations apply + * to the number of fds. + */ + static const int sMagic = 0x3141592; + + private_handle_t( + int _flags, + uint64_t _alloc_sizes[3], + uint64_t _consumer_usage, uint64_t _producer_usage, + int _fds[5], int _fd_count, + int _req_format, uint64_t _alloc_format, + int _width, int _height, int _stride, + uint64_t _layer_count, plane_info_t _plane_info[MAX_PLANES]) + : private_handle_t() + { + flags = _flags; + fd_count = _fd_count; + width = _width; + height = _height; + req_format = _req_format; + producer_usage = _producer_usage; + consumer_usage = _consumer_usage; + stride = _stride; + alloc_format = _alloc_format; + layer_count = _layer_count; + allocating_pid = getpid(); + ref_count = 1; + version = sizeof(native_handle); + set_numfds(fd_count); + memcpy(plane_info, _plane_info, sizeof(plane_info_t) * MAX_PLANES); + + if (_fds) + memcpy(fds, _fds, sizeof(fds)); + + if (_alloc_sizes) + memcpy(alloc_sizes, _alloc_sizes, sizeof(alloc_sizes)); + + memset(bases, 0, sizeof(bases)); + memset(ion_handles, 0, sizeof(ion_handles)); + } + + ~private_handle_t() + { + magic = 0; + } + + /* Set the number of allocated fds in the handle to n*/ + void set_numfds(int n) + { + int total_ints = + (sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int); + + numFds = n; + numInts = total_ints - n; + } + + /* Increments number of allocated fds in the handle by n */ + int incr_numfds(int n) + { + numFds += n; + numInts -= n; + + return numFds; + } + + static int validate(const native_handle *h) + { + const private_handle_t *hnd = (const private_handle_t *)h; + if (!h || h->version != sizeof(native_handle) || hnd->magic != sMagic || + h->numFds + h->numInts != NUM_INTS_IN_PRIVATE_HANDLE) + { + return -EINVAL; + } + return 0; + } + + bool is_multi_plane() const + { + /* For multi-plane, the byte stride for the second plane will always be non-zero. */ + return (plane_info[1].byte_stride != 0); + } + + uint64_t get_usage() const + { + return producer_usage | consumer_usage; + } + + int get_share_attr_fd_index() const + { + /* share_attr can be at idx 1 to 4 */ + if (fd_count <= 0 || fd_count > 4) + return -1; + + return fd_count; + } + + int get_share_attr_fd() const + { + int idx = get_share_attr_fd_index(); + + if (idx <= 0) + return -1; + + return fds[idx]; + } + + void set_share_attr_fd(int fd) + { + int idx = get_share_attr_fd_index(); + + if (idx <= 0) + return; + + fds[idx] = fd; + } + + void close_share_attr_fd() + { + int fd = get_share_attr_fd(); + + if (fd < 0) + return; + + close(fd); + } + + void dump(const char *str) const + { + ALOGE("[%s] " + "numInts(%d) numFds(%d) fd_count(%d) " + "fd(%d %d %d %d %d) " + "flags(%d) " + "wh(%d %d) " + "req_format(%#x) alloc_format(%#" PRIx64 ") " + "usage_pc(0x%" PRIx64 " 0x%" PRIx64 ") " + "stride(%d) " + "psize(%" PRIu64 ") byte_stride(%d) internal_wh(%d %d) " + "psize1(%" PRIu64 ") byte_stride1(%d) internal_wh1(%d %d) " + "psize2(%" PRIu64 ") byte_stride2(%d) internal_wh2(%d %d) " + "alloc_format(0x%" PRIx64 ") " + "alloc_sizes(%" PRIu64 " %" PRIu64 " %" PRIu64 ") " + "layer_count(%d) " + "bases(%p %p %p %p) " + "\n", + str, + numInts, numFds, fd_count, + fds[0], fds[1], fds[2], fds[3], fds[4], + flags, + width, height, + req_format, alloc_format, + producer_usage, consumer_usage, + stride, + plane_info[0].size, plane_info[0].byte_stride, plane_info[0].alloc_width, plane_info[0].alloc_height, + plane_info[1].size, plane_info[1].byte_stride, plane_info[1].alloc_width, plane_info[1].alloc_height, + plane_info[2].size, plane_info[2].byte_stride, plane_info[2].alloc_width, plane_info[2].alloc_height, + alloc_format, + alloc_sizes[0], alloc_sizes[1], alloc_sizes[2], + layer_count, + (void*)bases[0], (void*)bases[1], (void*)bases[2], attr_base + ); + } + + int get_alloc_format() const + { + return (int)(alloc_format & 0x00000000ffffffffULL); + } + + static private_handle_t *dynamicCast(const native_handle *in) + { + if (validate(in) == 0) + { + return (private_handle_t *)in; + } + + return NULL; + } +#endif +}; +#ifndef __cplusplus +/* Restore previous diagnostic for pedantic */ +#pragma GCC diagnostic pop +#endif + +#endif /* MALI_GRALLOC_BUFFER_H_ */ diff --git a/GrallocHAL/src/mali_gralloc_buffer4.h b/GrallocHAL/src/mali_gralloc_buffer4.h new file mode 120000 index 0000000..a9c0f1e --- /dev/null +++ b/GrallocHAL/src/mali_gralloc_buffer4.h @@ -0,0 +1 @@ +mali_gralloc_buffer.h
\ No newline at end of file diff --git a/gralloc3/src/mali_gralloc_formats.h b/GrallocHAL/src/mali_gralloc_formats.h index 330d14d..246cae6 100644 --- a/gralloc3/src/mali_gralloc_formats.h +++ b/GrallocHAL/src/mali_gralloc_formats.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2019 ARM Limited. All rights reserved. + * Copyright (C) 2016-2020 ARM Limited. All rights reserved. * * Copyright (C) 2008 The Android Open Source Project * @@ -20,7 +20,10 @@ #define MALI_GRALLOC_FORMATS_H_ #include <system/graphics.h> -#include <log/log.h> + +#include "mali_gralloc_log.h" + +#include <aidl/android/hardware/graphics/common/PixelFormat.h> /* Internal formats are represented in gralloc as a 64bit identifier * where the 32 lower bits are a base format and the 32 upper bits are modifiers. @@ -45,7 +48,7 @@ typedef uint64_t mali_gralloc_internal_format; /* Base formats that do not have an identical HAL match * are defined starting at the Android private range */ -#define MALI_GRALLOC_FORMAT_INTERNAL_RANGE_BASE 0x200 +#define MALI_GRALLOC_FORMAT_INTERNAL_RANGE_BASE 0x1000 typedef enum { @@ -70,10 +73,9 @@ typedef enum MALI_GRALLOC_FORMAT_INTERNAL_RGB_888 = HAL_PIXEL_FORMAT_RGB_888, MALI_GRALLOC_FORMAT_INTERNAL_RGB_565 = HAL_PIXEL_FORMAT_RGB_565, MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, -#if PLATFORM_SDK_VERSION >= 26 MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 = HAL_PIXEL_FORMAT_RGBA_1010102, + /* 16-bit floating point format. */ MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 = HAL_PIXEL_FORMAT_RGBA_FP16, -#endif /* PLATFORM_SDK_VERSION >= 26 */ MALI_GRALLOC_FORMAT_INTERNAL_YV12 = HAL_PIXEL_FORMAT_YV12, MALI_GRALLOC_FORMAT_INTERNAL_Y8 = HAL_PIXEL_FORMAT_Y8, MALI_GRALLOC_FORMAT_INTERNAL_Y16 = HAL_PIXEL_FORMAT_Y16, @@ -86,7 +88,6 @@ typedef enum MALI_GRALLOC_FORMAT_INTERNAL_RAW_OPAQUE = HAL_PIXEL_FORMAT_RAW_OPAQUE, MALI_GRALLOC_FORMAT_INTERNAL_BLOB = HAL_PIXEL_FORMAT_BLOB, -#if PLATFORM_SDK_VERSION >= 28 /* Depth and stencil formats */ MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_16 = HAL_PIXEL_FORMAT_DEPTH_16, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24 = HAL_PIXEL_FORMAT_DEPTH_24, @@ -94,7 +95,6 @@ typedef enum MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F = HAL_PIXEL_FORMAT_DEPTH_32F, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F_STENCIL_8 = HAL_PIXEL_FORMAT_DEPTH_32F_STENCIL_8, MALI_GRALLOC_FORMAT_INTERNAL_STENCIL_8 = HAL_PIXEL_FORMAT_STENCIL_8, -#endif /* Flexible YUV formats would be parsed but not have any representation as * internal format itself but one of the ones below. @@ -122,7 +122,9 @@ typedef enum MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I, MALI_GRALLOC_FORMAT_INTERNAL_YUV444_10BIT_I, - /* Add more internal formats here. Make sure decode_internal_format() is updated. */ + /* Add more internal formats here. */ + MALI_GRALLOC_FORMAT_INTERNAL_R_8 = + static_cast<int>(aidl::android::hardware::graphics::common::PixelFormat::R_8), /* These are legacy 0.3 gralloc formats used only by the wrap/unwrap macros. */ MALI_GRALLOC_FORMAT_INTERNAL_YV12_WRAP, @@ -132,38 +134,47 @@ typedef enum MALI_GRALLOC_FORMAT_INTERNAL_RANGE_LAST, } mali_gralloc_pixel_format; - -/* Modifier Bits - these are now independent. */ +/* + * Compression type + */ /* This format will use AFBC */ #define MALI_GRALLOC_INTFMT_AFBC_BASIC (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 0)) + +/* + * AFBC modifier bits (valid with MALI_GRALLOC_INTFMT_AFBC_BASIC) + */ + /* This format uses AFBC split block mode */ -#define MALI_GRALLOC_INTFMT_AFBC_SPLITBLK (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 1)) +#define MALI_GRALLOC_INTFMT_AFBC_SPLITBLK (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 2)) /* This format uses AFBC wide block mode */ -#define MALI_GRALLOC_INTFMT_AFBC_WIDEBLK (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 2)) +#define MALI_GRALLOC_INTFMT_AFBC_WIDEBLK (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 3)) /* This format uses AFBC tiled headers */ -#define MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 3)) +#define MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 4)) /* This format uses AFBC extra wide superblocks. */ -#define MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 4)) +#define MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 5)) /* This format is AFBC with double body buffer (used as a frontbuffer) */ -#define MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 5)) +#define MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 6)) /* This format uses AFBC buffer content hints in LSB of superblock offset. */ -#define MALI_GRALLOC_INTFMT_AFBC_BCH (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 6)) +#define MALI_GRALLOC_INTFMT_AFBC_BCH (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 7)) + +/* This format uses AFBC with YUV transform. */ +#define MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 8)) -/* This format uses AFBC with YUV transform. - * This is automatically enabled, and should not be set with GRALLOC_USAGE_PRIVATE_3. */ -#define MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM 0 +/* This format uses Sparse allocated AFBC. */ +#define MALI_GRALLOC_INTFMT_AFBC_SPARSE (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 9)) /* This mask should be used to check or clear support for AFBC for an internal format. */ #define MALI_GRALLOC_INTFMT_AFBCENABLE_MASK (uint64_t)(MALI_GRALLOC_INTFMT_AFBC_BASIC) + /* These are legacy Gralloc 0.3 support macros for passing private formats through the 0.3 alloc interface. * It packs modifier bits together with base format into a 32 bit format identifier. * Gralloc 1.0 interface should use private functions to set private buffer format in the buffer descriptor. @@ -200,7 +211,7 @@ static inline int mali_gralloc_format_wrapper(int format, int modifiers) if (format & ~MALI_GRALLOC_INTFMT_FMT_WRAP_MASK) { format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED; - ALOGE("Format is too large for private format wrapping"); + MALI_GRALLOC_LOGE("Format is too large for private format wrapping"); } return (modifiers | format); @@ -230,53 +241,62 @@ static inline uint64_t mali_gralloc_format_unwrap(int x) return (modifiers | base_format); } +/* + * Macro to add additional modifier(s) to existing wrapped private format. + * Arguments include wrapped private format and new modifier(s) to add. + */ +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(x, modifiers) \ + ((int)((x) | ((unsigned)((modifiers) >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT)))) + +/* + * Macro to remove modifier(s) to existing wrapped private format. + * Arguments include wrapped private format and modifier(s) to remove. + */ +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_REMOVE_MODIFIER(x, modifiers) \ + ((int)((x) & ~((unsigned)((modifiers) >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT)))) #define GRALLOC_PRIVATE_FORMAT_WRAPPER(x) (mali_gralloc_format_wrapper(x, 0)) -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC(x) (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC(x) \ + mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_BASIC | MALI_GRALLOC_INTFMT_AFBC_SPARSE) >> \ + MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT) -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_SPLITBLK(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT)))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_SPLITBLK(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC(x), \ + MALI_GRALLOC_INTFMT_AFBC_SPLITBLK) -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDEBLK(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT)))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDEBLK(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC(x), \ + MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDE_SPLIT(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT | \ - (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT) | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT)))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDE_SPLIT(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_SPLITBLK(x), \ + MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_BASIC(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT) | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_BASIC(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC(x), \ + MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_WIDE(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT | \ - (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT) | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT)))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_WIDE(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDEBLK(x), \ + MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_SPLIT(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT | \ - (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT) | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT)))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_SPLIT(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_SPLITBLK(x), \ + MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_WIDE_SPLIT(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT | \ - (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT) | \ - (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT) | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT)))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_WIDE_SPLIT(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDE_SPLIT(x), \ + MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) /* * AFBC format with extra-wide (64x4) superblocks. * * NOTE: Tiled headers are mandatory for this format. */ -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_EXTRAWIDEBLK(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT | \ - (MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT))))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_EXTRAWIDEBLK(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_BASIC(x), \ + MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) /* * AFBC multi-plane YUV format where luma (wide, 32x8) and @@ -285,31 +305,17 @@ static inline uint64_t mali_gralloc_format_unwrap(int x) * NOTE: Tiled headers are mandatory for this format. * NOTE: Base format (x) must be a multi-plane YUV format. */ -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDE_EXTRAWIDE(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT | \ - (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT) | \ - (MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT) | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> MALI_GRALLOC_INTFMT_EXT_WRAP_SHIFT)))) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDE_EXTRAWIDE(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_EXTRAWIDEBLK(x), \ + MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_DOUBLE_BODY(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_BASIC(x), \ + MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY) -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_DOUBLE_BODY(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 16 | \ - (MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY >> 16) | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))) - -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_SPLIT_DOUBLE_BODY(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 16 | \ - (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> 16) | \ - (MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY >> 16) | \ - (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))) - -/* - * Macro to add additional modifier(s) to existing wrapped private format. - * Arguments include wrapped private format and new modifier(s) to add. - */ -#define GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(x, modifiers) \ - ((int)((x) | ((int)((modifiers) >> 16)))) - +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_SPLIT_DOUBLE_BODY(x) \ + GRALLOC_PRIVATE_FORMAT_WRAPPER_ADD_MODIFIER(GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_SPLIT(x), \ + MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY) #define GRALLOC_PRIVATE_FORMAT_UNWRAP(x) mali_gralloc_format_unwrap(x) @@ -320,7 +326,7 @@ static inline uint64_t mali_gralloc_format_unwrap(int x) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC ((uint64_t)1 << 1) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK ((uint64_t)1 << 2) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK ((uint64_t)1 << 3) -#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_RESERVED_1 ((uint64_t)1 << 4) +#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WRITE_NON_SPARSE ((uint64_t)1 << 4) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_RESERVED_2 ((uint64_t)1 << 5) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_RESERVED_3 ((uint64_t)1 << 6) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS ((uint64_t)1 << 7) @@ -329,6 +335,8 @@ static inline uint64_t mali_gralloc_format_unwrap(int x) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_DOUBLE_BODY ((uint64_t)1 << 10) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_READ ((uint64_t)1 << 11) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE ((uint64_t)1 << 12) +#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_RGBA16161616 ((uint64_t)1 << 13) + #define MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102 ((uint64_t)1 << 32) #define MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616 ((uint64_t)1 << 33) @@ -339,7 +347,7 @@ static inline uint64_t mali_gralloc_format_unwrap(int x) struct mali_gralloc_format_caps { - uint64_t caps_mask; + uint64_t caps_mask = 0; }; typedef struct mali_gralloc_format_caps mali_gralloc_format_caps; @@ -357,25 +365,11 @@ void mali_gralloc_adjust_dimensions(const uint64_t internal_format, uint64_t mali_gralloc_select_format(const uint64_t req_format, const mali_gralloc_format_type type, const uint64_t usage, - const int buffer_size, - uint64_t * const internal_format); + const int buffer_size); bool is_subsampled_yuv(const uint32_t base_format); #endif -#ifdef __cplusplus -extern "C" { -#endif - -void mali_gralloc_get_caps(struct mali_gralloc_format_caps *gpu_caps, - struct mali_gralloc_format_caps *vpu_caps, - struct mali_gralloc_format_caps *dpu_caps, - struct mali_gralloc_format_caps *dpu_aeu_caps, - struct mali_gralloc_format_caps *cam_caps); -#ifdef __cplusplus -} -#endif - bool is_exynos_format(uint32_t base_format); #endif /* MALI_GRALLOC_FORMATS_H_ */ diff --git a/GrallocHAL/src/mali_gralloc_log.h b/GrallocHAL/src/mali_gralloc_log.h new file mode 100644 index 0000000..aa4e26c --- /dev/null +++ b/GrallocHAL/src/mali_gralloc_log.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2019 ARM Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MALI_GRALLOC_LOG_H +#define MALI_GRALLOC_LOG_H + +#ifndef LOG_TAG +#define LOG_TAG "mali_gralloc" +#endif + +#include <log/log.h> + +/* Delegate logging to Android */ +#define MALI_GRALLOC_LOGI(...) ALOGI(__VA_ARGS__) +#define MALI_GRALLOC_LOGV(...) ALOGV(__VA_ARGS__) +#define MALI_GRALLOC_LOGW(...) ALOGW(__VA_ARGS__) +#define MALI_GRALLOC_LOGE(...) ALOGE(__VA_ARGS__) + +#endif diff --git a/GrallocHAL/src/mali_gralloc_usages.h b/GrallocHAL/src/mali_gralloc_usages.h new file mode 100644 index 0000000..fb3b70e --- /dev/null +++ b/GrallocHAL/src/mali_gralloc_usages.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2017-2020 ARM Limited. All rights reserved. + * + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MALI_GRALLOC_USAGES_H_ +#define MALI_GRALLOC_USAGES_H_ + +#define GRALLOC_USAGE_PRIVATE_MASK (0xffff0000f0000000U) +#define GRALLOC_USAGE_PUBLIC_MASK ((uint64_t) ~GRALLOC_USAGE_PRIVATE_MASK) + +/* + * MALI_GRALLOC_USAGE_AFBC_PADDING is only valid if MALI_GRALLOC_USAGE_NO_AFBC + * is not present. + */ + + +#include <android/hardware/graphics/common/1.2/types.h> +/* BufferUsage is not defined in 1.2/types.h as there are no changes from previous version */ +namespace hidl_common = android::hardware::graphics::common::V1_1; + +#include <aidl/android/hardware/graphics/common/BufferUsage.h> +namespace aidl_common = aidl::android::hardware::graphics::common; + +/* Local macro definitions to emulate Gralloc 1.0 usage interface */ +#define GRALLOC_USAGE_PRIVATE_0 1ULL << 28 +#define GRALLOC_USAGE_PRIVATE_1 1ULL << 29 +#define GRALLOC_USAGE_PRIVATE_2 1ULL << 30 +#define GRALLOC_USAGE_PRIVATE_3 1ULL << 31 +#define GRALLOC_USAGE_PRIVATE_4 1ULL << 63 +#define GRALLOC_USAGE_PRIVATE_5 1ULL << 62 +#define GRALLOC_USAGE_PRIVATE_6 1ULL << 61 +#define GRALLOC_USAGE_PRIVATE_7 1ULL << 60 +#define GRALLOC_USAGE_PRIVATE_8 1ULL << 59 +#define GRALLOC_USAGE_PRIVATE_9 1ULL << 58 +#define GRALLOC_USAGE_PRIVATE_10 1ULL << 57 +#define GRALLOC_USAGE_PRIVATE_11 1ULL << 56 +#define GRALLOC_USAGE_PRIVATE_12 1ULL << 55 +#define GRALLOC_USAGE_PRIVATE_13 1ULL << 54 +#define GRALLOC_USAGE_PRIVATE_14 1ULL << 53 +#define GRALLOC_USAGE_PRIVATE_15 1ULL << 52 +#define GRALLOC_USAGE_PRIVATE_16 1ULL << 51 +#define GRALLOC_USAGE_PRIVATE_17 1ULL << 50 +#define GRALLOC_USAGE_PRIVATE_18 1ULL << 49 +#define GRALLOC_USAGE_PRIVATE_19 1ULL << 48 + +// TODO(b/183478446): Cleanup usage flags redefinition +typedef enum +{ + MALI_GRALLOC_USAGE_FRONTBUFFER = GRALLOC_USAGE_PRIVATE_12, + MALI_GRALLOC_USAGE_FORCE_BACKBUFFER = GRALLOC_USAGE_PRIVATE_13, + MALI_GRALLOC_USAGE_NO_AFBC = GRALLOC_USAGE_PRIVATE_1, + MALI_GRALLOC_USAGE_AFBC_PADDING = GRALLOC_USAGE_PRIVATE_14, + + /* SLSI specific usages */ + GRALLOC_USAGE_PRIVATE_NONSECURE = GRALLOC_USAGE_PRIVATE_8, + GRALLOC_USAGE_NOZEROED = GRALLOC_USAGE_PRIVATE_9, + + GRALLOC_USAGE_VIDEO_PRIVATE_DATA = GRALLOC_USAGE_PRIVATE_7, + + GRALLOC_USAGE_ROIINFO = GRALLOC_USAGE_PRIVATE_15, + + /* Google specific usages */ + GRALLOC_USAGE_GOOGLE_IP_BO = GRALLOC_USAGE_PRIVATE_16, + GRALLOC_USAGE_GOOGLE_IP_MFC = GRALLOC_USAGE_PRIVATE_17, + + /* FaceAuth specific usages. */ + GS101_GRALLOC_USAGE_TPU_INPUT = GRALLOC_USAGE_PRIVATE_5, + GS101_GRALLOC_USAGE_TPU_OUTPUT = GRALLOC_USAGE_PRIVATE_3, + GS101_GRALLOC_USAGE_CAMERA_STATS = GRALLOC_USAGE_PRIVATE_2, +} mali_gralloc_usage_type; + +#define GRALLOC_USAGE_SW_WRITE_RARELY static_cast<uint64_t>(hidl_common::BufferUsage::CPU_WRITE_RARELY) +#define GRALLOC_USAGE_SW_WRITE_OFTEN static_cast<uint64_t>(hidl_common::BufferUsage::CPU_WRITE_OFTEN) +#define GRALLOC_USAGE_SW_READ_RARELY static_cast<uint64_t>(hidl_common::BufferUsage::CPU_READ_RARELY) +#define GRALLOC_USAGE_SW_READ_OFTEN static_cast<uint64_t>(hidl_common::BufferUsage::CPU_READ_OFTEN) +#define GRALLOC_USAGE_RENDERSCRIPT static_cast<uint64_t>(hidl_common::BufferUsage::RENDERSCRIPT) +#define GRALLOC_USAGE_HW_FB static_cast<uint64_t>(hidl_common::BufferUsage::COMPOSER_CLIENT_TARGET) + +/* Bit 10 must be zero as per Gralloc 2.x interface specification. Used, however, for backward compatibility */ +#define GRALLOC_USAGE_HW_2D static_cast<uint64_t>(0x00000400) + +#define GRALLOC_USAGE_SW_WRITE_MASK static_cast<uint64_t>(hidl_common::BufferUsage::CPU_WRITE_MASK) +#define GRALLOC_USAGE_SW_READ_MASK static_cast<uint64_t>(hidl_common::BufferUsage::CPU_READ_MASK) +#define GRALLOC_USAGE_PROTECTED static_cast<uint64_t>(hidl_common::BufferUsage::PROTECTED) +#define GRALLOC_USAGE_CURSOR static_cast<uint64_t>(hidl_common::BufferUsage::COMPOSER_CURSOR) +#define GRALLOC_USAGE_HW_RENDER static_cast<uint64_t>(hidl_common::BufferUsage::GPU_RENDER_TARGET) +#define GRALLOC_USAGE_HW_CAMERA_WRITE static_cast<uint64_t>(hidl_common::BufferUsage::CAMERA_OUTPUT) +#define GRALLOC_USAGE_HW_CAMERA_READ static_cast<uint64_t>(hidl_common::BufferUsage::CAMERA_INPUT) +#define GRALLOC_USAGE_HW_TEXTURE static_cast<uint64_t>(hidl_common::BufferUsage::GPU_TEXTURE) +#define GRALLOC_USAGE_HW_VIDEO_ENCODER static_cast<uint64_t>(hidl_common::BufferUsage::VIDEO_ENCODER) +#define GRALLOC_USAGE_HW_VIDEO_DECODER static_cast<uint64_t>(hidl_common::BufferUsage::VIDEO_DECODER) +#define GRALLOC_USAGE_HW_COMPOSER static_cast<uint64_t>(hidl_common::BufferUsage::COMPOSER_OVERLAY) +#define GRALLOC_USAGE_EXTERNAL_DISP static_cast<uint64_t>(0x00002000) + +#define GRALLOC_USAGE_SENSOR_DIRECT_DATA static_cast<uint64_t>(hidl_common::BufferUsage::SENSOR_DIRECT_DATA) +#define GRALLOC_USAGE_GPU_DATA_BUFFER static_cast<uint64_t>(hidl_common::BufferUsage::GPU_DATA_BUFFER) +#define GRALLOC_USAGE_FRONT_BUFFER static_cast<uint64_t>(aidl_common::BufferUsage::FRONT_BUFFER) + + +/* Originally (Gralloc 0.x), Android did not provide an explicit DECODER usage. This was rectified in Android N-MR1/7.1 + * when Gralloc 1.0 defined GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER. However, libstagefright continues + * (currently, Android P/9.0) to use this old combination of flags to indicate decoder producer + */ +#define GRALLOC_USAGE_DECODER (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP) + +static const uint64_t VALID_USAGE = + GRALLOC_USAGE_SW_READ_MASK | /* 0x0FU */ + GRALLOC_USAGE_SW_WRITE_MASK | /* 0xF0U */ + GRALLOC_USAGE_HW_TEXTURE | /* 1U << 8 */ + GRALLOC_USAGE_HW_RENDER | /* 1U << 9 */ + GRALLOC_USAGE_HW_2D | /* 1U << 10 */ + GRALLOC_USAGE_HW_COMPOSER | /* 1U << 11 */ + GRALLOC_USAGE_HW_FB | /* 1U << 12 */ + GRALLOC_USAGE_EXTERNAL_DISP | /* 1U << 13 */ + GRALLOC_USAGE_PROTECTED | /* 1U << 14 */ + GRALLOC_USAGE_CURSOR | /* 1U << 15 */ + GRALLOC_USAGE_HW_VIDEO_ENCODER | /* 1U << 16 */ + GRALLOC_USAGE_HW_CAMERA_WRITE | /* 1U << 17 */ + GRALLOC_USAGE_HW_CAMERA_READ | /* 1U << 18 */ + GRALLOC_USAGE_RENDERSCRIPT | /* 1U << 20 */ + GRALLOC_USAGE_HW_VIDEO_DECODER | /* 1U << 22 */ + /* Producer and consumer usage are combined, but on Gralloc version 1 there is no way to differentiate these as they + * are mapped to the same value (1U << 23). */ + GRALLOC_USAGE_SENSOR_DIRECT_DATA | /* 1U << 23 */ + GRALLOC_USAGE_GPU_DATA_BUFFER | /* 1U << 24 */ + GRALLOC_USAGE_FRONT_BUFFER | /* 1U << 32 */ + + /* Google specific usages */ + GRALLOC_USAGE_GOOGLE_IP_BO | /* 1U << 51 */ + GRALLOC_USAGE_GOOGLE_IP_MFC | /* 1U << 50 */ + + GS101_GRALLOC_USAGE_TPU_INPUT | /* 1U << 62 */ + GS101_GRALLOC_USAGE_TPU_OUTPUT | /* 1U << 31 */ + GS101_GRALLOC_USAGE_CAMERA_STATS | /* 1U << 30 */ + + GRALLOC_USAGE_ROIINFO | /* 1U << 52 */ + MALI_GRALLOC_USAGE_AFBC_PADDING | /* 1U << 53 */ + MALI_GRALLOC_USAGE_FORCE_BACKBUFFER | /* 1U << 54 */ + MALI_GRALLOC_USAGE_NO_AFBC | /* 1U << 29 */ + 0; + +#endif /*MALI_GRALLOC_USAGES_H_*/ diff --git a/gralloc3/Android.mk b/gralloc3/Android.mk deleted file mode 100644 index 5e6623e..0000000 --- a/gralloc3/Android.mk +++ /dev/null @@ -1,117 +0,0 @@ -# -# Copyright (C) 2016-2018 ARM Limited. All rights reserved. -# -# Copyright (C) 2008 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. - -TOP_LOCAL_PATH := $(call my-dir) -MALI_GRALLOC_API_TESTS?=0 - -ifdef GRALLOC_USE_GRALLOC1_API - ifdef GRALLOC_API_VERSION - $(warning GRALLOC_API_VERSION flag is not compatible with GRALLOC_USE_GRALLOC1_API) - endif -endif - -include $(TOP_LOCAL_PATH)/gralloc.version.mk - -# Place and access VPU library from /vendor directory in unit testing as default -# /system is not in the linker permitted paths -ifeq ($(MALI_GRALLOC_API_TESTS), 1) -MALI_GRALLOC_VPU_LIBRARY_PATH := \"/vendor/lib/\" -endif - -#Build allocator for 2.x and gralloc libhardware HAL for all previous versions -GRALLOC_MAPPER := 0 -ifeq ($(shell expr $(GRALLOC_VERSION_MAJOR) \>= 2), 1) - $(info Build Gralloc allocator for 2.x) -else ifeq ($(shell expr $(GRALLOC_VERSION_MAJOR) \>= 1), 1) - $(info Build Gralloc 1.x libhardware HAL) -else - $(info Build Gralloc 0.x libhardware HAL) -endif -include $(TOP_LOCAL_PATH)/src/Android.mk - -# Build gralloc mapper for 2.x -ifeq ($(shell expr $(GRALLOC_VERSION_MAJOR) \>= 2), 1) - GRALLOC_MAPPER := 1 - $(info Build Gralloc mapper for 2.x) - include $(TOP_LOCAL_PATH)/src/Android.mk -endif - -# Build gralloc api tests. -ifeq ($(MALI_GRALLOC_API_TESTS), 1) -$(info Build gralloc API tests.) -include $(TOP_LOCAL_PATH)/api_tests/Android.mk -endif - -#################################################################################################### - -include $(CLEAR_VARS) -include $(TOP_LOCAL_PATH)/gralloc.version.mk - -LOCAL_SHARED_LIBRARIES := \ - liblog \ - libcutils \ - libutils \ - android.hardware.graphics.mapper@2.0 \ - libsync \ - libhardware \ - libhidlbase \ - libhidltransport \ - libnativewindow \ - libion_google \ - libdmabufheap - -LOCAL_STATIC_LIBRARIES := libarect -LOCAL_HEADER_LIBRARIES := libnativebase_headers - -LOCAL_C_INCLUDES := \ - $(TOP)/hardware/google/gchips/include \ - $(TOP)/hardware/google/gchips/gralloc3/include \ - $(TARGET_BOARD_KERNEL_HEADERS) - -LOCAL_SRC_FILES := \ - gralloc_vendor_interface.cpp \ - mali_gralloc_ion.cpp \ - gralloc_buffer_priv.cpp \ - format_info.cpp \ - mali_gralloc_bufferallocation.cpp \ - mali_gralloc_formats.cpp \ - mali_gralloc_debug.cpp - -# TODO(find out why setting this to $(HIDL_MAPPER_VERSION_SCALED) doesn't work) -LOCAL_CFLAGS := -DHIDL_MAPPER_VERSION_SCALED=200 -LOCAL_CFLAGS += -DGRALLOC_VERSION_MAJOR=$(GRALLOC_VERSION_MAJOR) -LOCAL_CFLAGS += -DGRALLOC_HFR_BATCH_SIZE=8 - -LOCAL_CFLAGS += -DMALI_GRALLOC_GPU_LIBRARY_PATH1=$(MALI_GRALLOC_GPU_LIBRARY_64_PATH1) -LOCAL_CFLAGS += -DMALI_GRALLOC_GPU_LIBRARY_PATH2=$(MALI_GRALLOC_GPU_LIBRARY_64_PATH2) - -ifeq ($(BOARD_EXYNOS_S10B_FORMAT_ALIGN), 64) -LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=$(BOARD_EXYNOS_S10B_FORMAT_ALIGN) -else -LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=16 -endif - -LOCAL_CFLAGS += -DGRALLOC_LIBRARY_BUILD=1 - -ifeq ($(BOARD_USES_VENDORIMAGE), true) -LOCAL_PROPRIETARY_MODULE := true -endif -LOCAL_MODULE := libGrallocWrapper -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice - -include $(BUILD_SHARED_LIBRARY) diff --git a/gralloc3/gralloc.version.mk b/gralloc3/gralloc.version.mk deleted file mode 100644 index 4e98216..0000000 --- a/gralloc3/gralloc.version.mk +++ /dev/null @@ -1,74 +0,0 @@ -# -# Copyright (C) 2016-2018 ARM Limited. All rights reserved. -# -# Copyright (C) 2008 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. - -# List of all valid Gralloc versions -GRALLOC_VALID_VERSIONS := 0.x 1.x 2.x - -#Set default Gralloc version -PLATFORM_SDK_GREATER_THAN_24 := $(shell expr $(PLATFORM_SDK_VERSION) \> 24) -ifeq ($(PLATFORM_SDK_GREATER_THAN_24), 1) - GRALLOC_API_VERSION?=1.x -else - GRALLOC_API_VERSION?=0.x -endif - -ifdef GRALLOC_USE_GRALLOC1_API - ifeq ($(GRALLOC_USE_GRALLOC1_API), 1) - GRALLOC_API_VERSION := 1.x - else - ifeq ($(GRALLOC_USE_GRALLOC1_API), 0) - GRALLOC_API_VERSION := 0.x - endif - endif -endif - -# Fail build if GRALLOC_API_VERSION isn't one of the following. -ifeq ($(filter $(GRALLOC_API_VERSION),$(GRALLOC_VALID_VERSIONS)),) - $(error Gralloc version $(GRALLOC_API_VERSION) is not valid. Valid versions are $(GRALLOC_VALID_VERSIONS)) -endif - -# Derive namespaces and associated (internal and scaled) versions for Gralloc 2.x -# Note: On a given SDK platform, versions of Allocator / Mapper / Common can be -# changed (somewhat) independently of each other. Scaled internal versions, encapsulating -# their major and minor versions, provide for building specific combinations -ifeq ($(GRALLOC_API_VERSION), 2.x) - - ifeq ($(shell expr $(PLATFORM_SDK_VERSION) \> 27), 1) - HIDL_IMAPPER_NAMESPACE := V2_1 - HIDL_IALLOCATOR_NAMESPACE := V2_0 - HIDL_COMMON_NAMESPACE := V1_1 - - #Allocator = 2.0, Mapper = 2.1 and Common = 1.1 - HIDL_ALLOCATOR_VERSION_SCALED := 200 - HIDL_MAPPER_VERSION_SCALED := 210 - HIDL_COMMON_VERSION_SCALED := 110 - - else ifeq ($(shell expr $(PLATFORM_SDK_VERSION) \> 25), 1) - HIDL_IMAPPER_NAMESPACE := V2_0 - HIDL_IALLOCATOR_NAMESPACE := V2_0 - HIDL_COMMON_NAMESPACE := V1_0 - - #Allocator = 2.0, Mapper = 2.0 and Common = 1.0 - HIDL_ALLOCATOR_VERSION_SCALED := 200 - HIDL_MAPPER_VERSION_SCALED := 200 - HIDL_COMMON_VERSION_SCALED := 100 - else - $(error Gralloc 2.x is not supported on platform SDK version $(PLATFORM_SDK_VERSION)) - endif -endif - -GRALLOC_VERSION_MAJOR := $(shell echo $(GRALLOC_API_VERSION) | cut -d. -f1) diff --git a/gralloc3/src/Android.mk b/gralloc3/src/Android.mk deleted file mode 100644 index 8ec1bca..0000000 --- a/gralloc3/src/Android.mk +++ /dev/null @@ -1,346 +0,0 @@ -# -# Copyright (C) 2016-2019 ARM Limited. All rights reserved. -# -# Copyright (C) 2008 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. - -LOCAL_PATH := $(call my-dir) - -# HAL module implemenation, not prelinked. -# Binary located in hw/gralloc.<ro.product.board>.so -include $(CLEAR_VARS) -ifndef PLATFORM_SDK_VERSION -include $(BUILD_SYSTEM)/version_defaults.mk -endif - -# Include makefile which exports Gralloc Major and Minor version numbers -include $(LOCAL_PATH)/../gralloc.version.mk - -# Include platform specific makefiles -include $(if $(wildcard $(LOCAL_PATH)/Android.$(TARGET_BOARD_PLATFORM).mk), $(LOCAL_PATH)/Android.$(TARGET_BOARD_PLATFORM).mk,) - -PLATFORM_SDK_GREATER_THAN_24 := $(shell expr $(PLATFORM_SDK_VERSION) \> 24) -PLATFORM_SDK_LESS_THAN_28 := $(shell expr $(PLATFORM_SDK_VERSION) \< 28) - -MALI_GRALLOC_VPU_LIBRARY_PATH?=\"/system/lib/\" -MALI_GRALLOC_GPU_LIBRARY_64_PATH1 := \"/vendor/lib64/egl/\" -MALI_GRALLOC_GPU_LIBRARY_64_PATH2 := \"/system/lib64/egl/\" -MALI_GRALLOC_DPU_LIBRARY_64_PATH := \"/vendor/lib64/hw/\" -MALI_GRALLOC_GPU_LIBRARY_32_PATH1 := \"/vendor/lib/egl/\" -MALI_GRALLOC_GPU_LIBRARY_32_PATH2 := \"/system/lib/egl/\" -MALI_GRALLOC_DPU_LIBRARY_32_PATH := \"/vendor/lib/hw/\" - -# 2.0+ specific. -# If set to the default value of zero then build the allocator. Otherwise build the mapper. -# The top-level make file builds both. -GRALLOC_MAPPER?=0 - -# -# Static hardware defines -# -# These defines are used in case runtime detection does not find the -# user-space driver to read out hardware capabilities - -ifeq ($(USE_SWIFTSHADER),true) -# GPU support for AFBC 1.0 -MALI_GPU_SUPPORT_AFBC_BASIC?=0 -# GPU support for AFBC 1.1 block split -MALI_GPU_SUPPORT_AFBC_SPLITBLK?=0 -# GPU support for AFBC 1.1 wide block -MALI_GPU_SUPPORT_AFBC_WIDEBLK?=0 -# GPU support for AFBC 1.2 tiled headers -MALI_GPU_SUPPORT_AFBC_TILED_HEADERS?=0 -# GPU support for writing AFBC YUV formats -MALI_GPU_SUPPORT_AFBC_YUV_WRITE?=0 -else # !USE_SWIFTSHADER -# GPU support for AFBC 1.0 -MALI_GPU_SUPPORT_AFBC_BASIC?=1 -# GPU support for AFBC 1.1 block split -MALI_GPU_SUPPORT_AFBC_SPLITBLK?=0 -# GPU support for AFBC 1.1 wide block -MALI_GPU_SUPPORT_AFBC_WIDEBLK?=1 -# GPU support for AFBC 1.2 tiled headers -MALI_GPU_SUPPORT_AFBC_TILED_HEADERS?=0 -# GPU support for writing AFBC YUV formats -MALI_GPU_SUPPORT_AFBC_YUV_WRITE?=1 -endif # USE_SWIFTSHADER - -# -# Software behaviour defines -# - -# The following defines are used to override default behaviour of which heap is selected for allocations. -# The default is to pick system heap. -# The following two defines enable either DMA heap or compound page heap for when the usage has -# GRALLOC_USAGE_HW_FB or GRALLOC_USAGE_HW_COMPOSER set and GRALLOC_USAGE_HW_VIDEO_ENCODER is not set. -# These defines should not be enabled at the same time. -GRALLOC_USE_ION_DMA_HEAP?=0 -GRALLOC_USE_ION_COMPOUND_PAGE_HEAP?=0 - -# fbdev bitdepth to use -GRALLOC_FB_BPP?=32 -# When enabled, forces display framebuffer format to BGRA_8888 -GRALLOC_FB_SWAP_RED_BLUE?=1 -# Disables the framebuffer HAL device. When a hwc impl is available. -GRALLOC_DISABLE_FRAMEBUFFER_HAL?=1 - -# When enabled, buffers will never be allocated with AFBC -GRALLOC_ARM_NO_EXTERNAL_AFBC?=1 -# Properly initializes an empty AFBC buffer -GRALLOC_INIT_AFBC?=0 - -ifeq ($(BOARD_USES_EXYNOS_AFBC_FEATURE), true) -GRALLOC_ARM_NO_EXTERNAL_AFBC:=0 -GRALLOC_INIT_AFBC:=1 -endif - -# Minimum buffer dimensions in pixels when buffer will use AFBC -GRALLOC_DISP_W?=0 -GRALLOC_DISP_H?=0 -GRALLOC_AFBC_MIN_SIZE?=75 - -ifdef BOARD_GRALLOC_AFBC_DISP_W -GRALLOC_DISP_W:=$(BOARD_GRALLOC_AFBC_DISP_W) -endif -ifdef BOARD_GRALLOC_AFBC_DISP_H -GRALLOC_DISP_H:=$(BOARD_GRALLOC_AFBC_DISP_H) -endif -ifdef BOARD_GRALLOC_AFBC_MIN_SIZE -GRALLOC_AFBC_MIN_SIZE := $(BOARD_GRALLOC_AFBC_MIN_SIZE) -endif - -# Vsync backend(not used) -GRALLOC_VSYNC_BACKEND?=default - -GRALLOC_USE_ION_DMABUF_SYNC?=1 - -MALI_GRALLOC_DISABLE_ALOGV?=1 - -# Set 1 to require importBuffer before locking raw buffers -GRALLOC_IMPORT_BUFFER_REQUIRED?=0 - -# Used for WFD on exynos3830 -ifeq ($(TARGET_BOARD_PLATFORM), exynos3830) -GRALLOC_ION_HEAP_CRYPTO_MASK:=1 -else -GRALLOC_ION_HEAP_CRYPTO_MASK:=0 -endif - -# Disable ION debug handle import on 7885 -ifneq ($(TARGET_SOC), exynos7885) -GRALLOC_ION_HANDLE_IMPORT:=1 -else -GRALLOC_ION_HANDLE_IMPORT:=0 -endif - -GRALLOC_USE_ASHMEM_METADATA:=0 - -GRALLOC_HFR_BATCH_SIZE?=8 - -ifeq ($(GRALLOC_USE_ION_DMA_HEAP), 1) -ifeq ($(GRALLOC_USE_ION_COMPOUND_PAGE_HEAP), 1) -$(error GRALLOC_USE_ION_DMA_HEAP and GRALLOC_USE_ION_COMPOUND_PAGE_HEAP can't be enabled at the same time) -endif -endif - -ifeq (,$(wildcard $(TARGET_BOARD_KERNEL_HEADERS)/video/mfc_macros.h)) -# b/175341085 -$(warning "Couldn't find video/mfc_macros in UAPI, using local_mfc_macros.h") -endif - -LOCAL_C_INCLUDES := $(MALI_LOCAL_PATH) $(MALI_DDK_INCLUDES) \ - $(TOP)/hardware/google/gchips/include \ - $(TARGET_BOARD_KERNEL_HEADERS) - -# General compilation flags -LOCAL_CFLAGS := -ldl -Werror -DLOG_TAG=\"gralloc\" -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) - -# ALOGV flag -LOCAL_CFLAGS += -DLOG_NDEBUG=$(MALI_GRALLOC_DISABLE_ALOGV) - -# Static hw flags -LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_BASIC=$(MALI_GPU_SUPPORT_AFBC_BASIC) -LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_SPLITBLK=$(MALI_GPU_SUPPORT_AFBC_SPLITBLK) -LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_WIDEBLK=$(MALI_GPU_SUPPORT_AFBC_WIDEBLK) -LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_TILED_HEADERS=$(MALI_GPU_SUPPORT_AFBC_TILED_HEADERS) -LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_YUV_WRITE=$(MALI_GPU_SUPPORT_AFBC_YUV_WRITE) - -LOCAL_CFLAGS_arm64 += -DMALI_GRALLOC_GPU_LIBRARY_PATH1=$(MALI_GRALLOC_GPU_LIBRARY_64_PATH1) -LOCAL_CFLAGS_arm64 += -DMALI_GRALLOC_GPU_LIBRARY_PATH2=$(MALI_GRALLOC_GPU_LIBRARY_64_PATH2) -LOCAL_CFLAGS_arm64 += -DMALI_GRALLOC_DPU_LIBRARY_PATH=$(MALI_GRALLOC_DPU_LIBRARY_64_PATH) -LOCAL_CFLAGS_arm += -DMALI_GRALLOC_GPU_LIBRARY_PATH1=$(MALI_GRALLOC_GPU_LIBRARY_32_PATH1) -LOCAL_CFLAGS_arm += -DMALI_GRALLOC_GPU_LIBRARY_PATH2=$(MALI_GRALLOC_GPU_LIBRARY_32_PATH2) -LOCAL_CFLAGS_arm += -DMALI_GRALLOC_DPU_LIBRARY_PATH=$(MALI_GRALLOC_DPU_LIBRARY_32_PATH) -LOCAL_CFLAGS += -DMALI_GRALLOC_VPU_LIBRARY_PATH=$(MALI_GRALLOC_VPU_LIBRARY_PATH) - -# Software behaviour flags -LOCAL_CFLAGS += -DGRALLOC_VERSION_MAJOR=$(GRALLOC_VERSION_MAJOR) -LOCAL_CFLAGS += -DHIDL_ALLOCATOR_VERSION_SCALED=$(HIDL_ALLOCATOR_VERSION_SCALED) -LOCAL_CFLAGS += -DHIDL_MAPPER_VERSION_SCALED=$(HIDL_MAPPER_VERSION_SCALED) -LOCAL_CFLAGS += -DHIDL_COMMON_VERSION_SCALED=$(HIDL_COMMON_VERSION_SCALED) -LOCAL_CFLAGS += -DHIDL_IALLOCATOR_NAMESPACE=$(HIDL_IALLOCATOR_NAMESPACE) -LOCAL_CFLAGS += -DHIDL_IMAPPER_NAMESPACE=$(HIDL_IMAPPER_NAMESPACE) -LOCAL_CFLAGS += -DHIDL_COMMON_NAMESPACE=$(HIDL_COMMON_NAMESPACE) -LOCAL_CFLAGS += -DGRALLOC_DISP_W=$(GRALLOC_DISP_W) -LOCAL_CFLAGS += -DGRALLOC_DISP_H=$(GRALLOC_DISP_H) -LOCAL_CFLAGS += -DGRALLOC_AFBC_MIN_SIZE=$(GRALLOC_AFBC_MIN_SIZE) -LOCAL_CFLAGS += -DDISABLE_FRAMEBUFFER_HAL=$(GRALLOC_DISABLE_FRAMEBUFFER_HAL) -LOCAL_CFLAGS += -DGRALLOC_USE_ION_DMA_HEAP=$(GRALLOC_USE_ION_DMA_HEAP) -LOCAL_CFLAGS += -DGRALLOC_USE_ION_COMPOUND_PAGE_HEAP=$(GRALLOC_USE_ION_COMPOUND_PAGE_HEAP) -LOCAL_CFLAGS += -DGRALLOC_INIT_AFBC=$(GRALLOC_INIT_AFBC) -LOCAL_CFLAGS += -DGRALLOC_FB_BPP=$(GRALLOC_FB_BPP) -LOCAL_CFLAGS += -DGRALLOC_FB_SWAP_RED_BLUE=$(GRALLOC_FB_SWAP_RED_BLUE) -LOCAL_CFLAGS += -DGRALLOC_ARM_NO_EXTERNAL_AFBC=$(GRALLOC_ARM_NO_EXTERNAL_AFBC) -LOCAL_CFLAGS += -DGRALLOC_LIBRARY_BUILD=1 -LOCAL_CFLAGS += -DGRALLOC_USE_ION_DMABUF_SYNC=$(GRALLOC_USE_ION_DMABUF_SYNC) -LOCAL_CFLAGS += -DGRALLOC_IMPORT_BUFFER_REQUIRED=$(GRALLOC_IMPORT_BUFFER_REQUIRED) -LOCAL_CFLAGS += -DGRALLOC_ION_HEAP_CRYPTO_MASK=$(GRALLOC_ION_HEAP_CRYPTO_MASK) -LOCAL_CFLAGS += -DGRALLOC_HFR_BATCH_SIZE=$(GRALLOC_HFR_BATCH_SIZE) -LOCAL_CFLAGS += -DGRALLOC_USE_ASHMEM_METADATA=$(GRALLOC_USE_ASHMEM_METADATA) -LOCAL_CFLAGS += -DGRALLOC_ION_HANDLE_IMPORT=$(GRALLOC_ION_HANDLE_IMPORT) - -ifeq ($(BOARD_USES_ALIGN_RESTRICTION), true) -LOCAL_CFLAGS += -DGRALLOC_MSCL_ALIGN_RESTRICTION -endif - -ifeq ($(BOARD_EXYNOS_S10B_FORMAT_ALIGN), 64) -LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=$(BOARD_EXYNOS_S10B_FORMAT_ALIGN) -else -LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=16 -endif - -ifeq ($(BOARD_USES_GRALLOC_ION_SYNC), true) -LOCAL_CFLAGS += -DGRALLOC_ION_SYNC -endif - -ifneq ($(BOARD_USES_EXYNOS_DATASPACE_FEATURE), true) -LOCAL_CFLAGS += -DGRALLOC_NO_CSC_SUPPORTED -endif - -ifeq ($(shell expr $(GRALLOC_VERSION_MAJOR) \<= 1), 1) -LOCAL_SHARED_LIBRARIES := libhardware liblog libcutils libGLESv1_CM libion_google libsync libutils libdmabufheap -else ifeq ($(GRALLOC_VERSION_MAJOR), 2) - ifeq ($(GRALLOC_MAPPER), 1) - LOCAL_SHARED_LIBRARIES := libhardware libhidlbase libhidltransport liblog libcutils libion_google libsync libutils libdmabufheap - LOCAL_SHARED_LIBRARIES += android.hardware.graphics.mapper@2.0 - ifeq ($(HIDL_MAPPER_VERSION_SCALED), 210) - LOCAL_SHARED_LIBRARIES += android.hardware.graphics.mapper@2.1 - endif - else - LOCAL_SHARED_LIBRARIES := libhardware libhidlbase libhidltransport liblog libcutils libion_google libsync libutils libdmabufheap - LOCAL_SHARED_LIBRARIES += android.hardware.graphics.allocator@2.0 - ifeq ($(HIDL_MAPPER_VERSION_SCALED), 210) - LOCAL_SHARED_LIBRARIES += android.hardware.graphics.mapper@2.1 - endif - endif -endif - -PLATFORM_SDK_GREATER_THAN_26 := $(shell expr $(PLATFORM_SDK_VERSION) \> 26) -ifeq ($(PLATFORM_SDK_GREATER_THAN_26), 1) -LOCAL_SHARED_LIBRARIES += libnativewindow -LOCAL_STATIC_LIBRARIES := libarect -LOCAL_HEADER_LIBRARIES := libnativebase_headers -endif - -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib -LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64 -ifeq ($(shell expr $(GRALLOC_VERSION_MAJOR) \<= 1), 1) - ifeq ($(TARGET_BOARD_PLATFORM),) - LOCAL_MODULE := gralloc.default - LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 - LOCAL_LICENSE_CONDITIONS := notice - else - LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM) - LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 - LOCAL_LICENSE_CONDITIONS := notice - endif -else ifeq ($(GRALLOC_VERSION_MAJOR), 2) - ifeq ($(GRALLOC_MAPPER), 1) - ifeq ($(HIDL_MAPPER_VERSION_SCALED), 200) - LOCAL_MODULE := android.hardware.graphics.mapper@2.0-impl - LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 - LOCAL_LICENSE_CONDITIONS := notice - else ifeq ($(HIDL_MAPPER_VERSION_SCALED), 210) - LOCAL_MODULE := android.hardware.graphics.mapper@2.0-impl-2.1 - LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 - LOCAL_LICENSE_CONDITIONS := notice - endif - else - LOCAL_MODULE := android.hardware.graphics.allocator@2.0-impl - LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 - LOCAL_LICENSE_CONDITIONS := notice - endif -endif - -LOCAL_MODULE_OWNER := arm -LOCAL_PROPRIETARY_MODULE := true - -LOCAL_MODULE_TAGS := optional -LOCAL_MULTILIB := both - -LOCAL_SRC_FILES := \ - gralloc_buffer_priv.cpp \ - mali_gralloc_bufferaccess.cpp \ - mali_gralloc_bufferallocation.cpp \ - mali_gralloc_bufferdescriptor.cpp \ - mali_gralloc_ion.cpp \ - mali_gralloc_formats.cpp \ - mali_gralloc_reference.cpp \ - mali_gralloc_debug.cpp \ - format_info.cpp - -ifeq ($(GRALLOC_VERSION_MAJOR), 0) - LOCAL_SRC_FILES += mali_gralloc_module.cpp \ - framebuffer_device.cpp \ - gralloc_vsync_${GRALLOC_VSYNC_BACKEND}.cpp \ - legacy/alloc_device.cpp -else ifeq ($(GRALLOC_VERSION_MAJOR), 1) - LOCAL_SRC_FILES += mali_gralloc_module.cpp \ - framebuffer_device.cpp \ - gralloc_vsync_${GRALLOC_VSYNC_BACKEND}.cpp \ - mali_gralloc_public_interface.cpp \ - mali_gralloc_private_interface.cpp -else ifeq ($(GRALLOC_VERSION_MAJOR), 2) - ifeq ($(GRALLOC_MAPPER), 1) - LOCAL_SRC_FILES += GrallocMapper.cpp - else - LOCAL_SRC_FILES += framebuffer_device.cpp \ - GrallocAllocator.cpp - endif - - LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \ - android.hardware.graphics.allocator@2.0 \ - libhidlbase \ - libhidltransport - - ifeq ($(HIDL_MAPPER_VERSION_SCALED), 200) - LOCAL_EXPORT_SHARED_LIBRARY_HEADERS += android.hardware.graphics.mapper@2.0 - LOCAL_EXPORT_SHARED_LIBRARY_HEADERS += android.hardware.graphics.common@1.0 - else ifeq ($(HIDL_MAPPER_VERSION_SCALED), 210) - LOCAL_EXPORT_SHARED_LIBRARY_HEADERS += android.hardware.graphics.mapper@2.1 - LOCAL_EXPORT_SHARED_LIBRARY_HEADERS += android.hardware.graphics.common@1.1 - endif - - ifeq ($(HIDL_COMMON_VERSION_SCALED), 100) - LOCAL_EXPORT_SHARED_LIBRARY_HEADERS += android.hardware.graphics.common@1.0 - else ifeq ($(HIDL_COMMON_VERSION_SCALED), 110) - LOCAL_EXPORT_SHARED_LIBRARY_HEADERS += android.hardware.graphics.common@1.1 - endif -endif - -LOCAL_MODULE_OWNER := arm - -include $(BUILD_SHARED_LIBRARY) diff --git a/gralloc3/src/GrallocAllocator.cpp b/gralloc3/src/GrallocAllocator.cpp deleted file mode 100644 index 58b8f19..0000000 --- a/gralloc3/src/GrallocAllocator.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2017-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "GrallocAllocator.h" -#include "GrallocBufferDescriptor.h" -#include "mali_gralloc_bufferallocation.h" -#include "mali_gralloc_bufferdescriptor.h" -#include "mali_gralloc_ion.h" -#include "framebuffer_device.h" - -namespace android { -namespace hardware { -namespace graphics { -namespace allocator { -namespace HIDL_IALLOCATOR_NAMESPACE { -namespace implementation { - -/** - * IAllocator constructor. All the state information required for the Gralloc - * private module is populated in its default constructor. Gralloc 2.0 specific - * state information can be populated here. - * - * @return None - */ - -GrallocAllocator::GrallocAllocator() -{ -} - -/* - * IAllocator destructor. All the resources acquired for Gralloc private module - * are released - * - * @return None - */ -GrallocAllocator::~GrallocAllocator() -{ - mali_gralloc_ion_close(); -} - -/* - * Retrieves implementation-defined debug information - * - * Retrieves implementation-defined debug information, which will be - * displayed during, for example, `dumpsys SurfaceFlinger` - * - * @param hidl_cb [in] HIDL callback function generating - - * String of debug information - * - * @return Void - */ -Return<void> GrallocAllocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) -{ - hidl_cb(hidl_string()); - return Void(); -} - -/* - * Allocates buffers with the properties specified by the descriptor - * - * @param descriptor: Specifies the properties of the buffers to allocate. - * @param count: Number of buffers to allocate. - * @param hidl_cb [in] HIDL callback function generating - - * error : NONE upon success. Otherwise, - * BAD_DESCRIPTOR when the descriptor is invalid. - * NO_RESOURCES when the allocation cannot be fulfilled - * UNSUPPORTED when any of the property encoded in the descriptor - * is not supported - * stride: Number of pixels between two consecutive rows of the - * buffers, when the concept of consecutive rows is defined. - * buffers: An array of raw handles to the newly allocated buffers - * - * @return Void - */ -Return<void> GrallocAllocator::allocate(const BufferDescriptor& descriptor, - uint32_t count, allocate_cb hidl_cb) -{ - buffer_descriptor_t bufferDescriptor; - Error error = Error::NONE; - int stride = 0, tmpStride = 0; - std::vector<hidl_handle> grallocBuffers; - gralloc_buffer_descriptor_t grallocBufferDescriptor[1]; - - if (!mapper::HIDL_IMAPPER_NAMESPACE::implementation::grallocDecodeBufferDescriptor(descriptor, bufferDescriptor)) - { - hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>()); - return Void(); - } - - grallocBufferDescriptor[0] = (gralloc_buffer_descriptor_t)(&bufferDescriptor); - grallocBuffers.reserve(count); - - for (uint32_t i = 0; i < count; i++) - { - buffer_handle_t tmpBuffer; - - int allocResult = 0; -#if DISABLE_FRAMEBUFFER_HAL != 1 - if ((bufferDescriptor.producer_usage & GRALLOC_USAGE_HW_FB) || - (bufferDescriptor.consumer_usage & GRALLOC_USAGE_HW_FB)) - { - allocResult = mali_gralloc_fb_allocate(&privateModule, &bufferDescriptor, - &tmpBuffer); - } - else -#endif - { - allocResult = mali_gralloc_buffer_allocate(&privateModule, grallocBufferDescriptor, - 1, &tmpBuffer, nullptr); - } - - if (allocResult < 0) - { - AERR("%s, buffer allocation failed with %d", __func__, allocResult); - error = Error::NO_RESOURCES; - break; - } - - mali_gralloc_query_getstride(tmpBuffer, &tmpStride); - - if (stride == 0) - { - stride = tmpStride; - } - else if (stride != tmpStride) - { - /* Stride must be the same for all allocations */ - mali_gralloc_buffer_free(tmpBuffer); - stride = 0; - error = Error::UNSUPPORTED; - break; - } - - grallocBuffers.emplace_back(hidl_handle(tmpBuffer)); - } - - /* Populate the array of buffers for application consumption */ - hidl_vec<hidl_handle> hidlBuffers; - if (error == Error::NONE) - { - hidlBuffers.setToExternal(grallocBuffers.data(), grallocBuffers.size()); - } - hidl_cb(error, stride, hidlBuffers); - - /* The application should import the Gralloc buffers using IMapper for - * further usage. Free the allocated buffers in IAllocator context - */ - for (const auto& buffer : grallocBuffers) - { - mali_gralloc_buffer_free(buffer.getNativeHandle()); - } - - return Void(); -} - -IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) -{ - ALOGV("Arm Module IAllocator %d.%d, pid = %d ppid = %d", GRALLOC_VERSION_MAJOR, - (HIDL_ALLOCATOR_VERSION_SCALED - (GRALLOC_VERSION_MAJOR * 100)) / 10, getpid(), getppid()); - - return new GrallocAllocator(); -} - -} // namespace implementation -} // namespace HIDL_IALLOCATOR_NAMESPACE -} // namespace allocator -} // namespace graphics -} // namespace hardware -} // namespace android diff --git a/gralloc3/src/GrallocAllocator.h b/gralloc3/src/GrallocAllocator.h deleted file mode 100644 index b40d36e..0000000 --- a/gralloc3/src/GrallocAllocator.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2017-2018 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_x_GRALLOC_H -#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_x_GRALLOC_H - -#if HIDL_ALLOCATOR_VERSION_SCALED == 200 -#include <android/hardware/graphics/allocator/2.0/IAllocator.h> -#endif - -#include "mali_gralloc_module.h" -#include "mali_gralloc_bufferdescriptor.h" - -namespace android { -namespace hardware { -namespace graphics { -namespace allocator { -namespace HIDL_IALLOCATOR_NAMESPACE { -namespace implementation { - -using android::hardware::graphics::mapper::V2_0::BufferDescriptor; -using android::hardware::graphics::mapper::V2_0::Error; - -class GrallocAllocator : public IAllocator -{ -public: - GrallocAllocator(); - virtual ~GrallocAllocator(); - - /* Override IAllocator interface */ - Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override; - Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count, - allocate_cb hidl_cb) override; -private: - struct private_module_t privateModule; -}; - -extern "C" IAllocator* HIDL_FETCH_IAllocator(const char* name); - -} // namespace implementation -} // namespace HIDL_IALLOCATOR_NAMESPACE -} // namespace allocator -} // namespace graphics -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_x_GRALLOC_H diff --git a/gralloc3/src/GrallocBufferDescriptor.h b/gralloc3/src/GrallocBufferDescriptor.h deleted file mode 100644 index 321bf88..0000000 --- a/gralloc3/src/GrallocBufferDescriptor.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2018 ARM Limited. All rights reserved. - * - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_GRAPHICS_V2_X_GRALLOCBUFFERDESCRIPTOR_H -#define ANDROID_HARDWARE_GRAPHICS_V2_X_GRALLOCBUFFERDESCRIPTOR_H - -#include <android/hardware/graphics/mapper/2.0/IMapper.h> -#if HIDL_MAPPER_VERSION_SCALED == 210 -#include <android/hardware/graphics/mapper/2.1/IMapper.h> -#endif - -#include "mali_gralloc_bufferdescriptor.h" - -namespace android { -namespace hardware { -namespace graphics { -namespace mapper { -namespace HIDL_IMAPPER_NAMESPACE { -namespace implementation { - -/** - * BufferDescriptor is created by IMapper and consumed by IAllocator. It is - * versioned so that IMapper and IAllocator can be updated independently. - * Gralloc creates the same BufferDescriptor configuration across all versions of - * IMapper (BufferDescriptorInfo) - */ -constexpr uint32_t grallocBufferDescriptorMagicVersion = HIDL_MAPPER_VERSION_SCALED; -constexpr uint32_t grallocBufferDescriptorSize = 7; - -/* - * Creates a buffer descriptor from incoming descriptor attributes - * - * @param descriptorInfo [in] Specifies the (2.1 IMapper) attributes of - * the descriptor. - * - * @return Newly created buffer descriptor; - */ -#if HIDL_MAPPER_VERSION_SCALED == 210 -inline V2_0::BufferDescriptor grallocEncodeBufferDescriptor( - const V2_1::IMapper::BufferDescriptorInfo& descriptorInfo) -{ - V2_0::BufferDescriptor descriptor; - descriptor.resize(grallocBufferDescriptorSize); - descriptor[0] = grallocBufferDescriptorMagicVersion; - descriptor[1] = descriptorInfo.width; - descriptor[2] = descriptorInfo.height; - descriptor[3] = descriptorInfo.layerCount; - descriptor[4] = static_cast<uint32_t>(descriptorInfo.format); - descriptor[5] = static_cast<uint32_t>(descriptorInfo.usage); - descriptor[6] = static_cast<uint32_t>(descriptorInfo.usage >> 32); - - return descriptor; -} -#endif - -/* - * Creates a buffer descriptor from incoming descriptor attributes - * - * @param descriptorInfo [in] Specifies the (2.0 IMapper) attributes of - * the descriptor. - * - * @return Newly created buffer descriptor; - */ -inline V2_0::BufferDescriptor grallocEncodeBufferDescriptor( - const V2_0::IMapper::BufferDescriptorInfo& descriptorInfo) -{ - V2_0::BufferDescriptor descriptor; - descriptor.resize(grallocBufferDescriptorSize); - descriptor[0] = grallocBufferDescriptorMagicVersion; - descriptor[1] = descriptorInfo.width; - descriptor[2] = descriptorInfo.height; - descriptor[3] = descriptorInfo.layerCount; - descriptor[4] = static_cast<uint32_t>(descriptorInfo.format); - descriptor[5] = static_cast<uint32_t>(descriptorInfo.usage); - descriptor[6] = static_cast<uint32_t>(descriptorInfo.usage >> 32); - - return descriptor; -} - -/* - * Decodes incoming buffer descriptor (previously encoded by gralloc for Android) - * and populates Gralloc's internal buffer descriptor (which is used across - * various versions of Gralloc) for allocation purpose - * - * @param androidDescriptor [in] Specifies the (encoded) properties of the buffers - * @param grallocDescriptor [out] Gralloc's internal buffer descriptor - * - * @return true, upon successful decode - * false, corrupted descriptor encountered - */ -inline bool grallocDecodeBufferDescriptor(const V2_0::BufferDescriptor& androidDescriptor, - buffer_descriptor_t& grallocDescriptor) -{ - if (androidDescriptor.size() != grallocBufferDescriptorSize) - { - AERR("Corrupted buffer size in descriptor = %p, pid = %d ", &androidDescriptor, getpid()); - return false; - } - - if (androidDescriptor[0] != grallocBufferDescriptorMagicVersion) - { - AERR("Corrupted buffer version in descriptor = %p, pid = %d ", &androidDescriptor, getpid()); - return false; - } - - grallocDescriptor.width = androidDescriptor[1]; - grallocDescriptor.height = androidDescriptor[2]; - grallocDescriptor.layer_count = androidDescriptor[3]; - grallocDescriptor.hal_format = static_cast<uint64_t>(androidDescriptor[4]); - grallocDescriptor.producer_usage = (static_cast<uint64_t>(androidDescriptor[6]) << 32) | androidDescriptor[5]; - grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage; - grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; - grallocDescriptor.signature = sizeof(buffer_descriptor_t); - - return true; -} - -} // namespace implementation -} // namespace HIDL_IMAPPER_NAMESPACE -} // namespace mapper -} // namespace graphics -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_GRAPHICS_V2_X_GRALLOCBUFFERDESCRIPTOR_H diff --git a/gralloc3/src/GrallocMapper.cpp b/gralloc3/src/GrallocMapper.cpp deleted file mode 100644 index 0af7032..0000000 --- a/gralloc3/src/GrallocMapper.cpp +++ /dev/null @@ -1,838 +0,0 @@ -/* - * Copyright (C) 2018-2019 ARM Limited. All rights reserved. - * - * Copyright 2016 The Android Open Source Project - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <inttypes.h> -#include <log/log.h> -#include <sync/sync.h> -#include <mutex> -#include <unordered_set> -#include <system/window.h> - -#include "GrallocMapper.h" -#include "GrallocBufferDescriptor.h" -#include "mali_gralloc_bufferallocation.h" -#include "mali_gralloc_bufferdescriptor.h" -#include "mali_gralloc_bufferaccess.h" -#include "mali_gralloc_reference.h" -#include "mali_gralloc_ion.h" -#include "mali_gralloc_buffer.h" - -namespace android { -namespace hardware { -namespace graphics { -namespace mapper { -namespace HIDL_IMAPPER_NAMESPACE { -namespace implementation { - -/* Default definitions for IMapper 2.x interface */ -using V2_0::Error; -using V2_0::BufferDescriptor; - -namespace { - -/* An unordered set to internally store / retrieve imported buffer handles */ -class RegisteredHandlePool -{ -public: - /* Stores the buffer handle in the internal list */ - bool add(buffer_handle_t bufferHandle) - { - std::lock_guard<std::mutex> lock(mutex); - return bufPool.insert(bufferHandle).second; - } - - /* Retrieves and removes the buffer handle from internal list */ - native_handle_t* remove(void* buffer) - { - auto bufferHandle = static_cast<native_handle_t*>(buffer); - - std::lock_guard<std::mutex> lock(mutex); - return bufPool.erase(bufferHandle) == 1 ? bufferHandle : nullptr; - } - - /* Retrieves the buffer handle from internal list */ - buffer_handle_t get(const void* buffer) - { - auto bufferHandle = static_cast<buffer_handle_t>(buffer); - - std::lock_guard<std::mutex> lock(mutex); - return bufPool.count(bufferHandle) == 1 ? bufferHandle : nullptr; - } - -private: - std::mutex mutex; - std::unordered_set<buffer_handle_t> bufPool; -}; - -/* GraphicBufferMapper is expected to be valid (and leaked) during process - * termination. IMapper, and in turn, gRegisteredHandles must be valid as - * well. Create the registered handle pool on the heap, and let - * it leak for simplicity. - * - * However, there is no way to make sure gralloc0/gralloc1 are valid. Any use - * of static/global object in gralloc0/gralloc1 that may have been destructed - * is potentially broken. - */ -RegisteredHandlePool* gRegisteredHandles = new RegisteredHandlePool; - -} /* anonymous namespace */ - -/** - * IMapper constructor. All the state information required for the Gralloc - * private module is populated in its default constructor. Gralloc 2.0 specific - * state information can be populated here. - * - * @return None - */ -GrallocMapper::GrallocMapper() -{ -} - -/* - * IMapper destructor. All the resources aquired for Gralloc private module - * (in the IMapper context) are released - * - * @return None - */ -GrallocMapper::~GrallocMapper() -{ - mali_gralloc_ion_close(); -} - -/* - * Validates incoming IMapper descriptor attributes - * - * @param descriptor_attr [in] Specifies the attributes of the descriptor. - * - * @return false, for invalid buffer attributes - * true, otherwise - * Note: Latest IMapper version encapsulates all previous versions, hence all - * incoming descriptor information is mapped to the latest IMapper for validation - */ -bool GrallocMapper::validateDescriptorInfo(void *descriptor_attr) const -{ - BufferDescriptorInfo * const descriptorInfo = (BufferDescriptorInfo *)descriptor_attr; - - using android::hardware::graphics::common::HIDL_COMMON_NAMESPACE::BufferUsage; - using android::hardware::graphics::common::HIDL_COMMON_NAMESPACE::PixelFormat; - - const uint64_t validUsageBits = -#if HIDL_MAPPER_VERSION_SCALED >= 210 - BufferUsage::GPU_CUBE_MAP | - BufferUsage::GPU_MIPMAP_COMPLETE | -#endif - BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | - BufferUsage::GPU_TEXTURE | BufferUsage::GPU_RENDER_TARGET | - BufferUsage::COMPOSER_OVERLAY | BufferUsage::COMPOSER_CLIENT_TARGET | - BufferUsage::CAMERA_INPUT | BufferUsage::CAMERA_OUTPUT | - BufferUsage::PROTECTED | - BufferUsage::COMPOSER_CURSOR | - BufferUsage::VIDEO_ENCODER | - BufferUsage::RENDERSCRIPT | - BufferUsage::VIDEO_DECODER | - BufferUsage::SENSOR_DIRECT_DATA | - BufferUsage::GPU_DATA_BUFFER | - BufferUsage::VENDOR_MASK; - - if (!descriptorInfo->width || !descriptorInfo->height || - !descriptorInfo->layerCount) - { - AERR("Invalid buffer descriptor (2.x mapper) attributes, width = %d height = %d layerCount = %d ", - descriptorInfo->width, descriptorInfo->height, descriptorInfo->layerCount); - return false; - } - - if (descriptorInfo->format == static_cast<PixelFormat>(0)) - { - return false; - } - - if (descriptorInfo->usage & ~validUsageBits) - { - /* It is possible that application uses private usage bits. */ - ALOGW("Buffer descriptor with invalid usage bits 0x%" PRIx64, - descriptorInfo->usage & ~validUsageBits); - } - - return true; -} - -/* - * Creates a buffer descriptor from incoming descriptor attributes - * - * @param descriptorInfo [in] Specifies the (2.0 IMapper) attributes of - * the descriptor. - * @param hidl_cb [in] HIDL callback function generating - - * error: NONE upon success. Otherwise, - * BAD_VALUE when any of the specified attributes are invalid - * descriptor: Newly created buffer descriptor. - * - * @return Void - */ -Return<void> GrallocMapper::createDescriptor( - const V2_0::IMapper::BufferDescriptorInfo& descriptorInfo, - createDescriptor_cb hidl_cb) -{ - if (validateDescriptorInfo((void *)&descriptorInfo)) - { - hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo)); - } - else - { - AERR("Invalid attributes to create descriptor for Mapper 2.0"); - hidl_cb(Error::BAD_VALUE, BufferDescriptor()); - } - - return Void(); -} - -/* - * Imports a raw buffer handle to create an imported buffer handle for use with - * the rest of the mapper or with other in-process libraries. - * - * @param rawHandle [in] Raw buffer handle to import. - * @param hidl_cb [in] HIDL Callback function to export output information - * @param hidl_cb [in] HIDL callback function generating - - * error : NONE upon success. Otherwise, - * BAD_BUFFER for an invalid buffer - * NO_RESOURCES when the raw handle cannot be imported - * BAD_VALUE when any of the specified attributes are invalid - * buffer : Imported buffer handle - * - * @return Void - */ -Return<void> GrallocMapper::importBuffer(const hidl_handle& rawHandle, - importBuffer_cb hidl_cb) -{ - if (!rawHandle.getNativeHandle()) - { - AERR("Invalid buffer handle to import"); - hidl_cb(Error::BAD_BUFFER, nullptr); - return Void(); - } - - native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle()); - if (!bufferHandle) - { - AERR("Failed to clone buffer handle"); - hidl_cb(Error::NO_RESOURCES, nullptr); - return Void(); - } - - const Error error = registerBuffer(bufferHandle); - if (error != Error::NONE) - { - native_handle_close(bufferHandle); - native_handle_delete(bufferHandle); - - hidl_cb(error, nullptr); - return Void(); - } - - if (gRegisteredHandles->add(bufferHandle) == false) - { - /* The newly cloned handle is already registered. This can only happen - * when a handle previously registered was native_handle_delete'd instead - * of freeBuffer'd. - */ - AERR("Handle %p has already been imported; potential fd leaking", - bufferHandle); - unregisterBuffer(bufferHandle); - native_handle_close(bufferHandle); - native_handle_delete(bufferHandle); - - hidl_cb(Error::NO_RESOURCES, nullptr); - return Void(); - } - - hidl_cb(Error::NONE, bufferHandle); - return Void(); -} - -/* - * Frees a buffer handle and releases all the resources associated with it - * - * @param buffer [in] Imported buffer to free - * - * @return Error::BAD_BUFFER for an invalid buffer / when failed to free the buffer - * Error::NONE on successful free - */ -Return<Error> GrallocMapper::freeBuffer(void* buffer) -{ - native_handle_t * const bufferHandle = gRegisteredHandles->remove(buffer); - if (!bufferHandle) - { - AERR("Invalid buffer handle %p to freeBuffer", buffer); - return Error::BAD_BUFFER; - } - - const Error status = unregisterBuffer(bufferHandle); - if (status != Error::NONE) - { - return status; - } - - native_handle_close(bufferHandle); - native_handle_delete(bufferHandle); - - return Error::NONE; -} - -/* - * Retrieves the file descriptor referring to a sync fence object - * - * @param fenceHandle [in] HIDL fence handle - * @param outFenceFd [out] Fence file descriptor. '-1' indicates no fence - * - * @return false, for an invalid HIDL fence handle - * true, otherwise - */ -bool GrallocMapper::getFenceFd(const hidl_handle& fenceHandle, - int* outFenceFd) const -{ - auto const handle = fenceHandle.getNativeHandle(); - if (handle && handle->numFds > 1) - { - AERR("Invalid fence handle with %d fds", handle->numFds); - return false; - } - - *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1; - return true; -} - -/* - * Populates the HIDL fence handle for the given fence object - * - * @param fenceFd [in] Fence file descriptor - * @param handleStorage [in] HIDL handle storage for fence - * - * @return HIDL fence handle - */ -hidl_handle GrallocMapper::getFenceHandle(int fenceFd, char* handleStorage) const -{ - native_handle_t* handle = nullptr; - if (fenceFd >= 0) - { - handle = native_handle_init(handleStorage, 1, 0); - handle->data[0] = fenceFd; - } - - return hidl_handle(handle); -} - -/* - * Locks the given buffer for the specified CPU usage. - * - * @param buffer [in] Buffer to lock - * @param cpuUsage [in] Specifies one or more CPU usage flags to request - * @param accessRegion [in] Portion of the buffer that the client intends to access - * @param acquireFence [in] Handle for aquire fence object - * @param hidl_cb [in] HIDL callback function generating - - * error: NONE upon success. Otherwise, - * BAD_BUFFER for an invalid buffer - * BAD_VALUE for an invalid input parameters - * data: CPU-accessible pointer to the buffer data - * - * @return Void - */ -Return<void> GrallocMapper::lock(void* buffer, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, - const hidl_handle& acquireFence, - lock_cb hidl_cb) -{ - buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); - if (!bufferHandle) - { - AERR("Buffer to lock: %p has not been registered with Gralloc", buffer); - hidl_cb(Error::BAD_BUFFER, nullptr); - return Void(); - } - - int fenceFd; - if (!getFenceFd(acquireFence, &fenceFd)) - { - hidl_cb(Error::BAD_VALUE, nullptr); - return Void(); - } - - void* data = nullptr; - const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data); - hidl_cb(error, data); - return Void(); -} - -/* - * Locks the given buffer for the specified CPU usage and exports cpu accessible - * data in YCbCr structure. - * - * @param buffer [in] Buffer to lock. - * @param cpuUsage [in] Specifies one or more CPU usage flags to request - * @param accessRegion [in] Portion of the buffer that the client intends to access. - * @param acquireFence [in] Handle for aquire fence object - * @param hidl_cb [in] HIDL callback function generating - - * error: NONE upon success. Otherwise, - * BAD_BUFFER for an invalid buffer - * BAD_VALUE for an invalid input parameters - * layout: Data layout of the buffer - * - * @return Void - */ -Return<void> GrallocMapper::lockYCbCr(void* buffer, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, - const hidl_handle& acquireFence, - lockYCbCr_cb hidl_cb) -{ - YCbCrLayout layout = {}; - - buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); - if (!bufferHandle) - { - AERR("Buffer to lock(YCbCr): %p has not been registered with Gralloc", buffer); - hidl_cb(Error::BAD_BUFFER, layout); - return Void(); - } - - int fenceFd; - if (!getFenceFd(acquireFence, &fenceFd)) - { - hidl_cb(Error::BAD_VALUE, layout); - return Void(); - } - - const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &layout); - hidl_cb(error, layout); - return Void(); -} - -/* - * Unlocks a buffer to indicate all CPU accesses to the buffer have completed - * - * @param buffer [in] Buffer to lock. - * @param hidl_cb [in] HIDL callback function generating - - * error: NONE upon success. Otherwise, - * BAD_BUFFER for an invalid buffer - * releaseFence: Referrs to a sync fence object - * - * @return Void - */ -Return<void> GrallocMapper::unlock(void* buffer, unlock_cb hidl_cb) -{ - buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); - if (!bufferHandle) - { - AERR("Buffer to unlock: %p has not been registered with Gralloc", buffer); - hidl_cb(Error::BAD_BUFFER, nullptr); - return Void(); - } - - int fenceFd; - const Error error = unlockBuffer(bufferHandle, &fenceFd); - if (error == Error::NONE) - { - NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0); - hidl_cb(error, getFenceHandle(fenceFd, fenceStorage)); - - if (fenceFd >= 0) - { - close(fenceFd); - } - } - else - { - hidl_cb(error, nullptr); - } - - return Void(); -} - -/* - * Translates the register buffer API into existing gralloc implementation - * - * @param bufferHandle [in] Private handle for the buffer to be imported - * - * @return Error::BAD_BUFFER for an invalid buffer - * Error::NO_RESOURCES when unable to import the given buffer - * Error::NONE on successful import - */ -Error GrallocMapper::registerBuffer(buffer_handle_t bufferHandle) const -{ - if (private_handle_t::validate(bufferHandle) < 0) - { - AERR("Buffer: %p is corrupted", bufferHandle); - return Error::BAD_BUFFER; - } - - if (mali_gralloc_reference_retain(&privateModule, bufferHandle) < 0) - { - return Error::NO_RESOURCES; - } - - return Error::NONE; -} - -/* - * Translates the unregister buffer API into existing gralloc implementation - * - * @param bufferHandle [in] Private handle for the buffer to be released - * - * @return Error::BAD_BUFFER for an invalid buffer / buffers which can't be released - * Error::NONE on successful release of the buffer - */ -Error GrallocMapper::unregisterBuffer(buffer_handle_t bufferHandle) const -{ - if (private_handle_t::validate(bufferHandle) < 0) - { - AERR("Buffer: %p is corrupted", bufferHandle); - return Error::BAD_BUFFER; - } - - const int status = mali_gralloc_reference_release(&privateModule, bufferHandle, true); - if (status != 0) - { - AERR("Unable to release buffer:%p", bufferHandle); - return Error::BAD_BUFFER; - } - - return Error::NONE; -} - -/* - * Locks the given buffer for the specified CPU usage. - * - * @param bufferHandle [in] Buffer to lock. - * @param cpuUsage [in] Specifies one or more CPU usage flags to request - * @param accessRegion [in] Portion of the buffer that the client intends to access. - * @param fenceFd [in] Fence file descriptor - * @param outData [out] CPU accessible buffer address - * - * @return Error::BAD_BUFFER for an invalid buffer - * Error::NO_RESOURCES when unable to duplicate fence - * Error::BAD_VALUE when locking fails - * Error::NONE on successful buffer lock - */ -Error GrallocMapper::lockBuffer(buffer_handle_t bufferHandle, - uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - void** outData) const -{ - /* dup fenceFd as it is going to be owned by gralloc. Note that it is - * gralloc's responsibility to close it, even on locking errors. - */ - if (fenceFd >= 0) - { - fenceFd = dup(fenceFd); - if (fenceFd < 0) - { - AERR("Error encountered while duplicating fence file descriptor"); - return Error::NO_RESOURCES; - } - } - - if (private_handle_t::validate(bufferHandle) < 0) - { - AERR("Buffer: %p is corrupted", bufferHandle); - return Error::BAD_BUFFER; - } - - void* data = nullptr; - if (mali_gralloc_lock_async(&privateModule, bufferHandle, cpuUsage, - accessRegion.left, accessRegion.top, - accessRegion.width, accessRegion.height, - &data, fenceFd) < 0) - { - return Error::BAD_VALUE; - } - - *outData = data; - return Error::NONE; -} - -/* - * Locks the given buffer for the specified CPU usage and exports cpu accessible - * data in YCbCr structure. - * - * @param bufferHandle [in] Buffer to lock. - * @param cpuUsage [in] Specifies one or more CPU usage flags to request - * @param accessRegion [in] Portion of the buffer that the client intends to access. - * @param fenceFd [in] Fence file descriptor - * @param outLayout [out] Describes CPU accessible information in YCbCr format - * - * @return Error::BAD_BUFFER for an invalid buffer - * Error::NO_RESOURCES when unable to duplicate fence - * Error::BAD_VALUE when locking fails - * Error::NONE on successful buffer lock - */ -Error GrallocMapper::lockBuffer(buffer_handle_t bufferHandle, - uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - YCbCrLayout* outLayout) const -{ - int result; - android_ycbcr ycbcr = {}; - - if (private_handle_t::validate(bufferHandle) < 0) - { - AERR("Buffer: %p is corrupted", bufferHandle); - return Error::BAD_BUFFER; - } - - if (fenceFd >= 0) - { - fenceFd = dup(fenceFd); - if (fenceFd < 0) - { - AERR("Error encountered while duplicating fence file descriptor"); - return Error::NO_RESOURCES; - } - } - - result = mali_gralloc_lock_ycbcr_async(&privateModule, bufferHandle, cpuUsage, - accessRegion.left, accessRegion.top, - accessRegion.width, accessRegion.height, - &ycbcr, fenceFd); - if (result) - { - AERR("Locking(YCbCr) failed with error: %d", result); - return Error::BAD_VALUE; - } - - outLayout->y = ycbcr.y; - outLayout->cb = ycbcr.cb; - outLayout->cr = ycbcr.cr; - outLayout->yStride = ycbcr.ystride; - outLayout->cStride = ycbcr.cstride; - outLayout->chromaStep = ycbcr.chroma_step; - - return Error::NONE; -} - -/* - * Unlocks a buffer to indicate all CPU accesses to the buffer have completed - * - * @param bufferHandle [in] Buffer to lock. - * @param outFenceFd [out] Fence file descriptor - * - * @return Error::BAD_BUFFER for an invalid buffer - * Error::BAD_VALUE when unlocking failed - * Error::NONE on successful buffer unlock - */ -Error GrallocMapper::unlockBuffer(buffer_handle_t bufferHandle, - int* outFenceFd) const -{ - if (private_handle_t::validate(bufferHandle) < 0) - { - AERR("Buffer: %p is corrupted", bufferHandle); - return Error::BAD_BUFFER; - } - - int fenceFd = -1; - const int result = mali_gralloc_unlock_async(&privateModule, bufferHandle, &fenceFd); - if (result) - { - AERR("Unlocking failed with error: %d", result); - return Error::BAD_VALUE; - } - - *outFenceFd = fenceFd; - - return Error::NONE; -} - -#if HIDL_MAPPER_VERSION_SCALED >= 210 - -/* - * Validates the buffer against specified descriptor attributes - * - * @param buffer [in] Buffer which needs to be validated. - * @param descriptorInfo [in] Required attributes of the buffer - * @param in_stride [in] Buffer stride returned by IAllocator::allocate - * - * @return Error::NONE upon success. Otherwise, - * Error::BAD_BUFFER upon bad buffer input - * Error::BAD_VALUE when any of the specified attributes are invalid - */ -Return<Error> GrallocMapper::validateBufferSize(void* buffer, - const V2_1::IMapper::BufferDescriptorInfo& descriptorInfo, - uint32_t in_stride) -{ - /* The buffer must have been allocated by Gralloc */ - buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); - if (!bufferHandle) - { - AERR("Buffer: %p has not been registered with Gralloc", buffer); - return Error::BAD_BUFFER; - } - - if (private_handle_t::validate(bufferHandle) < 0) - { - AERR("Buffer: %p is corrupted", bufferHandle); - return Error::BAD_BUFFER; - } - - /* All Gralloc allocated buffers must be conform to local descriptor validation */ - if (!validateDescriptorInfo((void *)&descriptorInfo)) - { - AERR("Invalid descriptor attributes for validating buffer size"); - return Error::BAD_VALUE; - } - - buffer_descriptor_t grallocDescriptor; - grallocDescriptor.width = descriptorInfo.width; - grallocDescriptor.height = descriptorInfo.height; - grallocDescriptor.layer_count = descriptorInfo.layerCount; - grallocDescriptor.hal_format = static_cast<uint64_t>(descriptorInfo.format); - grallocDescriptor.producer_usage = static_cast<uint64_t>(descriptorInfo.usage); - grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage; - grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; - - /* Derive the buffer size for the given descriptor */ - const int result = mali_gralloc_derive_format_and_size(&privateModule, - &grallocDescriptor); - if (result) - { - AERR("Unable to derive format and size for the given descriptor information. error: %d", result); - return Error::BAD_VALUE; - } - - /* Validate the buffer parameters against descriptor info */ - private_handle_t *gralloc_buffer = (private_handle_t *)bufferHandle; - - /* The buffer size must be greater than (or equal to) what would have been allocated with descriptor */ - if ((size_t)gralloc_buffer->size < grallocDescriptor.size) - { - ALOGW("Buf size mismatch. Buffer size = %u, Descriptor (derived) size = %zu", - gralloc_buffer->size, grallocDescriptor.size); - return Error::BAD_VALUE; - } - - if ((uint32_t)gralloc_buffer->stride != in_stride) - { - AERR("Stride mismatch. Expected stride = %d, Buffer stride = %d", - in_stride, gralloc_buffer->stride); - return Error::BAD_VALUE; - } - - if (gralloc_buffer->internal_format != grallocDescriptor.internal_format) - { - AERR("Buffer format :0x%" PRIx64" does not match descriptor (derived) format :0x%" - PRIx64, gralloc_buffer->internal_format, grallocDescriptor.internal_format); - return Error::BAD_VALUE; - } - - if ((uint32_t)gralloc_buffer->width != grallocDescriptor.width) - { - AERR("Width mismatch. Buffer width = %u, Descriptor width = %u", - gralloc_buffer->width, grallocDescriptor.width); - return Error::BAD_VALUE; - } - - if ((uint32_t)gralloc_buffer->height != grallocDescriptor.height) - { - AERR("Height mismatch. Buffer height = %u, Descriptor height = %u", - gralloc_buffer->height, grallocDescriptor.height); - return Error::BAD_VALUE; - } - - if (gralloc_buffer->layer_count != grallocDescriptor.layer_count) - { - AERR("Layer Count mismatch. Buffer layer_count = %u, Descriptor layer_count width = %u", - gralloc_buffer->layer_count, grallocDescriptor.layer_count); - return Error::BAD_VALUE; - } - - return Error::NONE; -} - -/* - * Get the transport size of a buffer - * - * @param buffer [in] Buffer for computing transport size - * @param hidl_cb [in] HIDL callback function generating - - * error: NONE upon success. Otherwise, - * BAD_BUFFER for an invalid buffer - * numFds: Number of file descriptors needed for transport - * numInts: Number of integers needed for transport - * - * @return Void - */ -Return<void> GrallocMapper::getTransportSize(void* buffer, getTransportSize_cb hidl_cb) -{ - /* The buffer must have been allocated by Gralloc */ - buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer); - if (!bufferHandle) - { - AERR("Buffer %p is not registered with Gralloc", bufferHandle); - hidl_cb(Error::BAD_BUFFER, -1, -1); - return Void(); - } - - if (private_handle_t::validate(bufferHandle) < 0) - { - AERR("Buffer %p is corrupted", buffer); - hidl_cb(Error::BAD_BUFFER, -1, -1); - return Void(); - } - - hidl_cb(Error::NONE, GRALLOC_ARM_NUM_FDS, NUM_INTS_IN_PRIVATE_HANDLE); - - return Void(); -} - -/* - * Creates a buffer descriptor from incoming descriptor attributes - * - * @param descriptorInfo [in] Specifies the (2.1 IMapper) attributes of - * the descriptor. - * @param hidl_cb [in] HIDL callback function generating - - * error: NONE upon success. Otherwise, - * BAD_VALUE when any of the specified attributes are invalid - * descriptor: Newly created buffer descriptor. - * - * @return Void - */ -Return<void> GrallocMapper::createDescriptor_2_1(const V2_1::IMapper::BufferDescriptorInfo& descriptorInfo, - createDescriptor_2_1_cb hidl_cb) -{ - if (validateDescriptorInfo((void *)&descriptorInfo)) - { - hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo)); - } - else - { - AERR("Invalid (IMapper 2.1) attributes to create descriptor"); - hidl_cb(Error::BAD_VALUE, V2_0::BufferDescriptor()); - } - - return Void(); -} -#endif /* HIDL_MAPPER_VERSION_SCALED >= 210 */ - -IMapper* HIDL_FETCH_IMapper(const char* /* name */) -{ - ALOGV("Arm Module IMapper %d.%d , pid = %d ppid = %d ", GRALLOC_VERSION_MAJOR, - (HIDL_MAPPER_VERSION_SCALED - (GRALLOC_VERSION_MAJOR * 100)) / 10, getpid(), getppid()); - - return new GrallocMapper(); -} - -} // namespace implementation -} // namespace HIDL_IMAPPER_NAMESPACE -} // namespace mapper -} // namespace graphics -} // namespace hardware -} // namespace android diff --git a/gralloc3/src/GrallocMapper.h b/gralloc3/src/GrallocMapper.h deleted file mode 100644 index a159558..0000000 --- a/gralloc3/src/GrallocMapper.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2018 ARM Limited. All rights reserved. - * - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_x_GRALLOC_MAPPER_H -#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_x_GRALLOC_MAPPER_H - -#if HIDL_MAPPER_VERSION_SCALED == 200 -#include <android/hardware/graphics/mapper/2.0/IMapper.h> -#elif HIDL_MAPPER_VERSION_SCALED == 210 -#include <android/hardware/graphics/mapper/2.1/IMapper.h> -#endif - -#include "mali_gralloc_module.h" - -namespace android { -namespace hardware { -namespace graphics { -namespace mapper { -namespace HIDL_IMAPPER_NAMESPACE { -namespace implementation { - -using V2_0::Error; -using V2_0::BufferDescriptor; -using V2_0::YCbCrLayout; - -class GrallocMapper : public IMapper -{ -public: - GrallocMapper(); - ~GrallocMapper(); - - /* Override the public IMapper 2.0 interface */ - - /* Creates a buffer descriptor */ - Return<void> createDescriptor(const V2_0::IMapper::BufferDescriptorInfo& descriptorInfo, - createDescriptor_cb hidl_cb) override; - - /* Imports a raw buffer handle to create an imported buffer handle */ - Return<void> importBuffer(const hidl_handle& rawHandle, - importBuffer_cb hidl_cb) override; - - /* Frees a buffer handle */ - Return<Error> freeBuffer(void* buffer) override; - - /* Locks the given buffer for the specified CPU usage */ - Return<void> lock(void* buffer, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, - const hidl_handle& acquireFence, - lock_cb hidl_cb) override; - - /* - * Locks the given buffer for the specified CPU usage and exports CPU - * accessible data in YCbCr structure - */ - Return<void> lockYCbCr(void* buffer, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, - const hidl_handle& acquireFence, - lockYCbCr_cb hidl_cb) override; - - /* Unlocks a buffer to indicate all CPU accesses to the buffer have completed */ - Return<void> unlock(void* buffer, unlock_cb hidl_cb) override; - -#if HIDL_MAPPER_VERSION_SCALED >= 210 - /* Override the public IMapper 2.1 specific interface */ - - /* Validates the buffer against specified descriptor attributes */ - Return<Error> validateBufferSize(void* buffer, - const V2_1::IMapper::BufferDescriptorInfo& descriptorInfo, - uint32_t stride) override; - - /* Get the transport size of a buffer */ - Return<void> getTransportSize(void* buffer, getTransportSize_cb _hidl_cb) override; - - /* Creates a descriptor using IMapper 2.1 version of descriptor attributes */ - Return<void> createDescriptor_2_1(const V2_1::IMapper::BufferDescriptorInfo& descriptorInfo, - createDescriptor_2_1_cb _hidl_cb) override; -#endif - -private: - /* Validates incoming IMapper descriptor attributes */ - bool validateDescriptorInfo(void *descriptor_attr) const; - - /* Register a buffer. The handle is already cloned by the caller */ - Error registerBuffer(buffer_handle_t bufferHandle) const; - - /* Unmap a buffer. The handle is already cloned by the caller */ - Error unregisterBuffer(buffer_handle_t bufferHandle) const; - - /* Lock a buffer. The fence is owned by the caller */ - Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - void** outData) const; - - /* Lock a buffer, with YCbCr data exported. The fence is owned by the caller */ - Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage, - const IMapper::Rect& accessRegion, int fenceFd, - YCbCrLayout* outLayout) const; - - /* Unlock a buffer. The returned fence is owned by the caller */ - Error unlockBuffer(buffer_handle_t bufferHandle, - int* outFenceFd) const; - - /* Retrieves the file descriptor referring to a sync fence object */ - bool getFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) const; - - /* Populates the HIDL fence handle for the given fence object */ - hidl_handle getFenceHandle(int fenceFd, char* handleStorage) const; - - /* To hold state information for the instance of mapper */ - struct private_module_t privateModule; -}; - -extern "C" IMapper* HIDL_FETCH_IMapper(const char* name); - -} // namespace implementation -} // namespace HIDL_IMAPPER_NAMESPACE -} // namespace mapper -} // namespace graphics -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_x_GRALLOC_MAPPER_H diff --git a/gralloc3/src/GrallocWrapper.cpp b/gralloc3/src/GrallocWrapper.cpp deleted file mode 100644 index 23b250a..0000000 --- a/gralloc3/src/GrallocWrapper.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "GrallocWrapper" - - -#include <log/log.h> -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wzero-length-array" -#include <sync/sync.h> -#pragma clang diagnostic pop - -#include "GrallocWrapper.h" - -namespace android { - -namespace GrallocWrapper { - -static constexpr Error kTransactionError = Error::NO_RESOURCES; - -Mapper::Mapper() -{ - mMapper = IMapper::getService(); - if (mMapper == nullptr || mMapper->isRemote()) { - LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode"); - } -} - -Error Mapper::createDescriptor( - const IMapper::BufferDescriptorInfo& descriptorInfo, - BufferDescriptor* outDescriptor) const -{ - Error error; - auto ret = mMapper->createDescriptor(descriptorInfo, - [&](const auto& tmpError, const auto& tmpDescriptor) - { - error = tmpError; - if (error != Error::NONE) { - return; - } - - *outDescriptor = tmpDescriptor; - }); - - return (ret.isOk()) ? error : kTransactionError; -} - -Error Mapper::importBuffer(const hardware::hidl_handle& rawHandle, - buffer_handle_t* outBufferHandle) const -{ - Error error; - auto ret = mMapper->importBuffer(rawHandle, - [&](const auto& tmpError, const auto& tmpBuffer) - { - error = tmpError; - if (error != Error::NONE) { - return; - } - - *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer); - }); - - return (ret.isOk()) ? error : kTransactionError; -} - -void Mapper::freeBuffer(buffer_handle_t bufferHandle) const -{ - auto buffer = const_cast<native_handle_t*>(bufferHandle); - auto ret = mMapper->freeBuffer(buffer); - - auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError; - ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", - buffer, error); -} - -Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, - const IMapper::Rect& accessRegion, - int acquireFence, void** outData) const -{ - auto buffer = const_cast<native_handle_t*>(bufferHandle); - - // put acquireFence in a hidl_handle - hardware::hidl_handle acquireFenceHandle; - NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); - if (acquireFence >= 0) { - auto h = native_handle_init(acquireFenceStorage, 1, 0); - h->data[0] = acquireFence; - acquireFenceHandle = h; - } - - Error error; - auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle, - [&](const auto& tmpError, const auto& tmpData) - { - error = tmpError; - if (error != Error::NONE) { - return; - } - - *outData = tmpData; - }); - - // we own acquireFence even on errors - if (acquireFence >= 0) { - close(acquireFence); - } - - return (ret.isOk()) ? error : kTransactionError; -} - -Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, - const IMapper::Rect& accessRegion, - int acquireFence, YCbCrLayout* outLayout) const -{ - auto buffer = const_cast<native_handle_t*>(bufferHandle); - - // put acquireFence in a hidl_handle - hardware::hidl_handle acquireFenceHandle; - NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); - if (acquireFence >= 0) { - auto h = native_handle_init(acquireFenceStorage, 1, 0); - h->data[0] = acquireFence; - acquireFenceHandle = h; - } - - Error error; - auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion, - acquireFenceHandle, - [&](const auto& tmpError, const auto& tmpLayout) - { - error = tmpError; - if (error != Error::NONE) { - return; - } - - *outLayout = tmpLayout; - }); - - // we own acquireFence even on errors - if (acquireFence >= 0) { - close(acquireFence); - } - - return (ret.isOk()) ? error : kTransactionError; -} - -int Mapper::unlock(buffer_handle_t bufferHandle) const -{ - auto buffer = const_cast<native_handle_t*>(bufferHandle); - - int releaseFence = -1; - Error error; - auto ret = mMapper->unlock(buffer, - [&](const auto& tmpError, const auto& tmpReleaseFence) - { - error = tmpError; - if (error != Error::NONE) { - return; - } - - auto fenceHandle = tmpReleaseFence.getNativeHandle(); - if (fenceHandle && fenceHandle->numFds == 1) { - int fd = dup(fenceHandle->data[0]); - if (fd >= 0) { - releaseFence = fd; - } else { - ALOGD("failed to dup unlock release fence"); - sync_wait(fenceHandle->data[0], -1); - } - } - }); - - if (!ret.isOk()) { - error = kTransactionError; - } - - if (error != Error::NONE) { - ALOGE("unlock(%p) failed with %d", buffer, error); - } - - return releaseFence; -} - -Allocator::Allocator(const Mapper& mapper) - : mMapper(mapper) -{ - mAllocator = IAllocator::getService(); - if (mAllocator == nullptr) { - LOG_ALWAYS_FATAL("gralloc-alloc is missing"); - } -} - -std::string Allocator::dumpDebugInfo() const -{ - std::string debugInfo; - - mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { - debugInfo = tmpDebugInfo.c_str(); - }); - - return debugInfo; -} - -Error Allocator::allocate(BufferDescriptor descriptor, uint32_t count, - uint32_t* outStride, buffer_handle_t* outBufferHandles) const -{ - Error error; - auto ret = mAllocator->allocate(descriptor, count, - [&](const auto& tmpError, const auto& tmpStride, - const auto& tmpBuffers) { - error = tmpError; - if (tmpError != Error::NONE) { - return; - } - - // import buffers - for (uint32_t i = 0; i < count; i++) { - error = mMapper.importBuffer(tmpBuffers[i], - &outBufferHandles[i]); - if (error != Error::NONE) { - for (uint32_t j = 0; j < i; j++) { - mMapper.freeBuffer(outBufferHandles[j]); - outBufferHandles[j] = nullptr; - } - return; - } - } - - *outStride = tmpStride; - }); - - return (ret.isOk()) ? error : kTransactionError; -} - -} // namespace GrallocWrapper - -} // namespace android diff --git a/gralloc3/src/format_info.cpp b/gralloc3/src/format_info.cpp deleted file mode 100644 index d5ea945..0000000 --- a/gralloc3/src/format_info.cpp +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Copyright (C) 2018-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <inttypes.h> -#include "gralloc_helper.h" -#include "mali_gralloc_formats.h" -#include "format_info.h" - -#include <unordered_map> -#include <mutex> - -/* Default width aligned to whole pixel (CPU access). */ -#define ALIGN_W_CPU_DEFAULT .align_w_cpu = 1 - -/* - * Format table, containing format properties. - * - * NOTE: This table should only be used within - * the gralloc library and not by clients directly. - */ -const format_info_t formats[] = { - - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGB_565, .npln = 1, .ncmp = 3, .bps = 6, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_RGB_565" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGB_888, .npln = 1, .ncmp = 3, .bps = 8, .bpp_afbc = { 24, 0, 0 }, .bpp = { 24, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_RGB_888" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888, .npln = 1, .ncmp = 4, .bps = 8, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = true, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888, .npln = 1, .ncmp = 4, .bps = 8, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = true, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888, .npln = 1, .ncmp = 3, .bps = 8, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = true, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888" }, -#if PLATFORM_SDK_VERSION >= 26 - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102, .npln = 1, .ncmp = 4, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = true, .is_rgb = true, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = true, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616, .npln = 1, .ncmp = 4, .bps = 16, .bpp_afbc = { 0, 0, 0 }, .bpp = { 64, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = true, .is_rgb = true, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616" }, -#endif /* PLATFORM_SDK_VERSION >= 26 */ - - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y8, .npln = 1, .ncmp = 1, .bps = 8, .bpp_afbc = { 8, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_Y8" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y16, .npln = 1, .ncmp = 1, .bps = 16, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 1, .vsub = 1, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_Y16" }, - - /* 420 (8-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I, .npln = 1, .ncmp = 3, .bps = 8, .bpp_afbc = { 12, 0, 0 }, .bpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = false, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV12, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 8, 16, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_NV12" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV21, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 8, 16, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_NV21" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YV12, .npln = 3, .ncmp = 3, .bps = 8, .bpp_afbc = { 8, 8, 8 }, .bpp = { 8, 8, 8 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_YV12" }, - - /* 422 (8-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT, .npln = 1, .ncmp = 3, .bps = 8, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 2, .vsub = 1, .align_w = 2, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV16, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 8, 16, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 1, .align_w = 2, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_NV16" }, - - /* 420 (10-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I, .npln = 1, .ncmp = 3, .bps = 10, .bpp_afbc = { 15, 0, 0 }, .bpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = false, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y0L2, .npln = 1, .ncmp = 4, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 2, .has_alpha = true, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_Y0L2" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_P010, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 10, 20, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_P010" }, - - /* 422 (10-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y210, .npln = 1, .ncmp = 3, .bps = 10, .bpp_afbc = { 20, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 2, .vsub = 1, .align_w = 2, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_Y210" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_P210, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 10, 20, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 1, .align_w = 2, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_P210" }, - - /* 444 (10-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV444_10BIT_I, .npln = 1, .ncmp = 3, .bps = 10, .bpp_afbc = { 30, 0, 0 }, .bpp = { 0, 0, 0 }, .hsub = 1, .vsub = 1, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = true, .linear = false, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_YUV444_10BIT_I" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y410, .npln = 1, .ncmp = 4, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 1, .vsub = 1, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = true, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_Y410" }, - - /* Other */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW16, .npln = 1, .ncmp = 1, .bps = 16, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_RAW16" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW12, .npln = 1, .ncmp = 1, .bps = 12, .bpp_afbc = { 0, 0, 0 }, .bpp = { 12, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 4, .align_h = 2, .align_w_cpu = 4, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_RAW12" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW10, .npln = 1, .ncmp = 1, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 10, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 4, .align_h = 2, .align_w_cpu = 4, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_RAW10" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_BLOB, .npln = 1, .ncmp = 1, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_BLOB" }, - -#if PLATFORM_SDK_VERSION >= 28 - /* Depth and Stencil */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_16, .npln = 1, .ncmp = 1, .bps = 16, .bpp_afbc = { 0, 0, 0}, .bpp = { 16, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_16" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24, .npln = 1, .ncmp = 1, .bps = 24, .bpp_afbc = { 0, 0, 0 }, .bpp = { 24, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24_STENCIL_8, .npln = 1, .ncmp = 2, .bps = 24, .bpp_afbc = { 0, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24_STENCIL_8" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F, .npln = 1, .ncmp = 1, .bps = 32, .bpp_afbc = { 0, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F_STENCIL_8, .npln = 1, .ncmp = 2, .bps = 32, .bpp_afbc = { 0, 0, 0 }, .bpp = { 40, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F_STENCIL_8" }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_STENCIL_8, .npln = 1, .ncmp = 1, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 1, .align_h = 1, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = false, .afbc = false, .linear = true, .yuv_transform = false, .flex = false, .planes_contiguous = false, .name = "MALI_GRALLOC_FORMAT_INTERNAL_STENCIL_8" }, -#endif - /* Exynos Formats */ - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YV12_M, .npln = 3, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 8, 8 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YV12_M" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, .npln = 3, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 8, 8 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 16,.has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, .npln = 3, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 8, 8 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P" }, - { .id = HAL_PIXEL_FORMAT_YCrCb_420_SP, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_YCrCb_420_SP" }, - - /* SBWC Formats */ - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60" }, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80" }, - - /* Google Formats */ - { .id = HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 64, .align_h = 8, .align_w_cpu = 64, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = true, .name = "HAL_PIXEL_FORMAT_GOOGLE_NV12_SP" }, - { .id = HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, .npln = 2, .ncmp = 3, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 64, .align_h = 8, .align_w_cpu = 64, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = true, .name = "HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B" }, - { .id = HAL_PIXEL_FORMAT_GOOGLE_R_8, .npln = 1, .ncmp = 1, .bps = 8, .bpp_afbc = { 8, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_GOOGLE_R_8" }, - { .id = HAL_PIXEL_FORMAT_GOOGLE_RG_88, .npln = 1, .ncmp = 2, .bps = 8, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false, .name = "HAL_PIXEL_FORMAT_GOOGLE_RG_88" }, - -}; - -const size_t num_formats = sizeof(formats)/sizeof(formats[0]); - - -#define S_LIN F_LIN -#define S_AFBC F_AFBC - -/* This table represents the superset of flags for each base format and producer/consumer. - * Where IP does not support a capability, it should be defined and not set. - */ -const format_ip_support_t formats_ip_support[] = { - - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGB_565, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN | F_AFBC, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_LIN | S_AFBC, .dpu_aeu_wr = F_AFBC, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGB_888, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN | F_AFBC, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_LIN, .dpu_rd = F_LIN | F_AFBC, .dpu_aeu_wr = F_AFBC, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN | F_AFBC, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_LIN, .dpu_rd = F_LIN | F_AFBC, .dpu_aeu_wr = F_AFBC, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = S_LIN, .gpu_rd = S_LIN, .dpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = S_LIN | S_AFBC, .gpu_rd = S_LIN | S_AFBC, .dpu_wr = F_LIN, .dpu_rd = F_LIN | S_AFBC, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, -#if PLATFORM_SDK_VERSION >= 26 - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN | F_AFBC, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_aeu_wr = F_AFBC, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, -#endif /* PLATFORM_SDK_VERSION >= 26 */ - - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y8, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y16, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - - /* 420 (8-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I, .cpu_wr = F_NONE, .cpu_rd = F_NONE, .gpu_wr = F_NONE, .gpu_rd = F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_AFBC, .dpu_aeu_wr = F_AFBC, .vpu_wr = F_AFBC, .vpu_rd = F_AFBC}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV12, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV21, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = S_LIN, .gpu_rd = S_LIN, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YV12, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - - /* 422 (8-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN | F_AFBC, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_LIN | F_AFBC, .dpu_aeu_wr = F_AFBC, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV16, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - - /* 420 (10-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I, .cpu_wr = F_NONE, .cpu_rd = F_NONE, .gpu_wr = F_AFBC, .gpu_rd = F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_AFBC, .dpu_aeu_wr = F_AFBC, .vpu_wr = F_AFBC, .vpu_rd = F_AFBC}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y0L2, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_P010, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - - /* 422 (10-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y210, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN | F_AFBC, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_P210, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - - /* 444 (10-bit) */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV444_10BIT_I, .cpu_wr = F_NONE, .cpu_rd = F_NONE, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y410, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN | F_AFBC, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - - /* Other */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW16, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW12, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW10, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_BLOB, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - -#if PLATFORM_SDK_VERSION >= 28 - /* Depth and Stencil */ - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_16, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24_STENCIL_8, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F_STENCIL_8, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_STENCIL_8, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_NONE, .gpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, -#endif - /* Exynos Formats */ - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YV12_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN, .gpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_YCrCb_420_SP, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = S_LIN, .gpu_rd = S_LIN, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - - /* SBWC Formats */ - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_NONE, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN , .gpu_rd = F_LIN , .dpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_wr = F_LIN, .vpu_rd = F_LIN}, - { .id = HAL_PIXEL_FORMAT_GOOGLE_R_8, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN | F_AFBC, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_NONE, .vpu_rd = F_NONE}, - { .id = HAL_PIXEL_FORMAT_GOOGLE_RG_88, .cpu_wr = F_LIN, .cpu_rd = F_LIN, .gpu_wr = F_LIN | F_AFBC, .gpu_rd = F_LIN | F_AFBC, .dpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_wr = F_NONE, .vpu_rd = F_NONE}, -}; - -const size_t num_ip_formats = sizeof(formats_ip_support)/sizeof(formats_ip_support[0]); - -typedef struct -{ - uint32_t hal_format; - bool is_flex; - uint32_t internal_format; -} hal_int_fmt; - - -static const hal_int_fmt hal_to_internal_format[] = -{ - { HAL_PIXEL_FORMAT_RGBA_8888, false, MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888 }, - { HAL_PIXEL_FORMAT_RGBX_8888, false, MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888 }, - { HAL_PIXEL_FORMAT_RGB_888, false, MALI_GRALLOC_FORMAT_INTERNAL_RGB_888 }, - { HAL_PIXEL_FORMAT_RGB_565, false, MALI_GRALLOC_FORMAT_INTERNAL_RGB_565 }, - { HAL_PIXEL_FORMAT_BGRA_8888, false, MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888 }, - { HAL_PIXEL_FORMAT_YCbCr_422_SP, false, MALI_GRALLOC_FORMAT_INTERNAL_NV16 }, - { HAL_PIXEL_FORMAT_YCrCb_420_SP, false, MALI_GRALLOC_FORMAT_INTERNAL_NV21 }, - { HAL_PIXEL_FORMAT_YCbCr_422_I, false, MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT }, -#if PLATFORM_SDK_VERSION >= 26 - { HAL_PIXEL_FORMAT_RGBA_FP16, false, MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 }, -#endif - { HAL_PIXEL_FORMAT_RAW16, false, MALI_GRALLOC_FORMAT_INTERNAL_RAW16 }, - { HAL_PIXEL_FORMAT_BLOB, false, MALI_GRALLOC_FORMAT_INTERNAL_BLOB }, - { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, true, MALI_GRALLOC_FORMAT_INTERNAL_NV12 }, - { HAL_PIXEL_FORMAT_YCbCr_420_888, true, MALI_GRALLOC_FORMAT_INTERNAL_NV12 }, - { HAL_PIXEL_FORMAT_RAW_OPAQUE, false, MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED }, - { HAL_PIXEL_FORMAT_RAW10, false, MALI_GRALLOC_FORMAT_INTERNAL_RAW10 }, - { HAL_PIXEL_FORMAT_RAW12, false, MALI_GRALLOC_FORMAT_INTERNAL_RAW12 }, - { HAL_PIXEL_FORMAT_YCbCr_422_888, true, MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT }, - { HAL_PIXEL_FORMAT_YCbCr_444_888, true, MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED }, - { HAL_PIXEL_FORMAT_FLEX_RGB_888, true, MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED }, - { HAL_PIXEL_FORMAT_FLEX_RGBA_8888, true, MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED }, -#if PLATFORM_SDK_VERSION >= 26 - { HAL_PIXEL_FORMAT_RGBA_1010102, false, MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 }, -#endif -#if PLATFORM_SDK_VERSION >= 28 - { HAL_PIXEL_FORMAT_DEPTH_16, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_16 }, - { HAL_PIXEL_FORMAT_DEPTH_24, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24 }, - { HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24_STENCIL_8 }, - { HAL_PIXEL_FORMAT_DEPTH_32F, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F }, - { HAL_PIXEL_FORMAT_DEPTH_32F_STENCIL_8, false, MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_32F_STENCIL_8 }, - { HAL_PIXEL_FORMAT_STENCIL_8, false, MALI_GRALLOC_FORMAT_INTERNAL_STENCIL_8 }, - { HAL_PIXEL_FORMAT_YCBCR_P010, false, MALI_GRALLOC_FORMAT_INTERNAL_P010 }, -#endif - { HAL_PIXEL_FORMAT_Y8, false, MALI_GRALLOC_FORMAT_INTERNAL_Y8 }, - { HAL_PIXEL_FORMAT_Y16, false, MALI_GRALLOC_FORMAT_INTERNAL_Y16 }, - { HAL_PIXEL_FORMAT_YV12, false, MALI_GRALLOC_FORMAT_INTERNAL_YV12 }, - /* Exynos Formats */ - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, true, MALI_GRALLOC_FORMAT_INTERNAL_NV12 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, false, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M }, - { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, false, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M }, - { HAL_PIXEL_FORMAT_EXYNOS_YV12_M, false, HAL_PIXEL_FORMAT_EXYNOS_YV12_M }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED}, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P }, - /* SBWC Formats */ - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC }, - { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC }, - { HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC, false, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC }, - - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60 }, - { HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80, false, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80 }, - { HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, true, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP }, - { HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, true, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B }, - { HAL_PIXEL_FORMAT_GOOGLE_R_8, false, HAL_PIXEL_FORMAT_GOOGLE_R_8 }, - { HAL_PIXEL_FORMAT_GOOGLE_RG_88, false, HAL_PIXEL_FORMAT_GOOGLE_RG_88 }, -}; - -const size_t num_hal_formats = sizeof(hal_to_internal_format)/sizeof(hal_to_internal_format[0]); - - -/* - * Finds "Look-up Table" index for the given format - * - * @param base_format [in] Format for which index is required. - * - * @return index, when the format is found in the look up table - * -1, otherwise - * - */ -int32_t get_format_index(const uint32_t base_format) -{ - int32_t format_idx; - for (format_idx = 0; format_idx < (int32_t)num_formats; format_idx++) - { - if (formats[format_idx].id == base_format) - { - break; - } - } - if (format_idx >= (int32_t)num_formats) - { - ALOGE("ERROR: Format allocation info not found for format: %" PRIx32, base_format); - return -1; - } - - return format_idx; -} - - -int32_t get_ip_format_index(const uint32_t base_format) -{ - int32_t format_idx; - for (format_idx = 0; format_idx < (int32_t)num_ip_formats; format_idx++) - { - if (formats_ip_support[format_idx].id == base_format) - { - break; - } - } - if (format_idx >= (int32_t)num_ip_formats) - { - ALOGE("ERROR: IP support not found for format: %" PRIx32, base_format); - return -1; - } - - return format_idx; -} - - -/* - * Attempt to map base HAL format to an internal format and - * validate format is supported for allocation. - * - * @param map_to_internal [in] 1: Forces mapping to (and validation of) internal format - * 0: Only maps flex HAL formats to internal - * - * @return internal_format, where internal format is found - * HAL format, where map_to_internal == 0 and base_format is not flex - * MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED, otherwise - * - * NOTE: Base format might be either a HAL format or (already) an internal format. - * - */ -uint32_t get_internal_format(const uint32_t base_format, const bool map_to_internal) -{ - uint32_t internal_format = base_format; - - if (is_exynos_format(internal_format)) - goto out; - - for (int idx = 0; idx < (int)num_hal_formats; idx++) - { - if (hal_to_internal_format[idx].hal_format == base_format) - { - if (hal_to_internal_format[idx].is_flex || map_to_internal) - { - internal_format = hal_to_internal_format[idx].internal_format; - } - break; - } - } - - /* Ensure internal format is valid when expected. */ - if (map_to_internal && get_format_index(internal_format) < 0) - { - internal_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED; - } - -out: - return internal_format; -} - - -bool is_power2(uint8_t n) -{ - return ((n & (n-1)) == 0); -} - - -bool sanitize_formats(void) -{ - bool fail = false; - - for (int i = 0; i < (int)num_formats; i++) - { - const format_info_t * format = &formats[i]; - - /* Identify invalid values. */ - if (format->id == 0 || - format->npln == 0 || format->npln > 3 || - format->ncmp == 0 || - format->bps == 0 || - format->align_w == 0 || - format->align_h == 0 || - format->align_w_cpu == 0 || - format->tile_size == 0) - { - AERR("Format [id:0x%" PRIx32 "] property zero/out of range (unexpected)", format->id); - fail = true; - } - - if (format->is_rgb && format->is_yuv) - { - AERR("Format [id:0x%" PRIx32 "] cannot be both RGB and YUV", format->id); - fail = true; - } - - if (format->npln > format->ncmp) - { - AERR("Format [id:0x%" PRIx32 "] planes cannot exceed components", format->id); - fail = true; - } - - if (format->linear && (format->bps > format->bpp[0])) - { - AERR("Format [id:0x%" PRIx32 "] bpp should be greater than/equal to bps", format->id); - fail = true; - } - - if (format->afbc && (format->bps > format->bpp_afbc[0])) - { - AERR("Format [id:0x%" PRIx32 "] bpp_afbc should be greater than/equal to bps", format->id); - fail = true; - } - - if (!format->linear && format->tile_size > 1) - { - AERR("Format [id:0x%" PRIx32 "] tile_size must be set to 1 for formats without linear support", format->id); - fail = true; - } - - for (int pln = 0; pln < 3; pln++) - { - if (format->linear && (pln < format->npln) && (format->bpp[pln] == 0)) - { - AERR("Format [id:0x%" PRIx32 "] does not have bpp defined for plane: %d", format->id, pln); - fail = true; - } - else if (format->linear && (pln >= format->npln) && (format->bpp[pln] != 0)) - { - AERR("Format [id:0x%" PRIx32 "] should not have bpp defined for plane: %d", format->id, pln); - fail = true; - } - else if (!format->linear && (format->bpp[pln] != 0)) - { - AERR("Format [id:0x%" PRIx32 "] which doesn't support linear should not have bpp defined", format->id); - fail = true; - } - - if (format->afbc && (pln < format->npln) && (format->bpp_afbc[pln] == 0)) - { - AERR("Format [id:0x%" PRIx32 "] does not have bpp_afbc defined for plane: %d", format->id, pln); - fail = true; - } - else if (format->afbc && (pln >= format->npln) && (format->bpp_afbc[pln] != 0)) - { - AERR("Format [id:0x%" PRIx32 "] should not have bpp_afbc defined for plane: %d", format->id, pln); - fail = true; - } - } - - if (format->is_yuv) - { - if (format->hsub == 0 || format->vsub == 0) - { - AERR("Format [id:0x%" PRIx32 "] hsub and vsub should be non-zero (YUV)", format->id); - fail = true; - } - - if (!is_power2(format->hsub) || !is_power2(format->vsub)) - { - AERR("Format [id:0x%" PRIx32 "] hsub and vsub should be powers of 2", format->id); - fail = true; - } - - if ((format->align_w % format->hsub) != 0) - { - AERR("Format [id:0x%" PRIx32 "] align_w should be a multiple of hsub", format->id); - fail = true; - } - - if ((format->align_h % format->vsub) != 0) - { - AERR("Format [id:0x%" PRIx32 "] align_h should be a multiple of vsub", format->id); - fail = true; - } - } - else - { - if (format->hsub != 0 || format->vsub != 0) - { - AERR("Format [id:0x%" PRIx32 "] hsub and vsub should be zero (non-YUV)", format->id); - fail = true; - } - } - - if (format->align_w == 0 || format->align_h == 0) - { - AERR("Format [id:0x%" PRIx32 "] align_w and align_h should be non-zero", format->id); - fail = true; - } - else - { - if (!is_power2(format->align_w) || !is_power2(format->align_h)) - { - AERR("Format [id:0x%" PRIx32 "] align_w and align_h should be powers of 2", format->id); - fail = true; - } - - if (!is_power2(format->align_w_cpu)) - { - AERR("Format [id:0x%" PRIx32 "] align_w_cpu should be a power of 2", format->id); - fail = true; - } - } - } - - return fail; -} - -const char *format_name(uint32_t base_format) { - static std::once_flag name_map_flag; - using NameMap = std::unordered_map<uint32_t, const char*>; - static NameMap name_map; - - std::call_once(name_map_flag, []() { - for (size_t i = 0; i < num_formats; ++i) { - const format_info_t &format = formats[i]; - if (name_map.count(format.id)) { - AERR("Format id 0x%" PRIx32 " mapped to %s and to %s", - format.id, name_map[format.id], format.name); - } else { - name_map[format.id] = format.name; - } - } - }); - - NameMap::const_iterator i = name_map.find(base_format); - if (i == name_map.end()) { - return "<unrecognized format>"; - } - return i->second; -} - -bool is_exynos_format(uint32_t base_format) -{ - switch (base_format) - { - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - case HAL_PIXEL_FORMAT_EXYNOS_YV12_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: - return true; - } - - return false; -} diff --git a/gralloc3/src/framebuffer_device.cpp b/gralloc3/src/framebuffer_device.cpp deleted file mode 100644 index f0bcf93..0000000 --- a/gralloc3/src/framebuffer_device.cpp +++ /dev/null @@ -1,703 +0,0 @@ -/* - * Copyright (C) 2010-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <linux/fb.h> - -#include <system/window.h> -#include <log/log.h> -#include <cutils/atomic.h> -#include <hardware/hardware.h> -#include <hardware/fb.h> - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#include <GLES/gl.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#include <GLES/gl.h> -#endif - -#include "mali_gralloc_module.h" -#include "mali_gralloc_private_interface_types.h" -#include "mali_gralloc_buffer.h" -#include "gralloc_helper.h" -#include "gralloc_vsync.h" -#include "mali_gralloc_bufferaccess.h" -#include "mali_gralloc_ion.h" -#include "gralloc_buffer_priv.h" - -/* Number of buffers for page flipping */ -#define NUM_BUFFERS NUM_FB_BUFFERS - -enum -{ - PAGE_FLIP = 0x00000001, -}; - -#if GRALLOC_VERSION_MAJOR <= 1 -static int fb_set_swap_interval(struct framebuffer_device_t *dev, int interval) -{ - if (interval < dev->minSwapInterval) - { - interval = dev->minSwapInterval; - } - else if (interval > dev->maxSwapInterval) - { - interval = dev->maxSwapInterval; - } - - private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); - m->swapInterval = interval; - - if (0 == interval) - { - gralloc_vsync_disable(dev); - } - else - { - gralloc_vsync_enable(dev); - } - - return 0; -} -#endif - -#if GRALLOC_VERSION_MAJOR <= 1 -static int fb_post(struct framebuffer_device_t *dev, buffer_handle_t buffer) -{ - if (private_handle_t::validate(buffer) < 0) - { - return -EINVAL; - } - - private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(buffer); - private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); - - if (m->currentBuffer) - { - mali_gralloc_unlock(m, m->currentBuffer); - m->currentBuffer = 0; - } - - if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) - { - /* Buffer is being locked for non-cpu usage, hence no need to populate a valid cpu address parameter */ - mali_gralloc_lock(m, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST, - 0, 0, 0, 0, NULL); - int interrupt; - m->info.activate = FB_ACTIVATE_VBL; - m->info.yoffset = hnd->offset / m->finfo.line_length; - - if (ioctl(m->framebuffer->fb_fd, FBIOPUT_VSCREENINFO, &m->info) == -1) - { - AERR("FBIOPUT_VSCREENINFO failed for fd: %d", m->framebuffer->fb_fd); - mali_gralloc_unlock(m, buffer); - return -errno; - } - - if (0 != gralloc_wait_for_vsync(dev)) - { - AERR("Gralloc wait for vsync failed for fd: %d", m->framebuffer->fb_fd); - mali_gralloc_unlock(m, buffer); - return -errno; - } - - m->currentBuffer = buffer; - } - else - { - void *fb_vaddr; - void *buffer_vaddr; - - mali_gralloc_lock(m, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, 0, 0, 0, 0, &fb_vaddr); - mali_gralloc_lock(m, buffer, GRALLOC_USAGE_SW_READ_RARELY, 0, 0, 0, 0, &buffer_vaddr); - // If buffer's alignment match framebuffer alignment we can do a direct copy. - // If not we must fallback to do an aligned copy of each line. - if (hnd->plane_info[0].byte_stride == (int)m->finfo.line_length) - { - memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres); - } - else - { - uintptr_t fb_offset = 0; - uintptr_t buffer_offset = 0; - unsigned int i; - - for (i = 0; i < m->info.yres; i++) - { - memcpy((void *)((uintptr_t)fb_vaddr + fb_offset), (void *)((uintptr_t)buffer_vaddr + buffer_offset), - m->finfo.line_length); - - fb_offset += m->finfo.line_length; - buffer_offset += hnd->plane_info[0].byte_stride; - } - } - - mali_gralloc_unlock(m, buffer); - mali_gralloc_unlock(m, m->framebuffer); - } - - return 0; -} -#endif - -static int init_frame_buffer_locked(struct private_module_t *module) -{ - if (module->framebuffer) - { - return 0; // Nothing to do, already initialized - } - - char const *const device_template[] = { "/dev/graphics/fb%u", "/dev/fb%u", NULL }; - - int fd = -1; - int i = 0; - char name[64]; - - while ((fd == -1) && device_template[i]) - { - snprintf(name, 64, device_template[i], 0); - fd = open(name, O_RDWR, 0); - i++; - } - - if (fd < 0) - { - return -errno; - } - - struct fb_fix_screeninfo finfo; - - if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) - { - close(fd); - return -errno; - } - - struct fb_var_screeninfo info; - - if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) - { - close(fd); - return -errno; - } - - info.reserved[0] = 0; - info.reserved[1] = 0; - info.reserved[2] = 0; - info.xoffset = 0; - info.yoffset = 0; - info.activate = FB_ACTIVATE_NOW; - -#if GRALLOC_FB_BPP == 16 - /* - * Explicitly request 5/6/5 - */ - info.bits_per_pixel = 16; - info.red.offset = 11; - info.red.length = 5; - info.green.offset = 5; - info.green.length = 6; - info.blue.offset = 0; - info.blue.length = 5; - info.transp.offset = 0; - info.transp.length = 0; -#elif GRALLOC_FB_BPP == 32 - /* - * Explicitly request 8/8/8 - */ - info.bits_per_pixel = 32; - info.red.offset = 16; - info.red.length = 8; - info.green.offset = 8; - info.green.length = 8; - info.blue.offset = 0; - info.blue.length = 8; - info.transp.offset = 0; - info.transp.length = 0; -#else -#error "Invalid framebuffer bit depth" -#endif - - /* - * Request NUM_BUFFERS screens (at lest 2 for page flipping) - */ - info.yres_virtual = info.yres * NUM_BUFFERS; - - uint32_t flags = PAGE_FLIP; - - if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) - { - info.yres_virtual = info.yres; - flags &= ~PAGE_FLIP; - AWAR("FBIOPUT_VSCREENINFO failed, page flipping not supported fd: %d", fd); - } - - if (info.yres_virtual < info.yres * 2) - { - // we need at least 2 for page-flipping - info.yres_virtual = info.yres; - flags &= ~PAGE_FLIP; - AWAR("page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres * 2); - } - - if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) - { - close(fd); - return -errno; - } - - int refreshRate = 0; - - if (info.pixclock > 0) - { - refreshRate = - 1000000000000000LLU / (uint64_t(info.upper_margin + info.lower_margin + info.yres + info.hsync_len) * - (info.left_margin + info.right_margin + info.xres + info.vsync_len) * info.pixclock); - } - else - { - AWAR("fbdev pixclock is zero for fd: %d", fd); - } - - if (refreshRate == 0) - { - refreshRate = 60 * 1000; // 60 Hz - } - - if (int(info.width) <= 0 || int(info.height) <= 0) - { - // the driver doesn't return that information - // default to 160 dpi - info.width = ((info.xres * 25.4f) / 160.0f + 0.5f); - info.height = ((info.yres * 25.4f) / 160.0f + 0.5f); - } - - float xdpi = (info.xres * 25.4f) / info.width; - float ydpi = (info.yres * 25.4f) / info.height; - float fps = refreshRate / 1000.0f; - - AINF("using (fd=%d)\n" - "id = %s\n" - "xres = %d px\n" - "yres = %d px\n" - "xres_virtual = %d px\n" - "yres_virtual = %d px\n" - "bpp = %d\n" - "r = %2u:%u\n" - "g = %2u:%u\n" - "b = %2u:%u\n", - fd, finfo.id, info.xres, info.yres, info.xres_virtual, info.yres_virtual, info.bits_per_pixel, info.red.offset, - info.red.length, info.green.offset, info.green.length, info.blue.offset, info.blue.length); - - AINF("width = %d mm (%f dpi)\n" - "height = %d mm (%f dpi)\n" - "refresh rate = %.2f Hz\n", - info.width, xdpi, info.height, ydpi, fps); - - if (0 == strncmp(finfo.id, "CLCD FB", 7)) - { - module->dpy_type = MALI_DPY_TYPE_CLCD; - } - else if (0 == strncmp(finfo.id, "ARM Mali HDLCD", 14)) - { - module->dpy_type = MALI_DPY_TYPE_HDLCD; - } - else if (0 == strncmp(finfo.id, "ARM HDLCD Control", 16)) - { - module->dpy_type = MALI_DPY_TYPE_HDLCD; - } - else - { - module->dpy_type = MALI_DPY_TYPE_UNKNOWN; - } - - if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) - { - close(fd); - return -errno; - } - - if (finfo.smem_len <= 0) - { - close(fd); - return -errno; - } - - module->flags = flags; - module->info = info; - module->finfo = finfo; - module->xdpi = xdpi; - module->ydpi = ydpi; - module->fps = fps; - module->swapInterval = 1; - - /* - * map the framebuffer - */ - size_t fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual); - void *vaddr = mmap(0, fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - - if (vaddr == MAP_FAILED) - { - close(fd); - AERR("Error mapping the framebuffer (%s)", strerror(errno)); - return -errno; - } - - memset(vaddr, 0, fbSize); - // Create a "fake" buffer object for the entire frame buffer memory, and store it in the module - module->framebuffer = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, fbSize, vaddr, - static_cast<uint64_t>(GRALLOC_USAGE_HW_FB), - static_cast<uint64_t>(GRALLOC_USAGE_HW_FB), dup(fd), 0, - finfo.line_length, info.xres_virtual, info.yres_virtual, - module->fbdev_format); - - module->numBuffers = info.yres_virtual / info.yres; - module->bufferMask = 0; - - return 0; -} - -static int init_frame_buffer(struct private_module_t *module) -{ - pthread_mutex_lock(&module->lock); - int err = init_frame_buffer_locked(module); - pthread_mutex_unlock(&module->lock); - return err; -} - -#if GRALLOC_VERSION_MAJOR <= 1 -static int fb_close(struct hw_device_t *device) -{ - framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(device); - - if (dev) - { - free(dev); - } - - return 0; -} -#endif - -static int fb_alloc_framebuffer_dmabuf(private_module_t *m, private_handle_t *hnd) -{ - struct fb_dmabuf_export fb_dma_buf; - int res; - res = ioctl(m->framebuffer->fb_fd, FBIOGET_DMABUF, &fb_dma_buf); - - if (res == 0) - { - hnd->share_fd = fb_dma_buf.fd; - return 0; - } - else - { - AINF("FBIOGET_DMABUF ioctl failed(%d). See gralloc_priv.h and the integration manual for vendor framebuffer " - "integration", - res); - return -1; - } -} - -static int fb_alloc_from_ion_module(mali_gralloc_module *m, int width, int height, int byte_stride, size_t buffer_size, - uint64_t consumer_usage, uint64_t producer_usage, buffer_handle_t *pHandle) -{ - buffer_descriptor_t fb_buffer_descriptor; - gralloc_buffer_descriptor_t gralloc_buffer_descriptor[1]; - bool shared = false; - int err = 0; - - fb_buffer_descriptor.width = width; - fb_buffer_descriptor.height = height; - fb_buffer_descriptor.size = buffer_size; - fb_buffer_descriptor.pixel_stride = width; - - memset(fb_buffer_descriptor.plane_info, 0, sizeof(fb_buffer_descriptor.plane_info)); - fb_buffer_descriptor.plane_info[0].alloc_width = width; - fb_buffer_descriptor.plane_info[0].alloc_height = height; - fb_buffer_descriptor.plane_info[0].byte_stride = byte_stride; - fb_buffer_descriptor.plane_info[0].offset = 0; - - fb_buffer_descriptor.internal_format = m->fbdev_format; - fb_buffer_descriptor.alloc_format = m->fbdev_format; - fb_buffer_descriptor.consumer_usage = consumer_usage; - fb_buffer_descriptor.producer_usage = producer_usage; - fb_buffer_descriptor.layer_count = 1; - - gralloc_buffer_descriptor[0] = (gralloc_buffer_descriptor_t)(&fb_buffer_descriptor); - - err = mali_gralloc_ion_allocate(gralloc_buffer_descriptor, 1, pHandle, &shared); - - return err; -} - -static int fb_alloc_framebuffer_locked(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage, - buffer_handle_t *pHandle, int *stride, int *byte_stride) -{ - // allocate the framebuffer - if (m->framebuffer == NULL) - { - // initialize the framebuffer, the framebuffer is mapped once and forever. - int err = init_frame_buffer_locked(m); - - if (err < 0) - { - return err; - } - - if (m->framebuffer == NULL) - { - return -1; - } - } - - uint32_t bufferMask = m->bufferMask; - const uint32_t numBuffers = m->numBuffers; - /* framebufferSize is used for allocating the handle to the framebuffer and refers - * to the size of the actual framebuffer. - * alignedFramebufferSize is used for allocating a possible internal buffer and - * thus need to consider internal alignment requirements. */ - const size_t framebufferSize = m->finfo.line_length * m->info.yres; - const size_t alignedFramebufferSize = GRALLOC_ALIGN(m->finfo.line_length, 64) * m->info.yres; - - *stride = m->info.xres; - - if (numBuffers == 1) - { - // If we have only one buffer, we never use page-flipping. Instead, - // we return a regular buffer which will be memcpy'ed to the main - // screen when post is called. - uint64_t newConsumerUsage = (consumer_usage & ~(static_cast<uint64_t>(GRALLOC_USAGE_HW_FB))); - uint64_t newProducerUsage = (producer_usage & ~(static_cast<uint64_t>(GRALLOC_USAGE_HW_FB))) | - static_cast<uint64_t>(GRALLOC_USAGE_HW_2D); - AWAR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres); - *byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64); - return fb_alloc_from_ion_module(m, m->info.xres, m->info.yres, *byte_stride, - alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle); - } - - if (bufferMask >= ((1LU << numBuffers) - 1)) - { - // We ran out of buffers, reset bufferMask - bufferMask = 0; - m->bufferMask = 0; - } - - uintptr_t framebufferVaddr = (uintptr_t)m->framebuffer->base; - - // find a free slot - for (uint32_t i = 0; i < numBuffers; i++) - { - if ((bufferMask & (1LU << i)) == 0) - { - m->bufferMask |= (1LU << i); - break; - } - - framebufferVaddr += framebufferSize; - } - - // The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory - private_handle_t *hnd = new private_handle_t( - private_handle_t::PRIV_FLAGS_FRAMEBUFFER, framebufferSize, (void *)framebufferVaddr, consumer_usage, - producer_usage, dup(m->framebuffer->fb_fd), (framebufferVaddr - (uintptr_t)m->framebuffer->base), - m->finfo.line_length, m->info.xres, m->info.yres, m->fbdev_format); - - /* - * Perform allocator specific actions. If these fail we fall back to a regular buffer - * which will be memcpy'ed to the main screen when fb_post is called. - */ - if (fb_alloc_framebuffer_dmabuf(m, hnd) == -1) - { - delete hnd; - uint64_t newConsumerUsage = (consumer_usage & ~(static_cast<uint64_t>(GRALLOC_USAGE_HW_FB))); - uint64_t newProducerUsage = (producer_usage & ~(static_cast<uint64_t>(GRALLOC_USAGE_HW_FB))) | - static_cast<uint64_t>(GRALLOC_USAGE_HW_2D); - AERR("Fallback to single buffering. Unable to map framebuffer memory to handle:%p", hnd); - *byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64); - return fb_alloc_from_ion_module(m, m->info.xres, m->info.yres, *byte_stride, - alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle); - } - - *pHandle = hnd; - *byte_stride = m->finfo.line_length; - - return 0; -} - -#if GRALLOC_VERSION_MAJOR <= 1 -int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device) -{ - int status = -EINVAL; - - GRALLOC_UNUSED(name); - GRALLOC_UNUSED(module); - GRALLOC_UNUSED(device); - -#if GRALLOC_VERSION_MAJOR == 1 - gralloc1_device_t *gralloc_device; -#else - alloc_device_t *gralloc_device; -#endif - -#if DISABLE_FRAMEBUFFER_HAL == 1 - AERR("Framebuffer HAL not support/disabled"); - return -ENODEV; -#else - -#if GRALLOC_VERSION_MAJOR == 1 - status = gralloc1_open(module, &gralloc_device); -#else - status = gralloc_open(module, &gralloc_device); -#endif - - if (status < 0) - { - return status; - } - - private_module_t *m = (private_module_t *)module; - - /* Populate frame buffer pixel format */ -#if GRALLOC_FB_BPP == 16 - m->fbdev_format = MALI_GRALLOC_FORMAT_INTERNAL_RGB_565; -#elif GRALLOC_FB_BPP == 32 - m->fbdev_format = MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888; -#else -#error "Invalid framebuffer bit depth" -#endif - - status = init_frame_buffer(m); - - /* malloc is used instead of 'new' to instantiate the struct framebuffer_device_t - * C++11 spec specifies that if a class/struct has a const member,default constructor - * is deleted. So, if 'new' is used to instantiate the class/struct, it will throw - * error complaining about deleted constructor. Even if the struct is wrapped in a class - * it will still try to use the base class constructor to initialize the members, resulting - * in error 'deleted constructor'. - * This leaves two options - * Option 1: initialize the const members at the instantiation time. With {value1, value2 ..} - * Which relies on the order of the members, and if members are reordered or a new member is introduced - * it will end up assiging wrong value to members. Designated assignment as well has been removed in C++11 - * Option 2: use malloc instead of 'new' to allocate the class/struct and initialize the members in code. - * This is the only maintainable option available. - */ - - framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(malloc(sizeof(framebuffer_device_t))); - - /* if either or both of init_frame_buffer() and malloc failed */ - if ((status < 0) || (!dev)) - { -#if GRALLOC_VERSION_MAJOR == 1 - gralloc1_close(gralloc_device); -#else - gralloc_close(gralloc_device); -#endif - (!dev) ? (void)(status = -ENOMEM) : free(dev); - return status; - } - - memset(dev, 0, sizeof(*dev)); - - /* initialize the procs */ - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->common.version = 0; - dev->common.module = const_cast<hw_module_t *>(module); - dev->common.close = fb_close; - dev->setSwapInterval = fb_set_swap_interval; - dev->post = fb_post; - dev->setUpdateRect = 0; - - int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3); - const_cast<uint32_t &>(dev->flags) = 0; - const_cast<uint32_t &>(dev->width) = m->info.xres; - const_cast<uint32_t &>(dev->height) = m->info.yres; - const_cast<int &>(dev->stride) = stride; - const_cast<int &>(dev->format) = m->fbdev_format; - const_cast<float &>(dev->xdpi) = m->xdpi; - const_cast<float &>(dev->ydpi) = m->ydpi; - const_cast<float &>(dev->fps) = m->fps; - const_cast<int &>(dev->minSwapInterval) = 0; - const_cast<int &>(dev->maxSwapInterval) = 1; - *device = &dev->common; - - gralloc_vsync_enable(dev); - - return status; -#endif -} -#endif - -#if DISABLE_FRAMEBUFFER_HAL != 1 -int32_t mali_gralloc_fb_allocate(private_module_t * const module, - const buffer_descriptor_t * const bufDescriptor, - buffer_handle_t * const outBuffers) -{ - uint64_t format = bufDescriptor->hal_format; - -#if GRALLOC_FB_SWAP_RED_BLUE == 1 -#if GRALLOC_FB_BPP == 16 - format = HAL_PIXEL_FORMAT_RGB_565; -#elif GRALLOC_FB_BPP == 32 - format = HAL_PIXEL_FORMAT_BGRA_8888; -#else -#error "Invalid framebuffer bit depth" -#endif -#endif - - int byte_stride, pixel_stride; - pthread_mutex_lock(&module->lock); - const int status = fb_alloc_framebuffer_locked(module, bufDescriptor->consumer_usage, - bufDescriptor->producer_usage, - outBuffers, &pixel_stride, &byte_stride); - pthread_mutex_unlock(&module->lock); - if (status < 0) - { - return status; - } - else - { - private_handle_t *hnd = (private_handle_t *)*outBuffers; - - /* Allocate a meta-data buffer for framebuffer too. fbhal - * ones wont need it but for hwc they will. - */ - (void)gralloc_buffer_attr_allocate(hnd); - - hnd->req_format = format; - hnd->yuv_info = MALI_YUV_BT601_NARROW; - hnd->internal_format = format; - hnd->alloc_format = format; - hnd->plane_info[0].byte_stride = byte_stride; - hnd->width = bufDescriptor->width; - hnd->height = bufDescriptor->height; - hnd->stride = pixel_stride; - hnd->plane_info[0].alloc_width = bufDescriptor->width;; - hnd->plane_info[0].alloc_heightt = bufDescriptor->height; - hnd->layer_count = 1; - return 0; - } -} -#endif diff --git a/gralloc3/src/framebuffer_device.h b/gralloc3/src/framebuffer_device.h deleted file mode 100644 index 8156935..0000000 --- a/gralloc3/src/framebuffer_device.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <hardware/hardware.h> -#include "gralloc_priv.h" -#include "mali_gralloc_module.h" -#include "mali_gralloc_bufferdescriptor.h" - -// Create a framebuffer device -int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device); - -// Initialize the framebuffer (must keep module lock before calling -int init_frame_buffer_locked(struct private_module_t *module); - -/* Allocate framebuffer buffer */ -int32_t mali_gralloc_fb_allocate(private_module_t * const module, - const buffer_descriptor_t * const bufDescriptor, - buffer_handle_t * const outBuffers); diff --git a/gralloc3/src/gralloc_buffer_priv.cpp b/gralloc3/src/gralloc_buffer_priv.cpp deleted file mode 100644 index 795f571..0000000 --- a/gralloc3/src/gralloc_buffer_priv.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2014-2018 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 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. - */ - -#if GRALLOC_USE_ASHMEM_METADATA == 1 -#include <cutils/ashmem.h> -#else -#include "mali_gralloc_ion.h" -#endif - -#include <log/log.h> -#include <sys/mman.h> - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include "mali_gralloc_module.h" -#include "mali_gralloc_private_interface_types.h" -#include "mali_gralloc_buffer.h" -#include "gralloc_buffer_priv.h" - -/* - * Allocate shared memory for attribute storage. Only to be - * used by gralloc internally. - * - * Return 0 on success. - */ -int gralloc_buffer_attr_allocate(private_handle_t *hnd) -{ - int rval = -1; - int share_attr_fd = -1; - - if (!hnd) - { - goto out; - } - - share_attr_fd = hnd->get_share_attr_fd(); - if (share_attr_fd >= 0) - { - ALOGW("Warning share attribute fd already exists during create. Closing."); - close(share_attr_fd); - } - -#if GRALLOC_USE_ASHMEM_METADATA == 1 - share_attr_fd = ashmem_create_region("gralloc_shared_attr", PAGE_SIZE); -#else - share_attr_fd = alloc_metadata(); -#endif - - if (share_attr_fd < 0) - { - ALOGE("Failed to allocate page for shared attribute region"); - goto err_ashmem; - } - - /* - * Default protection on the shm region is PROT_EXEC | PROT_READ | PROT_WRITE. - * - * Personality flag READ_IMPLIES_EXEC which is used by some processes, namely gdbserver, - * causes a mmap with PROT_READ to be translated to PROT_READ | PROT_EXEC. - * - * If we were to drop PROT_EXEC here with a call to ashmem_set_prot_region() - * this can potentially cause clients to fail importing this gralloc attribute buffer - * with EPERM error since PROT_EXEC is not allowed. - * - * Because of this we keep the PROT_EXEC flag. - */ - - hnd->attr_base = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, share_attr_fd, 0); - - if (hnd->attr_base != MAP_FAILED) - { - memset(hnd->attr_base, 0xff, PAGE_SIZE); - munmap(hnd->attr_base, PAGE_SIZE); - hnd->attr_base = MAP_FAILED; - } - else - { - ALOGE("Failed to mmap shared attribute region"); - goto err_ashmem; - } - - hnd->set_share_attr_fd(share_attr_fd); - - rval = 0; - goto out; - -err_ashmem: - - if (share_attr_fd >= 0) - { - close(share_attr_fd); - hnd->set_share_attr_fd(-1); - } - -out: - return rval; -} - -/* - * Frees the shared memory allocated for attribute storage. - * Only to be used by gralloc internally. - - * Return 0 on success. - */ -int gralloc_buffer_attr_free(private_handle_t *hnd) -{ - int rval = -1; - int share_attr_fd = -1; - - if (!hnd) - { - goto out; - } - - share_attr_fd = hnd->get_share_attr_fd(); - if (share_attr_fd < 0) - { - ALOGE("Shared attribute region not avail to free"); - goto out; - } - - if (hnd->attr_base != MAP_FAILED) - { - AWAR("Warning shared attribute region mapped at free. Unmapping on pid(%d) tid(%d)", getpid(), gettid()); - hnd->dump(__FUNCTION__); - munmap(hnd->attr_base, PAGE_SIZE); - hnd->attr_base = MAP_FAILED; - } - - close(share_attr_fd); - hnd->set_share_attr_fd(-1); - rval = 0; - -out: - return rval; -} diff --git a/gralloc3/src/gralloc_buffer_priv.h b/gralloc3/src/gralloc_buffer_priv.h deleted file mode 100644 index 58f3b87..0000000 --- a/gralloc3/src/gralloc_buffer_priv.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2014-2018 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef GRALLOC_BUFFER_PRIV_H_ -#define GRALLOC_BUFFER_PRIV_H_ - -#include "gralloc_priv.h" -#include <errno.h> -#include <string.h> -#include "mali_gralloc_private_interface_types.h" - -// private gralloc buffer manipulation API - -struct attr_region -{ - /* Rectangle to be cropped from the full frame (Origin in top-left corner!) */ - int crop_top; - int crop_left; - int crop_height; - int crop_width; - int use_yuv_transform; /* DEPRECATED. Now explicitly signalled by gralloc through MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM */ - int use_sparse_alloc; - mali_hdr_info hdr_info; - android_dataspace_t dataspace; - android_dataspace_t force_dataspace; -} __attribute__((packed)); - -typedef struct attr_region attr_region; - -/* - * Allocate shared memory for attribute storage. Only to be - * used by gralloc internally. - * - * Return 0 on success. - */ -int gralloc_buffer_attr_allocate(struct private_handle_t *hnd); - -/* - * Frees the shared memory allocated for attribute storage. - * Only to be used by gralloc internally. - - * Return 0 on success. - */ -int gralloc_buffer_attr_free(struct private_handle_t *hnd); - -/* - * Map the attribute storage area before attempting to - * read/write from it. - * - * Return 0 on success. - */ -static inline int gralloc_buffer_attr_map(struct private_handle_t *hnd, int readwrite) -{ - int rval = -1; - int prot_flags = PROT_READ; - int share_attr_fd = -1; - - if (!hnd) - { - goto out; - } - - share_attr_fd = hnd->get_share_attr_fd(); - if (share_attr_fd < 0) - { - ALOGE("Shared attribute region not available to be mapped"); - goto out; - } - - if (readwrite) - { - prot_flags |= PROT_WRITE; - } - - hnd->attr_base = mmap(NULL, PAGE_SIZE, prot_flags, MAP_SHARED, share_attr_fd, 0); - - if (hnd->attr_base == MAP_FAILED) - { - ALOGE("Failed to mmap shared attribute region err=%s", strerror(errno)); - goto out; - } - - rval = 0; - -out: - return rval; -} - -/* - * Unmap the attribute storage area when done with it. - * - * Return 0 on success. - */ -static inline int gralloc_buffer_attr_unmap(struct private_handle_t *hnd) -{ - int rval = -1; - - if (!hnd) - { - goto out; - } - - if (hnd->attr_base != MAP_FAILED) - { - if (munmap(hnd->attr_base, PAGE_SIZE) == 0) - { - hnd->attr_base = MAP_FAILED; - rval = 0; - } - } - -out: - return rval; -} - -/* - * Read or write an attribute from/to the storage area. - * - * Return 0 on success. - */ -static inline int gralloc_buffer_attr_write(struct private_handle_t *hnd, buf_attr attr, int *val) -{ - int rval = -1; - - if (!hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST) - { - goto out; - } - - if (hnd->attr_base != MAP_FAILED) - { - attr_region *region = (attr_region *)hnd->attr_base; - - switch (attr) - { - case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT: - memcpy(®ion->crop_top, val, sizeof(int) * 4); - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS: - region->use_yuv_transform = *val; - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC: - region->use_sparse_alloc = *val; - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_HDR_INFO: - memcpy(®ion->hdr_info, val, sizeof(mali_hdr_info)); - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_DATASPACE: - region->dataspace = *((android_dataspace_t *)val); - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_FORCE_DATASPACE: - region->force_dataspace = *((android_dataspace_t *)val); - rval = 0; - break; - } - } - -out: - return rval; -} - -static inline int gralloc_buffer_attr_read(struct private_handle_t *hnd, buf_attr attr, int *val) -{ - int rval = -1; - - if (!hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST) - { - goto out; - } - - if (hnd->attr_base != MAP_FAILED) - { - attr_region *region = (attr_region *)hnd->attr_base; - - switch (attr) - { - case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT: - memcpy(val, ®ion->crop_top, sizeof(int) * 4); - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS: - *val = region->use_yuv_transform; - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC: - *val = region->use_sparse_alloc; - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_HDR_INFO: - memcpy(val, ®ion->hdr_info, sizeof(mali_hdr_info)); - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_DATASPACE: - *val = region->dataspace; - rval = 0; - break; - - case GRALLOC_ARM_BUFFER_ATTR_FORCE_DATASPACE: - *val = region->force_dataspace; - rval = 0; - break; - } - } - -out: - return rval; -} - -#endif /* GRALLOC_BUFFER_PRIV_H_ */ diff --git a/gralloc3/src/gralloc_helper.h b/gralloc3/src/gralloc_helper.h deleted file mode 100644 index 676b011..0000000 --- a/gralloc3/src/gralloc_helper.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2010-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef GRALLOC_HELPER_H_ -#define GRALLOC_HELPER_H_ - -#include <unistd.h> -#include <sys/mman.h> -#include <android/log.h> - -#include "VendorVideoAPI.h" - -#if __has_include(<video/mfc_macros.h>) -#include <video/mfc_macros.h> -#else -#include "local_mfc_macros.h" -#endif - -#ifndef AWAR -#define AWAR(fmt, args...) \ - __android_log_print(ANDROID_LOG_WARN, "[Gralloc-Warning]", "%s:%d " fmt, __func__, __LINE__, ##args) -#endif -#ifndef AINF -#define AINF(fmt, args...) __android_log_print(ANDROID_LOG_INFO, "[Gralloc]", fmt, ##args) -#endif -#ifndef AERR -#define AERR(fmt, args...) \ - __android_log_print(ANDROID_LOG_ERROR, "[Gralloc-ERROR]", "%s:%d " fmt, __func__, __LINE__, ##args) -#endif -#ifndef AERR_IF -#define AERR_IF(eq, fmt, args...) \ - if ((eq)) \ - AERR(fmt, args) -#endif - -#define GRALLOC_ALIGN(value, base) ((((value) + (base) -1) / (base)) * (base)) - -#define GRALLOC_MAX(a, b) (((a)>(b))?(a):(b)) - -#define GRALLOC_UNUSED(x) ((void)x) - -/* LSI integration */ -#define GRALLOC1_USAGE_SW_WRITE_MASK 0x000000F0 -#define GRALLOC1_USAGE_SW_READ_MASK 0x0000000F -#define GRALLOC1_USAGE_READ_OFTEN ((1ULL << 1) | (1ULL << 2)) -#define GRALLOC1_USAGE_WRITE_OFTEN ((1ULL << 5) | (1ULL << 6)) - -#define VIDEO_PRIV_DATA_SIZE sizeof(ExynosVideoMeta) - -#define PLANE_SIZE(w, h, ext_size) ((w) * (h) + ext_size) -// 10bit format -#define P010_PLANE_SIZE(w, h, ext_size) ((((w) * 2) * (h)) + ext_size) - -// 8+2 format -#define NV12N_S8B_LUMA_SIZE(w, h, ext_size) PLANE_SIZE(w, h, ext_size) -#define NV12N_S8B_CHROMA_SIZE(w, h, ext_size) (GRALLOC_ALIGN(((w) * (h)) + ext_size, 16)) -#define NV12N_S2B_SIZE(w, h) ((GRALLOC_ALIGN((w) / 4, 16) * (h)) + 64) -#define NV12M_S8B_SIZE(w, h, ext_size) PLANE_SIZE(w, h, ext_size) - -#ifdef GRALLOC_MSCL_ALIGN_RESTRICTION -#define NV12M_S2B_LUMA_SIZE(w, h, ext_size) ((GRALLOC_ALIGN((w) / 4, 16) * (GRALLOC_ALIGN(h, 16))) + ext_size) -#define NV12M_S2B_CHROMA_SIZE(w, h, ext_size) ((GRALLOC_ALIGN((w) / 4, 16) * (GRALLOC_ALIGN(h, 16) / 2)) + ext_size) -#else -#define NV12M_S2B_LUMA_SIZE(w, h, ext_size) ((GRALLOC_ALIGN((w) / 4, 16) * (h)) + ext_size) -#define NV12M_S2B_CHROMA_SIZE(w, h, ext_size) ((GRALLOC_ALIGN((w) / 4, 16) * (h / 2)) + ext_size) -#endif - -// MSCL -#define MSCL_ALIGN 128 - -#ifdef GRALLOC_MSCL_ALIGN_RESTRICTION -#define MSCL_EXT_SIZE 512 -#else -#define MSCL_EXT_SIZE 0 -#endif - -#ifdef GRALLOC_MSCL_ALLOC_RESTRICTION -#define SIZE_4K 4096 -#else -#define SIZE_4K 0 -#endif - -static inline size_t round_up_to_page_size(size_t x) -{ - return (x + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); -} - -#endif /* GRALLOC_HELPER_H_ */ diff --git a/gralloc3/src/gralloc_priv.h b/gralloc3/src/gralloc_priv.h deleted file mode 100644 index a537456..0000000 --- a/gralloc3/src/gralloc_priv.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2017 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef GRALLOC_PRIV_H_ -#define GRALLOC_PRIV_H_ - -#include <stdint.h> -#include <pthread.h> -#include <errno.h> -#include <linux/fb.h> -#include <sys/types.h> -#include <unistd.h> -#include <sys/mman.h> -#include <cutils/native_handle.h> -#include <utils/Log.h> - -/* As this file is included by clients, support GRALLOC_USE_GRALLOC1_API - * flag for 0.3 and 1.0 clients. 2.x+ clients must set GRALLOC_VERSION_MAJOR, - * which is supported for all versions. - */ -#ifndef GRALLOC_VERSION_MAJOR - #ifdef GRALLOC_USE_GRALLOC1_API - #if GRALLOC_USE_GRALLOC1_API == 0 - #define GRALLOC_VERSION_MAJOR 0 - #elif GRALLOC_USE_GRALLOC1_API == 1 - #define GRALLOC_VERSION_MAJOR 1 - #endif - #else - #if PLATFORM_SDK_VERSION > 24 - #define GRALLOC_VERSION_MAJOR 1 - #else - #define GRALLOC_VERSION_MAJOR 0 - #endif - #endif -#endif - -#if GRALLOC_VERSION_MAJOR == 2 - #if PLATFORM_SDK_VERSION >= 28 - #define HIDL_IMAPPER_NAMESPACE V2_1 - #define HIDL_IALLOCATOR_NAMESPACE V2_0 - #define HIDL_COMMON_NAMESPACE V1_1 - - /* Allocator = 2.0, Mapper = 2.1 and Common = 1.1 */ - #define HIDL_ALLOCATOR_VERSION_SCALED 200 - #define HIDL_MAPPER_VERSION_SCALED 210 - #define HIDL_COMMON_VERSION_SCALED 110 - #elif PLATFORM_SDK_VERSION >= 26 - #define HIDL_IMAPPER_NAMESPACE V2_0 - #define HIDL_IALLOCATOR_NAMESPACE V2_0 - #define HIDL_COMMON_NAMESPACE V1_0 - - /* Allocator = 2.0, Mapper = 2.0 and Common = 1.0 */ - #define HIDL_ALLOCATOR_VERSION_SCALED 200 - #define HIDL_MAPPER_VERSION_SCALED 200 - #define HIDL_COMMON_VERSION_SCALED 100 - #else - #error "Gralloc 2.x is not supported on platform SDK version PLATFORM_SDK_VERSION" - #endif -#endif - -#if (GRALLOC_VERSION_MAJOR != 2) && (GRALLOC_VERSION_MAJOR != 1) && (GRALLOC_VERSION_MAJOR != 0) - #error " Gralloc version $(GRALLOC_VERSION_MAJOR) is not supported" -#endif - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include "mali_gralloc_formats.h" -#include "mali_gralloc_usages.h" -#include "gralloc_helper.h" - -#if (GRALLOC_VERSION_MAJOR == 2) || (GRALLOC_VERSION_MAJOR == 0) || \ - ((GRALLOC_VERSION_MAJOR == 1) && !defined(GRALLOC_DISABLE_PRIVATE_BUFFER_DEF)) - -/* - * This header file contains the private buffer definition. For gralloc 0.3 it will - * always be exposed, but for gralloc 1.0 it will be removed at some point in the future. - * - * GRALLOC_DISABLE_PRIVATE_BUFFER_DEF is intended for DDKs to test while implementing - * the new private API. - */ -#include "mali_gralloc_buffer.h" -#endif - -#if GRALLOC_VERSION_MAJOR == 1 - -/* gralloc 1.0 supports the new private interface that abstracts - * the private buffer definition to a set of defined APIs. - */ -#include "mali_gralloc_private_interface.h" -#endif - -#endif /* GRALLOC_PRIV_H_ */ diff --git a/gralloc3/src/gralloc_vendor_interface.cpp b/gralloc3/src/gralloc_vendor_interface.cpp deleted file mode 100644 index 1dd02bb..0000000 --- a/gralloc3/src/gralloc_vendor_interface.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include <gralloc3/gralloc_vendor_interface.h> - -#include <android/hardware/graphics/mapper/2.0/IMapper.h> - -#include "GrallocBufferDescriptor.h" -#include "mali_gralloc_buffer.h" -#include "mali_gralloc_bufferallocation.h" -#include "mali_gralloc_ion.h" -#include "mali_gralloc_formats.h" -#include "gralloc_buffer_priv.h" -#include "exynos_format.h" -#include "format_info.h" - -namespace android::hardware::graphics::allocator::priv { - -struct Descriptor { - unsigned int size = 0; - uint64_t producer_usage = 0; - uint64_t consumer_usage = 0; - - struct PlaneDescriptor { - int fd = -1; - size_t size = 0; - off_t offset = 0; - int stride_byte = 0; - }; - std::vector<PlaneDescriptor> planes; - - int width = 0; - int height = 0; - int stride_pixel = 0; - int format = 0; -}; - -Descriptor *createDescriptor() { return new Descriptor(); } -void deleteDescriptor(Descriptor *descriptor) { delete descriptor; } - -void setProducerUsage(Descriptor &descriptor, uint64_t usage) { - descriptor.producer_usage = usage; -} - -void setConsumerUsage(Descriptor &descriptor, uint64_t usage) { - descriptor.consumer_usage = usage; -} - -void setPlaneCount(Descriptor &descriptor, int count) { - descriptor.planes.resize(count); -} - -void setPlane(Descriptor &descriptor, int index, int fd, size_t size, off_t offset, int stride_byte) { - descriptor.planes[index].fd = fd; - descriptor.planes[index].size = size; - descriptor.planes[index].offset = offset; - descriptor.planes[index].stride_byte = stride_byte; -} - -void setWidth(Descriptor &descriptor, int width) { - descriptor.width = width; -} - -void setHeight(Descriptor &descriptor, int height) { - descriptor.height = height; -} - -void setStridePixel(Descriptor &descriptor, int stride_pixel) { - descriptor.stride_pixel = stride_pixel; -} - -void setFormat(Descriptor &descriptor, int format) { - descriptor.format = format; -} - -uint8_t getFormatBitsPerPixel(uint64_t format) { - auto idx = get_format_index(format); - if (idx == -1) { - ALOGE("getFormatBitsPerPixel failed, invalid format %" PRIu64 "", format); - return 0; - } - return formats[idx].bpp[0]; -} - -buffer_handle_t createNativeHandle(const Descriptor &descriptor) { - for (int i = 0; i < descriptor.planes.size(); ++i) { - off64_t fd_size = lseek64(descriptor.planes[i].fd, 0, SEEK_END); - if (fd_size < descriptor.planes[i].size) { - ALOGE("createNativeHandle failed: plane[%d] requested size greater than fd size.", - i); - return nullptr; - } - } - - buffer_descriptor_t buffer_descriptor; - - buffer_descriptor.pixel_stride = descriptor.stride_pixel; - buffer_descriptor.width = descriptor.width; - buffer_descriptor.height = descriptor.height; - buffer_descriptor.layer_count = 1; - buffer_descriptor.hal_format = descriptor.format; - buffer_descriptor.producer_usage = descriptor.producer_usage; - buffer_descriptor.consumer_usage = descriptor.consumer_usage; - buffer_descriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; - buffer_descriptor.signature = sizeof(buffer_descriptor_t); - - buffer_descriptor.alloc_format = buffer_descriptor.internal_format - = buffer_descriptor.hal_format; - - buffer_descriptor.fd_count = buffer_descriptor.plane_count - = descriptor.planes.size(); - for (int i = 0; i < descriptor.planes.size(); ++i) { - buffer_descriptor.sizes[i] = descriptor.planes[i].size; - } - - auto format_index = get_format_index(descriptor.format); - if (format_index == -1) { - ALOGE("get_format_index failed, invalid format %d", descriptor.format); - return 0; - } - for (int i = 0; i < descriptor.planes.size(); ++i) { - uint8_t bpp = formats[format_index].bpp[i]; - if (bpp == 0) { - ALOGE("createNativeHandle failed, format %d has bpp[%d]=0", - descriptor.format, i); - return nullptr; - } - buffer_descriptor.plane_info[i] = { - .byte_stride = static_cast<uint32_t>((descriptor.planes[i].stride_byte * bpp) / 8), - .alloc_width = buffer_descriptor.width, - .alloc_height = buffer_descriptor.height, - }; - } - - mali_gralloc_derive_format_and_size(nullptr, &buffer_descriptor); - - const gralloc_buffer_descriptor_t gralloc_buffer_descriptor = - reinterpret_cast<const gralloc_buffer_descriptor_t>(&buffer_descriptor); - - buffer_handle_t tmp_buffer; - bool shared; - // TODO(modan@, make mali_gralloc_ion_allocate accept multiple fds) - int allocResult = mali_gralloc_ion_allocate(&gralloc_buffer_descriptor, 1, &tmp_buffer, &shared, - descriptor.planes[0].fd); - if (allocResult < 0) { - return nullptr; - } - - private_handle_t *private_handle = const_cast<private_handle_t *>( - static_cast<const private_handle_t *>(tmp_buffer)); - // TODO(modan@, handle all plane offsets) - private_handle->offset = private_handle->plane_info[0].offset = descriptor.planes[0].offset; - - int err = gralloc_buffer_attr_allocate(private_handle); - if (err) { - ALOGE("createNativeHandle failed, gralloc_buffer_attr_allocate returned %d.", err); - mali_gralloc_ion_free(private_handle); - return nullptr; - } - return tmp_buffer; -} - -} // namespace android::hardware::graphics::allocator::priv diff --git a/gralloc3/src/gralloc_vsync.h b/gralloc3/src/gralloc_vsync.h deleted file mode 100644 index af2bd2b..0000000 --- a/gralloc3/src/gralloc_vsync.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2014 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _GRALLOC_VSYNC_H_ -#define _GRALLOC_VSYNC_H_ - -struct framebuffer_device_t; - -/* Enables vsync interrupt. */ -int gralloc_vsync_enable(struct framebuffer_device_t *dev); -/* Disables vsync interrupt. */ -int gralloc_vsync_disable(struct framebuffer_device_t *dev); -/* Waits for the vsync interrupt. */ -int gralloc_wait_for_vsync(struct framebuffer_device_t *dev); - -#endif /* _GRALLOC_VSYNC_H_ */ diff --git a/gralloc3/src/gralloc_vsync_default.cpp b/gralloc3/src/gralloc_vsync_default.cpp deleted file mode 100644 index 5909a06..0000000 --- a/gralloc3/src/gralloc_vsync_default.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2014-2018 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <sys/ioctl.h> -#include <errno.h> -#include <system/window.h> - -#include <hardware/hardware.h> -#include <hardware/fb.h> - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include "mali_gralloc_module.h" -#include "mali_gralloc_private_interface_types.h" -#include "mali_gralloc_buffer.h" -#include "gralloc_vsync.h" -#include "gralloc_vsync_report.h" - -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) - -int gralloc_vsync_enable(framebuffer_device_t *dev) -{ - GRALLOC_UNUSED(dev); - return 0; -} - -int gralloc_vsync_disable(framebuffer_device_t *dev) -{ - GRALLOC_UNUSED(dev); - return 0; -} - -int gralloc_wait_for_vsync(framebuffer_device_t *dev) -{ - private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); - - if (MALI_DPY_TYPE_CLCD == m->dpy_type || MALI_DPY_TYPE_HDLCD == m->dpy_type) - { - /* Silently ignore wait for vsync as neither PL111 nor HDLCD implement this IOCTL. */ - return 0; - } - - if (m->swapInterval) - { - int crtc = 0; - gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT); - - if (ioctl(m->framebuffer->fb_fd, FBIO_WAITFORVSYNC, &crtc) < 0) - { - gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); - return -errno; - } - - gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); - } - - return 0; -} diff --git a/gralloc3/src/mali_gralloc_buffer.h b/gralloc3/src/mali_gralloc_buffer.h deleted file mode 100644 index 7c7a8c7..0000000 --- a/gralloc3/src/mali_gralloc_buffer.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (C) 2017-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MALI_GRALLOC_BUFFER_H_ -#define MALI_GRALLOC_BUFFER_H_ - -#include <inttypes.h> -#include <stdint.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <sys/mman.h> -#include <cutils/native_handle.h> -#include <log/log.h> -#include <string.h> -//#include <linux/ion.h> - -#include "gralloc_helper.h" -#include "mali_gralloc_private_interface_types.h" - -typedef int ion_user_handle_t; - -/* NOTE: - * If your framebuffer device driver is integrated with dma_buf, you will have to - * change this IOCTL definition to reflect your integration with the framebuffer - * device. - * Expected return value is a structure filled with a file descriptor - * backing your framebuffer device memory. - */ -struct fb_dmabuf_export -{ - __u32 fd; - __u32 flags; -}; -#define FBIOGET_DMABUF _IOR('F', 0x21, struct fb_dmabuf_export) - -/* the max string size of GRALLOC_HARDWARE_GPU0 & GRALLOC_HARDWARE_FB0 - * 8 is big enough for "gpu0" & "fb0" currently - */ -#define MALI_GRALLOC_HARDWARE_MAX_STR_LEN 8 -#define NUM_FB_BUFFERS 2 - -/* Define number of shared file descriptors */ -#define GRALLOC_ARM_NUM_FDS 2 - -#define NUM_INTS_IN_PRIVATE_HANDLE ((sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int) - GRALLOC_ARM_NUM_FDS) - -#define SZ_4K 0x00001000 -#define SZ_2M 0x00200000 - -/* - * Maximum number of pixel format planes. - * Plane [0]: Single plane formats (inc. RGB, YUV) and Y - * Plane [1]: U/V, UV - * Plane [2]: V/U - */ -#define MAX_PLANES 3 - -typedef struct plane_info { - - /* - * Offset to plane (in bytes), - * from the start of the allocation. - */ - uint32_t offset; - - /* - * Byte Stride: number of bytes between two vertically adjacent - * pixels in given plane. This can be mathematically described by: - * - * byte_stride = ALIGN((alloc_width * bpp)/8, alignment) - * - * where, - * - * alloc_width: width of plane in pixels (c.f. pixel_stride) - * bpp: average bits per pixel - * alignment (in bytes): dependent upon pixel format and usage - * - * For uncompressed allocations, byte_stride might contain additional - * padding beyond the alloc_width. For AFBC, alignment is zero. - */ - uint32_t byte_stride; - - /* - * Dimensions of plane (in pixels). - * - * For single plane formats, pixels equates to luma samples. - * For multi-plane formats, pixels equates to the number of sample sites - * for the corresponding plane, even if subsampled. - * - * AFBC compressed formats: requested width/height are rounded-up - * to a whole AFBC superblock/tile (next superblock at minimum). - * Uncompressed formats: dimensions typically match width and height - * but might require pixel stride alignment. - * - * See 'byte_stride' for relationship between byte_stride and alloc_width. - * - * Any crop rectangle defined by GRALLOC_ARM_BUFFER_ATTR_CROP_RECT must - * be wholly within the allocation dimensions. The crop region top-left - * will be relative to the start of allocation. - */ - uint32_t alloc_width; - uint32_t alloc_height; -} plane_info_t; - -struct private_handle_t; - -#ifndef __cplusplus -/* C99 with pedantic don't allow anonymous unions which is used in below struct - * Disable pedantic for C for this struct only. - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" -#endif - -#ifdef __cplusplus -struct private_handle_t : public native_handle -{ -#else -struct private_handle_t -{ - struct native_handle nativeHandle; -#endif - -#ifdef __cplusplus - /* Never intended to be used from C code */ - enum - { - PRIV_FLAGS_FRAMEBUFFER = 1U << 0, - PRIV_FLAGS_USES_ION_COMPOUND_HEAP = 1U << 1, - PRIV_FLAGS_USES_ION = 1U << 2, - PRIV_FLAGS_USES_ION_DMA_HEAP = 1U << 3, - PRIV_FLAGS_USES_2PRIVATE_DATA = 1U << 4, - PRIV_FLAGS_USES_3PRIVATE_DATA = 1U << 5, - }; - - enum - { - LOCK_STATE_WRITE = 1 << 31, - LOCK_STATE_MAPPED = 1 << 30, - LOCK_STATE_READ_MASK = 0x3FFFFFFF - }; -#endif - - /* - * Shared file descriptor for dma_buf sharing. This must be the first element in the - * structure so that binder knows where it is and can properly share it between - * processes. - * DO NOT MOVE THIS ELEMENT! - */ - union - { - int share_fd; - int fds[5]; - }; - - // ints - int magic; - int flags; - - /* - * Input properties. - * - * req_format: Pixel format, base + private modifiers. - * width/height: Buffer dimensions. - * producer/consumer_usage: Buffer usage (indicates IP) - */ - int width; - int height; - int req_format; - uint64_t producer_usage; - uint64_t consumer_usage; - - /* - * DEPRECATED members. - * Equivalent information can be obtained from other fields: - * - * - 'internal_format' --> alloc_format - * - 'stride' (pixel stride) ~= plane_info[0].alloc_width - * - 'byte_stride' ~= plane_info[0].byte_stride - * - 'internalWidth' ~= plane_info[0].alloc_width - * - 'internalHeight' ~= plane_info[0].alloc_height - * - * '~=' (approximately equal) is used because the fields were either previously - * incorrectly populated by gralloc or the meaning has slightly changed. - * - * NOTE: 'stride' values sometimes vary significantly from plane_info[0].alloc_width. - */ - union - { - uint32_t format; - uint64_t internal_format = 0; - }; - - /* - * Allocation properties. - * - * alloc_format: Pixel format (base + modifiers). NOTE: base might differ from requested - * format (req_format) where fallback to single-plane format was required. - * plane_info: Per plane allocation information. - * size: Total bytes allocated for buffer (inc. all planes, layers. etc.). - * layer_count: Number of layers allocated to buffer. - * All layers are the same size (in bytes). - * Multi-layers supported in v1.0, where GRALLOC1_CAPABILITY_LAYERED_BUFFERS is enabled. - * Layer size: 'size' / 'layer_count'. - * Layer (n) offset: n * ('size' / 'layer_count'), n=0 for the first layer. - * - */ - uint64_t alloc_format; - plane_info_t plane_info[MAX_PLANES]; - union - { - int size; - int sizes[3]; - }; - uint32_t stride; - uint32_t layer_count; - - union - { - void *base; - uint64_t bases[3]; - }; - - uint64_t backing_store_id; - int backing_store_size; - int cpu_read; /**< Buffer is locked for CPU read when non-zero. */ - int cpu_write; /**< Buffer is locked for CPU write when non-zero. */ - int allocating_pid; - int remote_pid; - int ref_count; - // locally mapped shared attribute area - union - { - void *attr_base; - uint64_t padding3; - }; - - /* - * Deprecated. - * Use GRALLOC_ARM_BUFFER_ATTR_DATASPACE - * instead. - */ - mali_gralloc_yuv_info yuv_info; - - // Following members is for framebuffer only - int fb_fd; - union - { - off_t offset; - uint64_t padding4; - }; - - /* - * min_pgsz denotes minimum phys_page size used by this buffer. - * if buffer memory is physical contiguous set min_pgsz to buff->size - * if not sure buff's real phys_page size, you can use SZ_4K for safe. - */ - int min_pgsz = SZ_4K; - - int is_compressible = 0; - - ion_user_handle_t ion_handles[3] = {0, 0, 0}; - - int PRIVATE_1 = 0; - int PRIVATE_2 = 0; - int plane_count = 1; - -#ifdef __cplusplus - /* - * We track the number of integers in the structure. There are 16 unconditional - * integers (magic - pid, yuv_info, fd and offset). Note that the fd element is - * considered an int not an fd because it is not intended to be used outside the - * surface flinger process. The GRALLOC_ARM_NUM_INTS variable is used to track the - * number of integers that are conditionally included. Similar considerations apply - * to the number of fds. - */ - static const int sNumFds = GRALLOC_ARM_NUM_FDS; - static const int sMagic = 0x3141592; - - private_handle_t(int _flags, int _size, void *_base, uint64_t _consumer_usage, uint64_t _producer_usage, - int fb_file, off_t fb_offset, int _byte_stride, int _width, int _height, uint64_t _alloc_format) - : share_fd(-1) - , magic(sMagic) - , flags(_flags) - , width(0) - , height(0) - , req_format(0) - , producer_usage(_producer_usage) - , consumer_usage(_consumer_usage) - , alloc_format(_alloc_format) - , size(_size) - , stride(0) - , layer_count(0) - , base(_base) - , backing_store_id(0x0) - , backing_store_size(0) - , cpu_read(0) - , cpu_write(0) - , allocating_pid(getpid()) - , remote_pid(-1) - , ref_count(1) - , attr_base(MAP_FAILED) - , yuv_info(MALI_YUV_NO_INFO) - , fb_fd(fb_file) - , offset(fb_offset) - , plane_count(1) - { - version = sizeof(native_handle); - - fds[1] = fds[2] = fds[3] = fds[4] = -1; - sizes[1] = sizes[2] = 0; - - numFds = sNumFds; - numInts = NUM_INTS_IN_PRIVATE_HANDLE; - memset(plane_info, 0, sizeof(plane_info_t) * MAX_PLANES); - - bases[1] = 0; - bases[2] = 0; - - plane_info[0].offset = fb_offset; - plane_info[0].byte_stride = _byte_stride; - plane_info[0].alloc_width = _width; - plane_info[0].alloc_height = _height; - } - - private_handle_t(int _flags, int _size, int _size1, int _size2, int _min_pgsz, - uint64_t _consumer_usage, uint64_t _producer_usage, - int _shared_fd, int _fd_yuv1, int _fd_yuv2, - int _req_format, uint64_t _internal_format, uint64_t _alloc_format, - int _width, int _height, int _backing_store_size, uint32_t _stride, - uint64_t _layer_count, plane_info_t _plane_info[MAX_PLANES], int _is_compressible, int _plane_count) - : share_fd(_shared_fd) - , magic(sMagic) - , flags(_flags) - , width(_width) - , height(_height) - , req_format(_req_format) - , producer_usage(_producer_usage) - , consumer_usage(_consumer_usage) - , internal_format(_internal_format) - , alloc_format(_alloc_format) - , stride(_stride) - , layer_count(_layer_count) - , base(NULL) - , backing_store_id(0x0) - , backing_store_size(_backing_store_size) - , cpu_read(0) - , cpu_write(0) - , allocating_pid(getpid()) - , remote_pid(-1) - , ref_count(1) - , attr_base(MAP_FAILED) - , yuv_info(MALI_YUV_NO_INFO) - , fb_fd(-1) - , offset(0) - , min_pgsz(_min_pgsz) - , is_compressible(_is_compressible) - , plane_count(_plane_count) - { - version = sizeof(native_handle); - - fds[1] = fds[2] = fds[3] = fds[4] = -1; - sizes[0] = _size; - sizes[1] = _size1; - sizes[2] = _size2; - - numFds = sNumFds; - numInts = NUM_INTS_IN_PRIVATE_HANDLE; - memcpy(plane_info, _plane_info, sizeof(plane_info_t) * MAX_PLANES); - - if (_fd_yuv1 != -1) - { - fds[1] = _fd_yuv1; - numFds++; - numInts--; - } - if (_fd_yuv2 != -1) - { - fds[2] = _fd_yuv2; - numFds++; - numInts--; - } - - bases[1] = 0; - bases[2] = 0; - } - - ~private_handle_t() - { - magic = 0; - } - - void dump(const char *str) const - { - ALOGI("[%s] " - "fd(%d %d %d %d) " - "flags(%d) " - "wh(%d %d) " - "req_format(0x%x) " - "usage_pc(0x%" PRIx64 " 0x%" PRIx64 ") " - "interal_format(0x%" PRIx64 ") " - "stride(%d)" - "plane[0] (offset(%d) byte_stride(%d) internal_wh(%d %d)) " - "plane[1] (offset(%d) byte_stride(%d) internal_wh(%d %d)) " - "plane[2] (offset(%d) byte_stride(%d) internal_wh(%d %d)) " - "alloc_format(0x%" PRIx64 ") " - "size(%d %d %d) " - "layer_count(%d) plane_count(%d)" - "bases(0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 ") " - "\n", - str, - fds[0], fds[1], fds[2], fds[3], - flags, - width, height, - req_format, - producer_usage, consumer_usage, - internal_format, - stride, - plane_info[0].offset, plane_info[0].byte_stride, plane_info[0].alloc_width, plane_info[0].alloc_height, - plane_info[1].offset, plane_info[1].byte_stride, plane_info[1].alloc_width, plane_info[1].alloc_height, - plane_info[2].offset, plane_info[2].byte_stride, plane_info[2].alloc_width, plane_info[2].alloc_height, - alloc_format, - sizes[0], sizes[1], sizes[2], - layer_count, plane_count, - bases[0], bases[1], bases[2] - ); - } - - bool usesPhysicallyContiguousMemory() - { - return (flags & PRIV_FLAGS_FRAMEBUFFER) ? true : false; - } - - static int validate(const native_handle *h) - { - const private_handle_t *hnd = (const private_handle_t *)h; - - if (!h || h->version != sizeof(native_handle) || - hnd->numInts + hnd->numFds != NUM_INTS_IN_PRIVATE_HANDLE + sNumFds || - hnd->magic != sMagic) - { - return -EINVAL; - } - - return 0; - } - - bool is_multi_plane() const - { - /* For multi-plane, the byte stride for the second plane will always be non-zero. */ - return plane_count > 1; - } - - static private_handle_t *dynamicCast(const native_handle *in) - { - if (validate(in) == 0) - { - return (private_handle_t *)in; - } - - return NULL; - } - - int get_share_attr_fd() const - { - return fds[numFds - 1]; - } - - void set_share_attr_fd(int _share_attr_fd) - { - fds[numFds - 1] = _share_attr_fd; - } - - int get_num_ion_fds() const - { - return numFds - 1; - } -#endif -}; -#ifndef __cplusplus -/* Restore previous diagnostic for pedantic */ -#pragma GCC diagnostic pop -#endif - -#endif /* MALI_GRALLOC_BUFFER_H_ */ diff --git a/gralloc3/src/mali_gralloc_bufferaccess.cpp b/gralloc3/src/mali_gralloc_bufferaccess.cpp deleted file mode 100644 index 13dc737..0000000 --- a/gralloc3/src/mali_gralloc_bufferaccess.cpp +++ /dev/null @@ -1,1382 +0,0 @@ -/* - * Copyright (C) 2016-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <errno.h> -#include <inttypes.h> -#include <inttypes.h> -#include <sync/sync.h> - -#if GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#elif GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 2 -#include <android/hardware/graphics/mapper/2.0/IMapper.h> -#include <android/hardware/graphics/common/1.0/types.h> -using android::hardware::graphics::mapper::V2_0::Error; -#endif - -#include "mali_gralloc_module.h" -#include "mali_gralloc_private_interface_types.h" -#include "mali_gralloc_buffer.h" -#include "mali_gralloc_formats.h" -#include "mali_gralloc_usages.h" -#include "mali_gralloc_ion.h" -#include "gralloc_helper.h" -#include "format_info.h" - - -enum tx_direction -{ - TX_NONE = 0, - TX_TO_DEVICE, - TX_FROM_DEVICE, - TX_BOTH, -}; - - -static enum tx_direction get_tx_direction(const uint64_t usage) -{ - const bool read = (usage & GRALLOC_USAGE_SW_READ_MASK) ? true : false; - const bool write = (usage & GRALLOC_USAGE_SW_WRITE_MASK) ? true : false; - enum tx_direction dir = TX_NONE; - - if (read && write) - { - dir = TX_BOTH; - } - else if (write) - { - dir = TX_TO_DEVICE; - } - else if (read) - { - dir = TX_FROM_DEVICE; - } - - return dir; -} - -static void buffer_sync(private_handle_t * const hnd, - const enum tx_direction direction) -{ - const uint64_t usage = hnd->producer_usage | hnd->consumer_usage; - - if ((usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) == 0) - { - return; - } - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) - { - if (direction != TX_NONE) - { - hnd->cpu_read = (direction == TX_FROM_DEVICE || direction == TX_BOTH) ? 1 : 0; - hnd->cpu_write = (direction == TX_TO_DEVICE || direction == TX_BOTH) ? 1 : 0; - - const int status = mali_gralloc_ion_sync_start(hnd, - hnd->cpu_read ? true : false, - hnd->cpu_write ? true : false); - if (status < 0) - { - return; - } - } - else if (hnd->cpu_read || hnd->cpu_write) - { - const int status = mali_gralloc_ion_sync_end(hnd, - hnd->cpu_read ? true : false, - hnd->cpu_write ? true : false); - if (status < 0) - { - return; - } - - hnd->cpu_read = 0; - hnd->cpu_write = 0; - } - } -} - - -static int ion_map_for_lock(private_handle_t *hnd) -{ - int ret = 0; - - if (!hnd->bases[0] && !hnd->bases[1] && !hnd->bases[2]) - { - ret = mali_gralloc_ion_map(hnd); - - switch (ret) - { - case 1: - AWAR("AFBC buffer must not be mapped. handle(%p)", hnd); - break; - case 2: - if (!(hnd->flags & (private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA | private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA))) - { - AWAR("Secure buffer with no video private data cannot be mapped. handle(%p)", hnd); - } - break; - case 3: - AWAR("HFR buffer cannot be mapped. handle(%p)", hnd); - break; - } - } - - return ret; -} - - -/* - * Validates input parameters of lock request. - * - * @param buffer [in] The buffer to lock. - * @param l [in] Access region left offset (in pixels). - * @param t [in] Access region top offset (in pixels). - * @param w [in] Access region requested width (in pixels). - * @param h [in] Access region requested height (in pixels). - * @param usage [in] Lock request (producer and consumer combined) usage. - * - * @return 0,for valid input parameters; - * -EINVAL, for erroneous input parameters - */ -int validate_lock_input_parameters(const buffer_handle_t buffer, const int l, - const int t, const int w, const int h, - uint64_t usage) -{ - const int lock_pid = getpid(); - const private_handle_t * const hnd = (private_handle_t *)buffer; - - if ((l < 0) || (t < 0) || (w < 0) || (h < 0)) - { - AERR("Negative values for access region (l = %d t = %d w = %d and " - "h = %d) in buffer lock request are invalid. Locking PID:%d", - l, t, w, h, lock_pid); - return -EINVAL; - } - - /* Test overflow conditions on access region parameters */ - if (((l + w) < 0) || ((t + h) < 0)) - { - AERR("Encountered overflow with access region (l = %d t = %d w = %d and" - " h = %d) in buffer lock request. Locking PID:%d", - l, t, w, h, lock_pid); - return -EINVAL; - } - - /* Region of interest shall be inside the allocated buffer */ - if (((t + h) > hnd->height) || ((l + w) > hnd->width)) - { - if ((t + h) * (l + w) > hnd->height * hnd->width) - { - AERR("Buffer lock access region (l = %d t = %d w = %d " - "and h = %d) is larger than allocated buffer (width = %d and height = %d)" - " Locking PID:%d", l, t, w, h, hnd->width, hnd->height, lock_pid); - return -EINVAL; - } - else - { - AWAR("Buffer lock access region (l = %d t = %d w = %d " - "and h = %d) is outside allocated buffer (width = %d and height = %d)" - " Locking PID:%d", l, t, w, h, hnd->width, hnd->height, lock_pid); - } - } - -#if GRALLOC_IMPORT_BUFFER_REQUIRED == 1 - bool is_registered_process = false; - - /* Locking process should have a valid buffer virtual address. A process - * will have a valid buffer virtual address if it is the allocating - * process or it retained / registered a cloned buffer handle - */ - if ((hnd->allocating_pid == lock_pid) || (hnd->remote_pid == lock_pid)) - { - is_registered_process = true; - } - - if ((is_registered_process == false) || (hnd->base == NULL)) - { -#if GRALLOC_VERSION_MAJOR == 0 - AERR("The buffer must be registered before lock request"); -#else - AERR("The buffer must be retained before lock request"); -#endif - return -EINVAL; - } -#endif - - /* Reject lock requests for AFBC (compressed format) enabled buffers */ - if ((hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) != 0) - { - AERR("Lock is not supported for AFBC enabled buffers. wxh(%d %d) " - "Internal Format:0x%" PRIx64, hnd->width, hnd->height, hnd->alloc_format); - -#if GRALLOC_VERSION_MAJOR == 0 - return -EINVAL; -#elif GRALLOC_VERSION_MAJOR == 1 - return GRALLOC1_ERROR_UNSUPPORTED; -#elif GRALLOC_VERSION_MAJOR == 2 - return static_cast<int32_t>(Error::UNSUPPORTED); -#endif - } - -#if GRALLOC_VERSION_MAJOR == 0 - /* Check if the buffer was created with a usage mask incompatible with the - * requested usage flags. For compatibility, requested lock usage can be a - * subset of allocation usage - */ - if ((usage & (hnd->producer_usage | hnd->consumer_usage)) == 0) - { - AERR("Buffer lock usage:0x%" PRIx64" does not match allocation usage:0x%" - PRIx64, usage, (hnd->producer_usage | hnd->consumer_usage)); - return -EINVAL; - } -#else - /* Producer and consumer usage is verified in gralloc1 specific code. */ - GRALLOC_UNUSED(usage); -#endif - - return 0; -} - - -/* - * Locks the given buffer for the specified CPU usage. - * - * @param m [in] Gralloc module. - * @param buffer [in] The buffer to lock. - * @param usage [in] Producer and consumer combined usage. - * @param l [in] Access region left offset (in pixels). - * @param t [in] Access region top offset (in pixels). - * @param w [in] Access region requested width (in pixels). - * @param h [in] Access region requested height (in pixels). - * @param vaddr [out] To be filled with a CPU-accessible pointer to - * the buffer data for CPU usage. - * - * @return 0, when the locking is successful; - * Appropriate error, otherwise - * - * @Note: There is no way to ascertain whether buffer data is valid or not (for - * example, establishing if the h/w needs to finish rendering or if CPU - * caches need to be synchronized). - * - * @Note: Locking a buffer simultaneously for write or read/write leaves the - * buffer's content in an indeterminate state. - */ -int mali_gralloc_lock(const mali_gralloc_module * const m, buffer_handle_t buffer, - uint64_t usage, int l, int t, int w, int h, void **vaddr) -{ - int status; - GRALLOC_UNUSED(m); - - if (private_handle_t::validate(buffer) < 0) - { - AERR("Locking invalid buffer %p, returning error", buffer); - return -EINVAL; - } - - /* Validate input parameters for lock request */ - status = validate_lock_input_parameters(buffer, l, t, w, h, usage); - if (status != 0) - { - return status; - } - - private_handle_t *hnd = (private_handle_t *)buffer; - - /* HAL_PIXEL_FORMAT_YCbCr_*_888 buffers 'must' be locked with lock_ycbcr() */ - if ((hnd->req_format == HAL_PIXEL_FORMAT_YCbCr_420_888) || - (hnd->req_format == HAL_PIXEL_FORMAT_YCbCr_422_888) || - (hnd->req_format == HAL_PIXEL_FORMAT_YCbCr_444_888)) - { - AERR("Buffers with format YCbCr_*_888 must be locked using " - "(*lock_ycbcr). Requested format is:0x%x", hnd->req_format); - return -EINVAL; - } - - /* YUV compatible formats 'should' be locked with lock_ycbcr() */ - const int32_t format_idx = get_format_index(hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); - if (format_idx == -1) - { - AERR("Corrupted buffer format 0x%" PRIx64 " of buffer %p", hnd->alloc_format, hnd); - return -EINVAL; - } - - if (formats[format_idx].is_yuv == true) - { - switch (formats[format_idx].id) - { - case HAL_PIXEL_FORMAT_YCbCr_422_I: - case HAL_PIXEL_FORMAT_Y8: - case HAL_PIXEL_FORMAT_Y16: - case HAL_PIXEL_FORMAT_YV12: - break; - default: -#if GRALLOC_VERSION_MAJOR == 0 - AWAR("Buffers with YUV compatible formats should be locked using " - "(*lock_ycbcr). Requested format is:0x%x", hnd->req_format); -#elif GRALLOC_VERSION_MAJOR == 1 - AWAR("Buffers with YUV compatible formats should be locked using " - "GRALLOC1_FUNCTION_LOCK_FLEX. Requested format is:0x%x", hnd->req_format); -#endif - break; - } - } - - /* Populate CPU-accessible pointer when requested for CPU usage */ - if ((usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) != 0) - { - if (vaddr == NULL) - { - return -EINVAL; - } - - if (ion_map_for_lock(hnd) < 0) - { - return -EINVAL; - } - - *vaddr = (void *)hnd->base; - - buffer_sync(hnd, get_tx_direction(usage)); - } - - return 0; -} - -/* - * Locks the given ycbcr buffer for the specified CPU usage. This function can - * only be used for buffers with "8 bit sample depth" - * - * @param m [in] Gralloc module. - * @param buffer [in] The buffer to lock. - * @param usage [in] Producer and consumer combined usage. - * @param l [in] Access region left offset (in pixels). - * @param t [in] Access region top offset (in pixels). - * @param w [in] Access region requested width (in pixels). - * @param h [in] Access region requested height (in pixels). - * @param ycbcr [out] Describes YCbCr formats for consumption by applications. - * - * @return 0, when the locking is successful; - * Appropriate error, otherwise - * - * @Note: There is no way to ascertain whether buffer data is valid or not (for - * example, establishing if the h/w needs to finish rendering or if CPU - * caches need to be synchronized). - * - * @Note: Locking a buffer simultaneously for write or read/write leaves the - * buffer's content in an indeterminate state. - * - */ -int mali_gralloc_lock_ycbcr(const mali_gralloc_module *m, - const buffer_handle_t buffer, - const uint64_t usage, const int l, const int t, - const int w, const int h, android_ycbcr *ycbcr) -{ - GRALLOC_UNUSED(m); - int status; - - if (private_handle_t::validate(buffer) < 0) - { - AERR("Locking invalid buffer %p, returning error", buffer); - return -EINVAL; - } - - private_handle_t * const hnd = (private_handle_t *)buffer; - const uint32_t base_format = hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK; - - /* Validate input parameters for lock request */ - status = validate_lock_input_parameters(buffer, l, t, w, h, usage); - if (status != 0) - { - return status; - } - - const int32_t format_idx = get_format_index(base_format); - if (format_idx == -1) - { - AERR("Corrupted buffer format 0x%" PRIx64 " of buffer %p", hnd->alloc_format, hnd); - return -EINVAL; - } - - if (formats[format_idx].is_yuv != true) - { - AERR("Buffer format:0x%" PRIx64 " is not a YUV compatible format", hnd->alloc_format); - return -EINVAL; - } - - if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) - { - if (NULL == ycbcr) - { - return -EINVAL; - } - - if (ion_map_for_lock(hnd) < 0) - { - return -EINVAL; - } - - ycbcr->y = (char *)hnd->base; - ycbcr->ystride = hnd->plane_info[0].byte_stride; - - switch (base_format) - { - case MALI_GRALLOC_FORMAT_INTERNAL_Y8: - case MALI_GRALLOC_FORMAT_INTERNAL_Y16: - /* No UV plane */ - ycbcr->cstride = 0; - ycbcr->cb = NULL; - ycbcr->cr = NULL; - ycbcr->chroma_step = 0; - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_NV12: - /* UV plane */ - ycbcr->cstride = hnd->plane_info[1].byte_stride; - ycbcr->cb = (char *)hnd->base + hnd->plane_info[1].offset; - ycbcr->cr = (char *)ycbcr->cb + 1; - ycbcr->chroma_step = 2; - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_NV21: - /* VU plane */ - ycbcr->cstride = hnd->plane_info[1].byte_stride; - ycbcr->cr = (char *)hnd->base + hnd->plane_info[1].offset; - ycbcr->cb = (char *)ycbcr->cr + 1; - ycbcr->chroma_step = 2; - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_YV12: - /* V plane, U plane */ - ycbcr->cstride = hnd->plane_info[1].byte_stride; - ycbcr->cr = (char *)hnd->base + hnd->plane_info[1].offset; - ycbcr->cb = (char *)hnd->base + hnd->plane_info[2].offset; - ycbcr->chroma_step = 1; - break; - - default: - AERR("Buffer:%p of format 0x%" PRIx64 "can't be represented in" - " android_ycbcr format", hnd, hnd->alloc_format); - return -EINVAL; - } - - buffer_sync(hnd, get_tx_direction(usage)); - } - else - { - ycbcr->y = NULL; - ycbcr->cb = NULL; - ycbcr->cr = NULL; - ycbcr->ystride = 0; - ycbcr->cstride = 0; - ycbcr->chroma_step = 0; - } - - /* Reserved parameters should be set to 0 by gralloc's (*lock_ycbcr)()*/ - memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); - - return 0; -} - -/* - * Unlocks the given buffer. - * - * @param m [in] Gralloc module. - * @param buffer [in] The buffer to unlock. - * - * @return 0, when the locking is successful; - * Appropriate error, otherwise - * - * Note: unlocking a buffer which is not locked results in an unexpected behaviour. - * Though it is possible to create a state machine to track the buffer state to - * recognize erroneous conditions, it is expected of client to adhere to API - * call sequence - */ -int mali_gralloc_unlock(const mali_gralloc_module *m, buffer_handle_t buffer) -{ - GRALLOC_UNUSED(m); - - if (private_handle_t::validate(buffer) < 0) - { - AERR("Unlocking invalid buffer %p, returning error", buffer); - return -EINVAL; - } - - private_handle_t *hnd = (private_handle_t *)buffer; - buffer_sync(hnd, TX_NONE); - - return 0; -} - -#if GRALLOC_VERSION_MAJOR == 1 -/* - * Returns the number of flex layout planes which are needed to represent the - * given buffer. - * - * @param m [in] Gralloc module. - * @param buffer [in] The buffer handle for which the number of planes should be queried - * @param num_planes [out] The number of flex planes required to describe the given buffer - * - * @return GRALLOC1_ERROR_NONE The buffer's format can be represented in flex layout - * GRALLOC1_ERROR_UNSUPPORTED - The buffer's format can't be represented in flex layout - */ -int mali_gralloc_get_num_flex_planes(const mali_gralloc_module *const m, - const buffer_handle_t buffer, - uint32_t * const num_planes) -{ - GRALLOC_UNUSED(m); - - private_handle_t *hnd = (private_handle_t *)buffer; - const uint32_t base_format = hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK; - - if ((hnd->alloc_format & MALI_GRALLOC_INTFMT_EXT_MASK) != 0) - { - AERR("AFBC enabled buffers can't be represented in flex layout." - "Internal Format:0x%" PRIx64, hnd->alloc_format); - return GRALLOC1_ERROR_UNSUPPORTED; - } - - const int32_t format_idx = get_format_index(base_format); - if (format_idx == -1) - { - AERR("Corrupted buffer format 0x%" PRIx64 " of buffer %p", hnd->alloc_format, hnd); - return -EINVAL; - } - - if (formats[format_idx].flex != true) - { - AERR("Format 0x%" PRIx64 " of %p can't be represented in flex", hnd->alloc_format, hnd); - return GRALLOC1_ERROR_UNSUPPORTED; - } - - *num_planes = formats[format_idx].ncmp; - - return GRALLOC1_ERROR_NONE; -} -#endif - -/* - * Locks the given buffer asynchronously for the specified CPU usage. - * - * @param m [in] Gralloc1 module. - * @param buffer [in] The buffer to lock. - * @param usage [in] Producer and consumer combined usage. - * @param l [in] Access region left offset (in bytes). - * @param t [in] Access region top offset (in bytes). - * @param h [in] Access region requested height (in bytes). - * @param w [in] Access region requested width (in bytes). - * @param vaddr [out] To be filled with a CPU-accessible pointer to - * the buffer data for CPU usage. - * @param fence_fd [in] Refers to an acquire sync fence object. - * - * @return 0, when the locking is successful; - * Appropriate error, otherwise - */ -int mali_gralloc_lock_async(const mali_gralloc_module *m, buffer_handle_t buffer, - uint64_t usage, int l, int t, int w, int h, - void **vaddr, int32_t fence_fd) -{ - if (fence_fd >= 0) - { - sync_wait(fence_fd, -1); - close(fence_fd); - } - - return mali_gralloc_lock(m, buffer, usage, l, t, w, h, vaddr); -} - -/* - * Locks the given ycbcr buffer for the specified CPU usage asynchronously. - * This function can only be used for buffers with "8 bit sample depth" - * - * @param m [in] Gralloc module. - * @param buffer [in] The buffer to lock. - * @param usage [in] Producer and consumer combined usage. - * @param l [in] Access region left offset (in pixels). - * @param t [in] Access region top offset (in pixels). - * @param w [in] Access region requested width (in pixels). - * @param h [in] Access region requested height (in pixels). - * @param ycbcr [out] Describes YCbCr formats for consumption by applications. - * @param fence_fd [in] Refers to an acquire sync fence object. - * - * @return 0, when the locking is successful; - * Appropriate error, otherwise - */ -int mali_gralloc_lock_ycbcr_async(const mali_gralloc_module *m, - const buffer_handle_t buffer, const uint64_t usage, - const int l, const int t, const int w, - const int h, android_ycbcr *ycbcr, - const int32_t fence_fd) -{ - if (fence_fd >= 0) - { - sync_wait(fence_fd, -1); - close(fence_fd); - } - - return mali_gralloc_lock_ycbcr(m, buffer, usage, l, t, w, h, ycbcr); -} - -#if GRALLOC_VERSION_MAJOR == 1 - -/* - * Sets Android flex layout parameters. - * - * @param top_left [in] Pointer to the first byte of the top-left - * pixel of the plane. - * @param component [in] Plane's flex format (YUVA/RGBA). - * @param bits_per_component [in] Bits allocated for the component in each pixel. - * @param bits_used [in] Number of the most significant bits used in - * the format for this component. - * @param h_increment [in] Horizontal increment, in bytes, in plane to - * traverse to next horizontal pixel - * @param v_increment [in] Vertical increment, in bytes, in plane to - * traverse to next vertical pixel - * @param h_subsampling [in] Horizontal subsampling. Must be a positive power of 2. - * @param v_subsampling [in] Vertical subsampling. Must be a positive power of 2. - * @param plane [out] Flex plane layout, to be composed. - * - */ -static void set_flex_plane_params(uint8_t * const top_left, - const android_flex_component_t component, - const int32_t bits_per_component, - const int32_t bits_used, - const int32_t h_increment, - const int32_t v_increment, - const int32_t h_subsampling, - const int32_t v_subsampling, - android_flex_plane_t * const plane) -{ - plane->top_left = top_left; - plane->component = component; - plane->bits_per_component = bits_per_component; - plane->bits_used = bits_used; - plane->h_increment = h_increment; - plane->v_increment = v_increment; - plane->h_subsampling = h_subsampling; - plane->v_subsampling = v_subsampling; - - return; -} - - -static int get_flexlayout_exynos_formats_only (int base_format, uint64_t usage, - private_handle_t * const hnd, struct android_flex_layout * const flex_layout) -{ - static const int ext_size = 256; - size_t uOffset; - size_t vOffset; - android_ycbcr ycbcr; - uint32_t r = 100; - - switch (base_format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - uOffset = 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - ycbcr.cb = (void *)(((unsigned long)hnd->bases[1]) + uOffset); - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cb = (void *)((unsigned long)hnd->bases[2]); - } - - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - vOffset = 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)((unsigned long)hnd->bases[1]); - ycbcr.cr = (void *)(((unsigned long)hnd->bases[1]) + vOffset); - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[2]); - } - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC: - - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - uOffset = (SBWC_8B_Y_SIZE(hnd->width, hnd->height) + SBWC_8B_Y_HEADER_SIZE(hnd->width, hnd->height)); - vOffset = uOffset + 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)(((unsigned long)hnd->base) + uOffset); - ycbcr.cr = (void *)(((unsigned long)hnd->base) + vOffset); - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - } - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - uOffset = (SBWC_10B_Y_SIZE(hnd->width, hnd->height) + SBWC_10B_Y_HEADER_SIZE(hnd->width, hnd->height)); - vOffset = uOffset + 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)(((unsigned long)hnd->base) + uOffset); - ycbcr.cr = (void *)(((unsigned long)hnd->base) + vOffset); - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - } - break; - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - vOffset = ycbcr.ystride * hnd->height; - uOffset = vOffset + 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)(((unsigned long)hnd->base) + uOffset); - ycbcr.cr = (void *)(((unsigned long)hnd->base) + vOffset); - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - } - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: - switch (hnd->format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: - r = 50; - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: - r = 75; - break; - } - - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - uOffset = SBWCL_8B_Y_SIZE(hnd->width, hnd->height, r); - vOffset = uOffset + 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)(((unsigned long)hnd->base) + uOffset); - ycbcr.cr = (void *)(((unsigned long)hnd->base) + vOffset); - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - } - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: - switch (hnd->format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: - r = 40; - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: - r = 60; - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: - r = 80; - break; - } - - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - uOffset = SBWCL_10B_Y_SIZE(hnd->width, hnd->height, r); - vOffset = uOffset + 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)(((unsigned long)hnd->base) + uOffset); - ycbcr.cr = (void *)(((unsigned long)hnd->base) + vOffset); - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - } - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - uOffset = 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - ycbcr.cb = (void *)(((unsigned long)hnd->bases[1]) + uOffset); - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cb = (void *)((unsigned long)hnd->bases[2]); - } - - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B: - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - vOffset = 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)((unsigned long)hnd->bases[1]); - ycbcr.cr = (void *)(((unsigned long)hnd->bases[1]) + vOffset); - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[2]); - } - - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P: - ycbcr.ystride = hnd->plane_info[0].alloc_width; - ycbcr.cstride = GRALLOC_ALIGN(ycbcr.ystride/2, 16); - uOffset = ycbcr.ystride * hnd->height; - vOffset = uOffset + (ycbcr.cstride * (hnd->height / 2)); - ycbcr.chroma_step = 1; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)(((unsigned long)hnd->base) + uOffset); - ycbcr.cr = (void *)(((unsigned long)hnd->base) + vOffset); - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED: - if (usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) - { - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].byte_stride; - ycbcr.chroma_step = 1; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)((unsigned long)hnd->bases[1]); - ycbcr.cr = NULL; - } else { - AERR("Unexpected internal format %" PRIx64, hnd->internal_format); - return -EINVAL; - } - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M: - ycbcr.ystride = hnd->plane_info[0].alloc_width; - ycbcr.cstride = GRALLOC_ALIGN(ycbcr.ystride/2, 16); - ycbcr.chroma_step = 1; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)((unsigned long)hnd->bases[1]); - ycbcr.cr = (void *)((unsigned long)hnd->bases[2]); - break; - case HAL_PIXEL_FORMAT_EXYNOS_YV12_M: - ycbcr.ystride = hnd->plane_info[0].alloc_width; - ycbcr.cstride = GRALLOC_ALIGN(ycbcr.ystride/2, 16); - ycbcr.chroma_step = 1; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - ycbcr.cb = (void *)((unsigned long)hnd->bases[2]); - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN: - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - uOffset = NV12N_S8B_LUMA_SIZE(ycbcr.ystride, hnd->plane_info[0].alloc_height, ext_size); - vOffset = uOffset + 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)(((unsigned long)hnd->base) + uOffset); - ycbcr.cr = (void *)(((unsigned long)hnd->base) + vOffset); - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - } - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B: - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - uOffset = NV12N_S8B_LUMA_SIZE(ycbcr.ystride, hnd->plane_info[0].alloc_height, ext_size) + NV12N_S2B_SIZE(hnd->width, hnd->plane_info[0].alloc_height); - vOffset = uOffset + 1; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)(((unsigned long)hnd->base) + uOffset); - ycbcr.cr = (void *)(((unsigned long)hnd->base) + vOffset); - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[1]); - } - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M: - ycbcr.ystride = ycbcr.cstride = hnd->plane_info[0].alloc_width; - vOffset = 2; - ycbcr.chroma_step = 2; - ycbcr.y = (void *)((unsigned long)hnd->base); - ycbcr.cb = (void *)((unsigned long)hnd->bases[1]); - ycbcr.cr = (void *)((unsigned long)hnd->bases[1] + vOffset); - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA - && usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - ycbcr.cr = (void *)((unsigned long)hnd->bases[2]); - } - break; - default: - AERR("not exynos format: format(0x%" PRIx32 ") usage(0x%" PRIx64 ")", base_format, usage); - return -1; - } - - flex_layout->format = FLEX_FORMAT_YCbCr; - flex_layout->num_planes = 3; - for (uint32_t i = 0; i < flex_layout->num_planes; i++) { - switch (base_format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: - /* Mapper2.0 expoects bits_per_componect and bits_used to be 8 - * or else locking fails at Mapper2.0 - */ - flex_layout->planes[i].bits_per_component = 8; - flex_layout->planes[i].bits_used = 8; - break; - default: - flex_layout->planes[i].bits_per_component = 8; - flex_layout->planes[i].bits_used = 8; - } - - flex_layout->planes[i].h_increment = 1; - flex_layout->planes[i].v_increment = 1; - flex_layout->planes[i].h_subsampling = 2; - flex_layout->planes[i].v_subsampling = 2; - } - - flex_layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y); - flex_layout->planes[0].component = FLEX_COMPONENT_Y; - flex_layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride); - - flex_layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb); - flex_layout->planes[1].component = FLEX_COMPONENT_Cb; - flex_layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step); - flex_layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride); - - flex_layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr); - flex_layout->planes[2].component = FLEX_COMPONENT_Cr; - flex_layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step); - flex_layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride); - - return 0; -} - - -/* - * Locks the Gralloc 1.0 buffer, for the specified CPU usage, asynchronously. - * This function can be called on any format but populates layout parameters - * only for formats compatible with Android Flex Format. - * - * @param m [in] Gralloc module. - * @param buffer [in] The buffer to lock. - * @param usage [in] Producer and consumer combined usage. - * @param l [in] Access region left offset (in pixels). - * @param t [in] Access region top offset (in pixels). - * @param w [in] Access region requested width (in pixels). - * @param h [in] Access region requested height (in pixels). - * @param flex_layout [out] Describes flex YUV format for consumption by applications. - * @param fence_fd [in] Refers to an acquire sync fence object. - * - * @return 0, when the locking is successful; - * Appropriate error, otherwise - */ -int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, - const buffer_handle_t buffer, - const uint64_t usage, const int l, const int t, - const int w, const int h, - struct android_flex_layout * const flex_layout, - const int32_t fence_fd) -{ - GRALLOC_UNUSED(m); - - if (fence_fd >= 0) - { - sync_wait(fence_fd, -1); - close(fence_fd); - } - - private_handle_t * const hnd = (private_handle_t *)buffer; - const uint32_t base_format = hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK; - - /* Validate input parameters for lock request */ - int status = validate_lock_input_parameters(buffer, l, t, w, h, usage); - if (status != 0) - { - return status; - } - - const int32_t format_idx = get_format_index(base_format); - if (format_idx == -1) - { - AERR("Corrupted buffer format 0x%" PRIx64 " of buffer %p", hnd->alloc_format, hnd); - return -EINVAL; - } - - if (formats[format_idx].flex != true) - { - AERR("Format 0x%" PRIx64 " of %p can't be represented in flex", hnd->alloc_format, hnd); - return GRALLOC1_ERROR_UNSUPPORTED; - } - - if (ion_map_for_lock(hnd) < 0) - { - return -EINVAL; - } - - if (is_exynos_format((uint32_t)base_format)) - { - if (get_flexlayout_exynos_formats_only(base_format, usage, hnd, flex_layout) < 0) - { - AERR("Can't lock buffer %p: format %" PRIx64 " not handled", hnd, hnd->alloc_format); - return GRALLOC1_ERROR_UNSUPPORTED; - } - - buffer_sync(hnd, get_tx_direction(usage)); - - return GRALLOC1_ERROR_NONE; - } - - flex_layout->num_planes = formats[format_idx].ncmp; - switch (base_format) - { - case MALI_GRALLOC_FORMAT_INTERNAL_Y8: - flex_layout->format = FLEX_FORMAT_Y; - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 8, 8, 1, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_Y16: - flex_layout->format = FLEX_FORMAT_Y; - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 16, 16, 2, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_NV12: - /* Y:UV 4:2:0 */ - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 8, 8, 1, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset, - FLEX_COMPONENT_Cb, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset + 1, - FLEX_COMPONENT_Cr, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[2]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_NV21: - /* Y:VU 4:2:0 ordering. The flex format plane order must still - * follow YCbCr order (as defined by 'android_flex_component_t'). - */ - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 8, 8, 1, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset + 1, - FLEX_COMPONENT_Cb, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset, - FLEX_COMPONENT_Cr, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[2]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_YV12: - /* Y:V:U 4:2:0 . The flex format plane order must still follow YCbCr - * order (as defined by 'android_flex_component_t'). - */ - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 8, 8, 1, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[2].offset, - FLEX_COMPONENT_Cb, 8, 8, 1, - hnd->plane_info[2].byte_stride, 2, 2, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset, - FLEX_COMPONENT_Cr, 8, 8, 1, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[2]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_P010: - /* Y:UV 4:2:0 */ - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 16, 10, 2, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset, - FLEX_COMPONENT_Cb, 16, 10, 4, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset + 2, - FLEX_COMPONENT_Cr, 16, 10, 4, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[2]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_P210: - /* Y:UV 4:2:2 */ - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 16, 10, 2, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset, - FLEX_COMPONENT_Cb, 16, 10, 4, - hnd->plane_info[1].byte_stride, 2, 1, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset + 2, - FLEX_COMPONENT_Cr, 16, 10, 4, - hnd->plane_info[1].byte_stride, 2, 1, - &flex_layout->planes[2]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT: - /* YUYV 4:2:2 */ - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 8, 8, 2, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + 1, FLEX_COMPONENT_Cb, 8, 8, 4, - hnd->plane_info[0].byte_stride, 2, 1, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + 3, FLEX_COMPONENT_Cr, 8, 8, 4, - hnd->plane_info[0].byte_stride, 2, 1, - &flex_layout->planes[2]); - - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_NV16: - /* Y:UV 4:2:2 */ - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 8, 8, 1, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset, - FLEX_COMPONENT_Cb, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 1, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset + 1, - FLEX_COMPONENT_Cr, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 1, - &flex_layout->planes[2]); - - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_Y210: - /* YUYV 4:2:2 */ - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 16, 10, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + 2, FLEX_COMPONENT_Cb, 16, 10, 8, - hnd->plane_info[0].byte_stride, 2, 1, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + 6, FLEX_COMPONENT_Cr, 16, 10, 8, - hnd->plane_info[0].byte_stride, 2, 1, - &flex_layout->planes[2]); - - break; - -#if PLATFORM_SDK_VERSION >= 26 - /* 64-bit format that has 16-bit R, G, B, and A components, in that order */ - case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616: - flex_layout->format = FLEX_FORMAT_RGBA; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_R, 16, 16, 8, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + 2, FLEX_COMPONENT_G, 16, 16, 8, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + 4, FLEX_COMPONENT_B, 16, 16, 8, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[2]); - set_flex_plane_params((uint8_t *)hnd->base + 6, FLEX_COMPONENT_A, 16, 16, 8, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[3]); - break; -#endif - - case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888: - /* 32-bit format that has 8-bit R, G, B, and A components, in that order */ - flex_layout->format = FLEX_FORMAT_RGBA; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_R, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + 1, FLEX_COMPONENT_G, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + 2, FLEX_COMPONENT_B, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[2]); - set_flex_plane_params((uint8_t *)hnd->base + 3, FLEX_COMPONENT_A, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[3]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888: - /* 32-bit format that has 8-bit R, G, B, and unused components, in that order */ - flex_layout->format = FLEX_FORMAT_RGB; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_R, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + 1, FLEX_COMPONENT_G, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + 2, FLEX_COMPONENT_B, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[2]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888: - /* 24-bit format that has 8-bit R, G, and B components, in that order */ - flex_layout->format = FLEX_FORMAT_RGB; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_R, 8, 8, 3, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + 1, FLEX_COMPONENT_G, 8, 8, 3, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + 2, FLEX_COMPONENT_B, 8, 8, 3, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[2]); - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888: - /* 32-bit format that has 8-bit B, G, R, and A components, in that order. - * The flex format plane order must still follow FLEX_FORMAT_RGBA - * order (as defined by 'android_flex_component_t'). - */ - flex_layout->format = FLEX_FORMAT_RGBA; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_B, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[2]); - set_flex_plane_params((uint8_t *)hnd->base + 1, FLEX_COMPONENT_G, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + 2, FLEX_COMPONENT_R, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + 3, FLEX_COMPONENT_A, 8, 8, 4, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[3]); - break; - case HAL_PIXEL_FORMAT_GOOGLE_NV12_SP: - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 8, 8, 1, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset, - FLEX_COMPONENT_Cb, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset + 1, - FLEX_COMPONENT_Cr, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[2]); - break; - case HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B: - /* With Mapper2.0's default Gralloc1Hal, bits_per_component - * is restricted to 8 bits. - */ - flex_layout->format = FLEX_FORMAT_YCbCr; - - set_flex_plane_params((uint8_t *)hnd->base, FLEX_COMPONENT_Y, 8, 8, 1, - hnd->plane_info[0].byte_stride, 1, 1, - &flex_layout->planes[0]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset, - FLEX_COMPONENT_Cb, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[1]); - set_flex_plane_params((uint8_t *)hnd->base + hnd->plane_info[1].offset + 1, - FLEX_COMPONENT_Cr, 8, 8, 2, - hnd->plane_info[1].byte_stride, 2, 2, - &flex_layout->planes[2]); - break; - - default: - AERR("Can't lock buffer %p: format 0x%" PRIx64 " not handled", hnd, hnd->alloc_format); - return GRALLOC1_ERROR_UNSUPPORTED; - } - - buffer_sync(hnd, get_tx_direction(usage)); - - return GRALLOC1_ERROR_NONE; -} -#endif - -/* - * Unlocks the buffer asynchronously. - * - * @param m [in] Gralloc module. - * @param buffer [in] The buffer to unlock. - * @param fence_fd [out] Refers to an acquire sync fence object. - * - * @return 0, when the locking is successful; - * Appropriate error, otherwise - * - * Note: unlocking a buffer which is not locked results in an unexpected behaviour. - * Though it is possible to create a state machine to track the buffer state to - * recognize erroneous conditions, it is expected of client to adhere to API - * call sequence - */ -int mali_gralloc_unlock_async(const mali_gralloc_module *m, buffer_handle_t buffer, - int32_t * const fence_fd) -{ - *fence_fd = -1; - - if (mali_gralloc_unlock(m, buffer) < 0) - { - return -EINVAL; - } - - return 0; -} diff --git a/gralloc3/src/mali_gralloc_bufferaccess.h b/gralloc3/src/mali_gralloc_bufferaccess.h deleted file mode 100644 index 28e0959..0000000 --- a/gralloc3/src/mali_gralloc_bufferaccess.h +++ /dev/null @@ -1,40 +0,0 @@ - -/* - * Copyright (C) 2016-2017 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MALI_GRALLOC_BUFFERACCESS_H_ -#define MALI_GRALLOC_BUFFERACCESS_H_ - -#include "gralloc_priv.h" -#include "mali_gralloc_module.h" - -int mali_gralloc_lock(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w, int h, - void **vaddr); -int mali_gralloc_lock_ycbcr(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w, - int h, android_ycbcr *ycbcr); -int mali_gralloc_unlock(const mali_gralloc_module *m, buffer_handle_t buffer); - -int mali_gralloc_get_num_flex_planes(const mali_gralloc_module *m, buffer_handle_t buffer, uint32_t *num_planes); -int mali_gralloc_lock_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w, - int h, void **vaddr, int32_t fence_fd); -int mali_gralloc_lock_ycbcr_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, - int w, int h, android_ycbcr *ycbcr, int32_t fence_fd); -int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, - int w, int h, struct android_flex_layout *flex_layout, int32_t fence_fd); -int mali_gralloc_unlock_async(const mali_gralloc_module *m, buffer_handle_t buffer, int32_t *fence_fd); - -#endif /* MALI_GRALLOC_BUFFERACCESS_H_ */ diff --git a/gralloc3/src/mali_gralloc_bufferallocation.cpp b/gralloc3/src/mali_gralloc_bufferallocation.cpp deleted file mode 100644 index 09a1a29..0000000 --- a/gralloc3/src/mali_gralloc_bufferallocation.cpp +++ /dev/null @@ -1,1471 +0,0 @@ -/* - * Copyright (C) 2016-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <inttypes.h> -#include <assert.h> -#include <atomic> - -#include <cutils/properties.h> - -#if GRALLOC_VERSION_MAJOR <= 1 -#include <hardware/hardware.h> -#endif - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include "mali_gralloc_module.h" -#include "mali_gralloc_bufferallocation.h" -#include "mali_gralloc_ion.h" -#include "mali_gralloc_private_interface_types.h" -#include "mali_gralloc_buffer.h" -#include "gralloc_buffer_priv.h" -#include "mali_gralloc_bufferdescriptor.h" -#include "mali_gralloc_debug.h" -#include "format_info.h" - -#define AFBC_PIXELS_PER_BLOCK 256 -#define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY 16 -#define EXT_SIZE 256 - -bool afbc_format_fallback(uint32_t * const format_idx, const uint64_t usage, bool force); - - -/* - * Get a global unique ID - */ -static uint64_t getUniqueId() -{ - static std::atomic<uint32_t> counter(0); - uint64_t id = static_cast<uint64_t>(getpid()) << 32; - return id | counter++; -} - -static void afbc_buffer_align(const bool is_tiled, int *size) -{ - const uint16_t AFBC_BODY_BUFFER_BYTE_ALIGNMENT = 1024; - - int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - - if (is_tiled) - { - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } - - *size = GRALLOC_ALIGN(*size, buffer_byte_alignment); -} - -/* - * Obtain AFBC superblock dimensions from type. - */ -static rect_t get_afbc_sb_size(AllocBaseType alloc_base_type) -{ - const uint16_t AFBC_BASIC_BLOCK_WIDTH = 16; - const uint16_t AFBC_BASIC_BLOCK_HEIGHT = 16; - const uint16_t AFBC_WIDE_BLOCK_WIDTH = 32; - const uint16_t AFBC_WIDE_BLOCK_HEIGHT = 8; - const uint16_t AFBC_EXTRAWIDE_BLOCK_WIDTH = 64; - const uint16_t AFBC_EXTRAWIDE_BLOCK_HEIGHT = 4; - - rect_t sb = {0, 0}; - - switch(alloc_base_type) - { - case UNCOMPRESSED: - break; - case AFBC: - sb.width = AFBC_BASIC_BLOCK_WIDTH; - sb.height = AFBC_BASIC_BLOCK_HEIGHT; - break; - case AFBC_WIDEBLK: - sb.width = AFBC_WIDE_BLOCK_WIDTH; - sb.height = AFBC_WIDE_BLOCK_HEIGHT; - break; - case AFBC_EXTRAWIDEBLK: - sb.width = AFBC_EXTRAWIDE_BLOCK_WIDTH; - sb.height = AFBC_EXTRAWIDE_BLOCK_HEIGHT; - break; - } - return sb; -} - -/* - * Obtain AFBC superblock dimensions for specific plane. - * - * See alloc_type_t for more information. - */ -static rect_t get_afbc_sb_size(alloc_type_t alloc_type, const uint8_t plane) -{ - if (plane > 0 && alloc_type.is_afbc() && alloc_type.is_multi_plane) - { - return get_afbc_sb_size(AFBC_EXTRAWIDEBLK); - } - else - { - return get_afbc_sb_size(alloc_type.primary_type); - } -} - - -bool get_alloc_type(const uint64_t format_ext, - const uint32_t format_idx, - const uint64_t usage, - alloc_type_t * const alloc_type) -{ - alloc_type->primary_type = UNCOMPRESSED; - alloc_type->is_multi_plane = formats[format_idx].npln > 1; - alloc_type->is_tiled = false; - alloc_type->is_padded = false; - alloc_type->is_frontbuffer_safe = false; - - /* Determine AFBC type for this format. This is used to decide alignment. - Split block does not affect alignment, and therefore doesn't affect the allocation type. */ - if (format_ext & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) - { - /* YUV transform shall not be enabled for a YUV format */ - if ((formats[format_idx].is_yuv == true) && (format_ext & MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM)) - { - ALOGW("YUV Transform is incorrectly enabled for format = (%s 0x%x). Extended internal format = (%s 0x%" PRIx64 ")\n", - format_name(formats[format_idx].id), formats[format_idx].id, format_name(format_ext), format_ext); - } - - /* Determine primary AFBC (superblock) type. */ - alloc_type->primary_type = AFBC; - if (format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) - { - alloc_type->primary_type = AFBC_WIDEBLK; - } - else if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) - { - alloc_type->primary_type = AFBC_EXTRAWIDEBLK; - } - - if (format_ext & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) - { - alloc_type->is_tiled = true; - - if (formats[format_idx].npln > 1 && - (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) == 0) - { - ALOGW("Extra-wide AFBC must be signalled for multi-plane formats. " - "Falling back to single plane AFBC."); - alloc_type->is_multi_plane = false; - } - - if (format_ext & MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY) - { - alloc_type->is_frontbuffer_safe = true; - } - } - else - { - if (formats[format_idx].npln > 1) - { - ALOGW("Multi-plane AFBC is not supported without tiling. " - "Falling back to single plane AFBC."); - } - alloc_type->is_multi_plane = false; - } - - if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK && - !alloc_type->is_tiled) - { - /* Headers must be tiled for extra-wide. */ - ALOGE("ERROR: Invalid to specify extra-wide block without tiled headers."); - return false; - } - - if (alloc_type->is_frontbuffer_safe && - (format_ext & (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK | MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK))) - { - ALOGE("ERROR: Front-buffer safe not supported with wide/extra-wide block."); - } - - if (formats[format_idx].npln == 1 && - format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK && - format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) - { - /* "Wide + Extra-wide" implicitly means "multi-plane". */ - ALOGE("ERROR: Invalid to specify multiplane AFBC with single plane format."); - return false; - } - - if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING) - { - alloc_type->is_padded = true; - } - } - - return true; -} - -/* - * Initialise AFBC header based on superblock layout. - * Width and height should already be AFBC aligned. - */ -void init_afbc(uint8_t *buf, const uint64_t alloc_format, - const bool is_multi_plane, - const int w, const int h) -{ - const bool is_tiled = ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) - == MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS); - const uint32_t n_headers = (w * h) / AFBC_PIXELS_PER_BLOCK; - int body_offset = n_headers * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; - - afbc_buffer_align(is_tiled, &body_offset); - - /* - * Declare the AFBC header initialisation values for each superblock layout. - * Tiled headers (AFBC 1.2) can be initialised to zero for non-subsampled formats - * (SB layouts: 0, 3, 4, 7). - */ - uint32_t headers[][4] = { - { (uint32_t)body_offset, 0x1, 0x10000, 0x0 }, /* Layouts 0, 3, 4, 7 */ - { ((uint32_t)body_offset + (1 << 28)), 0x80200040, 0x1004000, 0x20080 } /* Layouts 1, 5 */ - }; - if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)) - { - /* Zero out body_offset for non-subsampled formats. */ - memset(headers[0], 0, sizeof(uint32_t) * 4); - } - - /* Map base format to AFBC header layout */ - const uint32_t base_format = alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK; - - /* Sub-sampled formats use layouts 1 and 5 which is index 1 in the headers array. - * 1 = 4:2:0 16x16, 5 = 4:2:0 32x8. - * - * Non-subsampled use layouts 0, 3, 4 and 7, which is index 0. - * 0 = 16x16, 3 = 32x8 + split, 4 = 32x8, 7 = 64x4. - * - * When using separated planes for YUV formats, the header layout is the non-subsampled one - * as there is a header per-plane and there is no sub-sampling within the plane. - * Separated plane only supports 32x8 or 64x4 for the luma plane, so the first plane must be 4 or 7. - * Seperated plane only supports 64x4 for subsequent planes, so these must be header layout 7. - */ - const uint32_t layout = is_subsampled_yuv(base_format) && !is_multi_plane ? 1 : 0; - - ALOGV("Writing AFBC header layout %d for format (%s %" PRIx32 ")", layout, format_name(base_format), base_format); - - for (uint32_t i = 0; i < n_headers; i++) - { - memcpy(buf, headers[layout], sizeof(headers[layout])); - buf += sizeof(headers[layout]); - } -} - -static int max(int a, int b) -{ - return a > b ? a : b; -} - -static int max(int a, int b, int c) -{ - return c > max(a, b) ? c : max(a, b); -} - -static int max(int a, int b, int c, int d) -{ - return d > max(a, b, c) ? d : max(a, b, c); -} - -/* - * Obtain plane allocation dimensions (in pixels). - * - * NOTE: pixel stride, where defined for format, is - * incorporated into allocation dimensions. - */ -static void get_pixel_w_h(uint32_t * const width, - uint32_t * const height, - const format_info_t format, - const alloc_type_t alloc_type, - const uint8_t plane, - bool has_cpu_usage) -{ - const rect_t sb = get_afbc_sb_size(alloc_type, plane); - - /* - * Round-up plane dimensions, to multiple of: - * - Samples for all channels (sub-sampled formats) - * - Memory bytes/words (some packed formats) - */ - if (plane == 0 || !format.planes_contiguous) - { - *width = GRALLOC_ALIGN(*width, format.align_w); - *height = GRALLOC_ALIGN(*height, format.align_h); - } - - /* - * Sub-sample (sub-sampled) planes. - */ - if (plane > 0) - { - *width /= format.hsub; - *height /= format.vsub; - } - - /* - * Pixel alignment (width), - * where format stride is stated in pixels. - */ - int pixel_align_w = 0, pixel_align_h = 0; - if (has_cpu_usage && (plane == 0 || !format.planes_contiguous)) - { - pixel_align_w = format.align_w_cpu; - } - else if (alloc_type.is_afbc()) - { -#define HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS (0) - uint32_t num_sb_align = 0; - if (alloc_type.is_padded && !format.is_yuv) - { - /* Align to 4 superblocks in width --> 64-byte, - * assuming 16-byte header per superblock. - */ - num_sb_align = 4; - } - pixel_align_w = max(HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS, num_sb_align) * sb.width; - } - - /* - * Determine AFBC tile size when allocating tiled headers. - */ - rect_t afbc_tile = sb; - if (alloc_type.is_tiled) - { - afbc_tile.width = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.width : 8 * afbc_tile.width; - afbc_tile.height = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.height : 8 * afbc_tile.height; - } - - if (AFBC_WIDEBLK == alloc_type.primary_type && !alloc_type.is_tiled) - { - /* - * Special case for wide block (32x8) AFBC with linear (non-tiled) - * headers: hardware reads and writes 32x16 blocks so we need to - * pad the body buffer accordingly. - * - * Note that this branch will not be taken for multi-plane AFBC - * since that requires tiled headers. - */ - pixel_align_h = max(pixel_align_h, 16); - } - - ALOGV("Plane[%hhu]: [SUB-SAMPLE] w:%d, h:%d\n", plane, *width, *height); - ALOGV("Plane[%hhu]: [PIXEL_ALIGN] w:%d, h:%d\n", plane, pixel_align_w, pixel_align_h); - ALOGV("Plane[%hhu]: [LINEAR_TILE] w:%" PRIu16 "\n", plane, format.tile_size); - ALOGV("Plane[%hhu]: [AFBC_TILE] w:%" PRIu16 ", h:%" PRIu16 "\n", plane, afbc_tile.width, afbc_tile.height); - - *width = GRALLOC_ALIGN(*width, max(1, pixel_align_w, format.tile_size, afbc_tile.width)); - *height = GRALLOC_ALIGN(*height, max(1, pixel_align_h, format.tile_size, afbc_tile.height)); - -} - - - -static uint32_t gcd(uint32_t a, uint32_t b) -{ - uint32_t r, t; - - if (a == b) - { - return a; - } - else if (a < b) - { - t = a; - a = b; - b = t; - } - - while (b != 0) - { - r = a % b; - a = b; - b = r; - } - - return a; -} - -uint32_t lcm(uint32_t a, uint32_t b) -{ - if (a != 0 && b != 0) - { - return (a * b) / gcd(a, b); - } - - return max(a, b); -} - - -/* - * YV12 stride has additional complexity since chroma stride - * must conform to the following: - * - * c_stride = ALIGN(stride/2, 16) - * - * Since the stride alignment must satisfy both CPU and HW - * constraints, the luma stride must be doubled. - */ -static void update_yv12_stride(int8_t plane, - uint32_t luma_stride, - uint32_t stride_align, - uint32_t * byte_stride) -{ - if (plane == 0) - { - /* - * Ensure luma stride is aligned to "2*lcm(hw_align, cpu_align)" so - * that chroma stride can satisfy both CPU and HW alignment - * constraints when only half luma stride (as mandated for format). - */ - *byte_stride = GRALLOC_ALIGN(luma_stride, 2 * stride_align); - } - else - { - /* - * Derive chroma stride from luma and verify it is: - * 1. Aligned to lcm(hw_align, cpu_align) - * 2. Multiple of 16px (16 bytes) - */ - *byte_stride = luma_stride / 2; - assert(*byte_stride == GRALLOC_ALIGN(*byte_stride, stride_align)); - assert(*byte_stride & 15 == 0); - } -} - - -/* - * Calculate allocation size. - * - * Determine the width and height of each plane based on pixel alignment for - * both uncompressed and AFBC allocations. - * - * @param width [in] Buffer width. - * @param height [in] Buffer height. - * @param alloc_type [in] Allocation type inc. whether tiled and/or multi-plane. - * @param format [in] Pixel format. - * @param has_cpu_usage [in] CPU usage requested (in addition to any other). - * @param size [out] Total calculated buffer size including all planes. - * @param plane_info [out] Array of calculated information for each plane. Includes - * offset, byte stride and allocation width and height. - */ -static void calc_allocation_size(const int width, - const int height, - const alloc_type_t alloc_type, - const format_info_t format, - const bool has_cpu_usage, - const bool has_hw_usage, - size_t * const size, - plane_info_t plane_info[MAX_PLANES]) -{ - plane_info[0].offset = 0; - - *size = 0; - for (uint8_t plane = 0; plane < format.npln; plane++) - { - plane_info[plane].alloc_width = width; - plane_info[plane].alloc_height = height; - get_pixel_w_h(&plane_info[plane].alloc_width, - &plane_info[plane].alloc_height, - format, - alloc_type, - plane, - has_cpu_usage); - ALOGV("Aligned w=%d, h=%d (in pixels)", - plane_info[plane].alloc_width, plane_info[plane].alloc_height); - - /* - * Calculate byte stride (per plane). - */ - if (alloc_type.is_afbc()) - { - assert((plane_info[plane].alloc_width * format.bpp_afbc[plane]) % 8 == 0); - plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp_afbc[plane]) / 8; - } - else - { - assert((plane_info[plane].alloc_width * format.bpp[plane]) % 8 == 0); - plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp[plane]) / 8; - - /* - * Align byte stride (uncompressed allocations only). - * - * Find the lowest-common-multiple of: - * 1. hw_align: Minimum byte stride alignment for HW IP (has_hw_usage == true) - * 2. cpu_align: Byte equivalent of 'align_w_cpu' (has_cpu_usage == true) - * - * NOTE: Pixel stride is defined as multiple of 'align_w_cpu'. - */ - uint16_t hw_align = 0; - if (has_hw_usage) - { - hw_align = format.is_yuv ? 16 : (format.is_rgb ? 64 : 0); - } - - uint32_t cpu_align = 0; - assert((format.bpp[plane] * format.align_w_cpu) % 8 == 0); - if (plane == 0 || !format.planes_contiguous) - cpu_align = (format.bpp[plane] * format.align_w_cpu) / 8; - - uint32_t stride_align = lcm(hw_align, cpu_align); - if (stride_align) - { - plane_info[plane].byte_stride = GRALLOC_ALIGN(plane_info[plane].byte_stride, stride_align); - plane_info[plane].alloc_width = plane_info[plane].byte_stride * 8 / format.bpp[plane]; - } - - /* - * Update YV12 stride with both CPU & HW usage due to constraint of chroma stride. - * Width is anyway aligned to 16px for luma and chroma (has_cpu_usage). - */ - /* - * This function can make yv12 align to 32 pixels or higher. - * Some apps do not use the provided stride value when a buffer is created - * Those apps may assume yv12 buffers are aligned to 32 pixels. - * So do not call this function. - if (format.id == MALI_GRALLOC_FORMAT_INTERNAL_YV12 && has_hw_usage && has_cpu_usage) - { - update_yv12_stride(plane, - plane_info[0].byte_stride, - stride_align, - &plane_info[plane].byte_stride); - } - */ - GRALLOC_UNUSED(update_yv12_stride); - } - ALOGV("Byte stride: %d", plane_info[plane].byte_stride); - - /* - * Pixel stride (CPU usage only). - * Not used in size calculation but exposed to client. - */ - if (plane == 0) - { - assert((plane_info[plane].byte_stride * 8) % format.bpp[plane] == 0); - ALOGV("Pixel stride: %d", (plane_info[plane].byte_stride * 8) / format.bpp[plane]); - } - - const uint32_t sb_num = (plane_info[plane].alloc_width * plane_info[plane].alloc_height) - / AFBC_PIXELS_PER_BLOCK; - - /* - * Calculate body size (per plane). - */ - int body_size = 0; - if (alloc_type.is_afbc()) - { - const rect_t sb = get_afbc_sb_size(alloc_type, plane); - const int sb_bytes = GRALLOC_ALIGN((format.bpp_afbc[plane] * sb.width * sb.height) / 8, 128); - body_size = sb_num * sb_bytes; - - /* When AFBC planes are stored in separate buffers and this is not the last plane, - also align the body buffer to make the subsequent header aligned. */ - if (format.npln > 1 && plane < 2) - { - afbc_buffer_align(alloc_type.is_tiled, &body_size); - } - - if (alloc_type.is_frontbuffer_safe) - { - int back_buffer_size = body_size; - afbc_buffer_align(alloc_type.is_tiled, &back_buffer_size); - body_size += back_buffer_size; - } - } - else - { - body_size = (plane_info[plane].byte_stride) * plane_info[plane].alloc_height; - } - ALOGV("Body size: %d", body_size); - - - /* - * Calculate header size (per plane). - */ - int header_size = 0; - if (alloc_type.is_afbc()) - { - /* As this is AFBC, calculate header size for this plane. - * Always align the header, which will make the body buffer aligned. - */ - header_size = sb_num * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; - afbc_buffer_align(alloc_type.is_tiled, &header_size); - } - ALOGV("AFBC Header size: %d", header_size); - - /* - * Set offset for separate chroma planes. - */ - if (plane > 0) - { - plane_info[plane].offset = *size; - } - - /* - * Set overall size. - * Size must be updated after offset. - */ - *size += body_size + header_size; - ALOGV("size=%zu",*size); - } -} - - - -/* - * Validate selected format against requested. - * Return true if valid, false otherwise. - */ -static bool validate_format(const format_info_t * const format, - const alloc_type_t alloc_type, - const buffer_descriptor_t * const bufDescriptor) -{ - if (alloc_type.is_afbc()) - { - /* - * Validate format is supported by AFBC specification and gralloc. - */ - if (format->afbc == false) - { - ALOGE("ERROR: AFBC selected but not supported for base format: (%s 0x%" PRIx32")", - format_name(format->id), format->id); - return false; - } - - /* - * Enforce consistency between number of format planes and - * request for single/multi-plane AFBC. - */ - if (((format->npln == 1 && alloc_type.is_multi_plane) || - (format->npln > 1 && !alloc_type.is_multi_plane))) - { - ALOGE("ERROR: Format ((%s %" PRIx32 "), num planes: %u) is incompatible with %s-plane AFBC request", - format_name(format->id), format->id, format->npln, (alloc_type.is_multi_plane) ? "multi" : "single"); - return false; - } - } - else - { - if (format->linear == false) - { - ALOGE("ERROR: Uncompressed format requested but not supported for base format: (%s %" PRIx32 ")", - format_name(format->id), format->id); - return false; - } - } - - if (format->id == MALI_GRALLOC_FORMAT_INTERNAL_BLOB && - bufDescriptor->height != 1) - { - ALOGE("ERROR: Height for format BLOB must be 1."); - return false; - } - - return true; -} - -static int color_space_for_dimensions(int width, int height) { - auto [sm, lg] = std::minmax(width, height); - int64_t area = static_cast<int64_t>(sm) * static_cast<int64_t>(lg); - - if ((lg >= 3840) || (sm >= 3840) || (area >= (3840ll * 1634ll))) - { - return HAL_DATASPACE_STANDARD_BT2020; - } - - if (lg <= 720) - { - if (sm <= 480) - { - return HAL_DATASPACE_STANDARD_BT601_525; - } - - if (sm <= 576) - { - return HAL_DATASPACE_STANDARD_BT601_625; - } - } - - return HAL_DATASPACE_STANDARD_BT709; -} - -static int set_dataspace(private_handle_t * const hnd, uint64_t usage, int32_t format_idx) -{ - int color_space = HAL_DATASPACE_STANDARD_UNSPECIFIED; - int range = HAL_DATASPACE_RANGE_UNSPECIFIED; - int data_space = 0; - hnd->yuv_info = MALI_YUV_NO_INFO; - int rval = -1; - int width = hnd->width; - int height = hnd->height; - - static int csc_supported = -1; - - if (csc_supported == -1) - { - csc_supported = property_get_int32("ro.vendor.gpu.dataspace", 0); -#ifdef GRALLOC_NO_CSC_SUPPORTED - csc_supported = 0; -#endif - } - - if (gralloc_buffer_attr_map(hnd, true) < 0) - { - ALOGE("Failed to map attribute region."); - goto out; - } - - if (!csc_supported) - { - if (formats[format_idx].is_yuv) - { - color_space = HAL_DATASPACE_STANDARD_BT601_625; - range = HAL_DATASPACE_RANGE_LIMITED; - hnd->yuv_info = MALI_YUV_BT601_NARROW; - - /* Special cases for Camera producers */ - switch (hnd->format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: - if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) - { - range = HAL_DATASPACE_RANGE_FULL; - hnd->yuv_info = MALI_YUV_BT601_WIDE; - } - } - - data_space = color_space | range; - } - else - { - data_space = HAL_DATASPACE_STANDARD_BT709 | HAL_DATASPACE_RANGE_FULL; - } - - gralloc_buffer_attr_write(hnd, GRALLOC_ARM_BUFFER_ATTR_FORCE_DATASPACE, &data_space); - } - else if (formats[format_idx].is_yuv) - { - /* Default YUV dataspace. */ - color_space = HAL_DATASPACE_STANDARD_BT709; - range = HAL_DATASPACE_RANGE_LIMITED; - - /* SDR 10-bit YUV is assumed to be narrow BT709. - * Dataspace for HDR content will be set (by producer) according to the HDR metadata. - */ - if (formats[format_idx].bps >= 10) - { - color_space = HAL_DATASPACE_STANDARD_BT2020; - } - else - { - color_space = color_space_for_dimensions(width, height); - } - -#if GRALLOC_VERSION_MAJOR >= 1 - /* Override YUV dataspace based on private usage. */ - switch (usage & MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_MASK) - { - case MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT601: - color_space = HAL_DATASPACE_STANDARD_BT601_625; - break; - case MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT709: - color_space = HAL_DATASPACE_STANDARD_BT709; - break; - case MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT2020: - color_space = HAL_DATASPACE_STANDARD_BT2020; - break; - } - - switch (usage & MALI_GRALLOC_USAGE_RANGE_MASK) - { - case MALI_GRALLOC_USAGE_RANGE_NARROW: - range = HAL_DATASPACE_RANGE_LIMITED; - break; - case MALI_GRALLOC_USAGE_RANGE_WIDE: - range = HAL_DATASPACE_RANGE_FULL; - break; - } - - /* Special cases for Camera producers */ - switch (hnd->format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: - if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) - { - color_space = HAL_DATASPACE_STANDARD_BT601_625; - range = HAL_DATASPACE_RANGE_FULL; - } - } - - data_space = color_space | range; - - /* Set deprecated yuv_info field. */ - switch (color_space) - { - case HAL_DATASPACE_STANDARD_BT601_625: - if (range == HAL_DATASPACE_RANGE_LIMITED) - { - hnd->yuv_info = MALI_YUV_BT601_NARROW; - } - else - { - hnd->yuv_info = MALI_YUV_BT601_WIDE; - } - break; - case HAL_DATASPACE_STANDARD_BT709: - if (range == HAL_DATASPACE_RANGE_LIMITED) - { - hnd->yuv_info = MALI_YUV_BT709_NARROW; - } - else - { - hnd->yuv_info = MALI_YUV_BT709_WIDE; - } - break; - } -#endif - } - else if (formats[format_idx].is_rgb) - { - /* Default RGB dataspace. */ - data_space = HAL_DATASPACE_STANDARD_BT709 | HAL_DATASPACE_RANGE_FULL; - } - - gralloc_buffer_attr_write(hnd, GRALLOC_ARM_BUFFER_ATTR_DATASPACE, &data_space); - - gralloc_buffer_attr_unmap(hnd); - - rval = 0; -out: - return rval; -} - -/* - * Compute SBWC buffer geometry for a buffer containing packed SBWC YUV data - * with bits per pixel bpp, width w, and height h. - * Returns a pair of { luma size, chroma size }. - */ -template <int bpp> -static std::pair<size_t, size_t> sbwc_sizes(int w, int h) { - static_assert(bpp == 8 || bpp == 10, "Unexpected bit width"); - - const size_t luma_body_size = (bpp == 8) ? - SBWC_8B_Y_SIZE(w, h) : SBWC_10B_Y_SIZE(w, h); - const size_t luma_header_size = (bpp == 8) ? - SBWC_8B_Y_HEADER_SIZE(w, h) : SBWC_10B_Y_HEADER_SIZE(w, h); - - const size_t chroma_body_size = (bpp == 8) ? - SBWC_8B_CBCR_SIZE(w, h) : SBWC_10B_CBCR_SIZE(w, h); - const size_t chroma_header_size = (bpp == 8) ? - SBWC_8B_CBCR_HEADER_SIZE(w, h) : SBWC_10B_CBCR_HEADER_SIZE(w, h); - - ALOGV("SBWC luma body size 0x%zx, header size 0x%zx", luma_body_size, luma_header_size); - ALOGV("SBWC chroma body size 0x%zx, header size 0x%zx", chroma_body_size, chroma_header_size); - - return { luma_body_size + luma_header_size, - chroma_body_size + chroma_header_size }; -} - -static int prepare_descriptor_exynos_formats(buffer_descriptor_t *bufDescriptor) -{ - size_t luma_size=0, chroma_size=0, ext_size=256; - int fd_count = 1; - int stride = 0, byte_stride = 0; - size_t luma_vstride = 0; - // Keep around original requested format for later validation - int w = bufDescriptor->width; - int h = bufDescriptor->height; - uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage; - int is_multiplane = 1; - - // Set default stride - stride = GRALLOC_ALIGN(w, 16); - luma_vstride = GRALLOC_ALIGN(h, 16); - byte_stride = stride; - - if (usage & (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER)) - { - usage |= GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA; - bufDescriptor->producer_usage |= GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA; - bufDescriptor->consumer_usage |= GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA; - } - - /* SWBC Formats have special size requirements */ - switch ((uint32_t)bufDescriptor->internal_format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC: - { - std::tie(luma_size, chroma_size) = sbwc_sizes<8>(w, h); - byte_stride = SBWC_8B_STRIDE(w); - stride = GRALLOC_ALIGN(w, 32); - luma_vstride = __ALIGN_UP(h, 8); - - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: - { - std::tie(luma_size, chroma_size) = sbwc_sizes<10>(w, h); - byte_stride = SBWC_10B_STRIDE(w); - stride = GRALLOC_ALIGN(w, 32); - luma_vstride = __ALIGN_UP(h, 8); - - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: - { - uint32_t r = 100; - - switch ((uint32_t)bufDescriptor->internal_format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: - r = 50; - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: - r = 75; - break; - } - - luma_size = SBWCL_8B_Y_SIZE(w, h, r); - chroma_size = SBWCL_8B_CBCR_SIZE(w, h, r); - - /* How to set this information for lossy formats? */ - byte_stride = SBWCL_8B_STRIDE(w, r); - - stride = GRALLOC_ALIGN(w, 32); - luma_vstride = __ALIGN_UP(h, 8); - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: - { - uint32_t r = 100; - - switch ((uint32_t)bufDescriptor->internal_format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: - r = 40; - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: - r = 60; - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: - r = 80; - break; - } - - luma_size = SBWCL_10B_Y_SIZE(w, h, r); - chroma_size = SBWCL_10B_CBCR_SIZE(w, h, r); - - byte_stride = SBWCL_10B_STRIDE(w, r); - - stride = GRALLOC_ALIGN(w, 32); - luma_vstride = __ALIGN_UP(h, 8); - - break; - } - } - - // Decide plane count and sizes - switch ((uint32_t)bufDescriptor->internal_format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: - { - fd_count = 2; - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: - { - luma_size += chroma_size; - chroma_size = 0; - - fd_count = 1; - break; - } - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - { - stride = w; - byte_stride = stride; - luma_size = PLANE_SIZE(stride , h * 3 / 2, ext_size); - luma_vstride = h; - fd_count = 1; - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YV12_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M: - { - stride = GRALLOC_ALIGN(w, 32); - byte_stride = stride; - luma_size = PLANE_SIZE(stride, luma_vstride, ext_size); -#ifdef EXYNOS_CHROMA_VSTRIDE_ALIGN - chroma_size = PLANE_SIZE(GRALLOC_ALIGN(stride / 2, 16), GRALLOC_ALIGN(luma_vstride / 2, CHROMA_VALIGN), ext_size); -#else - chroma_size = PLANE_SIZE(GRALLOC_ALIGN(stride / 2, 16), (luma_vstride / 2), ext_size); -#endif - fd_count = 3; - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED: - { - size_t chroma_vstride = GRALLOC_ALIGN(h / 2, 32); - luma_vstride = GRALLOC_ALIGN(h, 32); - luma_size = PLANE_SIZE(stride, luma_vstride, ext_size); - chroma_size = PLANE_SIZE(stride, chroma_vstride, ext_size); - byte_stride = stride * 16; - fd_count = 2; - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P: - { - /* Same as HAL_PIXEL_FORMAT_YV12 */ - chroma_size = PLANE_SIZE(GRALLOC_ALIGN(stride / 2, 16), h, ext_size); - luma_size = PLANE_SIZE(stride, h, 0) + chroma_size; - is_multiplane = 0; - fd_count = 1; - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M: - { - if (usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - { - luma_vstride = GRALLOC_ALIGN(h, 32); - } - - luma_size = PLANE_SIZE(stride, luma_vstride, ext_size); -#ifdef EXYNOS_CHROMA_VSTRIDE_ALIGN - chroma_size = PLANE_SIZE(stride, GRALLOC_ALIGN(luma_vstride / 2, CHROMA_VALIGN), ext_size); -#else - chroma_size = PLANE_SIZE(stride, luma_vstride / 2, ext_size); -#endif - fd_count = 2; - - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN: - { -#ifdef EXYNOS_CHROMA_VSTRIDE_ALIGN - chroma_size = NV12N_S8B_CHROMA_SIZE(stride, GRALLOC_ALIGN(luma_vstride / 2, CHROMA_VALIGN), ext_size); -#else - chroma_size = NV12N_S8B_CHROMA_SIZE(stride, luma_vstride / 2, ext_size); -#endif - luma_size = NV12N_S8B_LUMA_SIZE(stride, luma_vstride, ext_size) + chroma_size; - - fd_count = 1; - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B: - { - stride = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN); - byte_stride = stride; - luma_size = NV12M_S8B_SIZE(stride, luma_vstride, ext_size) + NV12M_S2B_LUMA_SIZE(w, h, ext_size); - chroma_size = NV12M_S8B_SIZE(stride, luma_vstride / 2, ext_size) + NV12M_S2B_CHROMA_SIZE(w, h, ext_size); - fd_count = 2; - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B: - { - stride = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN); - byte_stride = stride; - chroma_size = NV12N_S8B_CHROMA_SIZE(stride, luma_vstride / 2, ext_size) + NV12N_S2B_SIZE(w, luma_vstride / 2); - luma_size = NV12N_S8B_LUMA_SIZE(stride, luma_vstride, ext_size) + NV12N_S2B_SIZE(w, luma_vstride) + chroma_size; - fd_count = 1; - break; - } - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M: - { - chroma_size = P010_PLANE_SIZE(stride, luma_vstride / 2, ext_size); - luma_size = P010_PLANE_SIZE(stride, luma_vstride, ext_size); - byte_stride = stride * 2; - fd_count = 2; - break; - } - default: - AERR("invalid yuv format %x\n", (uint32_t)bufDescriptor->internal_format); - return -1; - } - - switch ((uint32_t)bufDescriptor->internal_format) - { - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B: - if (usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA) - bufDescriptor->alloc_video_private_data = 1; - - break; - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M: - bufDescriptor->alloc_video_private_data = 1; - } - - // Add MSCL_EXT_SIZE - if (w % MSCL_ALIGN) - { - luma_size += MSCL_EXT_SIZE; - chroma_size += MSCL_EXT_SIZE/2; - } - - for (int i = 0; i < fd_count; i++) - { - size_t alloc_height = i == 0 ? luma_vstride : (luma_vstride / 2); - size_t size = i == 0 ? luma_size : chroma_size; - -#ifdef GRALLOC_MSCL_ALLOC_RESTRICTION - size = size < SIZE_4K ? SIZE_4K : size; -#endif - bufDescriptor->sizes[i] = size; - - bufDescriptor->plane_info[i].alloc_width = stride; - bufDescriptor->plane_info[i].alloc_height = alloc_height; - bufDescriptor->plane_info[i].byte_stride = byte_stride; - bufDescriptor->plane_info[i].offset = 0; - } - - bufDescriptor->fd_count = fd_count; - - return 0; -} - - -int mali_gralloc_derive_format_and_size(mali_gralloc_module *m, - buffer_descriptor_t * const bufDescriptor) -{ - GRALLOC_UNUSED(m); - alloc_type_t alloc_type; - static bool warn_about_mutual_exclusive = true; - - int alloc_width = bufDescriptor->width; - int alloc_height = bufDescriptor->height; - uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage; - - /* - * Select optimal internal pixel format based upon - * usage and requested format. - */ - bufDescriptor->alloc_format = mali_gralloc_select_format(bufDescriptor->hal_format, - bufDescriptor->format_type, - usage, - bufDescriptor->width * bufDescriptor->height, - &bufDescriptor->internal_format); - if (bufDescriptor->alloc_format == MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED) - { - ALOGE("ERROR: Unrecognized and/or unsupported format 0x%" PRIx64 " and usage 0x%" PRIx64, - bufDescriptor->hal_format, usage); - return -EINVAL; - } - else if (warn_about_mutual_exclusive && - (bufDescriptor->alloc_format & 0x0000000100000000ULL) && - (bufDescriptor->alloc_format & 0x0000000e00000000ULL)) - { - /* - * Modifier bits are no longer mutually exclusive. Warn when - * any bits are set in addition to AFBC basic since these might - * have been handled differently by clients under the old scheme. - * AFBC basic is guaranteed to be signalled when any other AFBC - * flags are set. - * This flag is to avoid the mutually exclusive modifier bits warning - * being continuously emitted. (see comment below for explanation of warning). - */ - warn_about_mutual_exclusive = false; - ALOGW("WARNING: internal format modifier bits not mutually exclusive. " - "AFBC basic bit is always set, so extended AFBC support bits must always be checked."); - } - - int32_t format_idx = get_format_index(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); - if (format_idx == -1) - { - return -EINVAL; - } - ALOGV("alloc_format: (%s 0x%" PRIx64 ") format_idx: %d", - format_name(bufDescriptor->alloc_format), bufDescriptor->alloc_format, format_idx); - - /* - * Obtain allocation type (uncompressed, AFBC basic, etc...) - */ - if (!get_alloc_type(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_EXT_MASK, - format_idx, usage, &alloc_type)) - { - return -EINVAL; - } - - if (!validate_format(&formats[format_idx], alloc_type, bufDescriptor)) - { - return -EINVAL; - } - - if (is_exynos_format((uint32_t)bufDescriptor->alloc_format)) - { - prepare_descriptor_exynos_formats(bufDescriptor); - } - else - { - /* - * Resolution of frame (allocation width and height) might require adjustment. - * This adjustment is only based upon specific usage and pixel format. - * If using AFBC, further adjustments to the allocation width and height will be made later - * based on AFBC alignment requirements and, for YUV, the plane properties. - */ - mali_gralloc_adjust_dimensions(bufDescriptor->alloc_format, - usage, - &alloc_width, - &alloc_height); - - /* Obtain buffer size and plane information. */ - calc_allocation_size(alloc_width, - alloc_height, - alloc_type, - formats[format_idx], - usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), - usage & ~(GRALLOC_USAGE_PRIVATE_MASK | GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), - &bufDescriptor->size, - bufDescriptor->plane_info); - - } - - bufDescriptor->plane_count = formats[format_idx].npln; - - switch ((uint32_t)bufDescriptor->alloc_format) - { - case MALI_GRALLOC_FORMAT_INTERNAL_RAW12: - case MALI_GRALLOC_FORMAT_INTERNAL_RAW10: - // RAW10 image width needs to be multiple of 16 so that the data can be CPU accessed - // in 32bit unit - if (bufDescriptor->width % 16 != 0) { - ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW10 buffers has to be multiple of 16."); - return -EINVAL; - } - // TODO: revert this back when b/152045385 is fixed. - bufDescriptor->pixel_stride = bufDescriptor->width * 5 / 4; - break; - default: - bufDescriptor->pixel_stride = bufDescriptor->plane_info[0].alloc_width; - } - - /* - * Each layer of a multi-layer buffer must be aligned so that - * it is accessible by both producer and consumer. In most cases, - * the stride alignment is also sufficient for each layer, however - * for AFBC the header buffer alignment is more constrained (see - * AFBC specification v3.4, section 2.15: "Alignment requirements"). - * Also update the buffer size to accommodate all layers. - */ - if (bufDescriptor->layer_count > 1) - { - if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) - { - if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) - { - bufDescriptor->size = GRALLOC_ALIGN(bufDescriptor->size, 4096); - } - else - { - bufDescriptor->size = GRALLOC_ALIGN(bufDescriptor->size, 128); - } - } - - bufDescriptor->size *= bufDescriptor->layer_count; - } - - /* MFC requires EXT_SIZE padding */ - bufDescriptor->size += EXT_SIZE; - -#ifdef GRALLOC_MSCL_ALIGN_RESTRICTION - if (bufDescriptor->width % MSCL_ALIGN) - { - bufDescriptor->size += MSCL_EXT_SIZE; - } -#endif - - ALOGV("size after padding = %zu %zu %zu", bufDescriptor->sizes[0], bufDescriptor->sizes[1], bufDescriptor->sizes[2]); - - return 0; -} - - -int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors, - uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend) -{ - bool shared = false; - uint64_t backing_store_id = 0x0; - int err; - - for (uint32_t i = 0; i < numDescriptors; i++) - { - buffer_descriptor_t * const bufDescriptor = (buffer_descriptor_t *)(descriptors[i]); - - err = mali_gralloc_derive_format_and_size(m, bufDescriptor); - if (err != 0) - { - return err; - } - } - - /* Allocate ION backing store memory */ - err = mali_gralloc_ion_allocate(descriptors, numDescriptors, pHandle, &shared); - if (err < 0) - { - return err; - } - - if (shared) - { - backing_store_id = getUniqueId(); - } - - for (uint32_t i = 0; i < numDescriptors; i++) - { - buffer_descriptor_t * const bufDescriptor = (buffer_descriptor_t *)descriptors[i]; - private_handle_t *hnd = (private_handle_t *)pHandle[i]; - uint64_t usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage; - - err = gralloc_buffer_attr_allocate(hnd); - - if (err < 0) - { - /* free all allocated ion buffer& attr buffer here.*/ - for (int idx = 0; idx < numDescriptors; idx++) - { - mali_gralloc_buffer_free(pHandle[idx]); - } - return err; - } - - mali_gralloc_dump_buffer_add(hnd); - - const int32_t format_idx = get_format_index(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK); - if (format_idx == -1) - { - return -EINVAL; - } - const int ret = set_dataspace(hnd, usage, format_idx); - if (ret < 0) - { - return ret; - } - -#if GRALLOC_ARM_NO_EXTERNAL_AFBC == 0 - int afbc_prop = property_get_int32("ro.vendor.ddk.set.afbc", 0); - - if (afbc_prop == 1 && hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) - { - hnd->is_compressible = 1; - - int *mapAddr = (int*)mmap(0, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fds[1], 0); - if(mapAddr == NULL || mapAddr == MAP_FAILED) - { - int errnum = errno; - ALOGE("Unable to mmap fd %d errno: %s", hnd->fds[1], strerror(errnum)); - hnd->is_compressible = 0; - hnd->alloc_format = ((uint64_t)hnd->alloc_format & ~MALI_GRALLOC_INTFMT_AFBCENABLE_MASK); - hnd->internal_format = ((uint64_t)hnd->internal_format & ~MALI_GRALLOC_INTFMT_AFBCENABLE_MASK); - } - else - { -#define AFBC_INFO_SIZE (sizeof(int)) -#define AFBC_ENABLE (0xafbc) - int afbc_flag = AFBC_ENABLE; - memcpy(mapAddr, &afbc_flag, AFBC_INFO_SIZE); - munmap(mapAddr, sizeof(int)); - } - } - else - { - hnd->is_compressible = 0; - hnd->alloc_format = ((uint64_t)hnd->alloc_format & ~MALI_GRALLOC_INTFMT_AFBCENABLE_MASK); - hnd->internal_format = ((uint64_t)hnd->internal_format & ~MALI_GRALLOC_INTFMT_AFBCENABLE_MASK); - } -#endif - - if (shared) - { - /*each buffer will share the same backing store id.*/ - hnd->backing_store_id = backing_store_id; - } - else - { - /* each buffer will have an unique backing store id.*/ - hnd->backing_store_id = getUniqueId(); - } - } - - if (NULL != shared_backend) - { - *shared_backend = shared; - } - - return 0; -} - -int mali_gralloc_buffer_free(buffer_handle_t pHandle) -{ - int rval = -1; - private_handle_t * const hnd = (private_handle_t * const)(pHandle); - - if (hnd != NULL) - { - rval = gralloc_buffer_attr_free(hnd); - mali_gralloc_ion_free(hnd); - } - - return rval; -} diff --git a/gralloc3/src/mali_gralloc_bufferdescriptor.cpp b/gralloc3/src/mali_gralloc_bufferdescriptor.cpp deleted file mode 100644 index 8edfd28..0000000 --- a/gralloc3/src/mali_gralloc_bufferdescriptor.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (C) 2016-2018 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <inttypes.h> - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include "mali_gralloc_module.h" -#include "mali_gralloc_bufferdescriptor.h" -#include "mali_gralloc_private_interface_types.h" -#include "mali_gralloc_buffer.h" - -/* - * Validate descriptor to ensure that it originated from this version - * of gralloc. Rudimentary signature is simply calculated from size of - * buffer descriptor structure and initialised immediately after - * structure is allocated. - * - * @param buffer_descriptor [in] Buffer descriptor. - * - * @return true, for valid buffer descriptor; - * false, otherwise - */ -static bool descriptor_is_valid(buffer_descriptor_t *buffer_descriptor) -{ - if (buffer_descriptor && buffer_descriptor->signature == sizeof(*buffer_descriptor)) - { - return true; - } - - return false; -} - -#if GRALLOC_VERSION_MAJOR == 1 -int mali_gralloc_create_descriptor_internal(gralloc1_buffer_descriptor_t *outDescriptor) -{ - buffer_descriptor_t *buffer_descriptor; - - if (NULL == outDescriptor) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - buffer_descriptor = reinterpret_cast<buffer_descriptor_t *>(malloc(sizeof(buffer_descriptor_t))); - - if (NULL == buffer_descriptor) - { - AERR("failed to create buffer descriptor"); - return GRALLOC1_ERROR_NO_RESOURCES; - } - - /* - * Initialise the buffer descriptor. - * - * Layer count is initialised to a single layer in - * case clients don't support multi-layer or use - * function GRALLOC1_PFN_SET_LAYER_COUNT. - */ - memset((void *)buffer_descriptor, 0, sizeof(*buffer_descriptor)); - buffer_descriptor->fd_count = 1; - buffer_descriptor->layer_count = 1; - buffer_descriptor->signature = sizeof(buffer_descriptor_t); - - *outDescriptor = (gralloc1_buffer_descriptor_t)buffer_descriptor; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_destroy_descriptor_internal(gralloc1_buffer_descriptor_t descriptor) -{ - buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor; - if (!descriptor_is_valid(buffer_descriptor)) - { - AERR("Invalid buffer descriptor %p", buffer_descriptor); - return GRALLOC1_ERROR_BAD_DESCRIPTOR; - } - - free(buffer_descriptor); - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_set_dimensions_internal(gralloc1_buffer_descriptor_t descriptor, uint32_t width, uint32_t height) -{ - buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor; - if (!descriptor_is_valid(buffer_descriptor)) - { - AERR("Invalid buffer descriptor %p", buffer_descriptor); - return GRALLOC1_ERROR_BAD_DESCRIPTOR; - } - - buffer_descriptor->width = width; - buffer_descriptor->height = height; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_set_format_internal(gralloc1_buffer_descriptor_t descriptor, int32_t format) -{ - buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor; - if (!descriptor_is_valid(buffer_descriptor)) - { - AERR("Invalid buffer descriptor %p", buffer_descriptor); - return GRALLOC1_ERROR_BAD_DESCRIPTOR; - } - - /* - * Explicit cast to unsigned 64-bit 'hal_format', - * which can also store internal_format provided - * through mali_gralloc_private_set_priv_fmt(). - */ - buffer_descriptor->hal_format = (uint64_t)format; - buffer_descriptor->format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_set_producerusage_internal(gralloc1_buffer_descriptor_t descriptor, uint64_t usage) -{ - buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor; - if (!descriptor_is_valid(buffer_descriptor)) - { - AERR("Invalid buffer descriptor %p", buffer_descriptor); - return GRALLOC1_ERROR_BAD_DESCRIPTOR; - } - - buffer_descriptor->producer_usage = usage; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_set_consumerusage_internal(gralloc1_buffer_descriptor_t descriptor, uint64_t usage) -{ - buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor; - if (!descriptor_is_valid(buffer_descriptor)) - { - AERR("Invalid buffer descriptor %p", buffer_descriptor); - return GRALLOC1_ERROR_BAD_DESCRIPTOR; - } - - buffer_descriptor->consumer_usage = usage; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_get_backing_store_internal(buffer_handle_t buffer, gralloc1_backing_store_t *outStore) -{ - if (private_handle_t::validate(buffer) < 0) - { - AERR("Invalid buffer %p, returning error", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outStore == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - private_handle_t *hnd = (private_handle_t *)buffer; - - *outStore = (gralloc1_backing_store_t)hnd->backing_store_id; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_get_consumer_usage_internal(buffer_handle_t buffer, uint64_t *outUsage) -{ - if (private_handle_t::validate(buffer) < 0) - { - AERR("Invalid buffer %p, returning error", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outUsage == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - private_handle_t *hnd = (private_handle_t *)buffer; - *outUsage = hnd->consumer_usage; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_get_dimensions_internal(buffer_handle_t buffer, uint32_t *outWidth, uint32_t *outHeight) -{ - if (private_handle_t::validate(buffer) < 0) - { - AERR("Invalid buffer %p, returning error", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outWidth == NULL || outHeight == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - private_handle_t *hnd = (private_handle_t *)buffer; - *outWidth = (uint32_t)hnd->width; - *outHeight = (uint32_t)hnd->height; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_get_format_internal(buffer_handle_t buffer, int32_t *outFormat) -{ - if (private_handle_t::validate(buffer) < 0) - { - AERR("Invalid buffer %p, returning error", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outFormat == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - private_handle_t *hnd = (private_handle_t *)buffer; - *outFormat = hnd->req_format; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_get_producer_usage_internal(buffer_handle_t buffer, uint64_t *outUsage) -{ - if (private_handle_t::validate(buffer) < 0) - { - AERR("Invalid buffer %p, returning error", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outUsage == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - private_handle_t *hnd = (private_handle_t *)buffer; - *outUsage = hnd->producer_usage; - return GRALLOC1_ERROR_NONE; -} - -#if PLATFORM_SDK_VERSION >= 26 -int mali_gralloc_set_layer_count_internal(gralloc1_buffer_descriptor_t descriptor, uint32_t layerCount) -{ - buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor; - if (!descriptor_is_valid(buffer_descriptor)) - { - AERR("Invalid buffer descriptor %p", buffer_descriptor); - return GRALLOC1_ERROR_BAD_DESCRIPTOR; - } - - if (layerCount == 0) - { - AERR("Invalid layer count: %" PRIu32, layerCount); - return GRALLOC1_ERROR_BAD_VALUE; - } - - buffer_descriptor->layer_count = layerCount; - return GRALLOC1_ERROR_NONE; -} - -int mali_gralloc_get_layer_count_internal(buffer_handle_t buffer, uint32_t *outLayerCount) -{ - if (private_handle_t::validate(buffer) < 0) - { - AERR("Invalid buffer %p, returning error", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outLayerCount == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - private_handle_t *hnd = (private_handle_t *)buffer; - *outLayerCount = hnd->layer_count; - return GRALLOC1_ERROR_NONE; -} -#endif /* PLATFORM_SDK_VERSION >= 26 */ - -#endif -int mali_gralloc_query_getstride(buffer_handle_t buffer, int *pixelStride) -{ - if (private_handle_t::validate(buffer) < 0) - { - AERR("Invalid buffer %p, returning error", buffer); -#if GRALLOC_VERSION_MAJOR == 1 - return GRALLOC1_ERROR_BAD_HANDLE; -#else - return -EINVAL; -#endif - } - - if (pixelStride == NULL) - { -#if GRALLOC_VERSION_MAJOR == 1 - return GRALLOC1_ERROR_BAD_VALUE; -#else - return -EINVAL; -#endif - } - - private_handle_t *hnd = (private_handle_t *)buffer; - *pixelStride = hnd->stride; - -#if GRALLOC_VERSION_MAJOR == 1 - return GRALLOC1_ERROR_NONE; -#else - return 0; -#endif -} diff --git a/gralloc3/src/mali_gralloc_bufferdescriptor.h b/gralloc3/src/mali_gralloc_bufferdescriptor.h deleted file mode 100644 index fa169ba..0000000 --- a/gralloc3/src/mali_gralloc_bufferdescriptor.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2016-2018 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MALI_GRALLOC_BUFFERDESCRIPTOR_H_ -#define MALI_GRALLOC_BUFFERDESCRIPTOR_H_ - -#include <hardware/hardware.h> -#include "gralloc_priv.h" -#include "mali_gralloc_module.h" -#include "mali_gralloc_formats.h" - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -typedef uint64_t gralloc_buffer_descriptor_t; - -typedef struct buffer_descriptor -{ - uint32_t signature; - - uint32_t width; - uint32_t height; - uint64_t producer_usage; - uint64_t consumer_usage; - uint64_t hal_format; - uint32_t layer_count; - - mali_gralloc_format_type format_type; - union - { - size_t size; - size_t sizes[3]; - uint64_t padding[3]; - }; - int pixel_stride; - uint64_t internal_format; - uint64_t alloc_format; - int fd_count; - int alloc_video_private_data; - plane_info_t plane_info[MAX_PLANES]; - int plane_count; - -#ifdef __cplusplus - buffer_descriptor() : - signature(0), - width(0), - height(0), - producer_usage(0), - consumer_usage(0), - hal_format(0), - layer_count(0), - format_type(MALI_GRALLOC_FORMAT_TYPE_USAGE), - pixel_stride(0), - internal_format(0), - alloc_format(0), - fd_count(1), - alloc_video_private_data(0), - plane_count(0) - - { - sizes[0] = sizes[1] = sizes[2] = 0; - memset(plane_info, 0, sizeof(plane_info_t) * MAX_PLANES); - } -#endif - - void dump() const - { - ALOGI("buffer_descriptor: " - "wh(%u %u) " - "usage_pc(0x%" PRIx64 " 0x%" PRIx64 ") " - "hal_format(0x%" PRIx64 ") " - "layer_count(%u) sizes(%zu %zu %zu) " - "strde(%d) byte_stride(%d) alloc_wh(%d %d) " - "internal_format(0x%" PRIx64 ") alloc_format(0x%" PRIx64 ") " - "fd_count(%d) plane_count(%d)" - "\n", - width, height, producer_usage, consumer_usage, hal_format, - layer_count, sizes[0], sizes[1], sizes[2], - pixel_stride, plane_info[0].byte_stride, plane_info[0].alloc_width, plane_info[0].alloc_height, - internal_format, alloc_format, fd_count, plane_count - ); - } -} buffer_descriptor_t; - -#if GRALLOC_VERSION_MAJOR == 1 -int mali_gralloc_create_descriptor_internal(gralloc1_buffer_descriptor_t *outDescriptor); -int mali_gralloc_destroy_descriptor_internal(gralloc1_buffer_descriptor_t descriptor); -int mali_gralloc_set_dimensions_internal(gralloc1_buffer_descriptor_t descriptor, uint32_t width, uint32_t height); -int mali_gralloc_set_format_internal(gralloc1_buffer_descriptor_t descriptor, int32_t format); -int mali_gralloc_set_producerusage_internal(gralloc1_buffer_descriptor_t descriptor, uint64_t usage); -int mali_gralloc_set_consumerusage_internal(gralloc1_buffer_descriptor_t descriptor, uint64_t usage); - -int mali_gralloc_get_backing_store_internal(buffer_handle_t buffer, gralloc1_backing_store_t *outStore); -int mali_gralloc_get_consumer_usage_internal(buffer_handle_t buffer, uint64_t *outUsage); -int mali_gralloc_get_dimensions_internal(buffer_handle_t buffer, uint32_t *outWidth, uint32_t *outHeight); -int mali_gralloc_get_format_internal(buffer_handle_t buffer, int32_t *outFormat); -int mali_gralloc_get_producer_usage_internal(buffer_handle_t buffer, uint64_t *outUsage); -#if PLATFORM_SDK_VERSION >= 26 -int mali_gralloc_set_layer_count_internal(gralloc1_buffer_descriptor_t descriptor, uint32_t layerCount); -int mali_gralloc_get_layer_count_internal(buffer_handle_t buffer, uint32_t *outLayerCount); -#endif -#endif -int mali_gralloc_query_getstride(buffer_handle_t handle, int *pixelStride); - -#endif /* MALI_GRALLOC_BUFFERDESCRIPTOR_H_ */ diff --git a/gralloc3/src/mali_gralloc_ion.cpp b/gralloc3/src/mali_gralloc_ion.cpp deleted file mode 100644 index 32c9790..0000000 --- a/gralloc3/src/mali_gralloc_ion.cpp +++ /dev/null @@ -1,1251 +0,0 @@ -/* - * Copyright (C) 2016-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include <errno.h> -#include <inttypes.h> -#include <pthread.h> -#include <stdlib.h> -#include <limits.h> - -#include <log/log.h> -#include <cutils/atomic.h> - -#include <sys/ioctl.h> - -#include <hardware/hardware.h> - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include <BufferAllocator/BufferAllocator.h> -#include "mali_gralloc_module.h" -#include "mali_gralloc_private_interface_types.h" -#include "mali_gralloc_buffer.h" -#include "gralloc_helper.h" -#include "framebuffer_device.h" -#include "mali_gralloc_formats.h" -#include "mali_gralloc_usages.h" -#include "mali_gralloc_bufferdescriptor.h" -#include "mali_gralloc_bufferallocation.h" - -#include <hardware/exynos/ion.h> -#include <hardware/exynos/dmabuf_container.h> -#include <linux/ion.h> - -#include <array> - -#define INIT_ZERO(obj) (memset(&(obj), 0, sizeof((obj)))) - -#define HEAP_MASK_FROM_ID(id) (1 << id) -#define HEAP_MASK_FROM_TYPE(type) (1 << type) - -static const enum ion_heap_type ION_HEAP_TYPE_INVALID = ((enum ion_heap_type)~0); -static const enum ion_heap_type ION_HEAP_TYPE_SECURE = (enum ion_heap_type)(((unsigned int)ION_HEAP_TYPE_CUSTOM) + 1); - -#if defined(ION_HEAP_SECURE_MASK) -#if (HEAP_MASK_FROM_TYPE(ION_HEAP_TYPE_SECURE) != ION_HEAP_SECURE_MASK) -#error "ION_HEAP_TYPE_SECURE value is not compatible with ION_HEAP_SECURE_MASK" -#endif -#endif - -static std::unique_ptr<BufferAllocator> buffer_allocator; -static int ion_client = -1; -static bool secure_heap_exists = true; - -static const char kDmabufSensorDirectHeapName[] = "sensor_direct_heap"; -static const char kDmabufFaceauthTpuHeapName[] = "faceauth_tpu-secure"; -static const char kDmabufFaceauthImgHeapName[] = "faimg-secure"; -static const char kDmabufFaceauthRawImgHeapName[] = "farawimg-secure"; -static const char kDmabufFaceauthPrevHeapName[] = "faprev-secure"; -static const char kDmabufFaceauthModelHeapName[] = "famodel-secure"; -static const char kDmabufVframeSecureHeapName[] = "vframe-secure"; -static const char kDmabufVstreamSecureHeapName[] = "vstream-secure"; - -static void set_ion_flags(enum ion_heap_type heap_type, uint64_t usage, - unsigned int *priv_heap_flag, unsigned int *ion_flags) -{ -#if !GRALLOC_USE_ION_DMA_HEAP - GRALLOC_UNUSED(heap_type); -#endif - - if (priv_heap_flag) - { -#if GRALLOC_USE_ION_DMA_HEAP - if (heap_type == ION_HEAP_TYPE_DMA) - { - *priv_heap_flag = private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP; - } -#endif - } - - if (ion_flags) - { -#if GRALLOC_USE_ION_DMA_HEAP - if (heap_type != ION_HEAP_TYPE_DMA) - { -#endif - if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) - { - *ion_flags = ION_FLAG_CACHED; - } -#if GRALLOC_USE_ION_DMA_HEAP - } -#endif - /* LSI Integration */ - if ((usage & GRALLOC1_USAGE_SW_READ_MASK) == GRALLOC1_USAGE_READ_OFTEN) - { - *ion_flags = ION_FLAG_CACHED; - } - - // DRM or Secure Camera - if (usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) - { - *ion_flags |= ION_FLAG_PROTECTED; - } -#if GRALLOC_ION_HEAP_CRYPTO_MASK == 1 - if (usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_NONSECURE && usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) - { - *ion_flags |= ION_FLAG_PROTECTED; - } -#endif - /* Sensor direct channels require uncached allocations. */ - if (usage & GRALLOC_USAGE_SENSOR_DIRECT_DATA) - { - *ion_flags &= ~ION_FLAG_CACHED; - } - } -} - -static unsigned int select_faceauth_heap_mask(uint64_t usage) -{ - struct HeapSpecifier - { - uint64_t usage_bits; // exact match required - unsigned int mask; - }; - - static constexpr std::array<HeapSpecifier, 5> faceauth_heaps = - {{ - { // isp_image_heap - GRALLOC_USAGE_PROTECTED | GRALLOC_USAGE_HW_CAMERA_WRITE | GS101_GRALLOC_USAGE_TPU_INPUT, - EXYNOS_ION_HEAP_FA_IMG_MASK - }, - { // isp_internal_heap - GRALLOC_USAGE_PROTECTED | GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_HW_CAMERA_READ, - EXYNOS_ION_HEAP_FA_RAWIMG_MASK - }, - { // isp_preview_heap - GRALLOC_USAGE_PROTECTED | GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_HW_COMPOSER | - GRALLOC_USAGE_HW_TEXTURE, - EXYNOS_ION_HEAP_FA_PREV_MASK - }, - { // ml_model_heap - GRALLOC_USAGE_PROTECTED | GS101_GRALLOC_USAGE_TPU_INPUT, - EXYNOS_ION_HEAP_FA_MODEL_MASK - }, - { // tpu_heap - GRALLOC_USAGE_PROTECTED | GS101_GRALLOC_USAGE_TPU_OUTPUT | GS101_GRALLOC_USAGE_TPU_INPUT, - EXYNOS_ION_HEAP_FA_TPU_MASK - } - }}; - - for (const HeapSpecifier &heap : faceauth_heaps) - { - if (usage == heap.usage_bits) - { - ALOGV("Using FaceAuth heap mask 0x%x for usage 0x%" PRIx64 "\n", - heap.mask, usage); - return heap.mask; - } - } - - return 0; -} - -static unsigned int select_heap_mask(uint64_t usage) -{ - if (unsigned int faceauth_heap_mask = select_faceauth_heap_mask(usage); - faceauth_heap_mask != 0) - { - return faceauth_heap_mask; - } - - unsigned int heap_mask; - - if (usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) - { - if (usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_NONSECURE) - heap_mask = EXYNOS_ION_HEAP_SYSTEM_MASK; - else { - if ((usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) && - !(usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) && - !(usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) - heap_mask = EXYNOS_ION_HEAP_VIDEO_SCALER_MASK; - else - heap_mask = EXYNOS_ION_HEAP_VIDEO_FRAME_MASK; - } - } -#if GRALLOC_ION_HEAP_CRYPTO_MASK == 1 - else if (usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_NONSECURE && usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) - { - heap_mask = EXYNOS_ION_HEAP_CRYPTO_MASK; - } -#endif - else if (usage & GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA) - { - heap_mask = EXYNOS_ION_HEAP_SENSOR_DIRECT_MASK; - } - else - { - heap_mask = EXYNOS_ION_HEAP_SYSTEM_MASK; - } - - return heap_mask; -} - - -/* - * Returns positive number if not mapping due to AFBC or protected memory - * Returns negative errno if mapping failed to mmap - */ -static int gralloc_map(buffer_handle_t handle) -{ - private_handle_t *hnd = (private_handle_t*)handle; - int ret = 0; - hnd->bases[0] = hnd->bases[1] = hnd->bases[2] = 0; - - /* - * VideoMetaData must be mapped for CPU access even if the buffer is a secure buffer - */ - if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA | private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA)) - { - int idx = hnd->flags & private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA ? 2 : 1; - void *cpuPtr = mmap(0, hnd->sizes[idx], PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fds[idx], 0); - - if (cpuPtr == MAP_FAILED) - { - ret = -errno; - AERR("could not mmap %s for PRIVATE_DATA at fd%d", strerror(errno), idx); - goto err; - } - - hnd->bases[idx] = (uint64_t)cpuPtr; - } - - // AFBC must not be mapped. - if (hnd->is_compressible) - { - return 1; - } - - // Don't be mapped for Secure DRM & Secure Camera - if ((hnd->producer_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED && !(hnd->consumer_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_NONSECURE))) - { - return 2; - } - - if (!(hnd->producer_usage & - (GRALLOC1_PRODUCER_USAGE_PROTECTED | GRALLOC1_PRODUCER_USAGE_NOZEROED))) - { - for (int idx = 0; idx < hnd->get_num_ion_fds(); idx++) - { - if (hnd->fds[idx] >= 0 && !hnd->bases[idx]) - { - void *cpuPtr = (void*)mmap(0, hnd->sizes[idx], PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fds[idx], 0); - - if (cpuPtr == MAP_FAILED) - { - ret = -errno; - AERR("could not mmap %s for fd%d", strerror(errno), idx); - goto err; - } - - if (idx == 0) - hnd->bases[idx] = (uint64_t)cpuPtr + hnd->offset; - else - hnd->bases[idx] = (uint64_t)cpuPtr; - } - } - } - - return 0; - -err: - for (int idx = 0; idx < hnd->get_num_ion_fds(); idx++) - { - if (hnd->bases[idx] != 0 && munmap((void *)hnd->bases[idx], hnd->sizes[idx]) != 0) - { - AERR("Failed to munmap handle %p fd%d", hnd, idx); - } - else - { - hnd->bases[idx] = 0; - } - } - - return ret; - -} - -/* - * Selects a DMA-BUF heap name. - * - * @param heap_mask [in] ION heap mask for which equivalent DMA-BUF heap name - * needs to be looked up. - * - * @return a tuple in std::pair form with the first member as heap - * name and second as minimum page size (in bytes). - * - */ -static std::pair<std::string, int> select_dmabuf_heap(unsigned int heap_mask) -{ - switch (heap_mask) { - case EXYNOS_ION_HEAP_SENSOR_DIRECT_MASK: - return std::make_pair(kDmabufSensorDirectHeapName, SZ_4K); - case EXYNOS_ION_HEAP_FA_TPU_MASK: - return std::make_pair(kDmabufFaceauthTpuHeapName, SZ_4K); - case EXYNOS_ION_HEAP_FA_IMG_MASK: - return std::make_pair(kDmabufFaceauthImgHeapName, SZ_4K); - case EXYNOS_ION_HEAP_FA_RAWIMG_MASK: - return std::make_pair(kDmabufFaceauthRawImgHeapName, SZ_4K); - case EXYNOS_ION_HEAP_FA_PREV_MASK: - return std::make_pair(kDmabufFaceauthPrevHeapName, SZ_4K); - case EXYNOS_ION_HEAP_FA_MODEL_MASK: - return std::make_pair(kDmabufFaceauthModelHeapName, SZ_4K); - case EXYNOS_ION_HEAP_VIDEO_FRAME_MASK: - return std::make_pair(kDmabufVframeSecureHeapName, SZ_4K); - case EXYNOS_ION_HEAP_VIDEO_STREAM_MASK: - return std::make_pair(kDmabufVstreamSecureHeapName, SZ_4K); - default: - return {}; - } -} - -/* - * Allocates in the DMA-BUF heap with name @heap_name. If allocation fails from - * the DMA-BUF heap or if it does not exist, falls back to an ION heap of the - * same name. - * - * @param heap_name [in] DMA-BUF heap name for allocation - * @param size [in] Requested buffer size (in bytes). - * @param flags [in] ION allocation attributes defined by ION_FLAG_* to - * be used for ION allocations. Will not be used with - * DMA-BUF heaps since the framework does not support - * allocation flags. - * - * @return fd of the allocated buffer on success, -1 otherwise; - */ -static int alloc_from_dmabuf_heap(const std::string& heap_name, size_t size, unsigned int flags) -{ - if (!buffer_allocator) - { - return -1; - } - - int shared_fd = buffer_allocator->Alloc(heap_name, size, flags); - if (shared_fd < 0) - { - ALOGE("Allocation failed for heap %s error: %d\n", heap_name.c_str(), shared_fd); - return -1; - } - - return shared_fd; -} - -/* - * Identifies a heap and retrieves file descriptor from ION for allocation - * - * @param usage [in] Producer and consumer combined usage. - * @param size [in] Requested buffer size (in bytes). - * @param heap_type [in] Requested heap type. - * @param flags [in] ION allocation attributes defined by ION_FLAG_*. - * @param min_pgsz [out] Minimum page size (in bytes). - * - * @return File handle which can be used for allocation, on success - * -1, otherwise. - */ -static int alloc_from_ion_heap(uint64_t usage, size_t size, - enum ion_heap_type heap_type, unsigned int flags, - int *min_pgsz) -{ - if (size == 0 || min_pgsz == NULL) - { - return -1; - } - - unsigned int heap_mask = select_heap_mask(usage); - - auto dmabuf_heap_info = select_dmabuf_heap(heap_mask); - auto dmabuf_heap_name = dmabuf_heap_info.first; - - int shared_fd; - if (!dmabuf_heap_name.empty()) - { - shared_fd = alloc_from_dmabuf_heap(dmabuf_heap_name, size, flags); - if (shared_fd >= 0) - { - *min_pgsz = dmabuf_heap_info.second; - } - return shared_fd; - } - - if (ion_client < 0 || heap_type == ION_HEAP_TYPE_INVALID) - { - return -1; - } - - shared_fd = exynos_ion_alloc(ion_client, size, heap_mask, flags); - - /* Check if allocation from selected heap failed and fall back to system - * heap if possible. - */ - if (shared_fd < 0) - { - /* Don't allow falling back to sytem heap if secure was requested. */ - if (heap_type == ION_HEAP_TYPE_SECURE) - { - return -1; - } - - /* Can't fall back to system heap if system heap was the heap that - * already failed - */ - if (heap_type == ION_HEAP_TYPE_SYSTEM) - { - AERR("%s: Allocation failed on on system heap. Cannot fallback.", __func__); - return -1; - } - - heap_type = ION_HEAP_TYPE_SYSTEM; - - /* Set ION flags for system heap allocation */ - set_ion_flags(heap_type, usage, NULL, &flags); - - shared_fd = exynos_ion_alloc(ion_client, size, EXYNOS_ION_HEAP_SYSTEM_MASK, flags); - - if (shared_fd < 0) - { - AERR("Fallback ion_alloc_fd(%d, %zd, %d, %u, %p) failed", - ion_client, size, 0, flags, &shared_fd); - return -1; - } - else - { - AWAR("allocating to system heap as fallback: fd(%d) usage(%" PRIx64 ") size(%zu) heap_type(%d) heap_mask(0x%x) flags(%u)", - shared_fd, usage, size, heap_type, heap_mask, flags); - } - } - - switch (heap_type) - { - case ION_HEAP_TYPE_SYSTEM: - *min_pgsz = SZ_4K; - break; - -#if GRALLOC_USE_ION_DMA_HEAP - case ION_HEAP_TYPE_DMA: - *min_pgsz = size; - break; -#endif -#if GRALLOC_USE_ION_COMPOUND_PAGE_HEAP - case ION_HEAP_TYPE_COMPOUND_PAGE: - *min_pgsz = SZ_2M; - break; -#endif - /* If have customized heap please set the suitable pg type according to - * the customized ION implementation - */ - case ION_HEAP_TYPE_CUSTOM: - *min_pgsz = SZ_4K; - break; - default: - *min_pgsz = SZ_4K; - break; - } - - return shared_fd; -} - -#if GRALLOC_USE_ASHMEM_METADATA != 1 -int alloc_metadata() -{ - int min_pgsz = 0; - return alloc_from_ion_heap(GRALLOC1_USAGE_READ_OFTEN | GRALLOC1_USAGE_WRITE_OFTEN, PAGE_SIZE, ION_HEAP_TYPE_SYSTEM, ION_FLAG_CACHED, &min_pgsz); -} -#endif - -static enum ion_heap_type pick_ion_heap(uint64_t usage) -{ - enum ion_heap_type heap_type = ION_HEAP_TYPE_INVALID; - - if (usage & GRALLOC_USAGE_PROTECTED) - { - if (secure_heap_exists) - { - heap_type = ION_HEAP_TYPE_SECURE; - } - else - { - AERR("Protected ION memory is not supported on this platform."); - } - } - else if (!(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER))) - { -#if GRALLOC_USE_ION_COMPOUND_PAGE_HEAP - heap_type = ION_HEAP_TYPE_COMPOUND_PAGE; -#elif GRALLOC_USE_ION_DMA_HEAP - heap_type = ION_HEAP_TYPE_DMA; -#else - heap_type = ION_HEAP_TYPE_SYSTEM; -#endif - } - else - { - heap_type = ION_HEAP_TYPE_SYSTEM; - } - - return heap_type; -} - - -static bool check_buffers_sharable(const gralloc_buffer_descriptor_t *descriptors, - uint32_t numDescriptors) -{ - enum ion_heap_type shared_backend_heap_type = ION_HEAP_TYPE_INVALID; - unsigned int shared_ion_flags = 0; - uint64_t usage; - uint32_t i; - - if (numDescriptors <= 1) - { - return false; - } - - for (i = 0; i < numDescriptors; i++) - { - unsigned int ion_flags; - enum ion_heap_type heap_type; - - buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)descriptors[i]; - - usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage; - - heap_type = pick_ion_heap(usage); - if (heap_type == ION_HEAP_TYPE_INVALID) - { - return false; - } - - set_ion_flags(heap_type, usage, NULL, &ion_flags); - - if (shared_backend_heap_type != ION_HEAP_TYPE_INVALID) - { - if (shared_backend_heap_type != heap_type || shared_ion_flags != ion_flags) - { - return false; - } - } - else - { - shared_backend_heap_type = heap_type; - shared_ion_flags = ion_flags; - } - } - - return true; -} - -static int get_max_buffer_descriptor_index(const gralloc_buffer_descriptor_t *descriptors, uint32_t numDescriptors) -{ - uint32_t i, max_buffer_index = 0; - size_t max_buffer_size = 0; - - for (i = 0; i < numDescriptors; i++) - { - buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)descriptors[i]; - - if (max_buffer_size < bufDescriptor->size) - { - max_buffer_index = i; - max_buffer_size = bufDescriptor->size; - } - } - - return max_buffer_index; -} - -/* - * Opens the ION module. Queries heap information and stores it for later use - * - * @return ionfd in case of success - * -1 for all error cases - */ -static int open_and_query_ion(void) -{ - if (ion_client >= 0) - { - AWAR("ION device already open"); - return 0; - } - - ion_client = exynos_ion_open(); - if (ion_client < 0) - { - AERR("ion_open failed with %s", strerror(errno)); - return -1; - } - -#if defined(ION_HEAP_SECURE_MASK) - secure_heap_exists = true; -#endif - - return ion_client; -} - -int mali_gralloc_ion_open(void) -{ - if (!buffer_allocator) - { - buffer_allocator = std::make_unique<BufferAllocator>(); - if (!buffer_allocator) - AERR("Unable to create BufferAllocator object"); - } - return open_and_query_ion(); -} - -static int mali_gralloc_ion_sync(const private_handle_t * const hnd, - const bool read, - const bool write, - const bool start) -{ - int ret = 0; - - if (hnd == NULL) - { - return -EINVAL; - } - -#ifdef GRALLOC_ION_SYNC - if (ion_client <= 0) - { - /* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/ - AWAR("ion_client not specified"); - - if (int status = open_and_query_ion(); status < 0) - { - return status; - } - } - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && - !(hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP)) - { - int direction = 0; - - if (read) - { - direction |= ION_SYNC_READ; - } - if (write) - { - direction |= ION_SYNC_WRITE; - } - - for (int idx = 0; idx < hnd->get_num_ion_fds(); idx++) - { - if (start) - { - ret |= exynos_ion_sync_start(ion_client, hnd->fds[idx], direction); - } - else - { - ret |= exynos_ion_sync_end(ion_client, hnd->fds[idx], direction); - } - } - } -#else - GRALLOC_UNUSED(read); - GRALLOC_UNUSED(write); - GRALLOC_UNUSED(start); -#endif - - return ret; -} - -/* - * Signal start of CPU access to the DMABUF exported from ION. - * - * @param hnd [in] Buffer handle - * @param read [in] Flag indicating CPU read access to memory - * @param write [in] Flag indicating CPU write access to memory - * - * @return 0 in case of success - * errno for all error cases - */ -int mali_gralloc_ion_sync_start(const private_handle_t * const hnd, - const bool read, - const bool write) -{ - return mali_gralloc_ion_sync(hnd, read, write, true); -} - - -/* - * Signal end of CPU access to the DMABUF exported from ION. - * - * @param hnd [in] Buffer handle - * @param read [in] Flag indicating CPU read access to memory - * @param write [in] Flag indicating CPU write access to memory - * - * @return 0 in case of success - * errno for all error cases - */ -int mali_gralloc_ion_sync_end(const private_handle_t * const hnd, - const bool read, - const bool write) -{ - return mali_gralloc_ion_sync(hnd, read, write, false); -} - - -void mali_gralloc_ion_free(private_handle_t * const hnd) -{ - if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) - { - return; - } - else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) - { - /* Buffer might be unregistered already so we need to assure we have a valid handle */ - - for (int idx = 0; idx < hnd->get_num_ion_fds(); idx++) - { - if (hnd->fds[idx] >= 0) - { - if (hnd->bases[idx] != 0) - { - if (munmap((void *)hnd->bases[idx], hnd->sizes[idx]) != 0) - { - AERR("Failed to munmap handle %p fd%d", hnd, idx); - } - } - - close(hnd->fds[idx]); - } - } - - memset((void *)hnd, 0, sizeof(*hnd)); - } -} - -static void mali_gralloc_ion_free_internal(buffer_handle_t * const pHandle, - const uint32_t num_hnds) -{ - for (uint32_t i = 0; i < num_hnds; i++) - { - if (pHandle[i] != NULL) - { - private_handle_t * const hnd = (private_handle_t * const)pHandle[i]; - mali_gralloc_ion_free(hnd); - } - } -} - -static int allocate_to_fds(buffer_descriptor_t *bufDescriptor, enum ion_heap_type heap_type, - uint32_t ion_flags, uint32_t *priv_heap_flag, int *min_pgsz, int* fd0, int* fd1, int* fd2, int ion_fd = -1) -{ - int fd_arr[3] = {-1, -1, -1}; - uint64_t usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage; - - for (int idx = 0; idx < bufDescriptor->fd_count; idx++) - { - if (ion_fd != -1 && idx == 0) { - fd_arr[idx] = ion_fd; - } else { - fd_arr[idx] = alloc_from_ion_heap(usage, bufDescriptor->sizes[idx], heap_type, ion_flags, min_pgsz); - } - - if (fd_arr[idx] < 0) - { - AERR("ion_alloc failed from client ( %d )", ion_client); - goto err; - } - } - - if (bufDescriptor->alloc_video_private_data) - { - int idx = bufDescriptor->fd_count; - - if (idx != 1 && idx != 2) - { - AERR("cannot allocate video private metadata for formate(%#x)", (uint32_t)bufDescriptor->internal_format); - goto err; - } - - usage = usage & ~GRALLOC1_PRODUCER_USAGE_PROTECTED; - fd_arr[idx] = alloc_from_ion_heap(usage, VIDEO_PRIV_DATA_SIZE, ION_HEAP_TYPE_SYSTEM, 0, min_pgsz); - if (fd_arr[idx] < 0) - { - AERR("ion_alloc failed from client ( %d )", ion_client); - goto err; - } - - bufDescriptor->sizes[idx] = VIDEO_PRIV_DATA_SIZE; - - switch (idx) - { - case 2: - *priv_heap_flag |= private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA; - break; - case 1: - *priv_heap_flag |= private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA; - break; - } - - bufDescriptor->fd_count++; - } - - *fd0 = fd_arr[0]; - *fd1 = fd_arr[1]; - *fd2 = fd_arr[2]; - - return 0; - -err: - for (int i = 0; i < 3; i++) - { - if (fd_arr[i] >= 0) - { - close(fd_arr[i]); - } - } - - return -1; -} - - -/* - * Allocates ION buffers - * - * @param descriptors [in] Buffer request descriptors - * @param numDescriptors [in] Number of descriptors - * @param pHandle [out] Handle for each allocated buffer - * @param shared_backend [out] Shared buffers flag - * @param ion_fd [in] Optional fd of an allocated ION buffer - * - * @return File handle which can be used for allocation, on success - * -1, otherwise. - * - * In the case ion_fd != -1, this functions wraps ion_fd in a buffer_handle_t - * instead. - */ -int mali_gralloc_ion_allocate(const gralloc_buffer_descriptor_t *descriptors, - uint32_t numDescriptors, buffer_handle_t *pHandle, - bool *shared_backend, int ion_fd) -{ - unsigned int priv_heap_flag = 0; - enum ion_heap_type heap_type; -#if GRALLOC_INIT_AFBC == 1 - unsigned char *cpu_ptr = NULL; -#endif - uint64_t usage; - uint32_t i, max_buffer_index = 0; - union - { - int shared_fd; - int fd_arr[3]; - }; - unsigned int ion_flags = 0; - int min_pgsz = 0; - int is_compressible = 0; - - fd_arr[0] = fd_arr[1] = fd_arr[2] = -1; - - if (ion_client < 0) - { - int status = 0; - status = open_and_query_ion(); - if (status < 0) - { - return status; - } - } - - *shared_backend = check_buffers_sharable(descriptors, numDescriptors); - - if (*shared_backend) - { - buffer_descriptor_t *max_bufDescriptor; - - max_buffer_index = get_max_buffer_descriptor_index(descriptors, numDescriptors); - max_bufDescriptor = (buffer_descriptor_t *)(descriptors[max_buffer_index]); - usage = max_bufDescriptor->consumer_usage | max_bufDescriptor->producer_usage; - - heap_type = pick_ion_heap(usage); - if (heap_type == ION_HEAP_TYPE_INVALID) - { - AERR("Failed to find an appropriate ion heap"); - return -1; - } - - set_ion_flags(heap_type, usage, &priv_heap_flag, &ion_flags); - - if (allocate_to_fds(max_bufDescriptor, heap_type, ion_flags, &priv_heap_flag, &min_pgsz, - &fd_arr[0], &fd_arr[1], &fd_arr[2]) < 0) - { - AERR("ion_alloc failed form client: ( %d )", ion_client); - return -1; - } - - for (i = 0; i < numDescriptors; i++) - { - buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]); - int tmp_fd; - - if (i != max_buffer_index) - { - tmp_fd = dup(shared_fd); - - if (tmp_fd < 0) - { - AERR("Ion shared fd:%d of index:%d could not be duplicated for descriptor:%d", - shared_fd, max_buffer_index, i); - - /* It is possible that already opened shared_fd for the - * max_bufDescriptor is also not closed */ - if (i < max_buffer_index) - { - close(shared_fd); - } - - /* Need to free already allocated memory. */ - mali_gralloc_ion_free_internal(pHandle, numDescriptors); - return -1; - } - } - else - { - tmp_fd = shared_fd; - } - - if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) - { - is_compressible = 1; - - if (fd_arr[1] >= 0) - { - ALOGW("Warning afbc flag fd already exists during create. Closing."); - close(fd_arr[1]); - } - - bufDescriptor->sizes[1] = sizeof(int); - fd_arr[1] = exynos_ion_alloc(ion_client, bufDescriptor->sizes[1], EXYNOS_ION_HEAP_SYSTEM_MASK, 0); - if (fd_arr[1] < 0) - { - ALOGE("Failed to allocate page for afbc flag region"); - mali_gralloc_ion_free_internal(pHandle, numDescriptors); - return -1; - } - } - - private_handle_t *hnd = new private_handle_t( - private_handle_t::PRIV_FLAGS_USES_ION | priv_heap_flag, bufDescriptor->size, 0, 0, min_pgsz, - bufDescriptor->consumer_usage, bufDescriptor->producer_usage, tmp_fd, -1, -1, bufDescriptor->hal_format, - bufDescriptor->internal_format, bufDescriptor->alloc_format, - bufDescriptor->width, bufDescriptor->height, - max_bufDescriptor->size, bufDescriptor->pixel_stride, bufDescriptor->layer_count, - bufDescriptor->plane_info, is_compressible, bufDescriptor->plane_count); - - if (NULL == hnd) - { - AERR("Private handle could not be created for descriptor:%d of shared usecase", i); - - /* Close the obtained shared file descriptor for the current handle */ - close(tmp_fd); - - /* It is possible that already opened shared_fd for the - * max_bufDescriptor is also not closed */ - if (i < max_buffer_index) - { - close(shared_fd); - } - - /* Free the resources allocated for the previous handles */ - mali_gralloc_ion_free_internal(pHandle, numDescriptors); - return -1; - } - - pHandle[i] = hnd; - } - } - else - { - for (i = 0; i < numDescriptors; i++) - { - buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]); - usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage; - - heap_type = pick_ion_heap(usage); - if (heap_type == ION_HEAP_TYPE_INVALID) - { - AERR("Failed to find an appropriate ion heap"); - mali_gralloc_ion_free_internal(pHandle, numDescriptors); - return -1; - } - - set_ion_flags(heap_type, usage, &priv_heap_flag, &ion_flags); - - if (allocate_to_fds(bufDescriptor, heap_type, ion_flags, &priv_heap_flag, &min_pgsz, - &fd_arr[0], &fd_arr[1], &fd_arr[2], ion_fd) < 0) - { - AERR("ion_alloc failed from client ( %d )", ion_client); - - /* need to free already allocated memory. not just this one */ - mali_gralloc_ion_free_internal(pHandle, numDescriptors); - return -1; - } - - if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) - { - is_compressible = 1; - - if (fd_arr[1] >= 0) - { - ALOGW("Warning afbc flag fd already exists during create. Closing."); - close(fd_arr[1]); - } - - bufDescriptor->sizes[1] = sizeof(int); - fd_arr[1] = exynos_ion_alloc(ion_client, bufDescriptor->sizes[1], EXYNOS_ION_HEAP_SYSTEM_MASK, 0); - if (fd_arr[1] < 0) - { - ALOGE("Failed to allocate page for afbc flag region"); - mali_gralloc_ion_free_internal(pHandle, numDescriptors); - return -1; - } - } - - private_handle_t *hnd = new private_handle_t( - private_handle_t::PRIV_FLAGS_USES_ION | priv_heap_flag, bufDescriptor->size, - bufDescriptor->sizes[1], bufDescriptor->sizes[2], min_pgsz, - bufDescriptor->consumer_usage, bufDescriptor->producer_usage, - shared_fd, fd_arr[1], fd_arr[2], bufDescriptor->hal_format, - bufDescriptor->internal_format, bufDescriptor->alloc_format, - bufDescriptor->width, bufDescriptor->height, - bufDescriptor->size, bufDescriptor->pixel_stride, bufDescriptor->layer_count, - bufDescriptor->plane_info, is_compressible, bufDescriptor->plane_count); - - if (NULL == hnd) - { - AERR("Private handle could not be created for descriptor:%d in non-shared usecase", i); - - /* Close the obtained shared file descriptor for the current handle */ - close(shared_fd); - mali_gralloc_ion_free_internal(pHandle, numDescriptors); - return -1; - } - - pHandle[i] = hnd; - } - } - - for (i = 0; i < numDescriptors; i++) - { - buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]); -#if GRALLOC_INIT_AFBC == 1 - private_handle_t *hnd = (private_handle_t *)(pHandle[i]); -#endif - - usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage; - - if (!(usage & GRALLOC_USAGE_PROTECTED)) - { -#if GRALLOC_INIT_AFBC == 1 - if ((bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) && (!(*shared_backend))) - { - cpu_ptr = - (unsigned char *)mmap(NULL, bufDescriptor->size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0); - - if (MAP_FAILED == cpu_ptr) - { - AERR("mmap failed from client ( %d ), fd ( %d )", ion_client, hnd->share_fd); - mali_gralloc_ion_free_internal(pHandle, numDescriptors); - return -1; - } - - mali_gralloc_ion_sync_start(hnd, true, true); - - /* For separated plane YUV, there is a header to initialise per plane. */ - const plane_info_t *plane_info = bufDescriptor->plane_info; - const bool is_multi_plane = hnd->is_multi_plane(); - for (int i = 0; i < MAX_PLANES && (i == 0 || plane_info[i].byte_stride != 0); i++) - { - init_afbc(cpu_ptr + plane_info[i].offset, - bufDescriptor->alloc_format, - is_multi_plane, - plane_info[i].alloc_width, - plane_info[i].alloc_height); - } - - mali_gralloc_ion_sync_end(hnd, true, true); - - munmap((void *)cpu_ptr, bufDescriptor->size); - } -#endif - } - } - - return 0; -} - - -int import_exynos_ion_handles(private_handle_t *hnd) -{ - int retval = -1; - -#if GRALLOC_VERSION_MAJOR <= 1 - if (ion_client < 0) - { - /* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/ - int status = 0; - status = open_and_query_ion(); - if (status < 0) - { - return status; - } - } -#endif - - for (int idx = 0; idx < hnd->get_num_ion_fds(); idx++) - { - if (hnd->fds[idx] >= 0) - { - retval = exynos_ion_import_handle(ion_client, hnd->fds[idx], &hnd->ion_handles[idx]); - if (retval) - { - AERR("error importing handle[%d] format(%x)\n", idx, (uint32_t)hnd->internal_format); - goto clean_up; - } - } - } - - return retval; - -clean_up: - for (int idx = 0; idx < hnd->get_num_ion_fds(); idx++) - { - if (hnd->ion_handles[idx]) - { - exynos_ion_free_handle(ion_client, hnd->ion_handles[idx]); - } - } - - return retval; -} - - -void free_exynos_ion_handles(private_handle_t *hnd) -{ - for (int idx = 0; idx < hnd->get_num_ion_fds(); idx++) - { - if (hnd->ion_handles[idx]) - { - if (ion_client > 0 && hnd->ion_handles[idx] > 0 && - exynos_ion_free_handle(ion_client, hnd->ion_handles[idx])) - { - AERR("error freeing ion_client(%d), ion_handle[%d](%d) format(%x)\n", - ion_client, idx, hnd->ion_handles[idx], (uint32_t)hnd->internal_format); - } - } - } -} - - -int mali_gralloc_ion_map(private_handle_t *hnd) -{ - int retval = -EINVAL; - - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) - { -#if GRALLOC_VERSION_MAJOR <= 1 - if (ion_client < 0) - { - /* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/ - int status = 0; - status = open_and_query_ion(); - if (status < 0) - { - return status; - } - } -#endif - retval = gralloc_map(hnd); - } - - return retval; -} - -void mali_gralloc_ion_unmap(private_handle_t *hnd) -{ - if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) - { - int fail = 0; - - for (int idx = 0; idx < hnd->get_num_ion_fds(); idx++) - { - if (hnd->bases[idx]) - { - if (munmap((void *)hnd->bases[idx], hnd->sizes[idx]) < 0) - { - AERR("Could not munmap base:%p size:%u '%s'", (void *)hnd->bases[0], hnd->sizes[idx], strerror(errno)); - fail = 1; - } - else - { - hnd->bases[idx] = 0; - } - } - } - - if (!fail) - { - hnd->cpu_read = 0; - hnd->cpu_write = 0; - } - } -} - -void mali_gralloc_ion_close(void) -{ - if (ion_client != -1) - { - if (exynos_ion_close(ion_client)) - { - AERR("Failed to close ion_client: %d err=%s", ion_client, strerror(errno)); - } - - ion_client = -1; - } - - buffer_allocator.reset(); -} - diff --git a/gralloc3/src/mali_gralloc_module.cpp b/gralloc3/src/mali_gralloc_module.cpp deleted file mode 100644 index 8783419..0000000 --- a/gralloc3/src/mali_gralloc_module.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2016-2018 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <errno.h> -#include <pthread.h> -#include <inttypes.h> - -#include <log/log.h> -#include <cutils/atomic.h> -#include <system/window.h> -#include <hardware/hardware.h> -#include <hardware/fb.h> - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include "mali_gralloc_module.h" -#include "mali_gralloc_private_interface_types.h" -#include "mali_gralloc_buffer.h" -#include "gralloc_helper.h" -#include "framebuffer_device.h" -#include "gralloc_buffer_priv.h" -#include "mali_gralloc_formats.h" -#include "mali_gralloc_usages.h" -#include "mali_gralloc_bufferaccess.h" -#include "mali_gralloc_reference.h" - -#if GRALLOC_VERSION_MAJOR == 1 -#include "mali_gralloc_public_interface.h" -#elif GRALLOC_VERSION_MAJOR == 0 -#include "legacy/alloc_device.h" -#endif - -static int mali_gralloc_module_device_open(const hw_module_t *module, const char *name, - hw_device_t **device) -{ - int status = -EINVAL; - -#if GRALLOC_VERSION_MAJOR == 1 - - if (!strncmp(name, GRALLOC_HARDWARE_MODULE_ID, MALI_GRALLOC_HARDWARE_MAX_STR_LEN)) - { - status = mali_gralloc_device_open(module, name, device); - } - -#else - - if (!strncmp(name, GRALLOC_HARDWARE_GPU0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN)) - { - status = alloc_device_open(module, name, device); - } - -#endif - else if (!strncmp(name, GRALLOC_HARDWARE_FB0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN)) - { - status = framebuffer_device_open(module, name, device); - } - - return status; -} - -int gralloc_register_buffer(gralloc_module_t const *module, buffer_handle_t handle) -{ - const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module); - - return mali_gralloc_reference_retain(m, handle); -} - -int gralloc_unregister_buffer(gralloc_module_t const *module, buffer_handle_t handle) -{ - const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module); - - return mali_gralloc_reference_release(m, handle, false); -} - -int gralloc_lock(gralloc_module_t const *module, buffer_handle_t handle, int usage, - int l, int t, int w, int h, void **vaddr) -{ - const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module); - - return mali_gralloc_lock(m, handle, (unsigned int)usage, l, t, w, h, vaddr); -} - -int gralloc_lock_ycbcr(gralloc_module_t const *module, buffer_handle_t handle, - int usage, int l, int t, int w, int h, android_ycbcr *ycbcr) -{ - const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module); - - return mali_gralloc_lock_ycbcr(m, handle, (unsigned int)usage, l, t, w, h, ycbcr); -} - -int gralloc_unlock(gralloc_module_t const *module, buffer_handle_t handle) -{ - const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module); - - return mali_gralloc_unlock(m, handle); -} - -int gralloc_lock_async(gralloc_module_t const *module, buffer_handle_t handle, - int usage, int l, int t, int w, int h, void **vaddr, - int32_t fence_fd) -{ - const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module); - - return mali_gralloc_lock_async(m, handle, (unsigned int)usage, l, t, w, h, vaddr, fence_fd); -} - -int gralloc_lock_ycbcr_async(gralloc_module_t const *module, buffer_handle_t handle, - int usage, int l, int t, int w, int h, - android_ycbcr *ycbcr, int32_t fence_fd) -{ - const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module); - - return mali_gralloc_lock_ycbcr_async(m, handle, (unsigned int)usage, l, t, w, h, ycbcr, fence_fd); -} - -int gralloc_unlock_async(gralloc_module_t const *module, buffer_handle_t handle, - int32_t *fence_fd) -{ - const mali_gralloc_module *m = reinterpret_cast<const mali_gralloc_module *>(module); - - return mali_gralloc_unlock_async(m, handle, fence_fd); -} - -struct hw_module_methods_t mali_gralloc_module_methods = { mali_gralloc_module_device_open }; - -/* Export the private module as HAL_MODULE_INFO_SYM symbol as required by Gralloc v0.3 / v1.0 */ -struct private_module_t HAL_MODULE_INFO_SYM; diff --git a/gralloc3/src/mali_gralloc_module.h b/gralloc3/src/mali_gralloc_module.h deleted file mode 100644 index e94cfde..0000000 --- a/gralloc3/src/mali_gralloc_module.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2016, 2018-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MALI_GRALLOC_MODULE_H_ -#define MALI_GRALLOC_MODULE_H_ - -#include <system/window.h> -#include <linux/fb.h> -#include <pthread.h> -#include <log/log.h> - -#if GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#elif GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#else -#if HIDL_COMMON_VERSION_SCALED == 100 -#include <android/hardware/graphics/common/1.0/types.h> -#elif HIDL_COMMON_VERSION_SCALED == 110 -#include <android/hardware/graphics/common/1.1/types.h> -#endif -#endif - -typedef enum -{ - MALI_DPY_TYPE_UNKNOWN = 0, - MALI_DPY_TYPE_CLCD, - MALI_DPY_TYPE_HDLCD -} mali_dpy_type; - -#if GRALLOC_VERSION_MAJOR <= 1 -extern hw_module_methods_t mali_gralloc_module_methods; -#endif - -#if GRALLOC_VERSION_MAJOR == 1 -typedef struct -{ - struct hw_module_t common; -} gralloc_module_t; -#endif - -#if GRALLOC_VERSION_MAJOR == 0 -int gralloc_register_buffer(gralloc_module_t const *module, buffer_handle_t handle); -int gralloc_unregister_buffer(gralloc_module_t const *module, buffer_handle_t handle); -int gralloc_lock(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, - void **vaddr); -int gralloc_lock_ycbcr(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, - int h, android_ycbcr *ycbcr); -int gralloc_unlock(gralloc_module_t const *module, buffer_handle_t handle); -int gralloc_lock_async(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, - int h, void **vaddr, int32_t fence_fd); -int gralloc_lock_ycbcr_async(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, - int w, int h, android_ycbcr *ycbcr, int32_t fence_fd); -int gralloc_unlock_async(gralloc_module_t const *module, buffer_handle_t handle, int32_t *fence_fd); -#endif - -struct private_module_t -{ -#if GRALLOC_VERSION_MAJOR <= 1 - gralloc_module_t base; -#endif - - struct private_handle_t *framebuffer; - uint32_t flags; - uint32_t numBuffers; - uint32_t bufferMask; - pthread_mutex_t lock; - buffer_handle_t currentBuffer; - mali_dpy_type dpy_type; - - struct fb_var_screeninfo info; - struct fb_fix_screeninfo finfo; - float xdpi; - float ydpi; - float fps; - int swapInterval; - uint64_t fbdev_format; - int ionfd; - -#ifdef __cplusplus - /* Never intended to be used from C code */ - enum - { - // flag to indicate we'll post this buffer - PRIV_USAGE_LOCKED_FOR_POST = 0x80000000 - }; -#endif - -#ifdef __cplusplus - #define INIT_ZERO(obj) (memset(&(obj), 0, sizeof((obj)))) - private_module_t() - { - #if GRALLOC_VERSION_MAJOR <= 1 - base.common.tag = HARDWARE_MODULE_TAG; - #if GRALLOC_VERSION_MAJOR == 1 - base.common.version_major = GRALLOC_MODULE_API_VERSION_1_0; - ALOGI("Arm Module v1.0"); - #else - base.common.version_major = GRALLOC_MODULE_API_VERSION_0_3; - ALOGI("Arm Module v0.3"); - #endif - - base.common.version_minor = 0; - base.common.id = GRALLOC_HARDWARE_MODULE_ID; - base.common.name = "Graphics Memory Allocator Module"; - base.common.author = "ARM Ltd."; - base.common.methods = &mali_gralloc_module_methods; - base.common.dso = NULL; - INIT_ZERO(base.common.reserved); - - #if GRALLOC_VERSION_MAJOR == 0 - base.registerBuffer = gralloc_register_buffer; - base.unregisterBuffer = gralloc_unregister_buffer; - base.lock = gralloc_lock; - base.lock_ycbcr = gralloc_lock_ycbcr; - base.unlock = gralloc_unlock; - base.lockAsync = gralloc_lock_async; - base.lockAsync_ycbcr = gralloc_lock_ycbcr_async; - base.unlockAsync = gralloc_unlock_async; - base.perform = NULL; - INIT_ZERO(base.reserved_proc); - #endif - #endif - - framebuffer = NULL; - flags = 0; - numBuffers = 0; - bufferMask = 0; - pthread_mutex_init(&(lock), NULL); - currentBuffer = NULL; - INIT_ZERO(info); - INIT_ZERO(finfo); - xdpi = 0.0f; - ydpi = 0.0f; - fps = 0.0f; - swapInterval = 1; - ionfd = -1; - } - #undef INIT_ZERO -#endif /* For #ifdef __cplusplus */ -}; - -typedef struct private_module_t mali_gralloc_module; - -#endif /* MALI_GRALLOC_MODULE_H_ */ diff --git a/gralloc3/src/mali_gralloc_private_interface.cpp b/gralloc3/src/mali_gralloc_private_interface.cpp deleted file mode 100644 index fd3c41c..0000000 --- a/gralloc3/src/mali_gralloc_private_interface.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 2017 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <hardware/hardware.h> -#include <hardware/gralloc1.h> - -#include "mali_gralloc_private_interface.h" -#include "mali_gralloc_buffer.h" -#include "gralloc_helper.h" -#include "gralloc_buffer_priv.h" -#include "mali_gralloc_bufferdescriptor.h" - -#define CHECK_FUNCTION(A, B, C) \ - do \ - { \ - if (A == B) \ - return (gralloc1_function_pointer_t)C; \ - } while (0) - -static int32_t mali_gralloc_private_get_buff_int_fmt(gralloc1_device_t *device, buffer_handle_t handle, - uint64_t *internal_format) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (internal_format == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - const private_handle_t *hnd = static_cast<const private_handle_t *>(handle); - *internal_format = hnd->internal_format; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_get_buff_fd(gralloc1_device_t *device, buffer_handle_t handle, int *fd) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (fd == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - const private_handle_t *hnd = static_cast<const private_handle_t *>(handle); - *fd = hnd->share_fd; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_get_buff_int_dims(gralloc1_device_t *device, buffer_handle_t handle, - int *internalWidth, int *internalHeight) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (internalWidth == NULL || internalHeight == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - const private_handle_t *hnd = static_cast<const private_handle_t *>(handle); - *internalWidth = hnd->plane_info[0].alloc_width; - *internalHeight = hnd->plane_info[0].alloc_height; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_get_buff_offset(gralloc1_device_t *device, buffer_handle_t handle, int64_t *offset) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (offset == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - const private_handle_t *hnd = static_cast<const private_handle_t *>(handle); - *offset = hnd->offset; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_get_buff_bytestride(gralloc1_device_t *device, buffer_handle_t handle, - int *bytestride) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (bytestride == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - const private_handle_t *hnd = static_cast<const private_handle_t *>(handle); - *bytestride = hnd->plane_info[0].byte_stride; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_get_buff_yuvinfo(gralloc1_device_t *device, buffer_handle_t handle, - mali_gralloc_yuv_info *yuvinfo) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (yuvinfo == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - const private_handle_t *hnd = static_cast<const private_handle_t *>(handle); - *yuvinfo = hnd->yuv_info; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_get_buff_size(gralloc1_device_t *device, buffer_handle_t handle, int *size) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (size == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - const private_handle_t *hnd = static_cast<const private_handle_t *>(handle); - *size = hnd->size; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_get_buff_flags(gralloc1_device_t *device, buffer_handle_t handle, int *flags) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (flags == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - const private_handle_t *hnd = static_cast<const private_handle_t *>(handle); - *flags = hnd->flags; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_get_buff_min_page_size(gralloc1_device_t *device, buffer_handle_t handle, - int *min_pgsz) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (min_pgsz == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - const private_handle_t *hnd = static_cast<const private_handle_t *>(handle); - *min_pgsz = hnd->min_pgsz; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_get_attr_param(gralloc1_device_t *device, buffer_handle_t handle, buf_attr attr, - int32_t *val, int32_t last_call) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0 || val == NULL) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - const private_handle_t *const_hnd = static_cast<const private_handle_t *>(handle); - private_handle_t *hnd = const_cast<private_handle_t *>(const_hnd); - - if (hnd->attr_base == MAP_FAILED) - { - if (gralloc_buffer_attr_map(hnd, 1) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - } - - if (gralloc_buffer_attr_read(hnd, attr, val) < 0) - { - gralloc_buffer_attr_unmap(hnd); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (last_call) - { - gralloc_buffer_attr_unmap(hnd); - } - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_set_attr_param(gralloc1_device_t *device, buffer_handle_t handle, buf_attr attr, - int32_t *val, int32_t last_call) -{ - GRALLOC_UNUSED(device); - - if (private_handle_t::validate(handle) < 0 || val == NULL) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - const private_handle_t *const_hnd = static_cast<const private_handle_t *>(handle); - private_handle_t *hnd = const_cast<private_handle_t *>(const_hnd); - - if (hnd->attr_base == MAP_FAILED) - { - if (gralloc_buffer_attr_map(hnd, 1) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - } - - if (gralloc_buffer_attr_write(hnd, attr, val) < 0) - { - gralloc_buffer_attr_unmap(hnd); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (last_call) - { - gralloc_buffer_attr_unmap(hnd); - } - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_private_set_priv_fmt(gralloc1_device_t *device, gralloc1_buffer_descriptor_t desc, - uint64_t internal_format) -{ - GRALLOC_UNUSED(device); - - buffer_descriptor_t *priv_desc = reinterpret_cast<buffer_descriptor_t *>(desc); - - if (priv_desc == NULL) - { - return GRALLOC1_ERROR_BAD_DESCRIPTOR; - } - - priv_desc->hal_format = internal_format; - priv_desc->format_type = MALI_GRALLOC_FORMAT_TYPE_INTERNAL; - - return GRALLOC1_ERROR_NONE; -} - -gralloc1_function_pointer_t mali_gralloc_private_interface_getFunction(int32_t descriptor) -{ - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_INT_FMT, mali_gralloc_private_get_buff_int_fmt); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_FD, mali_gralloc_private_get_buff_fd); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_INTERNAL_DIMS, mali_gralloc_private_get_buff_int_dims); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_OFFSET, mali_gralloc_private_get_buff_offset); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_BYTESTRIDE, mali_gralloc_private_get_buff_bytestride); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_YUVINFO, mali_gralloc_private_get_buff_yuvinfo); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_SIZE, mali_gralloc_private_get_buff_size); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_FLAGS, mali_gralloc_private_get_buff_flags); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_BUFF_MIN_PAGESIZE, - mali_gralloc_private_get_buff_min_page_size); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_GET_ATTR_PARAM, mali_gralloc_private_get_attr_param); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_SET_ATTR_PARAM, mali_gralloc_private_set_attr_param); - CHECK_FUNCTION(descriptor, MALI_GRALLOC1_FUNCTION_SET_PRIV_FMT, mali_gralloc_private_set_priv_fmt); - - return NULL; -} diff --git a/gralloc3/src/mali_gralloc_private_interface.h b/gralloc3/src/mali_gralloc_private_interface.h deleted file mode 100644 index 5f9428a..0000000 --- a/gralloc3/src/mali_gralloc_private_interface.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2017 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MALI_GRALLOC_PRIVATE_INTERFACE_H_ -#define MALI_GRALLOC_PRIVATE_INTERFACE_H_ - -#include "mali_gralloc_private_interface_types.h" - -typedef enum -{ - - MALI_GRALLOC1_LAST_PUBLIC_FUNCTION = GRALLOC1_LAST_FUNCTION, - - MALI_GRALLOC1_FUNCTION_GET_BUFF_INT_FMT = MALI_GRALLOC1_LAST_PUBLIC_FUNCTION + 100, - MALI_GRALLOC1_FUNCTION_GET_BUFF_FD, - MALI_GRALLOC1_FUNCTION_GET_BUFF_INTERNAL_DIMS, - MALI_GRALLOC1_FUNCTION_GET_BUFF_OFFSET, - MALI_GRALLOC1_FUNCTION_GET_BUFF_BYTESTRIDE, - MALI_GRALLOC1_FUNCTION_GET_BUFF_YUVINFO, - MALI_GRALLOC1_FUNCTION_GET_BUFF_SIZE, - MALI_GRALLOC1_FUNCTION_GET_BUFF_FLAGS, - MALI_GRALLOC1_FUNCTION_GET_BUFF_MIN_PAGESIZE, - MALI_GRALLOC1_FUNCTION_SET_PRIV_FMT, - - /* API related to the shared attribute region */ - MALI_GRALLOC1_FUNCTION_GET_ATTR_PARAM, - MALI_GRALLOC1_FUNCTION_SET_ATTR_PARAM, - - MALI_GRALLOC1_LAST_PRIVATE_FUNCTION -} mali_gralloc1_function_descriptor_t; - -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_INT_FMT)(gralloc1_device_t *device, buffer_handle_t handle, - uint64_t *internal_format); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_FD)(gralloc1_device_t *device, buffer_handle_t handle, int *fd); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_INTERNAL_DIMS)(gralloc1_device_t *device, buffer_handle_t handle, - int *internalWidth, int *internalHeight); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_OFFSET)(gralloc1_device_t *device, buffer_handle_t handle, - int64_t *offset); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_BYTESTRIDE)(gralloc1_device_t *device, buffer_handle_t handle, - int *bytestride); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_YUVINFO)(gralloc1_device_t *device, buffer_handle_t handle, - mali_gralloc_yuv_info *yuvinfo); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_SIZE)(gralloc1_device_t *device, buffer_handle_t handle, int *size); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_FLAGS)(gralloc1_device_t *device, buffer_handle_t handle, int *flags); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_BUFF_MIN_PAGESIZE)(gralloc1_device_t *device, buffer_handle_t handle, - int *min_pgsz); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_GET_ATTR_PARAM)(gralloc1_device_t *device, buffer_handle_t handle, buf_attr attr, - int32_t *val, int32_t last_call); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_SET_ATTR_PARAM)(gralloc1_device_t *device, buffer_handle_t handle, buf_attr attr, - int32_t *val, int32_t last_call); -typedef int32_t (*GRALLOC1_PFN_PRIVATE_SET_PRIV_FMT)(gralloc1_device_t *device, gralloc1_buffer_descriptor_t desc, - uint64_t internal_format); - -#if defined(GRALLOC_LIBRARY_BUILD) -gralloc1_function_pointer_t mali_gralloc_private_interface_getFunction(int32_t descriptor); -#endif - -#endif /* MALI_GRALLOC_PRIVATE_INTERFACE_H_ */ diff --git a/gralloc3/src/mali_gralloc_private_interface_types.h b/gralloc3/src/mali_gralloc_private_interface_types.h deleted file mode 100644 index f91db25..0000000 --- a/gralloc3/src/mali_gralloc_private_interface_types.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2017 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MALI_GRALLOC_PRIVATE_INTERFACE_TYPES_H_ -#define MALI_GRALLOC_PRIVATE_INTERFACE_TYPES_H_ - -#define GRALLOC_ARM_BUFFER_ATTR_HDR_INFO_SUPPORT -#define GRALLOC_ARM_BUFFER_ATTR_DATASPACE_SUPPORT - -/* - * Deprecated. - * Use GRALLOC_ARM_BUFFER_ATTR_DATASPACE - * instead. - */ -typedef enum -{ - MALI_HDR_NO_INFO, - MALI_HDR_ST2084, - MALI_HDR_HLG, - MALI_HDR_LAST -} mali_transfer_function; - -typedef struct -{ - //values are in units of 0.00002 - uint16_t x; - uint16_t y; -} primaries; - -typedef struct -{ - primaries r; - primaries g; - primaries b; - primaries w; - uint16_t minDisplayLuminance; // in cd/m^2 - uint16_t maxDisplayLuminance; // in 0.0001 cd/m^2 - uint16_t maxContentLightLevel; // in cd/m^2 - uint16_t maxFrameAverageLightLevel; // in cd/m^2 - - /* Deprecated. Use GRALLOC_ARM_BUFFER_ATTR_DATASPACE instead. */ - mali_transfer_function eotf; -} mali_hdr_info; - -enum -{ - /* CROP_RECT and YUV_TRANS are intended to be - * written by producers and read by consumers. - * A producer should write these parameters before - * it queues a buffer to the consumer. - */ - - /* CROP RECT, defined as an int array of top, left, height, width. Origin in top-left corner */ - GRALLOC_ARM_BUFFER_ATTR_CROP_RECT = 1, - - /* DEPRECATED. Set if the AFBC format used a YUV transform before compressing */ - GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS = 2, - - /* Set if the AFBC format uses sparse allocation */ - GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC = 3, - - /* HDR Information */ - GRALLOC_ARM_BUFFER_ATTR_HDR_INFO = 4, - - /* Dataspace - used for YUV to RGB conversion. */ - GRALLOC_ARM_BUFFER_ATTR_DATASPACE = 5, - - /* Forced Dataspace - overrides ATTR_DATASPACE if not -1 - * Used to override dataspace used in GPU YUV->RGB conversion if dataspace support is - * disabled in gralloc or system-wide. - * Datspace support is disabled system-wide when ro.vendor.cscsupported == 0 or not set. - * Otherwise remains as -1 - * */ - GRALLOC_ARM_BUFFER_ATTR_FORCE_DATASPACE = 6, - - GRALLOC_ARM_BUFFER_ATTR_LAST -}; - -typedef uint32_t buf_attr; - -/* - * Deprecated. - * Use GRALLOC_ARM_BUFFER_ATTR_DATASPACE - * instead. - */ -typedef enum -{ - MALI_YUV_NO_INFO, - MALI_YUV_BT601_NARROW, - MALI_YUV_BT601_WIDE, - MALI_YUV_BT709_NARROW, - MALI_YUV_BT709_WIDE, - MALI_YUV_BT2020_NARROW, - MALI_YUV_BT2020_WIDE -} mali_gralloc_yuv_info; - -#endif /* MALI_GRALLOC_PRIVATE_INTERFACE_TYPES_H_ */ diff --git a/gralloc3/src/mali_gralloc_public_interface.cpp b/gralloc3/src/mali_gralloc_public_interface.cpp deleted file mode 100644 index c50683d..0000000 --- a/gralloc3/src/mali_gralloc_public_interface.cpp +++ /dev/null @@ -1,754 +0,0 @@ -/* - * Copyright (C) 2016, 2018-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <inttypes.h> -#include <hardware/hardware.h> -#include <hardware/gralloc1.h> - -#include "mali_gralloc_module.h" - -#include "mali_gralloc_private_interface.h" -#include "mali_gralloc_buffer.h" -#include "mali_gralloc_ion.h" -#include "mali_gralloc_bufferdescriptor.h" -#include "mali_gralloc_bufferallocation.h" -#include "mali_gralloc_reference.h" -#include "mali_gralloc_bufferaccess.h" -#include "framebuffer_device.h" -#include "gralloc_buffer_priv.h" -#include "mali_gralloc_debug.h" - -typedef struct mali_gralloc_func -{ - gralloc1_function_descriptor_t desc; - gralloc1_function_pointer_t func; -} mali_gralloc_func; - -static void mali_gralloc_dump(gralloc1_device_t *device, uint32_t *outSize, char *outBuffer) -{ - if (NULL == outSize) - { - ALOGE("Invalid pointer to outSize and return"); - return; - } - - mali_gralloc_dump_internal(outSize, outBuffer); - GRALLOC_UNUSED(device); -} - -static int32_t mali_gralloc_create_descriptor(gralloc1_device_t *device, gralloc1_buffer_descriptor_t *outDescriptor) -{ - int ret = 0; - ret = mali_gralloc_create_descriptor_internal(outDescriptor); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_destroy_descriptor(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor) -{ - int ret = 0; - ret = mali_gralloc_destroy_descriptor_internal(descriptor); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_set_consumer_usage(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, - /*uint64_t */ gralloc1_consumer_usage_t usage) -{ - int ret = 0; - ret = mali_gralloc_set_consumerusage_internal(descriptor, usage); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_set_dimensions(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, - uint32_t width, uint32_t height) -{ - int ret = 0; - ret = mali_gralloc_set_dimensions_internal(descriptor, width, height); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_set_format(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, - /*int32_t*/ android_pixel_format_t format) -{ - int ret = 0; - ret = mali_gralloc_set_format_internal(descriptor, format); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_set_producer_usage(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, - /*uint64_t */ gralloc1_producer_usage_t usage) -{ - int ret = 0; - ret = mali_gralloc_set_producerusage_internal(descriptor, usage); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_get_backing_store(gralloc1_device_t *device, buffer_handle_t buffer, - gralloc1_backing_store_t *outStore) -{ - int ret = 0; - ret = mali_gralloc_get_backing_store_internal(buffer, outStore); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_get_consumer_usage(gralloc1_device_t *device, buffer_handle_t buffer, - uint64_t * /*gralloc1_consumer_usage_t*/ outUsage) -{ - int ret = 0; - ret = mali_gralloc_get_consumer_usage_internal(buffer, outUsage); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_get_dimensions(gralloc1_device_t *device, buffer_handle_t buffer, uint32_t *outWidth, - uint32_t *outHeight) -{ - int ret = 0; - ret = mali_gralloc_get_dimensions_internal(buffer, outWidth, outHeight); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_get_format(gralloc1_device_t *device, buffer_handle_t buffer, int32_t *outFormat) -{ - int ret = 0; - ret = mali_gralloc_get_format_internal(buffer, outFormat); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_get_producer_usage(gralloc1_device_t *device, buffer_handle_t buffer, - uint64_t * /*gralloc1_producer_usage_t*/ outUsage) -{ - int ret = 0; - ret = mali_gralloc_get_producer_usage_internal(buffer, outUsage); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc_get_stride(gralloc1_device_t *device, buffer_handle_t buffer, uint32_t *outStride) -{ - GRALLOC_UNUSED(device); - int stride; - - const int ret = mali_gralloc_query_getstride(buffer, &stride); - if (ret == GRALLOC1_ERROR_NONE) - { - *outStride = (uint32_t)stride; - } - - return ret; -} - -int32_t mali_gralloc_allocate(gralloc1_device_t *device, uint32_t numDescriptors, - const gralloc1_buffer_descriptor_t *descriptors, buffer_handle_t *outBuffers) -{ - mali_gralloc_module *m; - m = reinterpret_cast<private_module_t *>(device->common.module); - buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(*descriptors); - uint64_t usage; - bool shared = false; - - /* Initialise output parameters. */ - for (uint32_t i = 0; i < numDescriptors; i++) - { - outBuffers[i] = NULL; - } - - usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage; - -#if DISABLE_FRAMEBUFFER_HAL != 1 - - if (usage & GRALLOC_USAGE_HW_FB) - { - if (mali_gralloc_fb_allocate(m, bufDescriptor, outBuffers) < 0) - { - return GRALLOC1_ERROR_NO_RESOURCES; - } - } - else -#endif - { - if (mali_gralloc_buffer_allocate(m, (gralloc_buffer_descriptor_t *)descriptors, numDescriptors, outBuffers, - &shared) < 0) - { - ALOGE("Failed to allocate buffer."); - return GRALLOC1_ERROR_NO_RESOURCES; - } - - if (!shared && 1 != numDescriptors) - { - return GRALLOC1_ERROR_NOT_SHARED; - } - } - - return GRALLOC1_ERROR_NONE; -} - - -static int32_t mali_gralloc_retain(gralloc1_device_t *device, buffer_handle_t buffer) -{ - mali_gralloc_module *m; - m = reinterpret_cast<private_module_t *>(device->common.module); - - if (private_handle_t::validate(buffer) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (mali_gralloc_reference_retain(m, buffer) < 0) - { - return GRALLOC1_ERROR_NO_RESOURCES; - } - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc_release(gralloc1_device_t *device, buffer_handle_t buffer) -{ - mali_gralloc_module *m; - m = reinterpret_cast<private_module_t *>(device->common.module); - - if (mali_gralloc_reference_release(m, buffer, true) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - return GRALLOC1_ERROR_NONE; -} - -/* - * Returns the number of flex layout planes which are needed to represent the - * given buffer. - * - * @param device [in] Gralloc device. - * @param buffer [in] The buffer handle for which the number of planes should be queried - * @param outNumPlanes [out] The number of flex planes required to describe the given buffer - * - * @return GRALLOC1_ERROR_NONE - The locking is successful; - * GRALLOC1_ERROR_BAD_HANDLE - The buffer handle is invalid - * GRALLOC1_ERROR_BAD_VALUE - The flex plane pointer is invalid - * Appropriate error, otherwise - */ -static int32_t mali_gralloc1_get_num_flex_planes(const gralloc1_device_t * const device, - const buffer_handle_t buffer, - uint32_t * const outNumPlanes) -{ - mali_gralloc_module *m; - m = reinterpret_cast<private_module_t *>(device->common.module); - - if (private_handle_t::validate(buffer) < 0) - { - AERR("Invalid buffer handle"); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outNumPlanes == NULL) - { - AERR("Invalid flex plane pointer"); - return GRALLOC1_ERROR_BAD_VALUE; - } - - int status = mali_gralloc_get_num_flex_planes(m, buffer, outNumPlanes); - if (status != 0) - { - return status; - } - - return GRALLOC1_ERROR_NONE; -} - -/* - * Locks the Gralloc 1.0 buffer for the specified CPU usage. - * - * @param device [in] Gralloc1 device. - * @param buffer [in] The buffer to lock. - * @param producerUsage [in] The producer usage flags to request (gralloc1_producer_usage_t). - * @param consumerUsage [in] The consumer usage flags to request (gralloc1_consumer_usage_t). - * @param accessRegion [in] The portion of the buffer that the client - * intends to access. - * @param outData [out] To be filled with a CPU-accessible pointer to - * the buffer data for CPU usage. - * @param acquireFence [in] Refers to an acquire sync fence object. - * - * @return GRALLOC1_ERROR_NONE, when locking is successful; - * appropriate error, otherwise - * - * @Notes: Locking a buffer simultaneously for write or read/write leaves the - * buffer's content into an indeterminate state. - */ -static int32_t mali_gralloc1_lock_async(gralloc1_device_t *device, - buffer_handle_t buffer, - uint64_t producerUsage, - uint64_t consumerUsage, - const gralloc1_rect_t *accessRegion, - void **outData, - int32_t acquireFence) -{ - int status = 0; - mali_gralloc_module *m; - m = reinterpret_cast<private_module_t *>(device->common.module); - - if (private_handle_t::validate(buffer) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (accessRegion == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - /* The lock usage constraints - * 1. Exactly one of producerUsage and consumerUsage must be *_USAGE_NONE. - * 2. The usage which is not *_USAGE_NONE must be one of the *_USAGE_CPU_* - * as applicable. - * are relaxed to accommodate an issue in shims with regard to lock usage mapping. - */ - //if (!((producerUsage | consumerUsage) & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))) - //{ - // return GRALLOC1_ERROR_BAD_VALUE; - //} - - status = mali_gralloc_lock_async(m, buffer, producerUsage | consumerUsage, - accessRegion->left, accessRegion->top, - accessRegion->width, accessRegion->height, - outData, acquireFence); - if (status != 0) - { - if (status == -EINVAL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - return GRALLOC1_ERROR_UNSUPPORTED; - } - - return GRALLOC1_ERROR_NONE; -} - -/* - * Locks the Gralloc 1.0 buffer, for the specified CPU usage, asynchronously. - * - * @param device [in] Gralloc1 device. - * @param buffer [in] The buffer to lock. - * @param producerUsage [in] The producer usage flags requested (gralloc1_producer_usage_t). - * @param consumerUsage [in] The consumer usage flags requested (gralloc1_consumer_usage_t). - * @param accessRegion [in] The portion of the buffer that the client - * intends to access. - * @param outFlexLayout [out] To be filled with the description of the planes - * in the buffer - * @param acquireFence [in] Refers to an acquire sync fence object. - * - * @return GRALLOC1_ERROR_NONE - Locking is successful; - * GRALLOC1_ERROR_BAD_HANDLE - Invalid buffer handle - * GRALLOC1_ERROR_BAD_VALUE - Invalid usage parameters - * GRALLOC1_ERROR_UNSUPPORTED - Any other error, like wrong access - * region parameters, invalid buffer ownership, etc. - * - * @Notes: Locking a buffer simultaneously for write or read/write leaves the - * buffer's content into an indeterminate state. - */ -static int32_t mali_gralloc1_lock_flex_async(gralloc1_device_t *device, buffer_handle_t buffer, - uint64_t producerUsage, - uint64_t consumerUsage, - const gralloc1_rect_t *accessRegion, - struct android_flex_layout *outFlexLayout, - int32_t acquireFence) -{ - int status = 0; - mali_gralloc_module *m; - m = reinterpret_cast<private_module_t *>(device->common.module); - - if (private_handle_t::validate(buffer) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outFlexLayout == NULL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - /* The lock usage constraints - * 1. Exactly one of producerUsage and consumerUsage must be *_USAGE_NONE. - * 2. The usage which is not *_USAGE_NONE must be one of the *_USAGE_CPU_* - * as applicable. - * are relaxed to accommodate an issue in shims with regard to lock usage mapping. - */ - //if (!((producerUsage | consumerUsage) & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))) - //{ - // return GRALLOC1_ERROR_BAD_VALUE; - //} - - status = mali_gralloc_lock_flex_async(m, buffer, producerUsage | consumerUsage, - accessRegion->left, accessRegion->top, - accessRegion->width, accessRegion->height, - outFlexLayout, acquireFence); - if (status != 0) - { - if (status == -EINVAL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - return GRALLOC1_ERROR_UNSUPPORTED; - } - - return GRALLOC1_ERROR_NONE; -} - -/* - * Unlocks the Gralloc 1.0 buffer asynchronously. - * - * @param device [in] Gralloc1 device. - * @param buffer [in] The buffer to unlock. - * @param outReleaseFence [out] Refers to an acquire sync fence object. - * - * @return 0, when the locking is successful; - * Appropriate error, otherwise - * - * Note: unlocking a buffer which is not locked results in an unexpected behaviour. - * Though it is possible to create a state machine to track the buffer state to - * recognize erroneous conditions, it is expected of client to adhere to API - * call sequence - */ -static int32_t mali_gralloc1_unlock_async(const gralloc1_device_t * const device, - buffer_handle_t buffer, - int32_t *const outReleaseFence) -{ - mali_gralloc_module *m; - m = reinterpret_cast<private_module_t *>(device->common.module); - - if (private_handle_t::validate(buffer) < 0) - { - return GRALLOC1_ERROR_BAD_HANDLE; - } - - const int status = mali_gralloc_unlock_async(m, buffer, outReleaseFence); - if (status != 0) - { - if (status == -EINVAL) - { - return GRALLOC1_ERROR_BAD_VALUE; - } - - return GRALLOC1_ERROR_UNSUPPORTED; - } - - return GRALLOC1_ERROR_NONE; -} - -#if PLATFORM_SDK_VERSION >= 26 -static int32_t mali_gralloc1_set_layer_count(gralloc1_device_t* device, - gralloc1_buffer_descriptor_t descriptor, - uint32_t layerCount) -{ - int ret = 0; - ret = mali_gralloc_set_layer_count_internal(descriptor, layerCount); - GRALLOC_UNUSED(device); - return ret; -} - -static int32_t mali_gralloc1_get_layer_count(gralloc1_device_t* device, buffer_handle_t buffer, uint32_t* outLayerCount) -{ - int ret = 0; - ret = mali_gralloc_get_layer_count_internal(buffer, outLayerCount); - GRALLOC_UNUSED(device); - return ret; -} -#endif - -static int32_t mali_gralloc1_validate_buffer_size(gralloc1_device_t* device, buffer_handle_t buffer, - const gralloc1_buffer_descriptor_info_t* descriptorInfo, - uint32_t stride) -{ - mali_gralloc_module *m; - m = reinterpret_cast<private_module_t *>(device->common.module); - - if (buffer == 0) - { - AERR("Bad input buffer handle %p to validate buffer size", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (private_handle_t::validate(buffer) < 0) - { - AERR("Buffer: %p is corrupted, for validating its size", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (!descriptorInfo->width || !descriptorInfo->height ||!descriptorInfo->layerCount) - { - AERR("Invalid buffer descriptor attributes, width = %d height = %d layerCount = %d", - descriptorInfo->width, descriptorInfo->height, descriptorInfo->layerCount); - return GRALLOC1_ERROR_BAD_VALUE; - } - - if (descriptorInfo->format == 0) - { - AERR("Invalid descriptor format to validate the buffer size"); - return GRALLOC1_ERROR_BAD_VALUE; - } - - buffer_descriptor_t grallocDescriptor; - grallocDescriptor.width = descriptorInfo->width; - grallocDescriptor.height = descriptorInfo->height; - grallocDescriptor.layer_count = descriptorInfo->layerCount; - grallocDescriptor.hal_format = descriptorInfo->format; - grallocDescriptor.producer_usage = descriptorInfo->producerUsage; - grallocDescriptor.consumer_usage = descriptorInfo->consumerUsage; - grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; - - /* Derive the buffer size for the given descriptor */ - const int result = mali_gralloc_derive_format_and_size(m, &grallocDescriptor); - if (result) - { - AERR("Failed to derive format and size for the given descriptor information. error: %d", result); - return GRALLOC1_ERROR_UNSUPPORTED; - } - - /* Validate the buffer parameters against descriptor info */ - private_handle_t *gralloc_buffer = (private_handle_t *)buffer; - - /* The buffer size must be greater than (or equal to) what would have been - * allocated with descriptor - */ - if ((size_t)gralloc_buffer->size < grallocDescriptor.size) - { - ALOGW("Buf size mismatch. Buffer size = %u, Descriptor (derived) size = %zu", - gralloc_buffer->size, grallocDescriptor.size); - return GRALLOC1_ERROR_BAD_VALUE; - } - - if ((uint32_t)gralloc_buffer->stride != stride) - { - ALOGW("Stride mismatch. Expected stride = %d, Buffer stride = %d", - stride, gralloc_buffer->stride); - return GRALLOC1_ERROR_BAD_VALUE; - } - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc1_get_transport_size(gralloc1_device_t* device, buffer_handle_t buffer, - uint32_t *outNumFds, uint32_t *outNumInts) -{ - GRALLOC_UNUSED(device); - - if (buffer == 0) - { - AERR("Bad input buffer handle %p to query transport size", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outNumFds == 0 || outNumInts == 0) - { - AERR("Bad output pointers outNumFds=%p outNumInts=%p to populate", outNumFds, outNumInts); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (private_handle_t::validate(buffer) < 0) - { - AERR("Buffer %p, for querying transport size, is corrupted", buffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - *outNumFds = buffer->numFds; - *outNumInts = buffer->numInts; - - return GRALLOC1_ERROR_NONE; -} - -static int32_t mali_gralloc1_import_buffer(gralloc1_device_t* device, const buffer_handle_t rawHandle, - buffer_handle_t* outBuffer) -{ - mali_gralloc_module *m; - m = reinterpret_cast<private_module_t *>(device->common.module); - - if (rawHandle == 0) - { - AERR("Bad input raw handle %p to import", rawHandle); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (outBuffer == 0) - { - AERR("Bad output buffer pointer %p to populate", outBuffer); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - /* The rawHandle could have been cloned locally or received from another - * HAL server/client or another process. Hence clone it locally before - * importing the buffer - */ - native_handle_t* bufferHandle = native_handle_clone(rawHandle); - if (!bufferHandle) - { - AERR("Failed to clone %p for importing it", rawHandle); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (private_handle_t::validate(bufferHandle) < 0) - { - AERR("Failed to import corrupted buffer: %p", bufferHandle); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - if (mali_gralloc_reference_retain(m, bufferHandle) < 0) - { - AERR("Buffer: %p cannot be imported", bufferHandle); - return GRALLOC1_ERROR_NO_RESOURCES; - } - - *outBuffer = bufferHandle; - - return GRALLOC1_ERROR_NONE; -} - -static const mali_gralloc_func mali_gralloc_func_list[] = { - { GRALLOC1_FUNCTION_DUMP, (gralloc1_function_pointer_t)mali_gralloc_dump }, - { GRALLOC1_FUNCTION_CREATE_DESCRIPTOR, (gralloc1_function_pointer_t)mali_gralloc_create_descriptor }, - { GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR, (gralloc1_function_pointer_t)mali_gralloc_destroy_descriptor }, - { GRALLOC1_FUNCTION_SET_CONSUMER_USAGE, (gralloc1_function_pointer_t)mali_gralloc_set_consumer_usage }, - { GRALLOC1_FUNCTION_SET_DIMENSIONS, (gralloc1_function_pointer_t)mali_gralloc_set_dimensions }, - { GRALLOC1_FUNCTION_SET_FORMAT, (gralloc1_function_pointer_t)mali_gralloc_set_format }, - { GRALLOC1_FUNCTION_SET_PRODUCER_USAGE, (gralloc1_function_pointer_t)mali_gralloc_set_producer_usage }, - { GRALLOC1_FUNCTION_GET_BACKING_STORE, (gralloc1_function_pointer_t)mali_gralloc_get_backing_store }, - { GRALLOC1_FUNCTION_GET_CONSUMER_USAGE, (gralloc1_function_pointer_t)mali_gralloc_get_consumer_usage }, - { GRALLOC1_FUNCTION_GET_DIMENSIONS, (gralloc1_function_pointer_t)mali_gralloc_get_dimensions }, - { GRALLOC1_FUNCTION_GET_FORMAT, (gralloc1_function_pointer_t)mali_gralloc_get_format }, - { GRALLOC1_FUNCTION_GET_PRODUCER_USAGE, (gralloc1_function_pointer_t)mali_gralloc_get_producer_usage }, - { GRALLOC1_FUNCTION_GET_STRIDE, (gralloc1_function_pointer_t)mali_gralloc_get_stride }, - { GRALLOC1_FUNCTION_ALLOCATE, (gralloc1_function_pointer_t)mali_gralloc_allocate }, - { GRALLOC1_FUNCTION_RETAIN, (gralloc1_function_pointer_t)mali_gralloc_retain }, - { GRALLOC1_FUNCTION_RELEASE, (gralloc1_function_pointer_t)mali_gralloc_release }, - { GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES, (gralloc1_function_pointer_t)mali_gralloc1_get_num_flex_planes }, - { GRALLOC1_FUNCTION_LOCK, (gralloc1_function_pointer_t)mali_gralloc1_lock_async }, - { GRALLOC1_FUNCTION_LOCK_FLEX, (gralloc1_function_pointer_t)mali_gralloc1_lock_flex_async }, - { GRALLOC1_FUNCTION_UNLOCK, (gralloc1_function_pointer_t)mali_gralloc1_unlock_async }, -#if PLATFORM_SDK_VERSION >= 26 - { GRALLOC1_FUNCTION_SET_LAYER_COUNT, (gralloc1_function_pointer_t)mali_gralloc1_set_layer_count }, - { GRALLOC1_FUNCTION_GET_LAYER_COUNT, (gralloc1_function_pointer_t)mali_gralloc1_get_layer_count }, -#endif - { GRALLOC1_FUNCTION_VALIDATE_BUFFER_SIZE, (gralloc1_function_pointer_t)mali_gralloc1_validate_buffer_size }, - { GRALLOC1_FUNCTION_GET_TRANSPORT_SIZE, (gralloc1_function_pointer_t)mali_gralloc1_get_transport_size }, - { GRALLOC1_FUNCTION_IMPORT_BUFFER, (gralloc1_function_pointer_t)mali_gralloc1_import_buffer }, - - /* GRALLOC1_FUNCTION_INVALID has to be the last descriptor on the list. */ - { GRALLOC1_FUNCTION_INVALID, NULL } -}; - -static void mali_gralloc_getCapabilities(gralloc1_device_t *dev, uint32_t *outCount, int32_t *outCapabilities) -{ - GRALLOC_UNUSED(dev); -#if PLATFORM_SDK_VERSION >= 26 - if (outCount != NULL) - { - *outCount = 1; - } - - if (outCapabilities != NULL) - { - *(outCapabilities++) = GRALLOC1_CAPABILITY_LAYERED_BUFFERS; - } -#else - GRALLOC_UNUSED(outCapabilities); - if (outCount != NULL) - { - *outCount = 0; - } -#endif -} - -static gralloc1_function_pointer_t mali_gralloc_getFunction(gralloc1_device_t *dev, int32_t descriptor) -{ - GRALLOC_UNUSED(dev); - gralloc1_function_pointer_t rval = NULL; - uint32_t pos = 0; - - while (mali_gralloc_func_list[pos].desc != GRALLOC1_FUNCTION_INVALID) - { - if (mali_gralloc_func_list[pos].desc == descriptor) - { - rval = mali_gralloc_func_list[pos].func; - break; - } - - pos++; - } - - if (rval == NULL) - { - rval = mali_gralloc_private_interface_getFunction(descriptor); - } - - return rval; -} - -static int mali_gralloc_device_close(struct hw_device_t *device) -{ - gralloc1_device_t *dev = reinterpret_cast<gralloc1_device_t *>(device); - if (dev) - { - delete dev; - } - - mali_gralloc_ion_close(); - - return 0; -} - -int mali_gralloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device) -{ - gralloc1_device_t *dev; - - GRALLOC_UNUSED(name); - - dev = new gralloc1_device_t; - - if (NULL == dev) - { - return -1; - } - - /* initialize our state here */ - memset(dev, 0, sizeof(*dev)); - - /* initialize the procs */ - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->common.version = 0; - dev->common.module = const_cast<hw_module_t *>(module); - dev->common.close = mali_gralloc_device_close; - - dev->getCapabilities = mali_gralloc_getCapabilities; - dev->getFunction = mali_gralloc_getFunction; - - private_module_t *p = reinterpret_cast<private_module_t*>(dev->common.module); - if (p->ionfd == -1) - p->ionfd = mali_gralloc_ion_open(); - - *device = &dev->common; - - return 0; -} diff --git a/gralloc3/src/mali_gralloc_reference.cpp b/gralloc3/src/mali_gralloc_reference.cpp deleted file mode 100644 index d8f2f89..0000000 --- a/gralloc3/src/mali_gralloc_reference.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2016, 2018-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 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. - */ - -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> -#endif - -#include "mali_gralloc_module.h" -#include "mali_gralloc_private_interface_types.h" -#include "mali_gralloc_buffer.h" -#include "mali_gralloc_ion.h" -#include "gralloc_buffer_priv.h" -#include "mali_gralloc_bufferallocation.h" -#include "mali_gralloc_debug.h" - -static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER; - -int mali_gralloc_reference_retain(mali_gralloc_module const *module, buffer_handle_t handle) -{ - GRALLOC_UNUSED(module); - - if (private_handle_t::validate(handle) < 0) - { - AERR("Registering/Retaining invalid buffer %p, returning error", handle); - return -EINVAL; - } - - private_handle_t *hnd = (private_handle_t *)handle; - pthread_mutex_lock(&s_map_lock); - - if (hnd->allocating_pid == getpid() || hnd->remote_pid == getpid()) - { - hnd->ref_count++; - pthread_mutex_unlock(&s_map_lock); - return 0; - } - else - { - hnd->remote_pid = getpid(); - hnd->ref_count = 1; - } - - int retval = -EINVAL; - - if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) - { - retval = 0; - } - else if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_ION)) - { - retval = mali_gralloc_ion_map(hnd); -#if GRALLOC_ION_HANDLE_IMPORT == 1 - if (retval >= 0) - { - /* failing to import ion handle is not fatal */ - import_exynos_ion_handles(hnd); - retval = 0; - } -#endif - } - else - { - AERR("Unknown buffer flags not supported. flags = %d", hnd->flags); - } - - pthread_mutex_unlock(&s_map_lock); - return retval; -} - -int mali_gralloc_reference_release(mali_gralloc_module const *module, buffer_handle_t handle, bool canFree) -{ - GRALLOC_UNUSED(module); - - if (private_handle_t::validate(handle) < 0) - { - AERR("unregistering/releasing invalid buffer %p, returning error", handle); - return -EINVAL; - } - - private_handle_t *hnd = (private_handle_t *)handle; - pthread_mutex_lock(&s_map_lock); - - if (hnd->ref_count == 0) - { - AERR("Buffer %p should have already been released", handle); - pthread_mutex_unlock(&s_map_lock); - return -EINVAL; - } - - if (hnd->allocating_pid == getpid()) - { - hnd->ref_count--; - - if (hnd->ref_count == 0 && canFree) - { - if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) - { - close(hnd->fb_fd); - } - else - { - mali_gralloc_dump_buffer_erase(hnd); - } - -#if GRALLOC_ION_HANDLE_IMPORT == 1 - free_exynos_ion_handles(hnd); -#endif - mali_gralloc_buffer_free(handle); - delete handle; - } - } - else if (hnd->remote_pid == getpid()) // never unmap buffers that were not imported into this process - { - hnd->ref_count--; - - if (hnd->ref_count == 0) - { - - if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_ION)) - { - mali_gralloc_ion_unmap(hnd); -#if GRALLOC_ION_HANDLE_IMPORT == 1 - free_exynos_ion_handles(hnd); -#endif - } - else - { - AERR("Unregistering/Releasing unknown buffer is not supported. Flags = %d", hnd->flags); - } - -#if GRALLOC_USE_ASHMEM_METADATA != 1 - /* - * Close shared attribute region file descriptor. It might seem strange to "free" - * this here since this can happen in a client process, but free here is nothing - * but unmapping and closing the duplicated file descriptor. The original ashmem - * fd instance is still open until alloc_device_free() is called. Even sharing - * of gralloc buffers within the same process should have fds dup:ed. - */ - gralloc_buffer_attr_free(hnd); -#endif - - hnd->base = 0; - } - } - else - { - AERR("Trying to unregister buffer %p from process %d that was not imported into current process: %d", hnd, - hnd->remote_pid, getpid()); - } - - pthread_mutex_unlock(&s_map_lock); - return 0; -} diff --git a/gralloc3/src/mali_gralloc_usages.h b/gralloc3/src/mali_gralloc_usages.h deleted file mode 100644 index c014847..0000000 --- a/gralloc3/src/mali_gralloc_usages.h +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (C) 2017-2019 ARM Limited. All rights reserved. - * - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MALI_GRALLOC_USAGES_H_ -#define MALI_GRALLOC_USAGES_H_ - -#ifndef GRALLOC_VERSION_MAJOR -#error "GRALLOC_VERSION_MAJOR must be defined." -#endif - -#define GRALLOC_USAGE_PRIVATE_MASK (0xffff0000f0000000U) - -/* - * Below usage types overlap, this is intentional. - * The reason is that for Gralloc 0.3 there are very - * few usage flags we have at our disposal. - * - * The overlapping is handled by processing the definitions - * in a specific order. - * - * MALI_GRALLOC_USAGE_PRIVATE_FORMAT and MALI_GRALLOC_USAGE_NO_AFBC - * don't overlap and are processed first. - * - * MALI_GRALLOC_USAGE_YUV_CONF are only for YUV formats and clients - * using MALI_GRALLOC_USAGE_NO_AFBC must never allocate YUV formats. - * The latter is strictly enforced and allocations will fail. - * - * MALI_GRALLOC_USAGE_AFBC_PADDING is only valid if MALI_GRALLOC_USAGE_NO_AFBC - * is not present. - */ - -/* - * Gralloc private usage 0-3 are the same in 0.3 and 1.0. - * We defined based our usages based on what is available. - */ -#if GRALLOC_VERSION_MAJOR == 1 -#include <hardware/gralloc1.h> - -/* - * Most gralloc code is fairly version agnostic, but certain - * places still use old usage defines. Make sure it works - * ok for usages that are backwards compatible. - */ -#define GRALLOC_USAGE_PRIVATE_0 GRALLOC1_CONSUMER_USAGE_PRIVATE_0 -#define GRALLOC_USAGE_PRIVATE_1 GRALLOC1_CONSUMER_USAGE_PRIVATE_1 -#define GRALLOC_USAGE_PRIVATE_2 GRALLOC1_CONSUMER_USAGE_PRIVATE_2 -#define GRALLOC_USAGE_PRIVATE_3 GRALLOC1_CONSUMER_USAGE_PRIVATE_3 - -#define GRALLOC_USAGE_PRIVATE_4 GRALLOC1_CONSUMER_USAGE_PRIVATE_4 -#define GRALLOC_USAGE_PRIVATE_5 GRALLOC1_CONSUMER_USAGE_PRIVATE_5 -#define GRALLOC_USAGE_PRIVATE_6 GRALLOC1_CONSUMER_USAGE_PRIVATE_6 -#define GRALLOC_USAGE_PRIVATE_7 GRALLOC1_CONSUMER_USAGE_PRIVATE_7 -#define GRALLOC_USAGE_PRIVATE_8 GRALLOC1_CONSUMER_USAGE_PRIVATE_8 -#define GRALLOC_USAGE_PRIVATE_9 GRALLOC1_CONSUMER_USAGE_PRIVATE_9 - -#define GRALLOC_USAGE_PRIVATE_10 GRALLOC1_PRODUCER_USAGE_PRIVATE_10 -#define GRALLOC_USAGE_PRIVATE_12 GRALLOC1_PRODUCER_USAGE_PRIVATE_12 -#define GRALLOC_USAGE_PRIVATE_13 GRALLOC1_PRODUCER_USAGE_PRIVATE_13 -#define GRALLOC_USAGE_PRIVATE_14 GRALLOC1_PRODUCER_USAGE_PRIVATE_14 -#define GRALLOC_USAGE_PRIVATE_15 GRALLOC1_PRODUCER_USAGE_PRIVATE_15 -#define GRALLOC_USAGE_PRIVATE_16 GRALLOC1_PRODUCER_USAGE_PRIVATE_16 -#define GRALLOC_USAGE_PRIVATE_17 GRALLOC1_PRODUCER_USAGE_PRIVATE_17 -#define GRALLOC_USAGE_PRIVATE_18 GRALLOC1_PRODUCER_USAGE_PRIVATE_18 -#define GRALLOC_USAGE_PRIVATE_19 GRALLOC1_PRODUCER_USAGE_PRIVATE_19 - -#define GRALLOC_USAGE_SW_WRITE_RARELY GRALLOC1_PRODUCER_USAGE_CPU_WRITE -#define GRALLOC_USAGE_SW_WRITE_OFTEN GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN -#define GRALLOC_USAGE_SW_READ_RARELY GRALLOC1_CONSUMER_USAGE_CPU_READ -#define GRALLOC_USAGE_SW_READ_OFTEN GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN -#define GRALLOC_USAGE_HW_FB GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET -#define GRALLOC_USAGE_HW_2D 0x00000400U - -#define GRALLOC_USAGE_SW_WRITE_MASK 0x000000F0U -#define GRALLOC_USAGE_SW_READ_MASK 0x0000000FU -#define GRALLOC_USAGE_PROTECTED GRALLOC1_PRODUCER_USAGE_PROTECTED -#define GRALLOC_USAGE_HW_RENDER GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET -#define GRALLOC_USAGE_HW_CAMERA_WRITE GRALLOC1_PRODUCER_USAGE_CAMERA -#define GRALLOC_USAGE_HW_CAMERA_READ GRALLOC1_CONSUMER_USAGE_CAMERA -#define GRALLOC_USAGE_HW_TEXTURE GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE -#define GRALLOC_USAGE_HW_VIDEO_ENCODER GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER -#define GRALLOC_USAGE_HW_COMPOSER GRALLOC1_CONSUMER_USAGE_HWCOMPOSER -#define GRALLOC_USAGE_EXTERNAL_DISP 0x00002000U - -#define GRALLOC_USAGE_SENSOR_DIRECT_DATA GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA -#define GRALLOC_USAGE_GPU_DATA_BUFFER GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER -#define GRALLOC_USAGE_VIDEO_DECODER GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER - -typedef enum -{ - /* - * Allocation will be used as a front-buffer, which - * supports concurrent producer-consumer access. - * - * NOTE: Must not be used with MALI_GRALLOC_USAGE_FORCE_BACKBUFFER - */ - MALI_GRALLOC_USAGE_FRONTBUFFER = GRALLOC1_PRODUCER_USAGE_PRIVATE_12, - - /* - * Allocation will be used as a back-buffer. - * Use when switching from front-buffer as a workaround for Android - * buffer queue, which does not re-allocate for a sub-set of - * existing usage. - * - * NOTE: Must not be used with MALI_GRALLOC_USAGE_FRONTBUFFER. - */ - MALI_GRALLOC_USAGE_FORCE_BACKBUFFER = GRALLOC1_PRODUCER_USAGE_PRIVATE_13, - - /* - * Buffer will not be allocated with AFBC. - * - * NOTE: Not compatible with MALI_GRALLOC_USAGE_FORCE_BACKBUFFER so cannot be - * used when switching from front-buffer to back-buffer. - */ - MALI_GRALLOC_USAGE_NO_AFBC = GRALLOC1_PRODUCER_USAGE_PRIVATE_1, - - /* Custom alignment for AFBC headers. - * - * NOTE: due to usage flag overlap, AFBC_PADDING cannot be used with FORCE_BACKBUFFER. - */ - MALI_GRALLOC_USAGE_AFBC_PADDING = GRALLOC1_PRODUCER_USAGE_PRIVATE_14, - /* Private format usage. - * 'format' argument to allocation function will be interpreted in a - * private manner and must be constructed via GRALLOC_PRIVATE_FORMAT_WRAPPER_* - * macros which pack base format and AFBC format modifiers into 32-bit value. - */ - MALI_GRALLOC_USAGE_PRIVATE_FORMAT = GRALLOC1_PRODUCER_USAGE_PRIVATE_15, - - /* SLSI specific usages */ - GRALLOC1_PRODUCER_USAGE_PRIVATE_NONSECURE = GRALLOC1_PRODUCER_USAGE_PRIVATE_8, - GRALLOC1_PRODUCER_USAGE_NOZEROED = GRALLOC1_PRODUCER_USAGE_PRIVATE_9, - - GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA = GRALLOC1_CONSUMER_USAGE_PRIVATE_7, - - /* FaceAuth specific usages */ - GS101_GRALLOC_USAGE_TPU_INPUT = GRALLOC1_CONSUMER_USAGE_PRIVATE_5, - GS101_GRALLOC_USAGE_TPU_OUTPUT = GRALLOC1_PRODUCER_USAGE_PRIVATE_3, - GS101_GRALLOC_USAGE_CAMERA_STATS = GRALLOC1_PRODUCER_USAGE_PRIVATE_2, - - /* YUV only. */ - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_DEFAULT = 0, - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT601 = GRALLOC1_PRODUCER_USAGE_PRIVATE_18, - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT709 = GRALLOC1_PRODUCER_USAGE_PRIVATE_19, - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT2020 = (GRALLOC1_PRODUCER_USAGE_PRIVATE_18 | GRALLOC1_PRODUCER_USAGE_PRIVATE_19), - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_MASK = MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT2020, - - MALI_GRALLOC_USAGE_RANGE_DEFAULT = 0, - MALI_GRALLOC_USAGE_RANGE_NARROW = GRALLOC1_PRODUCER_USAGE_PRIVATE_16, - MALI_GRALLOC_USAGE_RANGE_WIDE = GRALLOC1_PRODUCER_USAGE_PRIVATE_17, - MALI_GRALLOC_USAGE_RANGE_MASK = (GRALLOC1_PRODUCER_USAGE_PRIVATE_16 | GRALLOC1_PRODUCER_USAGE_PRIVATE_17), - - /* Google specific usages */ - GRALLOC_USAGE_GOOGLE_IP_BO = GRALLOC_USAGE_PRIVATE_16, - GRALLOC_USAGE_GOOGLE_IP_MFC = GRALLOC_USAGE_PRIVATE_17, - -} mali_gralloc_usage_type; - - -#elif GRALLOC_VERSION_MAJOR == 0 -#include <hardware/gralloc.h> - -typedef enum -{ - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_FRONTBUFFER = GRALLOC_USAGE_PRIVATE_0, - - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_FORCE_BACKBUFFER = GRALLOC_USAGE_PRIVATE_1, - - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_NO_AFBC = (GRALLOC_USAGE_PRIVATE_1 | GRALLOC_USAGE_PRIVATE_2), - - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_AFBC_PADDING = GRALLOC_USAGE_PRIVATE_2, - - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_PRIVATE_FORMAT = GRALLOC_USAGE_PRIVATE_3, - -} mali_gralloc_usage_type; - -#elif GRALLOC_VERSION_MAJOR == 2 -#if HIDL_COMMON_VERSION_SCALED == 100 -#include <android/hardware/graphics/common/1.0/types.h> -#elif HIDL_COMMON_VERSION_SCALED == 110 -#include <android/hardware/graphics/common/1.1/types.h> -#endif - -/* Local macro definitions to emulate Gralloc 1.0 usage interface */ -#define GRALLOC_USAGE_PRIVATE_12 1ULL << 55 -#define GRALLOC_USAGE_PRIVATE_13 1ULL << 54 -#define GRALLOC_USAGE_PRIVATE_14 1ULL << 53 -#define GRALLOC_USAGE_PRIVATE_15 1ULL << 52 -#define GRALLOC_USAGE_PRIVATE_16 1ULL << 51 -#define GRALLOC_USAGE_PRIVATE_17 1ULL << 50 -#define GRALLOC_USAGE_PRIVATE_18 1ULL << 49 -#define GRALLOC_USAGE_PRIVATE_19 1ULL << 48 - -typedef enum -{ - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_FRONTBUFFER = GRALLOC_USAGE_PRIVATE_12, - - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_FORCE_BACKBUFFER = GRALLOC_USAGE_PRIVATE_13, - - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_NO_AFBC = (GRALLOC_USAGE_PRIVATE_13 | GRALLOC_USAGE_PRIVATE_14), - - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_AFBC_PADDING = GRALLOC_USAGE_PRIVATE_14, - - /* See comment for Gralloc 1.0, above. */ - MALI_GRALLOC_USAGE_PRIVATE_FORMAT = GRALLOC_USAGE_PRIVATE_15, - - /* YUV-only. */ - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_DEFAULT = 0, - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT601 = GRALLOC_USAGE_PRIVATE_18, - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT709 = GRALLOC_USAGE_PRIVATE_19, - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT2020 = (GRALLOC_USAGE_PRIVATE_18 | GRALLOC_USAGE_PRIVATE_19), - MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_MASK = MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT2020, - - MALI_GRALLOC_USAGE_RANGE_DEFAULT = 0, - MALI_GRALLOC_USAGE_RANGE_NARROW = GRALLOC_USAGE_PRIVATE_16, - MALI_GRALLOC_USAGE_RANGE_WIDE = GRALLOC_USAGE_PRIVATE_17, - MALI_GRALLOC_USAGE_RANGE_MASK = (GRALLOC_USAGE_PRIVATE_16 | GRALLOC_USAGE_PRIVATE_17), -} mali_gralloc_usage_type; - -using android::hardware::graphics::common::HIDL_COMMON_NAMESPACE::BufferUsage; - -#define GRALLOC_USAGE_SW_WRITE_RARELY static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY) -#define GRALLOC_USAGE_SW_WRITE_OFTEN static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN) -#define GRALLOC_USAGE_SW_READ_RARELY static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY) -#define GRALLOC_USAGE_SW_READ_OFTEN static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN) -#define GRALLOC_USAGE_HW_FB static_cast<uint64_t>(BufferUsage::COMPOSER_CLIENT_TARGET) - -/* Bit 10 must be zero as per Gralloc 2.x interface specification. Used, however, for backward compatibility */ -#define GRALLOC_USAGE_HW_2D static_cast<uint64_t>(0x00000400) - -#define GRALLOC_USAGE_SW_WRITE_MASK static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK) -#define GRALLOC_USAGE_SW_READ_MASK static_cast<uint64_t>(BufferUsage::CPU_READ_MASK) -#define GRALLOC_USAGE_PROTECTED static_cast<uint64_t>(BufferUsage::PROTECTED) -#define GRALLOC_USAGE_HW_RENDER static_cast<uint64_t>(BufferUsage::GPU_RENDER_TARGET) -#define GRALLOC_USAGE_HW_CAMERA_WRITE static_cast<uint64_t>(BufferUsage::CAMERA_OUTPUT) -#define GRALLOC_USAGE_HW_CAMERA_READ static_cast<uint64_t>(BufferUsage::CAMERA_INPUT) -#define GRALLOC_USAGE_HW_TEXTURE static_cast<uint64_t>(BufferUsage::GPU_TEXTURE) -#define GRALLOC_USAGE_HW_VIDEO_ENCODER static_cast<uint64_t>(BufferUsage::VIDEO_ENCODER) -#define GRALLOC_USAGE_HW_COMPOSER static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY) -#define GRALLOC_USAGE_EXTERNAL_DISP static_cast<uint64_t>(0x00002000) - -#define GRALLOC_USAGE_SENSOR_DIRECT_DATA static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA) -#define GRALLOC_USAGE_GPU_DATA_BUFFER static_cast<uint64_t>(BufferUsage::GPU_DATA_BUFFER) -#define GRALLOC_USAGE_VIDEO_DECODER static_cast<uint64_t>(BufferUsage::VIDEO_DECODER) - -#endif - -/* Originally (Gralloc 0.x), Android did not provide an explicit DECODER usage. This was rectified in Android N-MR1/7.1 - * when Gralloc 1.0 defined GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER. However, libstagefright continues - * (currently, Android P/9.0) to use this old combination of flags to indicate decoder producer - */ -#define GRALLOC_USAGE_DECODER (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP) - -static const uint64_t VALID_USAGE = - GRALLOC_USAGE_SW_READ_MASK | /* 0x0FU */ - GRALLOC_USAGE_SW_WRITE_MASK | /* 0xF0U */ - GRALLOC_USAGE_HW_TEXTURE | /* 1U << 8 */ - GRALLOC_USAGE_HW_RENDER | /* 1U << 9 */ - GRALLOC_USAGE_HW_2D | /* 1U << 10 */ - GRALLOC_USAGE_HW_COMPOSER | /* 1U << 11 */ - GRALLOC_USAGE_HW_FB | /* 1U << 12 */ - GRALLOC_USAGE_EXTERNAL_DISP | /* 1U << 13 */ - GRALLOC_USAGE_PROTECTED | /* 1U << 14 */ - 1ULL << 15 | /* COMPOSER_CURSOR (types1.0) */ - GRALLOC_USAGE_HW_VIDEO_ENCODER | /* 1U << 16 */ - GRALLOC_USAGE_HW_CAMERA_WRITE | /* 1U << 17 */ - GRALLOC_USAGE_HW_CAMERA_READ | /* 1U << 18 */ - 1ULL << 19 | /* GRALLOC_USAGE_GVR_FRONT_BUFFER_MODE */ - 1ULL << 20 | /* RENDERSCRIPT */ - 1ULL << 21 | /* GRALLOC1_CONSUMER_USAGE_FOREIGN_BUFFERS (IGNORED) */ - 1ULL << 22 | /* VIDEO_DECODER */ - 1ULL << 23 | /* SENSOR_DIRECT_DATA */ - 1ULL << 24 | /* GPU_DATA_BUFFER */ - 1ULL << 25 | /* GPU_CUBE_MAP */ - 1ULL << 26 | /* GPU_MIPMAP_COMPLETE */ - -#if GRALLOC_VERSION_MAJOR >= 1 - /* As producer and consumer usage are combined there is no way to differentiate these - but they are both listed here to show that the intention is to include both. */ - GRALLOC_USAGE_SENSOR_DIRECT_DATA | /* 1U << 23 */ - GRALLOC_USAGE_GPU_DATA_BUFFER | /* 1U << 24 */ -#endif -#if GRALLOC_VERSION_MAJOR >= 1 - GRALLOC1_PRODUCER_USAGE_PRIVATE_NONSECURE | - GRALLOC1_PRODUCER_USAGE_NOZEROED | - GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA | - - GS101_GRALLOC_USAGE_TPU_INPUT | - GS101_GRALLOC_USAGE_TPU_OUTPUT | - GS101_GRALLOC_USAGE_CAMERA_STATS | - - GRALLOC_USAGE_PRIVATE_19 | /* 1U << 48 */ - GRALLOC_USAGE_PRIVATE_18 | /* 1U << 49 */ - GRALLOC_USAGE_PRIVATE_17 | /* 1U << 50 */ - GRALLOC_USAGE_PRIVATE_16 | /* 1U << 51 */ - GRALLOC_USAGE_PRIVATE_15 | /* 1U << 52 */ - GRALLOC_USAGE_PRIVATE_14 | /* 1U << 53 */ - GRALLOC_USAGE_PRIVATE_13 | /* 1U << 54 */ - GRALLOC_USAGE_PRIVATE_12 | /* 1U << 55 */ - - GRALLOC_USAGE_PRIVATE_10 | /* 1U << 57 */ - GRALLOC_USAGE_PRIVATE_9 | /* 1U << 58 */ - GRALLOC_USAGE_PRIVATE_8 | /* 1U << 59 */ - GRALLOC_USAGE_PRIVATE_7 | /* 1U << 60 */ - GRALLOC_USAGE_PRIVATE_6 | /* 1U << 61 */ - GRALLOC_USAGE_PRIVATE_5 | /* 1U << 62 */ - GRALLOC_USAGE_PRIVATE_4 | /* 1U << 63 */ -#endif - GRALLOC_USAGE_PRIVATE_0 | /* 1U << 28 */ - GRALLOC_USAGE_PRIVATE_1 | /* 1U << 29 */ - GRALLOC_USAGE_PRIVATE_2 | /* 1U << 30 */ - GRALLOC_USAGE_PRIVATE_3; /* 1U << 31 */ -#endif /*MALI_GRALLOC_USAGES_H_*/ diff --git a/gralloc4/.clang-format b/gralloc4/.clang-format new file mode 100644 index 0000000..03af56d --- /dev/null +++ b/gralloc4/.clang-format @@ -0,0 +1,13 @@ +BasedOnStyle: Google + +AccessModifierOffset: -4 +AlignOperands: false +AllowShortFunctionsOnASingleLine: Inline +AlwaysBreakBeforeMultilineStrings: false +ColumnLimit: 100 +CommentPragmas: NOLINT:.* +ConstructorInitializerIndentWidth: 6 +ContinuationIndentWidth: 8 +IndentWidth: 4 +PenaltyBreakBeforeFirstCallParameter: 100000 +SpacesBeforeTrailingComments: 1 diff --git a/gralloc4/Android.bp b/gralloc4/Android.bp index 5d2f785..8edc25a 100644 --- a/gralloc4/Android.bp +++ b/gralloc4/Android.bp @@ -15,6 +15,13 @@ * limitations under the License. */ +soong_namespace { + imports: [ + "hardware/google/graphics/common", + "hardware/google/gchips", + ] +} + package { default_applicable_licenses: ["Android-Apache-2.0"], } diff --git a/gralloc4/interfaces/libs/drmutils/Android.bp b/gralloc4/interfaces/libs/drmutils/Android.bp index 08a1641..69daf7b 100644 --- a/gralloc4/interfaces/libs/drmutils/Android.bp +++ b/gralloc4/interfaces/libs/drmutils/Android.bp @@ -33,6 +33,7 @@ cc_library_static { "liblog", "libdrm", "libcutils", + "android.hardware.graphics.common-V3-ndk", ], header_libs: [ "libgralloc_headers", diff --git a/gralloc4/service/aidl/Android.bp b/gralloc4/service/aidl/Android.bp new file mode 100644 index 0000000..a3d7a87 --- /dev/null +++ b/gralloc4/service/aidl/Android.bp @@ -0,0 +1,32 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_binary { + name: "android.hardware.graphics.allocator-V1-service", + proprietary: true, + relative_install_path: "hw", + srcs: [ + "service.cpp", + ], + init_rc: [ + "android.hardware.graphics.allocator-aidl-service.rc", + ], + vintf_fragments: ["manifest_gralloc_aidl.xml"], + header_libs: [ + "libgralloc_headers", + ], + shared_libs: [ + "android.hardware.graphics.allocator-V1-ndk", + "android.hardware.graphics.allocator-aidl-impl", + "libbinder_ndk", + "liblog", + "libutils", + ], + static_libs: [ + "libaidlcommonsupport", + ], + required: [ + "android.hardware.graphics.allocator-aidl-impl", + ], +} diff --git a/gralloc4/service/aidl/android.hardware.graphics.allocator-aidl-service.rc b/gralloc4/service/aidl/android.hardware.graphics.allocator-aidl-service.rc new file mode 100644 index 0000000..b069c5d --- /dev/null +++ b/gralloc4/service/aidl/android.hardware.graphics.allocator-aidl-service.rc @@ -0,0 +1,5 @@ +service vendor.graphics.allocator-default /vendor/bin/hw/android.hardware.graphics.allocator-V1-service + class hal animation + user system + group graphics drmrpc + capabilities SYS_NICE diff --git a/gralloc4/service/aidl/manifest_gralloc_aidl.xml b/gralloc4/service/aidl/manifest_gralloc_aidl.xml new file mode 100644 index 0000000..6848a99 --- /dev/null +++ b/gralloc4/service/aidl/manifest_gralloc_aidl.xml @@ -0,0 +1,7 @@ +<manifest version="1.0" type="device"> + <hal format="aidl"> + <name>android.hardware.graphics.allocator</name> + <fqname>IAllocator/default</fqname> + </hal> +</manifest> + diff --git a/gralloc4/service/aidl/service.cpp b/gralloc4/service/aidl/service.cpp new file mode 100644 index 0000000..26cf77e --- /dev/null +++ b/gralloc4/service/aidl/service.cpp @@ -0,0 +1,33 @@ +#define LOG_TAG "gralloc-V1-service" + +#include <android/binder_ibinder_platform.h> +#include <android/binder_manager.h> +#include <android/binder_process.h> +#include <android/binder_status.h> +#include <log/log.h> + +#include "aidl/GrallocAllocator.h" + +using namespace android; + +using pixel::allocator::GrallocAllocator; + +int main() { + auto service = ndk::SharedRefBase::make<GrallocAllocator>(); + auto binder = service->asBinder(); + + AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, -20); + + const auto instance = std::string() + GrallocAllocator::descriptor + "/default"; + auto status = AServiceManager_addService(binder.get(), instance.c_str()); + if (status != STATUS_OK) { + ALOGE("Failed to start AIDL gralloc allocator service"); + return -EINVAL; + } + + ABinderProcess_setThreadPoolMaxThreadCount(4); + ABinderProcess_startThreadPool(); + ABinderProcess_joinThreadPool(); + + return EXIT_FAILURE; // Unreachable +} diff --git a/gralloc4/src/4.x/Android.bp b/gralloc4/src/4.x/Android.bp index ab0fead..88c7a01 100644 --- a/gralloc4/src/4.x/Android.bp +++ b/gralloc4/src/4.x/Android.bp @@ -73,25 +73,6 @@ cc_defaults { } cc_library_shared { - name: "android.hardware.graphics.allocator@4.0-impl", - defaults: [ - "arm_gralloc_api_4x_defaults", - ], - shared_libs: [ - "android.hardware.graphics.allocator@4.0", - "android.hardware.graphics.mapper@4.0", - ], - srcs: [ - "GrallocAllocator.cpp", - ":libgralloc_hidl_common_allocator", - ":libgralloc_hidl_common_shared_metadata", - ], - include_dirs: [ - "hardware/google/gchips/include", - ], -} - -cc_library_shared { name: "android.hardware.graphics.mapper@4.0-impl", defaults: [ "arm_gralloc_api_4x_defaults", diff --git a/gralloc4/src/Android.bp b/gralloc4/src/Android.bp index 2de8907..867ff2e 100644 --- a/gralloc4/src/Android.bp +++ b/gralloc4/src/Android.bp @@ -67,6 +67,7 @@ cc_library_shared { "libnativewindow", "libion_google", "android.hardware.graphics.common@1.2", + "android.hardware.graphics.common-V3-ndk", "android.hardware.graphics.mapper@4.0", "libdmabufheap", "libgralloctypes", diff --git a/gralloc4/src/aidl/Android.bp b/gralloc4/src/aidl/Android.bp new file mode 100644 index 0000000..e2d9d04 --- /dev/null +++ b/gralloc4/src/aidl/Android.bp @@ -0,0 +1,30 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library_shared { + name: "android.hardware.graphics.allocator-aidl-impl", + proprietary: true, + relative_install_path: "hw", + defaults: [ + "arm_gralloc_api_4x_defaults", + ], + shared_libs: [ + "android.hardware.graphics.allocator-V1-ndk", + "android.hardware.graphics.allocator@4.0", + "android.hardware.graphics.mapper@4.0", + "libbinder_ndk", + ], + static_libs: [ + "libaidlcommonsupport", + ], + srcs: [ + "GrallocAllocator.cpp", + ":libgralloc_hidl_common_allocator", + ":libgralloc_hidl_common_shared_metadata", + ], + include_dirs: [ + "hardware/google/gchips/include", + ], +} + diff --git a/gralloc4/src/aidl/GrallocAllocator.cpp b/gralloc4/src/aidl/GrallocAllocator.cpp new file mode 100644 index 0000000..d7addc5 --- /dev/null +++ b/gralloc4/src/aidl/GrallocAllocator.cpp @@ -0,0 +1,88 @@ +#include "GrallocAllocator.h" + +#include <aidl/android/hardware/graphics/allocator/AllocationError.h> +#include <aidlcommonsupport/NativeHandle.h> +#include <android/binder_ibinder.h> +#include <android/binder_status.h> +#include <hidl/HidlSupport.h> + +#include "allocator/mali_gralloc_ion.h" +#include "hidl_common/Allocator.h" + +namespace pixel::allocator { + +namespace AidlAllocator = aidl::android::hardware::graphics::allocator; +namespace HidlAllocator = android::hardware::graphics::allocator::V4_0; + +using android::hardware::hidl_handle; +using android::hardware::hidl_vec; +using HidlError = android::hardware::graphics::mapper::V4_0::Error; + +unsigned long callingPid() { + return static_cast<unsigned long>(AIBinder_getCallingPid()); +} + +GrallocAllocator::GrallocAllocator() {} + +GrallocAllocator::~GrallocAllocator() { + mali_gralloc_ion_close(); +} + +ndk::ScopedAStatus GrallocAllocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count, + AidlAllocator::AllocationResult* result) { + MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid()); + + buffer_descriptor_t bufferDescriptor; + if (!arm::mapper::common::grallocDecodeBufferDescriptor(hidl_vec(descriptor), + bufferDescriptor)) { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR)); + } + + // TODO(layog@): This dependency between AIDL and HIDL backends is not good. + // Ideally common::allocate should return the result and it should be encoded + // by this interface into HIDL or AIDL. + HidlError error = HidlError::NONE; + auto hidl_cb = [&](HidlError _error, int _stride, hidl_vec<hidl_handle> _buffers) { + if (_error != HidlError::NONE) { + error = _error; + return; + } + + const uint32_t size = _buffers.size(); + + result->stride = _stride; + result->buffers.resize(size); + for (uint32_t i = 0; i < size; i++) { + // Dup here is necessary. After this callback returns common::allocate + // will free the buffer which will destroy the older fd. + result->buffers[i] = android::dupToAidl(static_cast<const native_handle*>(_buffers[i])); + } + }; + + arm::allocator::common::allocate(bufferDescriptor, count, hidl_cb); + + switch (error) { + case HidlError::NONE: + break; + + case HidlError::BAD_DESCRIPTOR: + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR)); + + case HidlError::NO_RESOURCES: + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(AidlAllocator::AllocationError::NO_RESOURCES)); + + case HidlError::UNSUPPORTED: + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast<int32_t>(AidlAllocator::AllocationError::UNSUPPORTED)); + + default: + return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR); + } + + return ndk::ScopedAStatus::ok(); +} + +} // namespace pixel::allocator diff --git a/gralloc4/src/aidl/GrallocAllocator.h b/gralloc4/src/aidl/GrallocAllocator.h new file mode 100644 index 0000000..82d4657 --- /dev/null +++ b/gralloc4/src/aidl/GrallocAllocator.h @@ -0,0 +1,26 @@ +#pragma once + +#include <aidl/android/hardware/graphics/allocator/AllocationResult.h> +#include <aidl/android/hardware/graphics/allocator/BnAllocator.h> +#include <aidlcommonsupport/NativeHandle.h> + +#include <cstdint> +#include <vector> + +namespace pixel { +namespace allocator { + +namespace AidlAllocator = aidl::android::hardware::graphics::allocator; + +class GrallocAllocator : public AidlAllocator::BnAllocator { +public: + GrallocAllocator(); + + ~GrallocAllocator(); + + virtual ndk::ScopedAStatus allocate(const std::vector<uint8_t>& descriptor, int32_t count, + AidlAllocator::AllocationResult* result) override; +}; + +} // namespace allocator +} // namespace pixel diff --git a/gralloc4/src/allocator/Android.bp b/gralloc4/src/allocator/Android.bp index 474a304..3051ced 100644 --- a/gralloc4/src/allocator/Android.bp +++ b/gralloc4/src/allocator/Android.bp @@ -90,6 +90,7 @@ arm_gralloc_allocator_cc_defaults { "libsync", "libutils", "libnativewindow", + "android.hardware.graphics.common-V3-ndk", ], header_libs: [ "libnativebase_headers", diff --git a/gralloc4/src/allocator/mali_gralloc_ion.cpp b/gralloc4/src/allocator/mali_gralloc_ion.cpp index 58790a3..8ac63af 100644 --- a/gralloc4/src/allocator/mali_gralloc_ion.cpp +++ b/gralloc4/src/allocator/mali_gralloc_ion.cpp @@ -16,6 +16,8 @@ * limitations under the License. */ +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + #include <string.h> #include <errno.h> #include <inttypes.h> @@ -25,6 +27,8 @@ #include <log/log.h> #include <cutils/atomic.h> +#include <utils/Trace.h> + #include <linux/dma-buf.h> #include <vector> @@ -342,6 +346,7 @@ static std::string select_dmabuf_heap(unsigned int heap_mask) int ion_device::alloc_from_dmabuf_heap(const std::string& heap_name, size_t size, unsigned int flags) { + ATRACE_NAME(("alloc_from_dmabuf_heap " + heap_name).c_str()); if (!buffer_allocator) { return -1; @@ -358,6 +363,7 @@ int ion_device::alloc_from_dmabuf_heap(const std::string& heap_name, size_t size int ion_device::alloc_from_ion_heap(uint64_t usage, size_t size, unsigned int flags, int *min_pgsz) { + ATRACE_CALL(); /* TODO: remove min_pgsz? I don't think this is useful on Exynos */ if (size == 0 || min_pgsz == NULL) { @@ -541,6 +547,7 @@ static void mali_gralloc_ion_free_internal(buffer_handle_t * const pHandle, int mali_gralloc_ion_allocate_attr(private_handle_t *hnd) { + ATRACE_CALL(); ion_device *dev = ion_device::get(); if (!dev) { diff --git a/gralloc4/src/capabilities/Android.bp b/gralloc4/src/capabilities/Android.bp index aea3ca1..dcc0ba1 100644 --- a/gralloc4/src/capabilities/Android.bp +++ b/gralloc4/src/capabilities/Android.bp @@ -119,6 +119,7 @@ arm_gralloc_capabilities_cc_defaults { "libcutils", "libsync", "libutils", + "android.hardware.graphics.common-V3-ndk", ], } diff --git a/gralloc4/src/core/Android.bp b/gralloc4/src/core/Android.bp index b01b0b7..a36ad39 100644 --- a/gralloc4/src/core/Android.bp +++ b/gralloc4/src/core/Android.bp @@ -75,6 +75,7 @@ arm_gralloc_core_cc_defaults { "libcutils", "libutils", "android.hardware.graphics.common@1.2", + "android.hardware.graphics.common-V3-ndk", ], target: { android: { diff --git a/gralloc4/src/core/format_info.cpp b/gralloc4/src/core/format_info.cpp index 21c3ee8..abb271a 100644 --- a/gralloc4/src/core/format_info.cpp +++ b/gralloc4/src/core/format_info.cpp @@ -111,8 +111,8 @@ const format_info_t formats[] = { { ID(HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 2, .align_h = 2, ALIGN_W_CPU_DEFAULT, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, /* Google Formats */ - { ID(HAL_PIXEL_FORMAT_GOOGLE_NV12_SP), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 64, .align_h = 8, .align_w_cpu = 64, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = true }, - { ID(HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 64, .align_h = 8, .align_w_cpu = 64, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = true }, + { ID(HAL_PIXEL_FORMAT_GOOGLE_NV12_SP), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .align_w = 64, .align_h = 8, .align_w_cpu = 64, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = true }, + { ID(HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B), .npln = 2, .ncmp = { 1, 2, 0 }, .bps = 10, .bpp_afbc = { 0, 0, 0 }, .bpp = { 16, 32, 0 }, .hsub = 2, .vsub = 2, .align_w = 64, .align_h = 8, .align_w_cpu = 64, .tile_size = 1, .has_alpha = false, .is_rgb = false, .is_yuv = true, .afbc = false, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = true }, { ID(HAL_PIXEL_FORMAT_GOOGLE_R_8), .npln = 1, .ncmp = { 1, 0, 0 }, .bps = 8, .bpp_afbc = { 8, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, { ID(HAL_PIXEL_FORMAT_GOOGLE_RG_88), .npln = 1, .ncmp = { 2, 0, 0 }, .bps = 8, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 0, .vsub = 0, .align_w = 16, .align_h = 16, .align_w_cpu = 16, .tile_size = 1, .has_alpha = false, .is_rgb = true, .is_yuv = false, .afbc = true, .linear = true, .yuv_transform = false, .flex = true, .planes_contiguous = false }, /* END ALIGNED SECTION */ @@ -131,22 +131,22 @@ const format_ip_support_t formats_ip_support[] = { { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_LIN, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_LIN, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_LIN, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_LIN, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_LIN, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y8, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y8, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y16, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, /* 420 (8-bit) */ { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I, .cpu_rd = F_NONE, .cpu_wr = F_NONE, .gpu_rd = F_AFBC, .gpu_wr = F_NONE, .dpu_rd = F_AFBC, .dpu_wr = F_NONE, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_AFBC, .vpu_wr = F_AFBC, .cam_wr = F_NONE, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV12, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_LIN, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_NONE, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV21, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_LIN, }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_YV12, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_YV12, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_LIN, }, /* 422 (8-bit) */ { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_LIN|F_AFBC, .dpu_wr = F_NONE, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_LIN, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_NV16, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, /* 420 (10-bit) */ { .id = MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I, .cpu_rd = F_NONE, .cpu_wr = F_NONE, .gpu_rd = F_AFBC, .gpu_wr = F_AFBC, .dpu_rd = F_AFBC, .dpu_wr = F_NONE, .dpu_aeu_wr = F_AFBC, .vpu_rd = F_AFBC, .vpu_wr = F_AFBC, .cam_wr = F_NONE, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y0L2, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_NONE, }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_P010, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_NONE, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_P010, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_LIN, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_LIN, .vpu_wr = F_LIN, .cam_wr = F_LIN, }, /* 422 (10-bit) */ { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y210, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN|F_AFBC, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_P210, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, @@ -155,9 +155,9 @@ const format_ip_support_t formats_ip_support[] = { { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y410, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN|F_AFBC, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, /* Other */ { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW16, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW12, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW10, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, - { .id = MALI_GRALLOC_FORMAT_INTERNAL_BLOB, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW12, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW10, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_BLOB, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_LIN, .gpu_wr = F_LIN, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_LIN, }, /* Depth and Stencil */ { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_16, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, { .id = MALI_GRALLOC_FORMAT_INTERNAL_DEPTH_24, .cpu_rd = F_LIN, .cpu_wr = F_LIN, .gpu_rd = F_NONE, .gpu_wr = F_NONE, .dpu_rd = F_NONE, .dpu_wr = F_NONE, .dpu_aeu_wr = F_NONE, .vpu_rd = F_NONE, .vpu_wr = F_NONE, .cam_wr = F_NONE, }, @@ -291,6 +291,7 @@ static const hal_int_fmt hal_to_internal_format[] = { HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, true, HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B }, { HAL_PIXEL_FORMAT_GOOGLE_R_8, true, HAL_PIXEL_FORMAT_GOOGLE_R_8 }, { HAL_PIXEL_FORMAT_GOOGLE_RG_88, true, HAL_PIXEL_FORMAT_GOOGLE_RG_88 }, + { MALI_GRALLOC_FORMAT_INTERNAL_R_8, false, HAL_PIXEL_FORMAT_GOOGLE_R_8 }, }; const size_t num_hal_formats = sizeof(hal_to_internal_format)/sizeof(hal_to_internal_format[0]); diff --git a/gralloc4/src/core/mali_gralloc_bufferallocation.cpp b/gralloc4/src/core/mali_gralloc_bufferallocation.cpp index 704812e..7656fcf 100644 --- a/gralloc4/src/core/mali_gralloc_bufferallocation.cpp +++ b/gralloc4/src/core/mali_gralloc_bufferallocation.cpp @@ -16,10 +16,13 @@ * limitations under the License. */ +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + #include <inttypes.h> #include <assert.h> #include <atomic> #include <algorithm> +#include <utils/Trace.h> #include <hardware/hardware.h> #include <hardware/gralloc1.h> @@ -462,6 +465,26 @@ static void update_yv12_stride(int8_t plane, #endif /* + * Logs and returns true if deprecated usage bits are found + * + * At times, framework introduces new usage flags which are identical to what + * vendor has been using internally. This method logs those bits and returns + * true if there is any deprecated usage bit. + * + * TODO(layog@): This check is also performed again during format deduction. At + * that point, the allocation is not aborted, just a log is printed to ALOGE + * (matched against `VALID_USAGE`). These should be aligned. + */ +static bool log_deprecated_usage_flags(uint64_t usage) { + if (usage & MALI_GRALLOC_USAGE_FRONTBUFFER) { + MALI_GRALLOC_LOGW("Using deprecated FRONTBUFFER usage bit, please upgrade to BufferUsage::FRONT_BUFFER"); + return true; + } + + return false; +} + +/* * Modify usage flag when BO is the producer * * BO cannot use the flags CPU_READ_RARELY as Codec layer redefines those flags @@ -512,6 +535,7 @@ static void calc_allocation_size(const int width, const bool has_cpu_usage, const bool has_hw_usage, const bool has_gpu_usage, + const bool has_camera_usage, int * const pixel_stride, uint64_t * const size, plane_info_t plane_info[MAX_PLANES]) @@ -583,15 +607,17 @@ static void calc_allocation_size(const int width, uint32_t cpu_align = 0; + if (!(has_camera_usage && !has_cpu_usage && format.id == MALI_GRALLOC_FORMAT_INTERNAL_RAW10)) { #if CAN_SKIP_CPU_ALIGN == 1 - if (has_cpu_usage) + if (has_cpu_usage) #endif - { - assert((format.bpp[plane] * format.align_w_cpu) % 8 == 0); - const bool is_primary_plane = (plane == 0 || !format.planes_contiguous); - if (is_primary_plane) { - cpu_align = (format.bpp[plane] * format.align_w_cpu) / 8; + assert((format.bpp[plane] * format.align_w_cpu) % 8 == 0); + const bool is_primary_plane = (plane == 0 || !format.planes_contiguous); + if (is_primary_plane) + { + cpu_align = (format.bpp[plane] * format.align_w_cpu) / 8; + } } } @@ -954,6 +980,16 @@ static int prepare_descriptor_exynos_formats( return 0; } +static bool validate_usage(const uint64_t usage) { + if (usage & GRALLOC_USAGE_FRONT_BUFFER) { + /* TODO(b/218383959): Enable front buffer rendering */ + MALI_GRALLOC_LOGW("Front buffer rendering is disabled."); + return false; + } + + return true; +} + int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescriptor) { alloc_type_t alloc_type{}; @@ -962,6 +998,11 @@ int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescripto int alloc_height = bufDescriptor->height; uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage; + if (!validate_usage(usage)) { + MALI_GRALLOC_LOGE("Usage flag validation failed."); + return -EINVAL; + } + /* * Select optimal internal pixel format based upon * usage and requested format. @@ -1025,6 +1066,7 @@ int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescripto usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), usage & ~(GRALLOC_USAGE_PRIVATE_MASK | GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER), + usage & (GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_HW_CAMERA_READ), &bufDescriptor->pixel_stride, &bufDescriptor->alloc_sizes[0], bufDescriptor->plane_info); @@ -1077,6 +1119,7 @@ int mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t *descriptors, uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend, int fd) { + ATRACE_CALL(); bool shared = false; uint64_t backing_store_id = 0x0; int err; @@ -1093,6 +1136,10 @@ int mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t *descriptors, bufDescriptor->consumer_usage = usage; } + if (log_deprecated_usage_flags(usage)) { + return -EINVAL; + } + /* Derive the buffer size from descriptor parameters */ err = mali_gralloc_derive_format_and_size(bufDescriptor); if (err != 0) diff --git a/gralloc4/src/core/mali_gralloc_formats.cpp b/gralloc4/src/core/mali_gralloc_formats.cpp index 9555727..528b1d3 100644 --- a/gralloc4/src/core/mali_gralloc_formats.cpp +++ b/gralloc4/src/core/mali_gralloc_formats.cpp @@ -615,7 +615,7 @@ static format_support_flags is_format_supported(const int32_t fmt_idx, } } - if (usage & MALI_GRALLOC_USAGE_FRONTBUFFER) + if (usage & GRALLOC_USAGE_FRONT_BUFFER) { if ((producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_DOUBLE_BODY) == 0) { @@ -831,7 +831,7 @@ static uint64_t get_afbc_format(const uint32_t base_format, { alloc_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; - if (usage & MALI_GRALLOC_USAGE_FRONTBUFFER && + if (usage & GRALLOC_USAGE_FRONT_BUFFER && producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_DOUBLE_BODY) { alloc_format |= MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY; diff --git a/gralloc4/src/core/mali_gralloc_reference.cpp b/gralloc4/src/core/mali_gralloc_reference.cpp index 954c2b3..8f12975 100644 --- a/gralloc4/src/core/mali_gralloc_reference.cpp +++ b/gralloc4/src/core/mali_gralloc_reference.cpp @@ -21,6 +21,7 @@ #include <android-base/thread_annotations.h> #include <hardware/gralloc1.h> +#include <algorithm> #include <map> #include <mutex> @@ -58,6 +59,54 @@ private: return hnd->get_usage() & cpu_access_usage; } + static off_t get_buffer_size(unsigned int fd) { + off_t current = lseek(fd, 0, SEEK_CUR); + off_t size = lseek(fd, 0, SEEK_END); + lseek(fd, current, SEEK_SET); + return size; + } + + static bool dmabuf_sanity_check(buffer_handle_t handle) { + private_handle_t *hnd = + static_cast<private_handle_t *>(const_cast<native_handle_t *>(handle)); + + int valid_fd_count = std::find(hnd->fds, hnd->fds + MAX_FDS, -1) - hnd->fds; + // One fd is reserved for metadata which is not accounted for in fd_count + if (hnd->fd_count != valid_fd_count - 1) { + MALI_GRALLOC_LOGE("%s failed: count of valid buffer fds does not match fd_count", + __func__); + return false; + } + + auto check_pid = [&](int fd, uint64_t allocated_size) -> bool { + auto size = get_buffer_size(fd); + auto size_padding = size - (off_t)allocated_size; + if ((size != -1) && ((size_padding < 0) || (size_padding > PAGE_SIZE))) { + MALI_GRALLOC_LOGE("%s failed: fd (%d) size (%jd) is not within a PAGE_SIZE of " + "expected size (%" PRIx64 ")", + __func__, fd, static_cast<intmax_t>(size), allocated_size); + return false; + } + return true; + }; + + // Check client facing dmabufs + for (auto i = 0; i < hnd->fd_count; i++) { + if (!check_pid(hnd->fds[i], hnd->alloc_sizes[i])) { + MALI_GRALLOC_LOGE("%s failed: Size check failed for alloc_sizes[%d]", __func__, i); + return false; + } + } + + // Check metadata dmabuf + if (!check_pid(hnd->get_share_attr_fd(), hnd->attr_size)) { + MALI_GRALLOC_LOGE("%s failed: Size check failed for metadata fd", __func__); + return false; + } + + return true; + } + int map_locked(buffer_handle_t handle) REQUIRES(lock) { private_handle_t *hnd = (private_handle_t *)handle; auto it = buffer_map.find(hnd); @@ -72,10 +121,15 @@ private: MALI_GRALLOC_LOGE("BUG: Found an imported buffer with ref count 0, expect errors"); } + // Return early if buffer is already mapped if (data.bases[0] != nullptr) { return 0; } + if (!dmabuf_sanity_check(handle)) { + return -EINVAL; + } + int error = mali_gralloc_ion_map(hnd); if (error != 0) { return error; @@ -115,7 +169,7 @@ private: } else { for (auto i = 0; i < MAX_BUFFER_FDS; i++) { if (hnd->bases[i] != 0 || data.bases[i] != nullptr) { - MALI_GRALLOC_LOGE("Validation failed: Expected nullptr for unmaped buffer"); + MALI_GRALLOC_LOGE("Validation failed: Expected nullptr for unmapped buffer"); return -EINVAL; } } diff --git a/gralloc4/src/hidl_common/Allocator.cpp b/gralloc4/src/hidl_common/Allocator.cpp index 8174f05..6ca758a 100644 --- a/gralloc4/src/hidl_common/Allocator.cpp +++ b/gralloc4/src/hidl_common/Allocator.cpp @@ -16,6 +16,10 @@ * limitations under the License. */ +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + +#include <utils/Trace.h> + #include "SharedMetadata.h" #include "Allocator.h" #include "core/mali_gralloc_bufferallocation.h" @@ -38,6 +42,7 @@ void allocate(const buffer_descriptor_t &bufferDescriptor, uint32_t count, IAllo #if DISABLE_FRAMEBUFFER_HAL GRALLOC_UNUSED(fb_allocator); #endif + ATRACE_CALL(); Error error = Error::NONE; int stride = 0; diff --git a/gralloc4/src/hidl_common/Mapper.cpp b/gralloc4/src/hidl_common/Mapper.cpp index e8f5b10..f6ebe6f 100644 --- a/gralloc4/src/hidl_common/Mapper.cpp +++ b/gralloc4/src/hidl_common/Mapper.cpp @@ -563,7 +563,7 @@ void isSupported(const IMapper::BufferDescriptorInfo& description, IMapper::isSu if (result != 0) { MALI_GRALLOC_LOGV("Allocation for the given description will not succeed. error: %d", result); - hidl_cb(Error::NO_RESOURCES, false); + hidl_cb(Error::NONE, false); } else { diff --git a/gralloc4/src/hidl_common/MapperMetadata.cpp b/gralloc4/src/hidl_common/MapperMetadata.cpp index ee743db..478c4a2 100644 --- a/gralloc4/src/hidl_common/MapperMetadata.cpp +++ b/gralloc4/src/hidl_common/MapperMetadata.cpp @@ -212,8 +212,8 @@ static std::vector<std::vector<PlaneLayoutComponent>> plane_layout_components_fr { .drm_fourcc = DRM_FORMAT_P010, .components = { - { { Y, 0, 8 } }, - { { CB, 0, 8 }, { CR, 16, 8 } } + { { Y, 6, 10 } }, + { { CB, 6, 10 }, { CR, 22, 10 } } } }, /* Planar 8 bit YUV 4:2:0 */ diff --git a/gralloc4/src/hidl_common/SharedMetadata.cpp b/gralloc4/src/hidl_common/SharedMetadata.cpp index 4247bd8..b5964f7 100644 --- a/gralloc4/src/hidl_common/SharedMetadata.cpp +++ b/gralloc4/src/hidl_common/SharedMetadata.cpp @@ -146,12 +146,6 @@ void get_smpte2094_40(const private_handle_t *hnd, std::optional<std::vector<uin android::status_t set_smpte2094_40(const private_handle_t *hnd, const std::optional<std::vector<uint8_t>> &smpte2094_40) { - if (!smpte2094_40.has_value() || smpte2094_40->size() == 0) - { - MALI_GRALLOC_LOGE("Empty SMPTE 2094-40 data"); - return android::BAD_VALUE; - } - auto *metadata = reinterpret_cast<shared_metadata *>(hnd->attr_base); const size_t size = smpte2094_40.has_value() ? smpte2094_40->size() : 0; if (size > metadata->smpte2094_40.capacity()) diff --git a/gralloc4/src/mali_gralloc_buffer.h b/gralloc4/src/mali_gralloc_buffer.h index 02172c6..3863342 100644 --- a/gralloc4/src/mali_gralloc_buffer.h +++ b/gralloc4/src/mali_gralloc_buffer.h @@ -177,6 +177,9 @@ struct private_handle_t int magic DEFAULT_INITIALIZER(sMagic); int flags DEFAULT_INITIALIZER(0); + /* + * Number of dmabuf fds, NOT including the metadata fd + */ int fd_count DEFAULT_INITIALIZER(1); /* diff --git a/gralloc4/src/mali_gralloc_formats.h b/gralloc4/src/mali_gralloc_formats.h index 64a7104..246cae6 100644 --- a/gralloc4/src/mali_gralloc_formats.h +++ b/gralloc4/src/mali_gralloc_formats.h @@ -23,6 +23,8 @@ #include "mali_gralloc_log.h" +#include <aidl/android/hardware/graphics/common/PixelFormat.h> + /* Internal formats are represented in gralloc as a 64bit identifier * where the 32 lower bits are a base format and the 32 upper bits are modifiers. * @@ -121,6 +123,8 @@ typedef enum MALI_GRALLOC_FORMAT_INTERNAL_YUV444_10BIT_I, /* Add more internal formats here. */ + MALI_GRALLOC_FORMAT_INTERNAL_R_8 = + static_cast<int>(aidl::android::hardware::graphics::common::PixelFormat::R_8), /* These are legacy 0.3 gralloc formats used only by the wrap/unwrap macros. */ MALI_GRALLOC_FORMAT_INTERNAL_YV12_WRAP, diff --git a/gralloc4/src/mali_gralloc_usages.h b/gralloc4/src/mali_gralloc_usages.h index 0774ba1..fb3b70e 100644 --- a/gralloc4/src/mali_gralloc_usages.h +++ b/gralloc4/src/mali_gralloc_usages.h @@ -32,6 +32,8 @@ /* BufferUsage is not defined in 1.2/types.h as there are no changes from previous version */ namespace hidl_common = android::hardware::graphics::common::V1_1; +#include <aidl/android/hardware/graphics/common/BufferUsage.h> +namespace aidl_common = aidl::android::hardware::graphics::common; /* Local macro definitions to emulate Gralloc 1.0 usage interface */ #define GRALLOC_USAGE_PRIVATE_0 1ULL << 28 @@ -106,6 +108,7 @@ typedef enum #define GRALLOC_USAGE_SENSOR_DIRECT_DATA static_cast<uint64_t>(hidl_common::BufferUsage::SENSOR_DIRECT_DATA) #define GRALLOC_USAGE_GPU_DATA_BUFFER static_cast<uint64_t>(hidl_common::BufferUsage::GPU_DATA_BUFFER) +#define GRALLOC_USAGE_FRONT_BUFFER static_cast<uint64_t>(aidl_common::BufferUsage::FRONT_BUFFER) /* Originally (Gralloc 0.x), Android did not provide an explicit DECODER usage. This was rectified in Android N-MR1/7.1 @@ -134,6 +137,7 @@ static const uint64_t VALID_USAGE = * are mapped to the same value (1U << 23). */ GRALLOC_USAGE_SENSOR_DIRECT_DATA | /* 1U << 23 */ GRALLOC_USAGE_GPU_DATA_BUFFER | /* 1U << 24 */ + GRALLOC_USAGE_FRONT_BUFFER | /* 1U << 32 */ /* Google specific usages */ GRALLOC_USAGE_GOOGLE_IP_BO | /* 1U << 51 */ diff --git a/include/VendorVideoAPI.h b/include/VendorVideoAPI.h index 7dc2a09..89f88ad 100644 --- a/include/VendorVideoAPI.h +++ b/include/VendorVideoAPI.h @@ -42,6 +42,7 @@ typedef enum _ExynosVideoInfoType { VIDEO_INFO_TYPE_YSUM_DATA = 0x1 << 3, VIDEO_INFO_TYPE_HDR_DYNAMIC = 0x1 << 4, VIDEO_INFO_TYPE_CHECK_PIXEL_FORMAT = 0x1 << 5, + VIDEO_INFO_TYPE_ROI_INFO = 0x1 << 7, VIDEO_INFO_TYPE_CROP_INFO = 0x1 << 8, } ExynosVideoInfoType; @@ -118,12 +119,22 @@ typedef struct _ExynosVideoCrop { int height; } ExynosVideoCrop; +#define MAX_ROIINFO_SIZE 32400 +typedef struct _ExynosVideoROIData { + int nUpperQpOffset; + int nLowerQpOffset; + int bUseRoiInfo; + int nRoiMBInfoSize; + char pRoiMBInfo[MAX_ROIINFO_SIZE]; +} ExynosVideoROIData; + typedef struct _ExynosVideoDecData { int nInterlacedType; } ExynosVideoDecData; typedef struct _ExynosVideoEncData { ExynosVideoYSUMData sYsumData; + unsigned long long pRoiData; /* for fixing byte alignment on 64x32 problem */ } ExynosVideoEncData; typedef struct _ExynosVideoMeta { diff --git a/include/exynos_format.h b/include/exynos_format.h index 6e4807e..e7ee86f 100644 --- a/include/exynos_format.h +++ b/include/exynos_format.h @@ -17,6 +17,8 @@ #ifndef _EXYNOS_FORMAT_H_ #define _EXYNOS_FORMAT_H_ +#include <stdint.h> + #ifdef __cplusplus extern "C" { #endif diff --git a/libvendorgraphicbuffer/Android.bp b/libvendorgraphicbuffer/Android.bp index 228d0c1..53e76aa 100644 --- a/libvendorgraphicbuffer/Android.bp +++ b/libvendorgraphicbuffer/Android.bp @@ -42,8 +42,10 @@ cc_library_shared { "libgralloctypes", "libhidlbase", ], + header_libs: [ + "libgralloc_headers", + ], include_dirs: [ - "hardware/google/gchips/gralloc4/src", "hardware/google/gchips/include", ], export_include_dirs: [ diff --git a/libvendorgraphicbuffer/gralloc3/vendor_graphicbuffer_mapper.cpp b/libvendorgraphicbuffer/gralloc3/vendor_graphicbuffer_mapper.cpp deleted file mode 100644 index 8dc268b..0000000 --- a/libvendorgraphicbuffer/gralloc3/vendor_graphicbuffer_mapper.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2020 Samsung Electronics Co. Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <ui/Gralloc.h> -#include "VendorGraphicBuffer.h" - -using namespace android; -using namespace vendor::graphics; - -status_t VendorGraphicBufferMapper::lock64(buffer_handle_t handle, uint64_t usage, const Rect& bounds, - void** vaddr, int32_t* outBytesPerPixel, int32_t* outBytesPerStride) -{ - return lockAsync(handle, usage, usage, bounds, vaddr, - -1, outBytesPerPixel, outBytesPerStride); -} - -status_t VendorGraphicBufferMapper::lockYCbCr64(buffer_handle_t handle, - uint64_t usage, const Rect& bounds, android_ycbcr *ycbcr) -{ - return getGrallocMapper().lock(handle, usage, bounds, -1, ycbcr); -} diff --git a/libvendorgraphicbuffer/gralloc3/vendor_graphicbuffer_meta.cpp b/libvendorgraphicbuffer/gralloc3/vendor_graphicbuffer_meta.cpp deleted file mode 100644 index 16e62bf..0000000 --- a/libvendorgraphicbuffer/gralloc3/vendor_graphicbuffer_meta.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) 2020 Samsung Electronics Co. Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <log/log.h> -#include "VendorGraphicBuffer.h" -#include "mali_gralloc_buffer.h" -#include "gralloc_buffer_priv.h" -#include "exynos_format.h" - -#define UNUSED(x) ((void)x) - -using namespace android; -using namespace vendor::graphics; - -int VendorGraphicBufferMeta::is_afbc(buffer_handle_t buffer_hnd_p) -{ - const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(buffer_hnd_p); - - if (!gralloc_hnd) - return 0; - - return gralloc_hnd->is_compressible; -} - -int VendorGraphicBufferMeta::is_sbwc(buffer_handle_t buffer_hnd_p) -{ - const private_handle_t *hnd = static_cast<const private_handle_t *>(buffer_hnd_p); - - switch (static_cast<uint32_t>(hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK)) { - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60: - case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80: - return true; - } - return false; -} - -#define GRALLOC_META_GETTER(__type__, __name__, __member__) \ -__type__ VendorGraphicBufferMeta::get_##__name__(buffer_handle_t hnd) \ -{ \ - const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); \ - if (!gralloc_hnd) return 0; \ - return gralloc_hnd->__member__; \ -} \ - - -GRALLOC_META_GETTER(uint32_t, format, format); -GRALLOC_META_GETTER(uint64_t, internal_format, internal_format); -GRALLOC_META_GETTER(uint64_t, frameworkFormat, req_format); - -GRALLOC_META_GETTER(int, width, width); -GRALLOC_META_GETTER(int, height, height); -GRALLOC_META_GETTER(uint32_t, stride, stride); -GRALLOC_META_GETTER(uint32_t, vstride, plane_info[0].alloc_height); - -GRALLOC_META_GETTER(uint64_t, producer_usage, producer_usage); -GRALLOC_META_GETTER(uint64_t, consumer_usage, consumer_usage); - -GRALLOC_META_GETTER(uint64_t, flags, flags); - -int VendorGraphicBufferMeta::get_dataspace(buffer_handle_t hnd) -{ - const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); - - if (!gralloc_hnd) - return -1; - - int attr_fd = gralloc_hnd->get_share_attr_fd(); - if (attr_fd < 0) - { - ALOGE("Shared attribute region not available to be mapped"); - return -1; - } - attr_region* region; - region = (attr_region *) mmap(NULL, sizeof(attr_region), PROT_READ, MAP_SHARED, attr_fd, 0); - if (region == NULL) - return -1; - else if (region == MAP_FAILED) - return -1; - - int dataspace = region->force_dataspace == -1 ? region->dataspace : region->force_dataspace; - - munmap(region, sizeof(attr_region)); - - return dataspace; -} - -int VendorGraphicBufferMeta::set_dataspace(buffer_handle_t hnd, android_dataspace_t dataspace) -{ - const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); - - if (!gralloc_hnd) - return -1; - - int attr_fd = gralloc_hnd->get_share_attr_fd(); - - if (attr_fd <0) - return -1; - - attr_region* region = (attr_region*)mmap(NULL, sizeof(attr_region), PROT_READ | PROT_WRITE, MAP_SHARED, attr_fd, 0); - if (region == NULL) - return -1; - else if (region == MAP_FAILED) - return -1; - - region->dataspace = dataspace; - region->force_dataspace = dataspace; - munmap(region, sizeof(attr_region)); - - return 0; -} - -int VendorGraphicBufferMeta::get_fd(buffer_handle_t hnd, int num) -{ - const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); - - if (!gralloc_hnd) - return -1; - - if (num > 2) - return -1; - - return gralloc_hnd->fds[num]; -} - -int VendorGraphicBufferMeta::get_size(buffer_handle_t hnd, int num) -{ - const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); - - if (!gralloc_hnd) - return 0; - - if (num > 2) - return 0; - - return gralloc_hnd->sizes[num]; -} - - -uint64_t VendorGraphicBufferMeta::get_usage(buffer_handle_t hnd) -{ - const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); - - if (!gralloc_hnd) - return 0; - - return gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage; -} - -void* VendorGraphicBufferMeta::get_video_metadata(buffer_handle_t hnd) -{ - private_handle_t *gralloc_hnd = - static_cast<private_handle_t *>(const_cast<native_handle_t *>(hnd)); - - if (!gralloc_hnd) - return nullptr; - - if (gralloc_hnd->flags & - (private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA | private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA)) - { - int idx = -1; - - if (gralloc_hnd->flags & private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA) - idx = 1; - else if (gralloc_hnd->flags & private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA) - idx = 2; - - if (gralloc_hnd->bases[idx] == 0) - ALOGE("buffer_handle(%p) did not map video metadata", hnd); - - return reinterpret_cast<void*>(gralloc_hnd->bases[idx]); - } - else - { - ALOGE("buffer_handle(%p) does not contain video metadata", hnd); - return nullptr; - } -} - -int VendorGraphicBufferMeta::get_video_metadata_fd(buffer_handle_t hnd) -{ - const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); - - if (!gralloc_hnd) - return -EINVAL; - - int idx = -1; - - if (gralloc_hnd->flags & VendorGraphicBufferMeta::PRIV_FLAGS_USES_2PRIVATE_DATA) - idx = 1; - else if (gralloc_hnd->flags & VendorGraphicBufferMeta::PRIV_FLAGS_USES_3PRIVATE_DATA) - idx = 2; - - if (idx < 0) - return -EINVAL; - - return gralloc_hnd->fds[idx]; -} - -/* This function is not supported with gralloc3. return nullptr */ -void* VendorGraphicBufferMeta::get_video_metadata_roiinfo(buffer_handle_t hnd) -{ - UNUSED(hnd); - return nullptr; -} - -/* This function is not used with gralloc3. return nullptr */ -buffer_handle_t VendorGraphicBufferMeta::import_buffer(buffer_handle_t hnd) -{ - UNUSED(hnd); - return nullptr; -} - -/* This function is not used with gralloc3. */ -int VendorGraphicBufferMeta::free_buffer(buffer_handle_t hnd) -{ - return 0; -} - -void VendorGraphicBufferMeta::init(const buffer_handle_t handle) -{ - const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(handle); - - if (!gralloc_hnd) - return; - - fd = gralloc_hnd->fds[0]; - fd1 = gralloc_hnd->fds[1]; - fd2 = gralloc_hnd->fds[2]; - - size = gralloc_hnd->sizes[0]; - size1 = gralloc_hnd->sizes[1]; - size2 = gralloc_hnd->sizes[2]; - - offsets[0] = gralloc_hnd->plane_info[0].offset; - offsets[1] = gralloc_hnd->plane_info[1].offset; - offsets[2] = gralloc_hnd->plane_info[2].offset; - - internal_format = gralloc_hnd->internal_format; - frameworkFormat = gralloc_hnd->req_format; - - width = gralloc_hnd->width; - height = gralloc_hnd->height; - stride = gralloc_hnd->stride;; - vstride = gralloc_hnd->plane_info[0].alloc_height; - - producer_usage = gralloc_hnd->producer_usage; - consumer_usage = gralloc_hnd->consumer_usage; - - flags = gralloc_hnd->flags; - - unique_id = gralloc_hnd->backing_store_id; -} - -VendorGraphicBufferMeta::VendorGraphicBufferMeta(buffer_handle_t handle) -{ - init(handle); -} - diff --git a/libvendorgraphicbuffer/gralloc4/vendor_graphicbuffer_meta.cpp b/libvendorgraphicbuffer/gralloc4/vendor_graphicbuffer_meta.cpp index cc0a20d..a155519 100644 --- a/libvendorgraphicbuffer/gralloc4/vendor_graphicbuffer_meta.cpp +++ b/libvendorgraphicbuffer/gralloc4/vendor_graphicbuffer_meta.cpp @@ -24,6 +24,7 @@ #include "mali_gralloc_buffer.h" #include "mali_gralloc_formats.h" #include "hidl_common/SharedMetadata.h" +#include "hidl_common/SharedMetadata_struct.h" #include "exynos_format.h" using namespace android; @@ -248,7 +249,8 @@ void* VendorGraphicBufferMeta::get_video_metadata_roiinfo(buffer_handle_t hnd) return nullptr; if (gralloc_hnd->get_usage() & VendorGraphicBufferUsage::ROIINFO) - return static_cast<char*>(gralloc_hnd->attr_base) + SZ_4k * 2; + return static_cast<char*>(gralloc_hnd->attr_base) + + sizeof(shared_metadata) + gralloc_hnd->reserved_region_size; return nullptr; } |