diff options
author | Vishal Bhoj <vishal.bhoj@linaro.org> | 2019-01-23 10:55:00 +0000 |
---|---|---|
committer | Vishal Bhoj <vishal.bhoj@linaro.org> | 2019-01-28 04:38:16 +0000 |
commit | 104697b4406e8ab0a18b80125dc66a9aa99b05f5 (patch) | |
tree | 13dbf3f27868dcfcb47b6e1ec935722bedfcc4cb | |
parent | d536ed60a262f2f267e5c59f77f2b66b2f4d51ed (diff) | |
download | juno-104697b4406e8ab0a18b80125dc66a9aa99b05f5.tar.gz |
Update to Pie
Update Gralloc to TX041-SW-99005-r27p0-01rel0.tgz
Fixes for getting Pie booted.
Change-Id: I95850f35ea572718a0cc9dff0694e8a0adef9ef4
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
40 files changed, 3337 insertions, 672 deletions
diff --git a/BoardConfig.mk b/BoardConfig.mk index ddba3c4..f2f1920 100644 --- a/BoardConfig.mk +++ b/BoardConfig.mk @@ -1,22 +1,14 @@ # Primary Arch TARGET_ARCH := arm64 TARGET_ARCH_VARIANT := armv8-a -ifneq (,$(wildcard $(LOCAL_PATH)/../../../bionic/libc/arch-arm64/cortex-a57)) -TARGET_CPU_VARIANT := cortex-a57 -else -TARGET_CPU_VARIANT := cortex-a53 -endif TARGET_CPU_ABI := arm64-v8a +TARGET_CPU_VARIANT := generic # Secondary Arch TARGET_2ND_ARCH := arm -TARGET_2ND_ARCH_VARIANT := armv7-a-neon -ifneq (,$(wildcard $(LOCAL_PATH)/../../../bionic/libc/arch-arm/cortex-a57)) -TARGET_2ND_CPU_VARIANT := cortex-a57 -else -TARGET_2ND_CPU_VARIANT := cortex-a53 -endif +TARGET_2ND_ARCH_VARIANT := armv8-a TARGET_2ND_CPU_ABI := armeabi-v7a +TARGET_2ND_CPU_VARIANT := generic TARGET_2ND_CPU_ABI2 := armeabi TARGET_USES_64_BIT_BINDER := true @@ -47,7 +39,7 @@ endif KERNEL_CONFIG ?= linaro/configs/linaro-base.conf \ linaro/configs/android.conf \ linaro/configs/vexpress64.conf \ - linaro/configs/mali.conf + linaro/configs/mali-v1.conf # Kernel Source and Device Tree TARGET_KERNEL_SOURCE ?= kernel/linaro/armlt @@ -33,6 +33,8 @@ PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\ $(LOCAL_PATH)/fstab.juno:$(TARGET_COPY_OUT_VENDOR)/etc/init/fstab.juno \ $(LOCAL_PATH)/init.juno.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.juno.rc \ $(LOCAL_PATH)/ueventd.juno.rc:$(TARGET_COPY_OUT_VENDOR)/ueventd.rc \ + frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_audio.xml \ + frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_video.xml \ $(LOCAL_PATH)/juno_monkey_blacklist:data/juno_monkey_blacklist \ $(LOCAL_PATH)/juno.kl:system/usr/keylayout/juno.kl) @@ -74,9 +76,11 @@ PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.ethernet.xml frameworks/native/data/etc/android.software.app_widgets.xml:system/etc/permissions/android.software.app_widgets.xml \ frameworks/native/data/etc/android.software.backup.xml:system/etc/permissions/android.software.backup.xml \ frameworks/native/data/etc/android.hardware.usb.accessory.xml:system/etc/permissions/android.hardware.usb.accessory.xml \ + frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi \ frameworks/native/data/etc/android.hardware.vulkan.version-1_0_3.xml:system/etc/permissions/android.hardware.vulkan.version-1_0_3.xml \ device/linaro/juno/manifest.xml:vendor/manifest.xml + PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\ vexpress-firmware/board_recovery_image.tar.bz2:boot/board_recovery_image.tar.bz2 ) @@ -122,7 +126,9 @@ PRODUCT_PACKAGES += \ PRODUCT_PACKAGES += \ android.hardware.graphics.allocator@2.0-impl \ android.hardware.graphics.allocator@2.0-service \ - android.hardware.graphics.mapper@2.0-impl + android.hardware.graphics.mapper@2.0-impl \ + android.hardware.graphics.composer@2.1-impl \ + android.hardware.graphics.composer@2.1-service PRODUCT_PACKAGES += memtrack.default \ android.hardware.memtrack@1.0-service \ @@ -145,9 +151,17 @@ $(call inherit-product-if-exists, device/linaro/juno/optee-packages.mk) # enable Treble PRODUCT_FULL_TREBLE_OVERRIDE := true +BOARD_VNDK_VERSION := current +PRODUCT_ENFORCE_VINTF_MANIFEST_OVERRIDE := true + +# PowerHAL +PRODUCT_PACKAGES += \ + android.hardware.power@1.0-impl \ + android.hardware.power@1.0-service PRODUCT_PACKAGES += \ android.hardware.renderscript@1.0.vndk-sp\ + android.hardware.graphics.composer@2.1.vndk-sp \ android.hardware.graphics.allocator@2.0.vndk-sp\ android.hardware.graphics.mapper@2.0.vndk-sp\ android.hardware.graphics.common@1.0.vndk-sp\ diff --git a/gralloc/src/Android.juno.mk b/gralloc/src/Android.juno.mk index e2ecd4a..7f22487 100644 --- a/gralloc/src/Android.juno.mk +++ b/gralloc/src/Android.juno.mk @@ -1,5 +1,5 @@ # -# Copyright (C) 2016 ARM Limited. All rights reserved. +# Copyright (C) 2016, 2018 ARM Limited. All rights reserved. # # Copyright (C) 2008 The Android Open Source Project # @@ -17,4 +17,4 @@ $(info gralloc for juno) GRALLOC_FB_SWAP_RED_BLUE := 1 -GRALLOC_DEPTH := GRALLOC_32_BITS +GRALLOC_FB_BPP := 32 diff --git a/gralloc/src/Android.mk b/gralloc/src/Android.mk index 37c5b73..1e1afa8 100644 --- a/gralloc/src/Android.mk +++ b/gralloc/src/Android.mk @@ -48,14 +48,22 @@ MALI_DISPLAY_VERSION?=0 # Gralloc1 support GRALLOC_USE_GRALLOC1_API?=0 -# Use ION DMA heap for all allocations. Default is system heap. + +# The following defines are used to override default behaviour of which heap is selected for allocations. +# The default is to pick system heap. +# This define must be set to allow GRALLOC_USAGE_PROTECTED to be specified to select secure heap. +# This defaults to 1 for now, but must be updated once ION_HEAP_SECURE_MASK no longer signals an enabled secure heap. +GRALLOC_ENABLE_ION_SECURE_HEAP?=1 +# 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 -# Use ION Compound heap for all allocations. Default is system heap. GRALLOC_USE_ION_COMPOUND_PAGE_HEAP?=0 + # Properly initializes an empty AFBC buffer GRALLOC_INIT_AFBC?=0 # fbdev bitdepth to use -GRALLOC_DEPTH?=GRALLOC_32_BITS +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. @@ -68,6 +76,15 @@ GRALLOC_DISP_H?=0 # Vsync backend(not used) GRALLOC_VSYNC_BACKEND?=default +PLATFORM_SDK_LESS_THAN_28 := $(shell expr $(PLATFORM_SDK_VERSION) \< 28) +ifeq ($(PLATFORM_SDK_LESS_THAN_28), 1) + # When this flag is set gralloc will not attempt to query the available ION heaps. + GRALLOC_USE_LEGACY_ION_API?=1 +else + GRALLOC_USE_LEGACY_ION_API?=0 +endif + + # HAL module implemenation, not prelinked and stored in # hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so include $(CLEAR_VARS) @@ -141,19 +158,30 @@ LOCAL_CFLAGS += -DGRALLOC_DISP_H=$(GRALLOC_DISP_H) 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_ENABLE_ION_SECURE_HEAP=$(GRALLOC_ENABLE_ION_SECURE_HEAP) LOCAL_CFLAGS += -DGRALLOC_INIT_AFBC=$(GRALLOC_INIT_AFBC) -LOCAL_CFLAGS += -D$(GRALLOC_DEPTH) +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_LEGACY_ION_API=$(GRALLOC_USE_LEGACY_ION_API) -LOCAL_SHARED_LIBRARIES := libhardware liblog libcutils libGLESv1_CM libion libsync libutils libnativewindow +LOCAL_SHARED_LIBRARIES := libhardware liblog libcutils libGLESv1_CM libion libsync libutils +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 LOCAL_MODULE := gralloc.juno -LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/hw/ -LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/hw/ +LOCAL_MODULE_OWNER := arm +LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional LOCAL_MULTILIB := both @@ -179,6 +207,4 @@ else LOCAL_SRC_FILES += legacy/alloc_device.cpp endif -LOCAL_MODULE_OWNER := arm - include $(BUILD_SHARED_LIBRARY) diff --git a/gralloc/src/Android.vexpress.mk b/gralloc/src/Android.vexpress.mk index 73ac119..85b4386 100644 --- a/gralloc/src/Android.vexpress.mk +++ b/gralloc/src/Android.vexpress.mk @@ -1,5 +1,5 @@ # -# Copyright (C) 2016 ARM Limited. All rights reserved. +# Copyright (C) 2016, 2018 ARM Limited. All rights reserved. # # Copyright (C) 2008 The Android Open Source Project # @@ -17,4 +17,4 @@ $(info gralloc for vexpress) GRALLOC_FB_SWAP_RED_BLUE := 0 -GRALLOC_DEPTH := GRALLOC_16_BITS +GRALLOC_FB_BPP := 16 diff --git a/gralloc/src/format_info.cpp b/gralloc/src/format_info.cpp new file mode 100644 index 0000000..528b07d --- /dev/null +++ b/gralloc/src/format_info.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 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 <inttypes.h> +#include "mali_gralloc_formats.h" +#include "format_info.h" + +/* Default width aligned to whole pixel. */ +#define PWA_DEFAULT .pwa = 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 = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = true, .linear = true, .flex = false, PWA_DEFAULT }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGB_888, .npln = 1, .ncmp = 3, .bps = 8, .bpp_afbc = { 24, 0, 0 }, .bpp = { 24, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888, .npln = 1, .ncmp = 4, .bps = 8, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = true, .is_yuv = false, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888, .npln = 1, .ncmp = 4, .bps = 8, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = true, .is_yuv = false, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888, .npln = 1, .ncmp = 3, .bps = 8, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, +#if PLATFORM_SDK_VERSION >= 26 + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102, .npln = 1, .ncmp = 4, .bps = 10, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = true, .is_yuv = false, .afbc = true, .linear = true, .flex = false, PWA_DEFAULT }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616, .npln = 1, .ncmp = 4, .bps = 16, .bpp_afbc = { 64, 0, 0 }, .bpp = { 64, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = true, .is_yuv = false, .afbc = false, .linear = true, .flex = true, PWA_DEFAULT }, +#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 = 2, .vsub = 2, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, .pwa = 16 }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y16, .npln = 1, .ncmp = 1, .bps = 16, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 2, .vsub = 2, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, .pwa = 16 }, + + /* 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, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = false, .flex = false, PWA_DEFAULT }, + { .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, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + { .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, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + { .id = HAL_PIXEL_FORMAT_YCrCb_420_SP, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 8, 16, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 2, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + { .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, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, .pwa = 16 }, + + /* 422 (8-bit) */ + { .id = HAL_PIXEL_FORMAT_YCbCr_422_I, .npln = 1, .ncmp = 3, .bps = 8, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 2, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + { .id = HAL_PIXEL_FORMAT_YCbCr_422_SP, .npln = 2, .ncmp = 3, .bps = 8, .bpp_afbc = { 8, 16, 0 }, .bpp = { 8, 16, 0 }, .hsub = 2, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + + /* 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, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = false, .flex = false, PWA_DEFAULT }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y0L2, .npln = 1, .ncmp = 4, .bps = 10, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 2, .vsub = 2, .tile_size = 2, .has_alpha = true, .is_yuv = true, .afbc = false, .linear = true, .flex = false, PWA_DEFAULT }, + { .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, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + + /* 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, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + { .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, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = true, .flex = true, PWA_DEFAULT }, + + /* 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, .tile_size = 1, .has_alpha = false, .is_yuv = true, .afbc = true, .linear = false, .flex = false, PWA_DEFAULT }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_Y410, .npln = 1, .ncmp = 4, .bps = 10, .bpp_afbc = { 32, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = true, .is_yuv = true, .afbc = false, .linear = true, .flex = false, PWA_DEFAULT }, + + /* Other */ + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW16, .npln = 1, .ncmp = 1, .bps = 16, .bpp_afbc = { 16, 0, 0 }, .bpp = { 16, 0, 0 }, .hsub = 2, .vsub = 2, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, .pwa = 16 }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW12, .npln = 1, .ncmp = 1, .bps = 12, .bpp_afbc = { 12, 0, 0 }, .bpp = { 12, 0, 0 }, .hsub = 4, .vsub = 2, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, .pwa = 4 }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_RAW10, .npln = 1, .ncmp = 1, .bps = 10, .bpp_afbc = { 10, 0, 0 }, .bpp = { 10, 0, 0 }, .hsub = 4, .vsub = 2, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, .pwa = 4 }, + { .id = MALI_GRALLOC_FORMAT_INTERNAL_BLOB, .npln = 1, .ncmp = 1, .bps = 8, .bpp_afbc = { 8, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, PWA_DEFAULT }, + +#if PLATFORM_SDK_VERSION >= 28 + /* Depth and Stencil */ + { .id = HAL_PIXEL_FORMAT_DEPTH_16, .npln = 1, .ncmp = 1, .bps = 16, .bpp_afbc = { 0, 0, 0}, .bpp = { 16, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, PWA_DEFAULT }, + { .id = HAL_PIXEL_FORMAT_DEPTH_24, .npln = 1, .ncmp = 1, .bps = 24, .bpp_afbc = { 0, 0, 0 }, .bpp = { 24, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, PWA_DEFAULT }, + { .id = HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8, .npln = 1, .ncmp = 2, .bps = 24, .bpp_afbc = { 0, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, PWA_DEFAULT }, + { .id = HAL_PIXEL_FORMAT_DEPTH_32F, .npln = 1, .ncmp = 1, .bps = 32, .bpp_afbc = { 0, 0, 0 }, .bpp = { 32, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, PWA_DEFAULT }, + { .id = HAL_PIXEL_FORMAT_DEPTH_32F_STENCIL_8, .npln = 1, .ncmp = 2, .bps = 32, .bpp_afbc = { 0, 0, 0 }, .bpp = { 40, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, PWA_DEFAULT }, + { .id = HAL_PIXEL_FORMAT_STENCIL_8, .npln = 1, .ncmp = 1, .bps = 8, .bpp_afbc = { 0, 0, 0 }, .bpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .tile_size = 1, .has_alpha = false, .is_yuv = false, .afbc = false, .linear = true, .flex = false, PWA_DEFAULT }, +#endif +}; + +const size_t num_formats = sizeof(formats)/sizeof(formats[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 uint64_t base_format) +{ + uint32_t format_idx; + for (format_idx = 0; format_idx < num_formats; format_idx++) + { + if (formats[format_idx].id == (uint32_t)base_format) + { + break; + } + } + if (format_idx >= num_formats) + { + return -1; + } + + return (int32_t)format_idx; +} diff --git a/gralloc/src/format_info.h b/gralloc/src/format_info.h new file mode 100644 index 0000000..9b802da --- /dev/null +++ b/gralloc/src/format_info.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 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 FORMAT_INFO_H_ +#define FORMAT_INFO_H_ + +#include "mali_gralloc_buffer.h" + +typedef struct +{ + uint16_t width; + uint16_t height; +} rect_t; + + +/* + * Pixel format information. + * + * These properties are used by gralloc for buffer allocation. + * Each format is uniquely identified with 'id'. + */ +typedef struct +{ + uint32_t id; /* Format ID. */ + uint8_t npln; /* Number of planes. */ + uint8_t ncmp; /* Number of components. */ + 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). + * NOTE: bpp[n] and/or (bpp[n] * pwa) must be multiples of 8. */ + uint8_t hsub; /* Horizontal sub-sampling (YUV formats). Pixel rounding in width (all formats). */ + uint8_t vsub; /* Vertical sub-sampling (YUV formats). Pixel rounding in height (all formats). */ + uint16_t tile_size; /* Tile size (in pixels), assumed square. Uncompressed only. */ + bool has_alpha; /* Alpha channel present. */ + bool is_yuv; /* YUV format (contains luma *and* chroma). */ + bool afbc; /* AFBC supported (per specification and by gralloc). IP support not considered. */ + bool linear; /* Linear/uncompressed supported. */ + bool flex; /* Linear version of format can be represented as flex. */ + uint8_t pwa; /* Width alignment for each plane (in pixels). PWA_DEFAULT: 1. Must be a power of 2. */ + +} format_info_t; + + +extern const format_info_t formats[]; +extern const size_t num_formats; +extern int32_t get_format_index(const uint64_t base_format); + +#endif diff --git a/gralloc/src/framebuffer_device.cpp b/gralloc/src/framebuffer_device.cpp index baa44c6..f4b2f9d 100644 --- a/gralloc/src/framebuffer_device.cpp +++ b/gralloc/src/framebuffer_device.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2017 ARM Limited. All rights reserved. + * Copyright (C) 2010-2018 ARM Limited. All rights reserved. * * Copyright (C) 2008 The Android Open Source Project * @@ -24,7 +24,7 @@ #include <linux/fb.h> #include <system/window.h> -#include <cutils/log.h> +#include <log/log.h> #include <cutils/atomic.h> #include <hardware/hardware.h> #include <hardware/fb.h> @@ -218,7 +218,7 @@ static int init_frame_buffer_locked(struct private_module_t *module) info.yoffset = 0; info.activate = FB_ACTIVATE_NOW; -#ifdef GRALLOC_16_BITS +#if GRALLOC_FB_BPP == 16 /* * Explicitly request 5/6/5 */ @@ -231,7 +231,7 @@ static int init_frame_buffer_locked(struct private_module_t *module) info.blue.length = 5; info.transp.offset = 0; info.transp.length = 0; -#else +#elif GRALLOC_FB_BPP == 32 /* * Explicitly request 8/8/8 */ @@ -244,6 +244,8 @@ static int init_frame_buffer_locked(struct private_module_t *module) info.blue.length = 8; info.transp.offset = 0; info.transp.length = 0; +#else +#error "Invalid framebuffer bit depth" #endif /* @@ -633,10 +635,12 @@ int framebuffer_device_open(hw_module_t const *module, const char *name, hw_devi const_cast<uint32_t &>(dev->width) = m->info.xres; const_cast<uint32_t &>(dev->height) = m->info.yres; const_cast<int &>(dev->stride) = stride; -#ifdef GRALLOC_16_BITS +#if GRALLOC_FB_BPP == 16 const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_RGB_565; -#else +#elif GRALLOC_FB_BPP == 32 const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888; +#else +#error "Invalid framebuffer bit depth" #endif const_cast<float &>(dev->xdpi) = m->xdpi; const_cast<float &>(dev->ydpi) = m->ydpi; diff --git a/gralloc/src/gralloc_buffer_priv.cpp b/gralloc/src/gralloc_buffer_priv.cpp index 274dec2..30b49ce 100644 --- a/gralloc/src/gralloc_buffer_priv.cpp +++ b/gralloc/src/gralloc_buffer_priv.cpp @@ -17,7 +17,7 @@ */ #include <cutils/ashmem.h> -#include <cutils/log.h> +#include <log/log.h> #include <sys/mman.h> #if GRALLOC_USE_GRALLOC1_API == 1 diff --git a/gralloc/src/gralloc_buffer_priv.h b/gralloc/src/gralloc_buffer_priv.h index a92f593..122ee2a 100644 --- a/gralloc/src/gralloc_buffer_priv.h +++ b/gralloc/src/gralloc_buffer_priv.h @@ -35,6 +35,7 @@ struct attr_region int crop_width; int use_yuv_transform; int use_sparse_alloc; + mali_hdr_info hdr_info; } __attribute__((packed)); typedef struct attr_region attr_region; @@ -157,6 +158,11 @@ static inline int gralloc_buffer_attr_write(struct private_handle_t *hnd, buf_at 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; } } @@ -193,6 +199,11 @@ static inline int gralloc_buffer_attr_read(struct private_handle_t *hnd, buf_att *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; } } diff --git a/gralloc/src/gralloc_priv.h b/gralloc/src/gralloc_priv.h index 82538bc..3a54c18 100644 --- a/gralloc/src/gralloc_priv.h +++ b/gralloc/src/gralloc_priv.h @@ -23,7 +23,6 @@ #include <pthread.h> #include <errno.h> #include <linux/fb.h> -#include <linux/ion.h> #include <sys/types.h> #include <unistd.h> #include <sys/mman.h> diff --git a/gralloc/src/ion/ion_4.12.h b/gralloc/src/ion/ion_4.12.h new file mode 100644 index 0000000..6ae79d4 --- /dev/null +++ b/gralloc/src/ion/ion_4.12.h @@ -0,0 +1,125 @@ +/* + * Adapted from drivers/staging/android/uapi/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _UAPI_LINUX_ION_NEW_H +#define _UAPI_LINUX_ION_NEW_H + +#include <linux/ioctl.h> +#include <linux/types.h> + +#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8) + +/** + * DOC: Ion Userspace API + * + * create a client by opening /dev/ion + * most operations handled via following ioctls + * + */ + +/** + * struct ion_new_allocation_data - metadata passed from userspace for allocations + * @len: size of the allocation + * @heap_id_mask: mask of heap ids to allocate from + * @flags: flags passed to heap + * @handle: pointer that will be populated with a cookie to use to + * refer to this allocation + * + * Provided by userspace as an argument to the ioctl - added _new to denote + * this belongs to the new ION interface. + */ +struct ion_new_allocation_data { + __u64 len; + __u32 heap_id_mask; + __u32 flags; + __u32 fd; + __u32 unused; +}; + +#define MAX_HEAP_NAME 32 + +/** + * struct ion_heap_data - data about a heap + * @name - first 32 characters of the heap name + * @type - heap type + * @heap_id - heap id for the heap + */ +struct ion_heap_data { + char name[MAX_HEAP_NAME]; + __u32 type; + __u32 heap_id; + __u32 reserved0; + __u32 reserved1; + __u32 reserved2; +}; + +/** + * struct ion_heap_query - collection of data about all heaps + * @cnt - total number of heaps to be copied + * @heaps - buffer to copy heap data + */ +struct ion_heap_query { + __u32 cnt; /* Total number of heaps to be copied */ + __u32 reserved0; /* align to 64bits */ + __u64 heaps; /* buffer to be populated */ + __u32 reserved1; + __u32 reserved2; +}; + +#define ION_IOC_MAGIC 'I' + +/** + * DOC: ION_IOC_NEW_ALLOC - allocate memory + * + * Takes an ion_allocation_data struct and returns it with the handle field + * populated with the opaque handle for the allocation. + * TODO: This IOCTL will clash by design; however, only one of + * ION_IOC_ALLOC or ION_IOC_NEW_ALLOC paths will be exercised, + * so this should not conflict. + */ +#define ION_IOC_NEW_ALLOC _IOWR(ION_IOC_MAGIC, 0, struct ion_new_allocation_data) + +/** + * DOC: ION_IOC_FREE - free memory + * + * Takes an ion_handle_data struct and frees the handle. + * + * #define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) + * This will come from the older kernels, so don't redefine here + */ + +/** + * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be passed to another process. The corresponding opaque handle can + * be retrieved via ION_IOC_IMPORT. + * + * #define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) + * This will come from the older kernels, so don't redefine here + */ + +/** + * DOC: ION_IOC_HEAP_QUERY - information about available heaps + * + * Takes an ion_heap_query structure and populates information about + * available Ion heaps. + */ +#define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, struct ion_heap_query) + +#endif /* _UAPI_LINUX_ION_NEW_H */ diff --git a/gralloc/src/legacy/alloc_device.cpp b/gralloc/src/legacy/alloc_device.cpp index fa381fc..1ea13ae 100644 --- a/gralloc/src/legacy/alloc_device.cpp +++ b/gralloc/src/legacy/alloc_device.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2017 ARM Limited. All rights reserved. + * Copyright (C) 2010-2018 ARM Limited. All rights reserved. * * Copyright (C) 2008 The Android Open Source Project * @@ -21,7 +21,7 @@ #include <pthread.h> #include <stdlib.h> -#include <cutils/log.h> +#include <log/log.h> #include <cutils/atomic.h> #include <hardware/hardware.h> #include <hardware/gralloc.h> @@ -58,10 +58,12 @@ static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int /* match the framebuffer format */ if (usage & GRALLOC_USAGE_HW_FB) { -#ifdef GRALLOC_16_BITS +#if GRALLOC_FB_BPP == 16 format = HAL_PIXEL_FORMAT_RGB_565; -#else +#elif GRALLOC_FB_BPP == 32 format = HAL_PIXEL_FORMAT_BGRA_8888; +#else +#error "Invalid framebuffer bit depth" #endif } @@ -97,6 +99,10 @@ static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int hnd->stride = pixel_stride; hnd->internalWidth = w; hnd->internalHeight = h; + if (pStride != NULL) + { + *pStride = pixel_stride; + } } } else @@ -106,11 +112,13 @@ static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int buffer_descriptor_t buffer_descriptor; gralloc_buffer_descriptor_t gralloc_buffer_descriptor[1]; + memset((void*)&buffer_descriptor, 0, sizeof(buffer_descriptor)); buffer_descriptor.hal_format = format; buffer_descriptor.consumer_usage = usage; buffer_descriptor.producer_usage = usage; buffer_descriptor.width = w; buffer_descriptor.height = h; + buffer_descriptor.layer_count = 1; buffer_descriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE; gralloc_buffer_descriptor[0] = (gralloc_buffer_descriptor_t)(&buffer_descriptor); diff --git a/gralloc/src/legacy/buffer_access.cpp b/gralloc/src/legacy/buffer_access.cpp new file mode 100644 index 0000000..ccde77b --- /dev/null +++ b/gralloc/src/legacy/buffer_access.cpp @@ -0,0 +1,430 @@ +/* + * Copyright (C) 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 <inttypes.h> + +#if GRALLOC_USE_GRALLOC1_API == 1 +#include <hardware/gralloc1.h> +#else +#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_formats.h" +#include "mali_gralloc_usages.h" +#include "mali_gralloc_ion.h" +#include "gralloc_helper.h" +#include <sync/sync.h> + +namespace legacy +{ + +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) +{ + GRALLOC_UNUSED(m); + GRALLOC_UNUSED(l); + GRALLOC_UNUSED(t); + GRALLOC_UNUSED(w); + GRALLOC_UNUSED(h); + + if (private_handle_t::validate(buffer) < 0) + { + AERR("Locking invalid buffer %p, returning error", buffer); + return -EINVAL; + } + + private_handle_t *hnd = (private_handle_t *)buffer; + + if (hnd->req_format == HAL_PIXEL_FORMAT_YCbCr_420_888) + { + AERR("Buffers with format YCbCr_420_888 must be locked using (*lock_ycbcr)"); + return -EINVAL; + } + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) + { + hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK; + } + + if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) + { + *vaddr = (void *)hnd->base; + } + + return 0; +} + +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) +{ + GRALLOC_UNUSED(m); + GRALLOC_UNUSED(l); + GRALLOC_UNUSED(t); + GRALLOC_UNUSED(w); + GRALLOC_UNUSED(h); + + if (private_handle_t::validate(buffer) < 0) + { + AERR("Locking invalid buffer %p, returning error", buffer); + return -EINVAL; + } + + if (NULL == ycbcr) + { + return -EINVAL; + } + + private_handle_t *hnd = (private_handle_t *)buffer; + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) + { + hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK; + } + + if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK) && + !(hnd->internal_format & MALI_GRALLOC_INTFMT_EXT_MASK)) + { + char *base = (char *)hnd->base; + int y_stride = hnd->byte_stride; + /* Ensure height is aligned for subsampled chroma before calculating buffer parameters */ + int adjusted_height = GRALLOC_ALIGN(hnd->height, 2); + int y_size = y_stride * adjusted_height; + + int u_offset = 0; + int v_offset = 0; + int c_stride = 0; + int step = 0; + + uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; + + switch (base_format) + { + case MALI_GRALLOC_FORMAT_INTERNAL_NV12: + c_stride = y_stride; + /* Y plane, UV plane */ + u_offset = y_size; + v_offset = y_size + 1; + step = 2; + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_NV21: + c_stride = y_stride; + /* Y plane, UV plane */ + v_offset = y_size; + u_offset = y_size + 1; + step = 2; + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_YV12: + { + int c_size; + + /* Stride alignment set to 16 as the SW access flags were set */ + c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16); + c_size = c_stride * (adjusted_height / 2); + /* Y plane, V plane, U plane */ + v_offset = y_size; + u_offset = y_size + c_size; + step = 1; + break; + } + + default: + AERR("Can't lock buffer %p: wrong format %" PRIx64, hnd, hnd->internal_format); + return -EINVAL; + } + + ycbcr->y = base; + ycbcr->cb = base + u_offset; + ycbcr->cr = base + v_offset; + ycbcr->ystride = y_stride; + ycbcr->cstride = c_stride; + ycbcr->chroma_step = step; + } + else + { + AERR("Don't support to lock buffer %p: with format %" PRIx64, hnd, hnd->internal_format); + return -EINVAL; + } + + return 0; +} + +int mali_gralloc_unlock(const mali_gralloc_module *m, buffer_handle_t buffer) +{ + 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; + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && hnd->writeOwner) + { + mali_gralloc_ion_sync(m, hnd); + } + + return 0; +} + +#if GRALLOC_USE_GRALLOC1_API == 1 +int mali_gralloc_get_num_flex_planes(const mali_gralloc_module *m, buffer_handle_t buffer, uint32_t *num_planes) +{ + GRALLOC_UNUSED(m); + + if (private_handle_t::validate(buffer) < 0) + { + AERR("Invalid buffer %p, returning error", buffer); + return -EINVAL; + } + + if (NULL == num_planes) + { + return -EINVAL; + } + + private_handle_t *hnd = (private_handle_t *)buffer; + uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; + + switch (base_format) + { + case MALI_GRALLOC_FORMAT_INTERNAL_NV12: + case MALI_GRALLOC_FORMAT_INTERNAL_NV21: + case MALI_GRALLOC_FORMAT_INTERNAL_YV12: + *num_planes = 3; + break; + + default: + AERR("Can't get planes number of buffer %p: with format %" PRIx64, hnd, hnd->internal_format); + return -EINVAL; + } + + return 0; +} +#endif + +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); +} + +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) +{ + 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_USE_GRALLOC1_API == 1 + +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) +{ + GRALLOC_UNUSED(m); + GRALLOC_UNUSED(l); + GRALLOC_UNUSED(t); + GRALLOC_UNUSED(w); + GRALLOC_UNUSED(h); + + if (private_handle_t::validate(buffer) < 0) + { + AERR("Locking invalid buffer %p, returning error", buffer); + return -EINVAL; + } + + if (NULL == flex_layout) + { + return -EINVAL; + } + + if (fence_fd >= 0) + { + sync_wait(fence_fd, -1); + close(fence_fd); + } + + private_handle_t *hnd = (private_handle_t *)buffer; + + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) + { + hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK; + } + + if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK) && + !(hnd->internal_format & MALI_GRALLOC_INTFMT_EXT_MASK)) + { + uint8_t *base = (uint8_t *)hnd->base; + int y_stride = hnd->byte_stride; + /* Ensure height is aligned for subsampled chroma before calculating buffer parameters */ + int adjusted_height = GRALLOC_ALIGN(hnd->height, 2); + int y_size = y_stride * adjusted_height; + + uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; + + switch (base_format) + { + case MALI_GRALLOC_FORMAT_INTERNAL_NV12: + flex_layout->format = FLEX_FORMAT_YCbCr; + flex_layout->num_planes = 3; + flex_layout->planes[0].top_left = base; + flex_layout->planes[0].component = FLEX_COMPONENT_Y; + flex_layout->planes[0].bits_per_component = 8; + flex_layout->planes[0].bits_used = 8; + flex_layout->planes[0].h_increment = 1; + flex_layout->planes[0].v_increment = y_stride; + flex_layout->planes[0].h_subsampling = 1; + flex_layout->planes[0].v_subsampling = 1; + flex_layout->planes[1].top_left = base + y_size; + flex_layout->planes[1].component = FLEX_COMPONENT_Cb; + flex_layout->planes[1].bits_per_component = 8; + flex_layout->planes[1].bits_used = 8; + flex_layout->planes[1].h_increment = 2; + flex_layout->planes[1].v_increment = y_stride; + flex_layout->planes[1].h_subsampling = 2; + flex_layout->planes[1].v_subsampling = 2; + flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + 1; + flex_layout->planes[2].component = FLEX_COMPONENT_Cr; + flex_layout->planes[2].bits_per_component = 8; + flex_layout->planes[2].bits_used = 8; + flex_layout->planes[2].h_increment = 2; + flex_layout->planes[2].v_increment = y_stride; + flex_layout->planes[2].h_subsampling = 2; + flex_layout->planes[2].v_subsampling = 2; + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_NV21: + /* + * NV21: YCrCb/YVU ordering. The flex format + * plane order must still follow YCbCr order + * (as defined by 'android_flex_component_t'). + */ + flex_layout->format = FLEX_FORMAT_YCbCr; + flex_layout->num_planes = 3; + flex_layout->planes[0].top_left = base; + flex_layout->planes[0].component = FLEX_COMPONENT_Y; + flex_layout->planes[0].bits_per_component = 8; + flex_layout->planes[0].bits_used = 8; + flex_layout->planes[0].h_increment = 1; + flex_layout->planes[0].v_increment = y_stride; + flex_layout->planes[0].h_subsampling = 1; + flex_layout->planes[0].v_subsampling = 1; + flex_layout->planes[1].top_left = base + y_size + 1; + flex_layout->planes[1].component = FLEX_COMPONENT_Cb; + flex_layout->planes[1].bits_per_component = 8; + flex_layout->planes[1].bits_used = 8; + flex_layout->planes[1].h_increment = 2; + flex_layout->planes[1].v_increment = y_stride; + flex_layout->planes[1].h_subsampling = 2; + flex_layout->planes[1].v_subsampling = 2; + flex_layout->planes[2].top_left = base + y_size; + flex_layout->planes[2].component = FLEX_COMPONENT_Cr; + flex_layout->planes[2].bits_per_component = 8; + flex_layout->planes[2].bits_used = 8; + flex_layout->planes[2].h_increment = 2; + flex_layout->planes[2].v_increment = y_stride; + flex_layout->planes[2].h_subsampling = 2; + flex_layout->planes[2].v_subsampling = 2; + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_YV12: + { + int c_size; + int c_stride; + /* Stride alignment set to 16 as the SW access flags were set */ + c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16); + c_size = c_stride * (adjusted_height / 2); + + /* + * YV12: YCrCb/YVU ordering. The flex format + * plane order must still follow YCbCr order + * (as defined by 'android_flex_component_t'). + */ + flex_layout->format = FLEX_FORMAT_YCbCr; + flex_layout->num_planes = 3; + flex_layout->planes[0].top_left = base; + flex_layout->planes[0].component = FLEX_COMPONENT_Y; + flex_layout->planes[0].bits_per_component = 8; + flex_layout->planes[0].bits_used = 8; + flex_layout->planes[0].h_increment = 1; + flex_layout->planes[0].v_increment = y_stride; + flex_layout->planes[0].h_subsampling = 1; + flex_layout->planes[0].v_subsampling = 1; + flex_layout->planes[1].top_left = base + y_size + c_size; + flex_layout->planes[1].component = FLEX_COMPONENT_Cb; + flex_layout->planes[1].bits_per_component = 8; + flex_layout->planes[1].bits_used = 8; + flex_layout->planes[1].h_increment = 1; + flex_layout->planes[1].v_increment = c_stride; + flex_layout->planes[1].h_subsampling = 2; + flex_layout->planes[1].v_subsampling = 2; + flex_layout->planes[2].top_left = base + y_size; + flex_layout->planes[2].component = FLEX_COMPONENT_Cr; + flex_layout->planes[2].bits_per_component = 8; + flex_layout->planes[2].bits_used = 8; + flex_layout->planes[2].h_increment = 1; + flex_layout->planes[2].v_increment = c_stride; + flex_layout->planes[2].h_subsampling = 2; + flex_layout->planes[2].v_subsampling = 2; + break; + } + + default: + AERR("Can't lock buffer %p: wrong format %" PRIx64, hnd, hnd->internal_format); + return -EINVAL; + } + } + else + { + AERR("Don't support to lock buffer %p: with format %" PRIx64, hnd, hnd->internal_format); + return -EINVAL; + } + + return 0; +} +#endif + +int mali_gralloc_unlock_async(const mali_gralloc_module *m, buffer_handle_t buffer, int32_t *fence_fd) +{ + *fence_fd = -1; + + if (mali_gralloc_unlock(m, buffer) < 0) + { + return -EINVAL; + } + + return 0; +} + + +} /* namespace legacy */ diff --git a/gralloc/src/legacy/buffer_access.h b/gralloc/src/legacy/buffer_access.h new file mode 100644 index 0000000..951ff07 --- /dev/null +++ b/gralloc/src/legacy/buffer_access.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 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 BUFFER_ACCESS_H_ +#define BUFFER_ACCESS_H_ + +namespace legacy +{ + +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 diff --git a/gralloc/src/legacy/buffer_alloc.cpp b/gralloc/src/legacy/buffer_alloc.cpp new file mode 100644 index 0000000..2e044be --- /dev/null +++ b/gralloc/src/legacy/buffer_alloc.cpp @@ -0,0 +1,998 @@ +/* + * Copyright (C) 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 <hardware/hardware.h> +#include <inttypes.h> +#include <atomic> + +#if GRALLOC_USE_GRALLOC1_API == 1 +#include <hardware/gralloc1.h> +#else +#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 "legacy/buffer_alloc.h" + +namespace legacy +{ + +#define AFBC_PIXELS_PER_BLOCK 16 +#define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY 16 + +#define AFBC_NORMAL_WIDTH_ALIGN 16 +#define AFBC_NORMAL_HEIGHT_ALIGN 16 +#define AFBC_WIDEBLK_WIDTH_ALIGN 32 +#define AFBC_WIDEBLK_HEIGHT_ALIGN 16 + +/* When using tiled headers the alignment is 8 times the super-block size in each dimension. */ +#define AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN 128 +#define AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN 128 +#define AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN 256 +#define AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN 64 +/* Tiled headers are always enabled with extra-wide block. */ +#define AFBC_TILED_EXTRAWIDEBLK_WIDTH_ALIGN 512 +#define AFBC_TILED_EXTRAWIDEBLK_HEIGHT_ALIGN 32 + +// This value is platform specific and should be set according to hardware YUV planes restrictions. +// Please note that EGL winsys platform config file needs to use the same value when importing buffers. +#define YUV_MALI_PLANE_ALIGN 128 + +// Default YUV stride aligment in Android +#define YUV_ANDROID_PLANE_ALIGN 16 + +static int mali_gralloc_buffer_free_internal(buffer_handle_t *pHandle, uint32_t num_hnds); + + + +static void afbc_buffer_align(const alloc_type_t type, int *size) +{ + const uint16_t AFBC_BODY_BUFFER_BYTE_ALIGNMENT = 1024; + + int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + + if (type.is_tiled) + { + buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + } + + *size = GRALLOC_ALIGN(*size, buffer_byte_alignment); +} + + +/* + * Alignment of width/height (in pixels) calculated for worst case (buffer size). + */ +void get_afbc_alignment(const int width, const int height, const alloc_type_t type, + int * const w_aligned, int * const h_aligned) +{ + *h_aligned = GRALLOC_ALIGN(height, AFBC_NORMAL_HEIGHT_ALIGN); + + if (type.primary_type == UNCOMPRESSED) + { + *w_aligned = width; + *h_aligned = height; + return; + } + else if (type.is_tiled && type.primary_type == AFBC) + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN); + *h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN); + } + else if (type.is_tiled && type.primary_type == AFBC_WIDEBLK) + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN); + *h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN); + } + else if (type.primary_type == AFBC_PADDED) + { + *w_aligned = GRALLOC_ALIGN(width, 64); + } + else if (type.primary_type == AFBC_WIDEBLK) + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN); + *h_aligned = GRALLOC_ALIGN(height, AFBC_WIDEBLK_HEIGHT_ALIGN); + } + else if (type.primary_type == AFBC_EXTRAWIDEBLK) + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_EXTRAWIDEBLK_WIDTH_ALIGN); + *h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_EXTRAWIDEBLK_HEIGHT_ALIGN); + } + else + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN); + } +} + + + +/* + * Computes the strides and size for an RGB buffer + * + * width width of the buffer in pixels + * height height of the buffer in pixels + * pixel_size size of one pixel in bytes + * + * pixel_stride (out) stride of the buffer in pixels + * byte_stride (out) stride of the buffer in bytes + * size (out) size of the buffer in bytes + * type (in) if buffer should be allocated for afbc + */ +static void get_rgb_stride_and_size(int width, int height, int pixel_size, bool cpu_usage, + int *pixel_stride, int *byte_stride, size_t *size, alloc_type_t type) +{ + int stride; + + if (type.primary_type != UNCOMPRESSED) + { + int nblocks; + int body_alignment; + + stride = width * pixel_size; + stride = GRALLOC_ALIGN(stride, 64); + + if (byte_stride != NULL) + { + *byte_stride = stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = stride / pixel_size; + } + + nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + + if (size != NULL) + { + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); + *size = stride * height + header_size; + } + } + else + { + stride = width * pixel_size; + + /* Align the lines to 64 bytes. + * It's more efficient to write to 64-byte aligned addresses because it's the burst size on the bus */ + const int stride_align = (cpu_usage) ? lcm(64, pixel_size) : 64; + stride = GRALLOC_ALIGN(stride, stride_align); + + if (size != NULL) + { + *size = stride *height; + } + + if (byte_stride != NULL) + { + *byte_stride = stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = stride / pixel_size; + } + } +} + +/* + * Computes the strides and size for an AFBC 8BIT YUV 4:2:0 buffer + * + * width Public known width of the buffer in pixels + * height Public known height of the buffer in pixels + * + * pixel_stride (out) stride of the buffer in pixels + * byte_stride (out) stride of the buffer in bytes + * size (out) size of the buffer in bytes + * type if buffer should be allocated for a certain afbc type + */ +static bool get_afbc_yuv420_8bit_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, + size_t *size, alloc_type_t type) +{ + int yuv420_afbc_luma_stride, yuv420_afbc_chroma_stride; + int nblocks; + + if (type.primary_type == UNCOMPRESSED) + { + AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV420_8BIT_AFBC!"); + return false; + } + else if (type.primary_type == AFBC_PADDED) + { + AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV"); + return false; + } + + yuv420_afbc_luma_stride = width; + yuv420_afbc_chroma_stride = GRALLOC_ALIGN(yuv420_afbc_luma_stride / 2, 16); /* Horizontal downsampling*/ + + if (size != NULL) + { + int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); + /* Simplification of (height * luma-stride + 2 * (height /2 * chroma_stride) */ + *size = (yuv420_afbc_luma_stride + yuv420_afbc_chroma_stride) * height + header_size; + } + + if (byte_stride != NULL) + { + *byte_stride = yuv420_afbc_luma_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = yuv420_afbc_luma_stride; + } + + return true; +} + +/* + * Computes the strides and size for an YV12 buffer + * + * width Public known width of the buffer in pixels + * height Public known height of the buffer in pixels + * + * pixel_stride (out) stride of the buffer in pixels + * byte_stride (out) stride of the buffer in bytes + * size (out) size of the buffer in bytes + * type (in) if buffer should be allocated for a certain afbc type + * stride_alignment (in) stride aligment value in bytes. + */ +static bool get_yv12_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size, + alloc_type_t type, int stride_alignment) +{ + int luma_stride; + + if (type.primary_type != UNCOMPRESSED) + { + return get_afbc_yuv420_8bit_stride_and_size(width, height, pixel_stride, byte_stride, size, type); + } + + /* 4:2:0 formats must have buffers with even height and width as the clump size is 2x2 pixels. + * Width will be even stride aligned anyway so just adjust height here for size calculation. */ + height = GRALLOC_ALIGN(height, 2); + + luma_stride = GRALLOC_ALIGN(width, stride_alignment); + + if (size != NULL) + { + int chroma_stride = GRALLOC_ALIGN(luma_stride / 2, stride_alignment); + /* Simplification of ((height * luma_stride ) + 2 * ((height / 2) * chroma_stride)). */ + *size = height *(luma_stride + chroma_stride); + } + + if (byte_stride != NULL) + { + *byte_stride = luma_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = luma_stride; + } + + return true; +} + +/* + * Computes the strides and size for an 8 bit YUYV 422 buffer + * + * width Public known width of the buffer in pixels + * height Public known height of the buffer in pixels + * + * pixel_stride (out) stride of the buffer in pixels + * byte_stride (out) stride of the buffer in bytes + * size (out) size of the buffer in bytes + */ +static bool get_yuv422_8bit_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size) +{ + int local_byte_stride, local_pixel_stride; + + /* 4:2:2 formats must have buffers with even width as the clump size is 2x1 pixels. + * This is taken care of by the even stride alignment. */ + + local_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN); + local_byte_stride = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN); /* 4 bytes per 2 pixels */ + + if (size != NULL) + { + *size = local_byte_stride *height; + } + + if (byte_stride != NULL) + { + *byte_stride = local_byte_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = local_pixel_stride; + } + + return true; +} + +/* + * Computes the strides and size for an AFBC 8BIT YUV 4:2:2 buffer + * + * width width of the buffer in pixels + * height height of the buffer in pixels + * + * pixel_stride (out) stride of the buffer in pixels + * byte_stride (out) stride of the buffer in bytes + * size (out) size of the buffer in bytes + * type if buffer should be allocated for a certain afbc type + */ +static bool get_afbc_yuv422_8bit_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, + size_t *size, alloc_type_t type) +{ + int yuv422_afbc_luma_stride; + int nblocks; + + if (type.primary_type == UNCOMPRESSED) + { + AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV422_8BIT_AFBC!"); + return false; + } + else if (type.primary_type == AFBC_PADDED) + { + AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV"); + return false; + } + + yuv422_afbc_luma_stride = width; + + if (size != NULL) + { + int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); + /* YUV 4:2:2 luma size equals chroma size */ + *size = yuv422_afbc_luma_stride * height * 2 + header_size; + } + + if (byte_stride != NULL) + { + *byte_stride = yuv422_afbc_luma_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = yuv422_afbc_luma_stride; + } + + return true; +} + +/* + * Calculate strides and sizes for a P010 (Y-UV 4:2:0) or P210 (Y-UV 4:2:2) buffer. + * + * @param width [in] Buffer width. + * @param height [in] Buffer height. + * @param vss [in] Vertical sub-sampling factor (2 for P010, 1 for + * P210. Anything else is invalid). + * @param pixel_stride [out] Pixel stride; number of pixels between + * consecutive rows. + * @param byte_stride [out] Byte stride; number of bytes between + * consecutive rows. + * @param size [out] Size of the buffer in bytes. Cumulative sum of + * sizes of all planes. + * + * @return true if the calculation was successful; false otherwise (invalid + * parameter) + */ +static bool get_yuv_pX10_stride_and_size(int width, int height, int vss, int *pixel_stride, int *byte_stride, + size_t *size) +{ + int luma_pixel_stride, luma_byte_stride; + + if (vss < 1 || vss > 2) + { + AERR("Invalid vertical sub-sampling factor: %d, should be 1 or 2", vss); + return false; + } + + /* 4:2:2 must have even width as the clump size is 2x1 pixels. This will be taken care of by the + * even stride alignment */ + if (vss == 2) + { + /* 4:2:0 must also have even height as the clump size is 2x2 */ + height = GRALLOC_ALIGN(height, 2); + } + + luma_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN); + luma_byte_stride = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN); + + if (size != NULL) + { + int chroma_size = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN) * (height / vss); + *size = luma_byte_stride *height + chroma_size; + } + + if (byte_stride != NULL) + { + *byte_stride = luma_byte_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = luma_pixel_stride; + } + + return true; +} + +/* + * Calculate strides and strides for Y210 (10 bit YUYV packed, 4:2:2) format buffer. + * + * @param width [in] Buffer width. + * @param height [in] Buffer height. + * @param pixel_stride [out] Pixel stride; number of pixels between + * consecutive rows. + * @param byte_stride [out] Byte stride; number of bytes between + * consecutive rows. + * @param size [out] Size of the buffer in bytes. Cumulative sum of + * sizes of all planes. + * + * @return true if the calculation was successful; false otherwise (invalid + * parameter) + */ +static bool get_yuv_y210_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size) +{ + int y210_byte_stride, y210_pixel_stride; + + /* 4:2:2 formats must have buffers with even width as the clump size is 2x1 pixels. + * This is taken care of by the even stride alignment */ + + y210_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN); + /* 4x16 bits per 2 pixels */ + y210_byte_stride = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN); + + if (size != NULL) + { + *size = y210_byte_stride *height; + } + + if (byte_stride != NULL) + { + *byte_stride = y210_byte_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = y210_pixel_stride; + } + + return true; +} + +/* + * Calculate strides and strides for Y0L2 (YUYAAYVYAA, 4:2:0) format buffer. + * + * @param width [in] Buffer width. + * @param height [in] Buffer height. + * @param pixel_stride [out] Pixel stride; number of pixels between + * consecutive rows. + * @param byte_stride [out] Byte stride; number of bytes between + * consecutive rows. + * @param size [out] Size of the buffer in bytes. Cumulative sum of + * sizes of all planes. + * + * @return true if the calculation was successful; false otherwise (invalid + * parameter) + * + * @note Each YUYAAYVYAA clump encodes a 2x2 area of pixels. YU&V are 10 bits. A is 1 bit. total 8 bytes + * + */ +static bool get_yuv_y0l2_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size) +{ + int y0l2_byte_stride, y0l2_pixel_stride; + + /* 4:2:0 formats must have buffers with even height and width + * as the clump size is 2x2 pixels. + * Width is take care of by the even stride alignment so just + * adjust height here for size calculation. */ + height = GRALLOC_ALIGN(height, 2); + + y0l2_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN); + y0l2_byte_stride = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN); /* 2 horiz pixels per 8 byte clump */ + + if (size != NULL) + { + *size = y0l2_byte_stride * height / 2; /* byte stride covers 2 vert pixels */ + } + + if (byte_stride != NULL) + { + *byte_stride = y0l2_byte_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = y0l2_pixel_stride; + } + + return true; +} + +/* + * Calculate strides and strides for Y410 (AVYU packed, 4:4:4) format buffer. + * + * @param width [in] Buffer width. + * @param height [in] Buffer height. + * @param pixel_stride [out] Pixel stride; number of pixels between + * consecutive rows. + * @param byte_stride [out] Byte stride; number of bytes between + * consecutive rows. + * @param size [out] Size of the buffer in bytes. Cumulative sum of + * sizes of all planes. + * + * @return true if the calculation was successful; false otherwise (invalid + * parameter) + */ +static bool get_yuv_y410_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size) +{ + int y410_byte_stride, y410_pixel_stride; + + y410_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN); + y410_byte_stride = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN); + + if (size != NULL) + { + /* 4x8bits per pixel */ + *size = y410_byte_stride *height; + } + + if (byte_stride != NULL) + { + *byte_stride = y410_byte_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = y410_pixel_stride; + } + + return true; +} + +/* + * Calculate strides and strides for YUV420_10BIT_AFBC (Compressed, 4:2:0) format buffer. + * + * @param width [in] Buffer width. + * @param height [in] Buffer height. + * @param pixel_stride [out] Pixel stride; number of pixels between + * consecutive rows. + * @param byte_stride [out] Byte stride; number of bytes between + * consecutive rows. + * @param size [out] Size of the buffer in bytes. Cumulative sum of + * sizes of all planes. + * @param type [in] afbc mode that buffer should be allocated with. + * + * @return true if the calculation was successful; false otherwise (invalid + * parameter) + */ +static bool get_yuv420_10bit_afbc_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, + size_t *size, alloc_type_t type) +{ + int yuv420_afbc_byte_stride, yuv420_afbc_pixel_stride; + int nblocks; + + if (width & 3) + { + return false; + } + + if (type.primary_type == UNCOMPRESSED) + { + AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV420_10BIT_AFBC!"); + return false; + } + else if (type.primary_type == AFBC_PADDED) + { + AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV"); + return false; + } + + yuv420_afbc_pixel_stride = GRALLOC_ALIGN(width, 16); + yuv420_afbc_byte_stride = GRALLOC_ALIGN(width * 4, 16); /* 64-bit packed and horizontally downsampled */ + + if (size != NULL) + { + int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); + + int w_aligned, h_aligned; + get_afbc_alignment(width, height/2, type, &w_aligned, &h_aligned); + + *size = yuv420_afbc_byte_stride * h_aligned + header_size; + } + + if (byte_stride != NULL) + { + *byte_stride = yuv420_afbc_byte_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = yuv420_afbc_pixel_stride; + } + + return true; +} + +/* + * Calculate strides and strides for YUV422_10BIT_AFBC (Compressed, 4:2:2) format buffer. + * + * @param width [in] Buffer width. + * @param height [in] Buffer height. + * @param pixel_stride [out] Pixel stride; number of pixels between + * consecutive rows. + * @param byte_stride [out] Byte stride; number of bytes between + * consecutive rows. + * @param size [out] Size of the buffer in bytes. Cumulative sum of + * sizes of all planes. + * @param type [in] afbc mode that buffer should be allocated with. + * + * @return true if the calculation was successful; false otherwise (invalid + * parameter) + */ +static bool get_yuv422_10bit_afbc_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, + size_t *size, alloc_type_t type) +{ + int yuv422_afbc_byte_stride, yuv422_afbc_pixel_stride; + int nblocks; + + if (width & 3) + { + return false; + } + + if (type.primary_type == UNCOMPRESSED) + { + AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV422_10BIT_AFBC!"); + return false; + } + else if (type.primary_type == AFBC_PADDED) + { + AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV"); + return false; + } + + yuv422_afbc_pixel_stride = GRALLOC_ALIGN(width, 16); + yuv422_afbc_byte_stride = GRALLOC_ALIGN(width * 2, 16); + + if (size != NULL) + { + int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); + /* YUV 4:2:2 chroma size equals to luma size */ + *size = yuv422_afbc_byte_stride * height * 2 + header_size; + } + + if (byte_stride != NULL) + { + *byte_stride = yuv422_afbc_byte_stride; + } + + if (pixel_stride != NULL) + { + *pixel_stride = yuv422_afbc_pixel_stride; + } + + return true; +} + +/* + * Calculate strides and strides for Camera RAW and Blob formats + * + * @param w [in] Buffer width. + * @param h [in] Buffer height. + * @param format [in] Requested HAL format + * @param out_stride [out] Pixel stride; number of pixels/bytes between + * consecutive rows. Format description calls for + * either bytes or pixels. + * @param size [out] Size of the buffer in bytes. Cumulative sum of + * sizes of all planes. + * + * @return true if the calculation was successful; false otherwise (invalid + * parameter) + */ +static bool get_camera_formats_stride_and_size(int w, int h, uint64_t format, int *out_stride, size_t *out_size) +{ + int stride, size; + + switch (format) + { + case HAL_PIXEL_FORMAT_RAW16: + stride = w; /* Format assumes stride in pixels */ + stride = GRALLOC_ALIGN(stride, 16); /* Alignment mandated by Android */ + size = stride * h * 2; /* 2 bytes per pixel */ + break; + + case HAL_PIXEL_FORMAT_RAW12: + if (w % 4 != 0) + { + ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW12 buffers has to be multiple of 4."); + return false; + } + + stride = (w / 2) * 3; /* Stride in bytes; 2 pixels in 3 bytes */ + size = stride * h; + break; + + case HAL_PIXEL_FORMAT_RAW10: + if (w % 4 != 0) + { + ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW10 buffers has to be multiple of 4."); + return false; + } + + stride = (w / 4) * 5; /* Stride in bytes; 4 pixels in 5 bytes */ + size = stride * h; + break; + + case HAL_PIXEL_FORMAT_BLOB: + if (h != 1) + { + ALOGE("ERROR: Height for HAL_PIXEL_FORMAT_BLOB must be 1."); + return false; + } + + stride = 0; /* No 'rows', it's effectively a long one dimensional array */ + size = w; + break; + + default: + return false; + } + + if (out_size != NULL) + { + *out_size = size; + } + + if (out_stride != NULL) + { + *out_stride = stride; + } + + return true; +} + +int get_alloc_size(uint64_t internal_format, + uint64_t usage, + alloc_type_t alloc_type, + int old_alloc_width, + int old_alloc_height, + int * old_byte_stride, + int * pixel_stride, + size_t * size) +{ + uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; + + switch (base_format) + { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: +#if PLATFORM_SDK_VERSION >= 26 + case HAL_PIXEL_FORMAT_RGBA_1010102: +#endif + get_rgb_stride_and_size(old_alloc_width, old_alloc_height, 4, + usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), + pixel_stride, old_byte_stride, size, alloc_type); + break; + + case HAL_PIXEL_FORMAT_RGB_888: + get_rgb_stride_and_size(old_alloc_width, old_alloc_height, 3, + usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), + pixel_stride, old_byte_stride, size, alloc_type); + break; + + case HAL_PIXEL_FORMAT_RGB_565: + get_rgb_stride_and_size(old_alloc_width, old_alloc_height, 2, + usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), + pixel_stride, old_byte_stride, size, alloc_type); + break; +#if PLATFORM_SDK_VERSION >= 26 + case HAL_PIXEL_FORMAT_RGBA_FP16: + get_rgb_stride_and_size(old_alloc_width, old_alloc_height, 8, + usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK), + pixel_stride, old_byte_stride, size, alloc_type); + break; +#endif + + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case MALI_GRALLOC_FORMAT_INTERNAL_YV12: + case MALI_GRALLOC_FORMAT_INTERNAL_NV12: + case MALI_GRALLOC_FORMAT_INTERNAL_NV21: + { + /* Mali subsystem prefers higher stride alignment values (128 bytes) for YUV, but software components assume + * default of 16. We only need to care about YV12 as it's the only, implicit, HAL YUV format in Android. + */ + int yv12_align = YUV_MALI_PLANE_ALIGN; + + if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) + { + yv12_align = YUV_ANDROID_PLANE_ALIGN; + } + + if (!get_yv12_stride_and_size(old_alloc_width, old_alloc_height, pixel_stride, + old_byte_stride, size, alloc_type, yv12_align)) + { + return -EINVAL; + } + + break; + } + + case HAL_PIXEL_FORMAT_YCbCr_422_I: + { + /* YUYV 4:2:2 */ + if (alloc_type.primary_type != UNCOMPRESSED || + !get_yuv422_8bit_stride_and_size(old_alloc_width, old_alloc_height, + pixel_stride, old_byte_stride, size)) + { + return -EINVAL; + } + + break; + } + + case HAL_PIXEL_FORMAT_RAW16: + case HAL_PIXEL_FORMAT_RAW12: + case HAL_PIXEL_FORMAT_RAW10: + case HAL_PIXEL_FORMAT_BLOB: + if (alloc_type.primary_type != UNCOMPRESSED) + { + return -EINVAL; + } + + get_camera_formats_stride_and_size(old_alloc_width, old_alloc_height, base_format, + pixel_stride, size); + /* For Raw/Blob formats stride is defined to be either in bytes or pixels per format */ + *old_byte_stride = *pixel_stride; + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2: + + /* YUYAAYUVAA 4:2:0 with and without AFBC */ + if (alloc_type.primary_type != UNCOMPRESSED) + { + if (!get_yuv420_10bit_afbc_stride_and_size( + old_alloc_width, old_alloc_height, pixel_stride, + old_byte_stride, size, alloc_type)) + { + return -EINVAL; + } + } + else + { + if (!get_yuv_y0l2_stride_and_size(old_alloc_width, old_alloc_height, + pixel_stride, old_byte_stride, size)) + { + return -EINVAL; + } + } + + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_P010: + + /* Y-UV 4:2:0 */ + if (alloc_type.primary_type != UNCOMPRESSED || + !get_yuv_pX10_stride_and_size(old_alloc_width, old_alloc_height, 2, + pixel_stride, old_byte_stride, size)) + { + return -EINVAL; + } + + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_P210: + + /* Y-UV 4:2:2 */ + if (alloc_type.primary_type != UNCOMPRESSED || + !get_yuv_pX10_stride_and_size(old_alloc_width, old_alloc_height, 1, + pixel_stride, old_byte_stride, size)) + { + return -EINVAL; + } + + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_Y210: + + /* YUYV 4:2:2 with and without AFBC */ + if (alloc_type.primary_type != UNCOMPRESSED) + { + if (!get_yuv422_10bit_afbc_stride_and_size(old_alloc_width, old_alloc_height, + pixel_stride, old_byte_stride, + size, alloc_type)) + { + return -EINVAL; + } + } + else + { + if (!get_yuv_y210_stride_and_size(old_alloc_width, old_alloc_height, + pixel_stride, old_byte_stride, size)) + { + return -EINVAL; + } + } + + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_Y410: + + /* AVYU 2-10-10-10 */ + if (alloc_type.primary_type != UNCOMPRESSED || + !get_yuv_y410_stride_and_size(old_alloc_width, old_alloc_height, pixel_stride, + old_byte_stride, size)) + { + return -EINVAL; + } + + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT: + + /* 8BIT AFBC YUV4:2:2 testing usage */ + + /* We only support compressed for this format right now. + * Below will fail in case format is uncompressed. + */ + if (!get_afbc_yuv422_8bit_stride_and_size(old_alloc_width, old_alloc_height, + pixel_stride, old_byte_stride, + size, alloc_type)) + { + return -EINVAL; + } + + break; + + /* + * Additional custom formats can be added here + * and must fill the variables pixel_stride, byte_stride and size. + */ + default: + return -EINVAL; + } + + + return 0; +} + + +} + + diff --git a/gralloc/src/legacy/buffer_alloc.h b/gralloc/src/legacy/buffer_alloc.h new file mode 100644 index 0000000..d36c6dd --- /dev/null +++ b/gralloc/src/legacy/buffer_alloc.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 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 BUFFER_ALLOC_H_ +#define BUFFER_ALLOC_H_ + +namespace legacy +{ + enum AllocBaseType + { + UNCOMPRESSED, + AFBC, + /* AN AFBC buffer with additional padding to ensure a 64-byte alignment + * for each row of blocks in the header */ + AFBC_PADDED, + AFBC_WIDEBLK, + AFBC_EXTRAWIDEBLK, + }; + + + typedef struct + { + AllocBaseType primary_type; + /* If is_multi_plane is true then chroma plane is implicitly extra wide block for AFBC. */ + bool is_multi_plane; + bool is_tiled; + + bool is_afbc() const + { + return primary_type != UNCOMPRESSED; + } + } alloc_type_t; + + + int get_alloc_size(uint64_t internal_format, + uint64_t usage, + alloc_type_t alloc_type, + int old_alloc_width, + int old_alloc_height, + int * old_byte_stride, + int * pixel_stride, + size_t * size); + + bool mali_gralloc_adjust_dimensions(const uint64_t internal_format, + const uint64_t usage, + const alloc_type_t type, + const uint32_t width, + const uint32_t height, + int * const internal_width, + int * const internal_height); + + + void get_afbc_alignment(const int width, const int height, const alloc_type_t type, + int * const w_aligned, int * const h_aligned); +} + +#endif diff --git a/gralloc/src/mali_gralloc_buffer.h b/gralloc/src/mali_gralloc_buffer.h index 8c32153..8786ee1 100644 --- a/gralloc/src/mali_gralloc_buffer.h +++ b/gralloc/src/mali_gralloc_buffer.h @@ -18,8 +18,11 @@ #ifndef MALI_GRALLOC_BUFFER_H_ #define MALI_GRALLOC_BUFFER_H_ -#include <linux/ion.h> +#include <stdint.h> +#include <unistd.h> +#include <errno.h> #include <sys/mman.h> +#include <cutils/native_handle.h> #include "mali_gralloc_private_interface_types.h" @@ -106,9 +109,40 @@ struct private_handle_t int size; int width; int height; + + /* + * Dimensions of allocation (in pixels). + * + * AFBC compressed formats: requested width/height are rounded-up + * to the next whole superblock (at minimum). + * Uncompressed formats: dimensions typically match width and height + * but might require additional padding. + * + * (pixel) stride and byte_stride are calculated using these allocation + * dimensions instead of width/height. + * + * 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. + */ int internalWidth; int internalHeight; + int stride; + + /* + * Multi-layer buffers. + * + * Gralloc 1.0 supports multiple image layers within the same + * buffer allocation, where GRALLOC1_CAPABILITY_LAYERED_BUFFERS is enabled. + * 'layer_count' defines the number of layers that have been allocated. + * All layers are the same size (in bytes) and 'size' defines the + * number of bytes in the whole allocation. + * Size of each layer = 'size' / 'layer_count'. + * Offset to nth layer = n * ('size' / 'layer_count'), + * where n=0 for the first layer. + */ + uint32_t layer_count; union { void *base; @@ -167,6 +201,7 @@ struct private_handle_t , width(0) , height(0) , stride(0) + , layer_count(0) , base(_base) , consumer_usage(_consumer_usage) , producer_usage(_producer_usage) @@ -188,7 +223,8 @@ struct private_handle_t private_handle_t(int _flags, int _size, int _min_pgsz, uint64_t _consumer_usage, uint64_t _producer_usage, int _shared_fd, int _req_format, uint64_t _internal_format, int _byte_stride, int _width, - int _height, int _stride, int _internalWidth, int _internalHeight, int _backing_store_size) + int _height, int _stride, int _internalWidth, int _internalHeight, int _backing_store_size, + uint64_t _layer_count) : share_fd(_shared_fd) , share_attr_fd(-1) , magic(sMagic) @@ -202,6 +238,7 @@ struct private_handle_t , internalWidth(_internalWidth) , internalHeight(_internalHeight) , stride(_stride) + , layer_count(_layer_count) , base(NULL) , consumer_usage(_consumer_usage) , producer_usage(_producer_usage) diff --git a/gralloc/src/mali_gralloc_bufferaccess.cpp b/gralloc/src/mali_gralloc_bufferaccess.cpp index ea77283..4ffa682 100644 --- a/gralloc/src/mali_gralloc_bufferaccess.cpp +++ b/gralloc/src/mali_gralloc_bufferaccess.cpp @@ -321,6 +321,11 @@ int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, buffer_handle_t b break; case MALI_GRALLOC_FORMAT_INTERNAL_NV21: + /* + * NV21: YCrCb/YVU ordering. The flex format + * plane order must still follow YCbCr order + * (as defined by 'android_flex_component_t'). + */ flex_layout->format = FLEX_FORMAT_YCbCr; flex_layout->num_planes = 3; flex_layout->planes[0].top_left = base; @@ -331,16 +336,16 @@ int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, buffer_handle_t b flex_layout->planes[0].v_increment = y_stride; flex_layout->planes[0].h_subsampling = 1; flex_layout->planes[0].v_subsampling = 1; - flex_layout->planes[1].top_left = base + y_size; - flex_layout->planes[1].component = FLEX_COMPONENT_Cr; + flex_layout->planes[1].top_left = base + y_size + 1; + flex_layout->planes[1].component = FLEX_COMPONENT_Cb; flex_layout->planes[1].bits_per_component = 8; flex_layout->planes[1].bits_used = 8; flex_layout->planes[1].h_increment = 2; flex_layout->planes[1].v_increment = y_stride; flex_layout->planes[1].h_subsampling = 2; flex_layout->planes[1].v_subsampling = 2; - flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + 1; - flex_layout->planes[2].component = FLEX_COMPONENT_Cb; + flex_layout->planes[2].top_left = base + y_size; + flex_layout->planes[2].component = FLEX_COMPONENT_Cr; flex_layout->planes[2].bits_per_component = 8; flex_layout->planes[2].bits_used = 8; flex_layout->planes[2].h_increment = 2; @@ -356,7 +361,12 @@ int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, buffer_handle_t b /* Stride alignment set to 16 as the SW access flags were set */ c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16); c_size = c_stride * (adjusted_height / 2); - /* Y plane, V plane, U plane */ + + /* + * YV12: YCrCb/YVU ordering. The flex format + * plane order must still follow YCbCr order + * (as defined by 'android_flex_component_t'). + */ flex_layout->format = FLEX_FORMAT_YCbCr; flex_layout->num_planes = 3; flex_layout->planes[0].top_left = base; @@ -367,16 +377,16 @@ int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, buffer_handle_t b flex_layout->planes[0].v_increment = y_stride; flex_layout->planes[0].h_subsampling = 1; flex_layout->planes[0].v_subsampling = 1; - flex_layout->planes[1].top_left = base + y_size; - flex_layout->planes[1].component = FLEX_COMPONENT_Cr; + flex_layout->planes[1].top_left = base + y_size + c_size; + flex_layout->planes[1].component = FLEX_COMPONENT_Cb; flex_layout->planes[1].bits_per_component = 8; flex_layout->planes[1].bits_used = 8; flex_layout->planes[1].h_increment = 1; flex_layout->planes[1].v_increment = c_stride; flex_layout->planes[1].h_subsampling = 2; flex_layout->planes[1].v_subsampling = 2; - flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + c_size; - flex_layout->planes[2].component = FLEX_COMPONENT_Cb; + flex_layout->planes[2].top_left = base + y_size; + flex_layout->planes[2].component = FLEX_COMPONENT_Cr; flex_layout->planes[2].bits_per_component = 8; flex_layout->planes[2].bits_used = 8; flex_layout->planes[2].h_increment = 1; diff --git a/gralloc/src/mali_gralloc_bufferallocation.cpp b/gralloc/src/mali_gralloc_bufferallocation.cpp index 0efc64e..129536d 100644 --- a/gralloc/src/mali_gralloc_bufferallocation.cpp +++ b/gralloc/src/mali_gralloc_bufferallocation.cpp @@ -38,18 +38,19 @@ #define AFBC_PIXELS_PER_BLOCK 16 #define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY 16 -#define AFBC_BODY_BUFFER_BYTE_ALIGNMENT 1024 #define AFBC_NORMAL_WIDTH_ALIGN 16 #define AFBC_NORMAL_HEIGHT_ALIGN 16 #define AFBC_WIDEBLK_WIDTH_ALIGN 32 #define AFBC_WIDEBLK_HEIGHT_ALIGN 16 -// Regarding Tiled Headers AFBC mode, both header and body buffer should aligned to 4KB -// and in non-wide mode (16x16), the width and height should be both rounded up to 128 -// in wide mode (32x8) the width should be rounded up to 256, the height should be rounded up to 64 + +/* When using tiled headers the alignment is 8 times the super-block size in each dimension. */ #define AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN 128 #define AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN 128 #define AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN 256 #define AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN 64 +/* Tiled headers are always enabled with extra-wide block. */ +#define AFBC_TILED_EXTRAWIDEBLK_WIDTH_ALIGN 512 +#define AFBC_TILED_EXTRAWIDEBLK_HEIGHT_ALIGN 32 // This value is platform specific and should be set according to hardware YUV planes restrictions. // Please note that EGL winsys platform config file needs to use the same value when importing buffers. @@ -58,24 +59,6 @@ // Default YUV stride aligment in Android #define YUV_ANDROID_PLANE_ALIGN 16 -/* - * Type of allocation - */ -enum AllocType -{ - UNCOMPRESSED = 0, - AFBC, - /* AFBC_WIDEBLK mode requires buffer to have 32 * 16 pixels alignment */ - AFBC_WIDEBLK, - /* AN AFBC buffer with additional padding to ensure a 64-bte alignment - * for each row of blocks in the header */ - AFBC_PADDED, - /* AFBC_TILED_HEADERS_AFBC_BASIC mode requires buffer to have 128*128 pixels alignment(16x16 superblocks) */ - AFBC_TILED_HEADERS_BASIC, - /* AFBC_TILED_HEADERS_AFBC_WIDEBLK mode requires buffer to have 256*64 pixels alignment(32x8 superblocks) */ - AFBC_TILED_HEADERS_WIDEBLK, -}; - static int mali_gralloc_buffer_free_internal(buffer_handle_t *pHandle, uint32_t num_hnds); /* @@ -88,6 +71,188 @@ static uint64_t getUniqueId() return id | counter++; } + +static void afbc_buffer_align(const AllocType type, int *size) +{ + const uint16_t AFBC_BODY_BUFFER_BYTE_ALIGNMENT = 1024; + + int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + + if (type == AFBC_TILED_HEADERS_BASIC || + type == AFBC_TILED_HEADERS_WIDEBLK) + { + buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + } + + *size = GRALLOC_ALIGN(*size, buffer_byte_alignment); +} + + +/* + * Determine AFBC type for this format, used to determine alignment. + * Split block does not affect alignment/AllocType. + */ +static bool get_alloc_type(const uint64_t internal_format, + const uint64_t usage, + AllocType * const type) +{ + *type = UNCOMPRESSED; + + if (internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) + { + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) + { + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) + { + *type = AFBC_TILED_HEADERS_WIDEBLK; + } + else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) + { + *type = AFBC_EXTRAWIDEBLK; + } + else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) + { + *type = AFBC_TILED_HEADERS_BASIC; + } + } + else if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING) + { + *type = AFBC_PADDED; + } + else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) + { + *type = AFBC_WIDEBLK; + } + else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) + { + ALOGE("It is not valid to specify extra-wide block without tiled headers."); + return false; + } + else + { + *type = AFBC; + } + } + return true; +} + + +/* + * Alignment of width/height (in pixels) calculated for worst case (buffer size). + */ +void get_afbc_alignment(const int width, const int height, const AllocType type, + int * const w_aligned, int * const h_aligned) +{ + *h_aligned = GRALLOC_ALIGN(height, AFBC_NORMAL_HEIGHT_ALIGN); + + if (type == UNCOMPRESSED) + { + *w_aligned = width; + *h_aligned = height; + return; + } + else if (type == AFBC_TILED_HEADERS_BASIC) + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN); + *h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN); + } + else if (type == AFBC_TILED_HEADERS_WIDEBLK) + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN); + *h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN); + } + else if (type == AFBC_PADDED) + { + *w_aligned = GRALLOC_ALIGN(width, 64); + } + else if (type == AFBC_WIDEBLK) + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN); + *h_aligned = GRALLOC_ALIGN(height, AFBC_WIDEBLK_HEIGHT_ALIGN); + } + else if (type == AFBC_EXTRAWIDEBLK) + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_EXTRAWIDEBLK_WIDTH_ALIGN); + *h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_EXTRAWIDEBLK_HEIGHT_ALIGN); + } + else + { + *w_aligned = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN); + } +} + + +/* + * Initialise AFBC header based on superblock layout. + */ +void init_afbc(uint8_t *buf, const uint64_t internal_format, + const int w, const int h, const uint64_t usage) +{ + int w_aligned, h_aligned, body_align; + AllocType type; + uint32_t layout; + + /* + * Determine the number of AFBC superblocks/headers. + * Superblock size (in pixels) is constant. 16x16 == 32x8 == 256. + * Arbitrarily use 16x16. + * Body buffer is located at the next aligned address after the AFBC header. + */ + get_alloc_type(internal_format, usage, &type); + get_afbc_alignment(w, h, type, &w_aligned, &h_aligned); + const uint32_t n_headers = w_aligned * h_aligned / (AFBC_PIXELS_PER_BLOCK * AFBC_PIXELS_PER_BLOCK); + int body_offset = n_headers * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &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 */ + { ((uint32_t)body_offset + (1 << 28)), 0x80200040, 0x1004000, 0x20080 } /* Layouts 1, 5 */ + }; + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) + { + memset(headers[0], 0, sizeof(uint32_t) * 4); + } + + /* Map base format to AFBC header layout */ + uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; + switch (base_format) + { + case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888: + /* Note that AFBC isn't supported for RGBX_8888 but the display drivers will treat it as RGBA8888 + * as a workaround for not supporting partial pre-fetch. However this format will be less + * efficient for GPU. */ + case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888: + case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888: + case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565: + case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888: + layout = 0; + break; + + case MALI_GRALLOC_FORMAT_INTERNAL_YV12: + case MALI_GRALLOC_FORMAT_INTERNAL_NV12: + case MALI_GRALLOC_FORMAT_INTERNAL_NV21: + case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT: + case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2: + case MALI_GRALLOC_FORMAT_INTERNAL_Y210: + layout = 1; + break; + } + + ALOGV("Writing AFBC header layout %d for format %" PRIu64, layout, base_format); + + for (uint32_t i = 0; i < n_headers; i++) + { + memcpy(buf, headers[layout], sizeof(headers[layout])); + buf += sizeof(headers[layout]); + } +} + + /* * Computes the strides and size for an RGB buffer * @@ -105,63 +270,46 @@ static void get_rgb_stride_and_size(int width, int height, int pixel_size, int * { int stride; - stride = width * pixel_size; - - /* Align the lines to 64 bytes. - * It's more efficient to write to 64-byte aligned addresses because it's the burst size on the bus */ - stride = GRALLOC_ALIGN(stride, 64); - - if (size != NULL) - { - *size = stride *height; - } - - if (byte_stride != NULL) - { - *byte_stride = stride; - } - - if (pixel_stride != NULL) - { - *pixel_stride = stride / pixel_size; - } - if (type != UNCOMPRESSED) { - int w_aligned; - int h_aligned = GRALLOC_ALIGN(height, AFBC_NORMAL_HEIGHT_ALIGN); int nblocks; - int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + int body_alignment; - if (type == AFBC_TILED_HEADERS_BASIC) - { - w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN); - h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } - else if (type == AFBC_TILED_HEADERS_WIDEBLK) - { - w_aligned = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN); - h_aligned = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } - else if (type == AFBC_PADDED) + stride = width * pixel_size; + stride = GRALLOC_ALIGN(stride, 64); + + if (byte_stride != NULL) { - w_aligned = GRALLOC_ALIGN(width, 64); + *byte_stride = stride; } - else if (type == AFBC_WIDEBLK) + + if (pixel_stride != NULL) { - w_aligned = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN); - h_aligned = GRALLOC_ALIGN(height, AFBC_WIDEBLK_HEIGHT_ALIGN); + *pixel_stride = stride / pixel_size; } - else + + nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + + if (size != NULL) { - w_aligned = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN); + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); + *size = stride * height + header_size; } + } + else + { + stride = width * pixel_size; - stride = w_aligned * pixel_size; + /* Align the lines to 64 bytes. + * It's more efficient to write to 64-byte aligned addresses because it's the burst size on the bus */ stride = GRALLOC_ALIGN(stride, 64); + if (size != NULL) + { + *size = stride *height; + } + if (byte_stride != NULL) { *byte_stride = stride; @@ -171,14 +319,6 @@ static void get_rgb_stride_and_size(int width, int height, int pixel_size, int * { *pixel_stride = stride / pixel_size; } - - nblocks = w_aligned / AFBC_PIXELS_PER_BLOCK * h_aligned / AFBC_PIXELS_PER_BLOCK; - - if (size != NULL) - { - *size = stride *h_aligned + - GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment); - } } } @@ -192,62 +332,23 @@ static void get_rgb_stride_and_size(int width, int height, int pixel_size, int * * byte_stride (out) stride of the buffer in bytes * size (out) size of the buffer in bytes * type if buffer should be allocated for a certain afbc type - * internalHeight (out) The internal height, which may be greater than the public known height. */ static bool get_afbc_yuv420_8bit_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, - size_t *size, AllocType type, int *internalHeight) + size_t *size, AllocType type) { int yuv420_afbc_luma_stride, yuv420_afbc_chroma_stride; - int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - - *internalHeight = height; - -#if MALI_VIDEO_VERSION != 0 - - /* If we have a greater internal height than public we set the internalHeight. This - * implies that cropping will be applied of internal dimensions to fit the public one. - * - * NOTE: This should really only be done when the producer is determined to be VPU decoder. - */ - *internalHeight += AFBC_PIXELS_PER_BLOCK; -#endif - - /* The actual height used in size calculation must include the possible extra row. But - * it must also be AFBC-aligned. Only the extra row-padding should be reported back in - * internalHeight. This as only this row needs to be considered when cropping. */ + int nblocks; if (type == UNCOMPRESSED) { AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV420_8BIT_AFBC!"); return false; } - else if (type == AFBC_TILED_HEADERS_BASIC) - { - width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN); - height = GRALLOC_ALIGN(*internalHeight, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } - else if (type == AFBC_TILED_HEADERS_WIDEBLK) - { - width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN); - height = GRALLOC_ALIGN(*internalHeight, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } else if (type == AFBC_PADDED) { AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV"); return false; } - else if (type == AFBC_WIDEBLK) - { - width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN); - height = GRALLOC_ALIGN(*internalHeight, AFBC_WIDEBLK_HEIGHT_ALIGN); - } - else - { - width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN); - height = GRALLOC_ALIGN(*internalHeight, AFBC_NORMAL_HEIGHT_ALIGN); - } yuv420_afbc_luma_stride = width; yuv420_afbc_chroma_stride = GRALLOC_ALIGN(yuv420_afbc_luma_stride / 2, 16); /* Horizontal downsampling*/ @@ -255,9 +356,10 @@ static bool get_afbc_yuv420_8bit_stride_and_size(int width, int height, int *pix if (size != NULL) { int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); /* Simplification of (height * luma-stride + 2 * (height /2 * chroma_stride) */ - *size = (yuv420_afbc_luma_stride + yuv420_afbc_chroma_stride) * height + - GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment); + *size = (yuv420_afbc_luma_stride + yuv420_afbc_chroma_stride) * height + header_size; } if (byte_stride != NULL) @@ -283,18 +385,16 @@ static bool get_afbc_yuv420_8bit_stride_and_size(int width, int height, int *pix * byte_stride (out) stride of the buffer in bytes * size (out) size of the buffer in bytes * type (in) if buffer should be allocated for a certain afbc type - * internalHeight (out) The internal height, which may be greater than the public known height. * stride_alignment (in) stride aligment value in bytes. */ static bool get_yv12_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, size_t *size, - AllocType type, int *internalHeight, int stride_alignment) + AllocType type, int stride_alignment) { int luma_stride; if (type != UNCOMPRESSED) { - return get_afbc_yuv420_8bit_stride_and_size(width, height, pixel_stride, byte_stride, size, type, - internalHeight); + return get_afbc_yuv420_8bit_stride_and_size(width, height, pixel_stride, byte_stride, size, type); } /* 4:2:0 formats must have buffers with even height and width as the clump size is 2x2 pixels. @@ -376,49 +476,28 @@ static bool get_afbc_yuv422_8bit_stride_and_size(int width, int height, int *pix size_t *size, AllocType type) { int yuv422_afbc_luma_stride; - int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + int nblocks; if (type == UNCOMPRESSED) { AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV422_8BIT_AFBC!"); return false; } - else if (type == AFBC_TILED_HEADERS_BASIC) - { - width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN); - height = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } - else if (type == AFBC_TILED_HEADERS_WIDEBLK) - { - width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN); - height = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } else if (type == AFBC_PADDED) { AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV"); return false; } - else if (type == AFBC_WIDEBLK) - { - width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN); - height = GRALLOC_ALIGN(height, AFBC_WIDEBLK_HEIGHT_ALIGN); - } - else - { - width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN); - height = GRALLOC_ALIGN(height, AFBC_NORMAL_HEIGHT_ALIGN); - } yuv422_afbc_luma_stride = width; if (size != NULL) { int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); /* YUV 4:2:2 luma size equals chroma size */ - *size = yuv422_afbc_luma_stride *height * 2 + - GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment); + *size = yuv422_afbc_luma_stride * height * 2 + header_size; } if (byte_stride != NULL) @@ -558,8 +637,10 @@ static bool get_yuv_y0l2_stride_and_size(int width, int height, int *pixel_strid { int y0l2_byte_stride, y0l2_pixel_stride; - /* 4:2:0 formats must have buffers with even height and width as the clump size is 2x2 pixels. - * Width is take care of by the even stride alignment so just adjust height here for size calculation. */ + /* 4:2:0 formats must have buffers with even height and width + * as the clump size is 2x2 pixels. + * Width is take care of by the even stride alignment so just + * adjust height here for size calculation. */ height = GRALLOC_ALIGN(height, 2); y0l2_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN); @@ -567,7 +648,7 @@ static bool get_yuv_y0l2_stride_and_size(int width, int height, int *pixel_strid if (size != NULL) { - *size = y0l2_byte_stride *height / 2; /* byte stride covers 2 vert pixels */ + *size = y0l2_byte_stride * height / 2; /* byte stride covers 2 vert pixels */ } if (byte_stride != NULL) @@ -637,78 +718,49 @@ static bool get_yuv_y410_stride_and_size(int width, int height, int *pixel_strid * sizes of all planes. * @param type [in] afbc mode that buffer should be allocated with. * - * @param internalHeight [out] Internal buffer height that used by consumer or producer - * * @return true if the calculation was successful; false otherwise (invalid * parameter) */ static bool get_yuv420_10bit_afbc_stride_and_size(int width, int height, int *pixel_stride, int *byte_stride, - size_t *size, AllocType type, int *internalHeight) + size_t *size, AllocType type) { int yuv420_afbc_byte_stride, yuv420_afbc_pixel_stride; - int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + int nblocks; if (width & 3) { return false; } - *internalHeight = height; -#if MALI_VIDEO_VERSION - /* If we have a greater internal height than public we set the internalHeight. This - * implies that cropping will be applied of internal dimensions to fit the public one. */ - *internalHeight += AFBC_PIXELS_PER_BLOCK; -#endif - - /* The actual height used in size calculation must include the possible extra row. But - * it must also be AFBC-aligned. Only the extra row-padding should be reported back in - * internalHeight. This as only this row needs to be considered when cropping. */ if (type == UNCOMPRESSED) { AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV420_10BIT_AFBC!"); return false; } - else if (type == AFBC_TILED_HEADERS_BASIC) - { - width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN); - height = GRALLOC_ALIGN(*internalHeight / 2, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } - else if (type == AFBC_TILED_HEADERS_WIDEBLK) - { - width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN); - height = GRALLOC_ALIGN(*internalHeight / 2, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } else if (type == AFBC_PADDED) { AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV"); return false; } - else if (type == AFBC_WIDEBLK) - { - width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN); - height = GRALLOC_ALIGN(*internalHeight / 2, AFBC_WIDEBLK_HEIGHT_ALIGN); - } - else - { - width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN); - height = GRALLOC_ALIGN(*internalHeight / 2, AFBC_NORMAL_HEIGHT_ALIGN); - } yuv420_afbc_pixel_stride = GRALLOC_ALIGN(width, 16); yuv420_afbc_byte_stride = GRALLOC_ALIGN(width * 4, 16); /* 64-bit packed and horizontally downsampled */ if (size != NULL) { - int nblocks = width / AFBC_PIXELS_PER_BLOCK * (*internalHeight) / AFBC_PIXELS_PER_BLOCK; - *size = yuv420_afbc_byte_stride *height + - GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment); + int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); + + int w_aligned, h_aligned; + get_afbc_alignment(width, height/2, type, &w_aligned, &h_aligned); + + *size = yuv420_afbc_byte_stride * h_aligned + header_size; } if (byte_stride != NULL) { - *byte_stride = yuv420_afbc_pixel_stride; + *byte_stride = yuv420_afbc_byte_stride; } if (pixel_stride != NULL) @@ -739,7 +791,7 @@ static bool get_yuv422_10bit_afbc_stride_and_size(int width, int height, int *pi size_t *size, AllocType type) { int yuv422_afbc_byte_stride, yuv422_afbc_pixel_stride; - int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + int nblocks; if (width & 3) { @@ -751,33 +803,11 @@ static bool get_yuv422_10bit_afbc_stride_and_size(int width, int height, int *pi AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV422_10BIT_AFBC!"); return false; } - else if (type == AFBC_TILED_HEADERS_BASIC) - { - width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN); - height = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } - else if (type == AFBC_TILED_HEADERS_WIDEBLK) - { - width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN); - height = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN); - buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT; - } else if (type == AFBC_PADDED) { AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV"); return false; } - else if (type == AFBC_WIDEBLK) - { - width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN); - height = GRALLOC_ALIGN(height, AFBC_WIDEBLK_HEIGHT_ALIGN); - } - else - { - width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN); - height = GRALLOC_ALIGN(height, AFBC_NORMAL_HEIGHT_ALIGN); - } yuv422_afbc_pixel_stride = GRALLOC_ALIGN(width, 16); yuv422_afbc_byte_stride = GRALLOC_ALIGN(width * 2, 16); @@ -785,9 +815,10 @@ static bool get_yuv422_10bit_afbc_stride_and_size(int width, int height, int *pi if (size != NULL) { int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK; + int header_size = nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; + afbc_buffer_align(type, &header_size); /* YUV 4:2:2 chroma size equals to luma size */ - *size = yuv422_afbc_byte_stride *height * 2 + - GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment); + *size = yuv422_afbc_byte_stride * height * 2 + header_size; } if (byte_stride != NULL) @@ -885,10 +916,14 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de { bool shared = false; uint64_t backing_store_id = 0x0; - AllocType alloc_type = UNCOMPRESSED; + AllocType alloc_type; uint64_t usage; uint32_t i = 0; int err; + /* This flag is to avoid the mutually exclusive modifier bits warning being continuously emitted. + * (see comment below for explanation of warning). + */ + static bool warn_about_mutual_exclusive = true; for (i = 0; i < numDescriptors; i++) { @@ -899,8 +934,12 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de */ bufDescriptor->internalWidth = bufDescriptor->width; bufDescriptor->internalHeight = bufDescriptor->height; - usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage; + /* + * Select optimal internal pixel format based upon + * usage and requested format. + */ + usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage; bufDescriptor->internal_format = mali_gralloc_select_format( bufDescriptor->hal_format, bufDescriptor->format_type, usage, bufDescriptor->width * bufDescriptor->height); @@ -910,40 +949,41 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de bufDescriptor->hal_format, usage); return -EINVAL; } + /* + * 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. + */ + else if (warn_about_mutual_exclusive && + (bufDescriptor->internal_format & 0x0000000100000000ULL) && + (bufDescriptor->internal_format & 0x0000000e00000000ULL)) + { + 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."); + } - /* Determine AFBC type for this format */ - if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) + /* + * Obtain allocation type (uncompressed, AFBC basic, etc...) + */ + if (!get_alloc_type(bufDescriptor->internal_format, usage, &alloc_type)) { - if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) - { - if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) - { - alloc_type = AFBC_TILED_HEADERS_WIDEBLK; - } - else if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) - { - alloc_type = AFBC_TILED_HEADERS_BASIC; - } - else if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK) - { - ALOGE("Unsupported format. Splitblk in tiled header configuration."); - return -EINVAL; - } - } - else if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING) - { - alloc_type = AFBC_PADDED; - } - else if (bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) - { - alloc_type = AFBC_WIDEBLK; - } - else - { - alloc_type = AFBC; - } + return -EINVAL; } + /* + * Resolution of frame (and internal dimensions) might require adjustment + * based upon specific usage and pixel format. + */ + mali_gralloc_adjust_dimensions(bufDescriptor->internal_format, + usage, + alloc_type, + bufDescriptor->width, + bufDescriptor->height, + &bufDescriptor->internalWidth, + &bufDescriptor->internalHeight); + uint64_t base_format = bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; switch (base_format) @@ -951,19 +991,28 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: - get_rgb_stride_and_size(bufDescriptor->width, bufDescriptor->height, 4, &bufDescriptor->pixel_stride, +#if PLATFORM_SDK_VERSION >= 26 + case HAL_PIXEL_FORMAT_RGBA_1010102: +#endif + get_rgb_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, 4, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type); break; case HAL_PIXEL_FORMAT_RGB_888: - get_rgb_stride_and_size(bufDescriptor->width, bufDescriptor->height, 3, &bufDescriptor->pixel_stride, + get_rgb_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, 3, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type); break; case HAL_PIXEL_FORMAT_RGB_565: - get_rgb_stride_and_size(bufDescriptor->width, bufDescriptor->height, 2, &bufDescriptor->pixel_stride, + get_rgb_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, 2, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type); break; +#if PLATFORM_SDK_VERSION >= 26 + case HAL_PIXEL_FORMAT_RGBA_FP16: + get_rgb_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, 8, &bufDescriptor->pixel_stride, + &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type); + break; +#endif case HAL_PIXEL_FORMAT_YCrCb_420_SP: case MALI_GRALLOC_FORMAT_INTERNAL_YV12: @@ -980,9 +1029,8 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de yv12_align = YUV_ANDROID_PLANE_ALIGN; } - if (!get_yv12_stride_and_size(bufDescriptor->width, bufDescriptor->height, &bufDescriptor->pixel_stride, - &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type, - &bufDescriptor->internalHeight, yv12_align)) + if (!get_yv12_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, &bufDescriptor->pixel_stride, + &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type, yv12_align)) { return -EINVAL; } @@ -994,7 +1042,7 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de { /* YUYV 4:2:2 */ if (alloc_type != UNCOMPRESSED || - !get_yuv422_8bit_stride_and_size(bufDescriptor->width, bufDescriptor->height, + !get_yuv422_8bit_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size)) { @@ -1013,7 +1061,7 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de return -EINVAL; } - get_camera_formats_stride_and_size(bufDescriptor->width, bufDescriptor->height, base_format, + get_camera_formats_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, base_format, &bufDescriptor->pixel_stride, &bufDescriptor->size); /* For Raw/Blob formats stride is defined to be either in bytes or pixels per format */ bufDescriptor->byte_stride = bufDescriptor->pixel_stride; @@ -1025,15 +1073,15 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de if (alloc_type != UNCOMPRESSED) { if (!get_yuv420_10bit_afbc_stride_and_size( - bufDescriptor->width, bufDescriptor->height, &bufDescriptor->pixel_stride, - &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type, &bufDescriptor->internalHeight)) + bufDescriptor->internalWidth, bufDescriptor->internalHeight, &bufDescriptor->pixel_stride, + &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type)) { return -EINVAL; } } else { - if (!get_yuv_y0l2_stride_and_size(bufDescriptor->width, bufDescriptor->height, + if (!get_yuv_y0l2_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size)) { @@ -1047,7 +1095,7 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de /* Y-UV 4:2:0 */ if (alloc_type != UNCOMPRESSED || - !get_yuv_pX10_stride_and_size(bufDescriptor->width, bufDescriptor->height, 2, + !get_yuv_pX10_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, 2, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size)) { @@ -1060,7 +1108,7 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de /* Y-UV 4:2:2 */ if (alloc_type != UNCOMPRESSED || - !get_yuv_pX10_stride_and_size(bufDescriptor->width, bufDescriptor->height, 1, + !get_yuv_pX10_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, 1, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size)) { @@ -1074,7 +1122,7 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de /* YUYV 4:2:2 with and without AFBC */ if (alloc_type != UNCOMPRESSED) { - if (!get_yuv422_10bit_afbc_stride_and_size(bufDescriptor->width, bufDescriptor->height, + if (!get_yuv422_10bit_afbc_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type)) { @@ -1083,7 +1131,7 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de } else { - if (!get_yuv_y210_stride_and_size(bufDescriptor->width, bufDescriptor->height, + if (!get_yuv_y210_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size)) { @@ -1097,7 +1145,7 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de /* AVYU 2-10-10-10 */ if (alloc_type != UNCOMPRESSED || - !get_yuv_y410_stride_and_size(bufDescriptor->width, bufDescriptor->height, &bufDescriptor->pixel_stride, + !get_yuv_y410_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size)) { return -EINVAL; @@ -1112,7 +1160,7 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de /* We only support compressed for this format right now. * Below will fail in case format is uncompressed. */ - if (!get_afbc_yuv422_8bit_stride_and_size(bufDescriptor->width, bufDescriptor->height, + if (!get_afbc_yuv422_8bit_stride_and_size(bufDescriptor->internalWidth, bufDescriptor->internalHeight, &bufDescriptor->pixel_stride, &bufDescriptor->byte_stride, &bufDescriptor->size, alloc_type)) { @@ -1128,6 +1176,31 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de default: return -EINVAL; } + + /* + * 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->internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) + { + if (bufDescriptor->internal_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; + } } { diff --git a/gralloc/src/mali_gralloc_bufferallocation.h b/gralloc/src/mali_gralloc_bufferallocation.h index 5148252..5c7c75e 100644 --- a/gralloc/src/mali_gralloc_bufferallocation.h +++ b/gralloc/src/mali_gralloc_bufferallocation.h @@ -28,4 +28,9 @@ int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_de uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend); int mali_gralloc_buffer_free(buffer_handle_t pHandle); +void get_afbc_alignment(const int width, const int height, const AllocType type, + int * const w_aligned, int * const h_aligned); + +void init_afbc(uint8_t *buf, uint64_t internal_format, int w, int h, uint64_t usage); + #endif /* MALI_GRALLOC_BUFFERALLOCATION_H_ */ diff --git a/gralloc/src/mali_gralloc_bufferdescriptor.cpp b/gralloc/src/mali_gralloc_bufferdescriptor.cpp index 11e3cb3..41e88fe 100644 --- a/gralloc/src/mali_gralloc_bufferdescriptor.cpp +++ b/gralloc/src/mali_gralloc_bufferdescriptor.cpp @@ -48,6 +48,16 @@ int mali_gralloc_create_descriptor_internal(gralloc1_buffer_descriptor_t *outDes return GRALLOC1_ERROR_BAD_DESCRIPTOR; } + /* + * 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->layer_count = 1; + *outDescriptor = (gralloc1_buffer_descriptor_t)buffer_descriptor; return GRALLOC1_ERROR_NONE; } @@ -181,6 +191,33 @@ int mali_gralloc_get_producer_usage_internal(buffer_handle_t buffer, uint64_t *o return GRALLOC1_ERROR_NONE; } +#if PLATFORM_SDK_VERSION >= 26 +int mali_gralloc_set_layer_count_internal(gralloc1_buffer_descriptor_t descriptor, uint32_t layerCount) +{ + if (!descriptor) + { + return GRALLOC1_ERROR_BAD_DESCRIPTOR; + } + + buffer_descriptor_t *buffer_descriptor = (buffer_descriptor_t *)descriptor; + 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; + } + + 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) { diff --git a/gralloc/src/mali_gralloc_bufferdescriptor.h b/gralloc/src/mali_gralloc_bufferdescriptor.h index 6783be0..7bb8a6b 100644 --- a/gralloc/src/mali_gralloc_bufferdescriptor.h +++ b/gralloc/src/mali_gralloc_bufferdescriptor.h @@ -39,6 +39,7 @@ typedef struct buffer_descriptor uint64_t producer_usage; uint64_t consumer_usage; uint64_t hal_format; + uint32_t layer_count; mali_gralloc_format_type format_type; size_t size; @@ -62,6 +63,10 @@ int mali_gralloc_get_consumer_usage_internal(buffer_handle_t buffer, uint64_t *o 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); diff --git a/gralloc/src/mali_gralloc_debug.cpp b/gralloc/src/mali_gralloc_debug.cpp index d4473ed..3fb0858 100644 --- a/gralloc/src/mali_gralloc_debug.cpp +++ b/gralloc/src/mali_gralloc_debug.cpp @@ -58,7 +58,7 @@ void mali_gralloc_dump_buffer_erase(private_handle_t *handle) } pthread_mutex_lock(&dump_lock); - dump_buffers.erase(std::remove(dump_buffers.begin(), dump_buffers.end(), handle)); + dump_buffers.erase(std::remove(dump_buffers.begin(), dump_buffers.end(), handle), dump_buffers.end()); pthread_mutex_unlock(&dump_lock); } diff --git a/gralloc/src/mali_gralloc_formats.cpp b/gralloc/src/mali_gralloc_formats.cpp index 0ab39d6..62b33b6 100644 --- a/gralloc/src/mali_gralloc_formats.cpp +++ b/gralloc/src/mali_gralloc_formats.cpp @@ -19,7 +19,7 @@ #include <string.h> #include <dlfcn.h> #include <inttypes.h> -#include <cutils/log.h> +#include <log/log.h> #if GRALLOC_USE_GRALLOC1_API == 1 #include <hardware/gralloc1.h> @@ -29,24 +29,33 @@ #include "mali_gralloc_module.h" #include "gralloc_priv.h" +#include "mali_gralloc_bufferallocation.h" static mali_gralloc_format_caps dpu_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" +/* VPU library path is the same for 32-bit and 64-bit. */ +#define MALI_GRALLOC_VPU_LIBRARY_PATH "/system/lib/" #if defined(__LP64__) #define MALI_GRALLOC_GPU_LIBRARY_PATH1 "/vendor/lib64/egl/" #define MALI_GRALLOC_GPU_LIBRARY_PATH2 "/system/lib64/egl/" +#define MALI_GRALLOC_DPU_LIBRARY_PATH "/vendor/lib64/hw/" #else #define MALI_GRALLOC_GPU_LIBRARY_PATH1 "/vendor/lib/egl/" #define MALI_GRALLOC_GPU_LIBRARY_PATH2 "/system/lib/egl/" +#define MALI_GRALLOC_DPU_LIBRARY_PATH "/vendor/lib/hw/" #endif +#define GRALLOC_AFBC_MIN_SIZE 75 -static bool get_block_capabilities(bool hal_module, const char *name, mali_gralloc_format_caps *block_caps) +static bool get_block_capabilities(const char *name, mali_gralloc_format_caps *block_caps) { void *dso_handle = NULL; bool rval = false; @@ -54,22 +63,7 @@ static bool get_block_capabilities(bool hal_module, const char *name, mali_grall /* Look for MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR symbol in user-space drivers * to determine hw format capabilities. */ - if (!hal_module) - { - dso_handle = dlopen(name, RTLD_LAZY); - } - else - { - /* libhardware does some heuristics to find hal modules - * and then stores the dso handle internally. Use this. - */ - const struct hw_module_t *module = { NULL }; - - if (hw_get_module(name, &module) >= 0) - { - dso_handle = module->dso; - } - } + dso_handle = dlopen(name, RTLD_LAZY); if (dso_handle) { @@ -80,11 +74,7 @@ static bool get_block_capabilities(bool hal_module, const char *name, mali_grall memcpy((void *)block_caps, sym, sizeof(mali_gralloc_format_caps)); rval = true; } - - if (!hal_module) - { - dlclose(dso_handle); - } + dlclose(dso_handle); } return rval; @@ -123,6 +113,9 @@ static bool is_afbc_supported(int req_format_mapped) case MALI_GRALLOC_FORMAT_INTERNAL_P010: case MALI_GRALLOC_FORMAT_INTERNAL_P210: case MALI_GRALLOC_FORMAT_INTERNAL_Y410: +#if PLATFORM_SDK_VERSION >= 26 + case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616: +#endif case HAL_PIXEL_FORMAT_YCbCr_422_I: rval = false; break; @@ -144,6 +137,7 @@ static bool is_android_yuv_format(int req_format) case HAL_PIXEL_FORMAT_YCbCr_422_888: case HAL_PIXEL_FORMAT_YCbCr_444_888: case MALI_GRALLOC_FORMAT_INTERNAL_NV12: + case MALI_GRALLOC_FORMAT_INTERNAL_NV21: case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: rval = true; break; @@ -152,12 +146,54 @@ static bool is_android_yuv_format(int req_format) return rval; } -static bool is_afbc_allowed(int buffer_size) +static bool is_afbc_format(uint64_t internal_format) { + return (internal_format & MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK) != 0; +} + +static void apply_gpu_producer_limitations(int req_format, uint64_t *producer_runtime_mask) +{ + if (is_android_yuv_format(req_format)) + { + if (gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE) + { + *producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; + } + else + { + /* All GPUs that can write YUV AFBC can only do it in 16x16, optionally with tiled */ + *producer_runtime_mask &= + ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK); + } + } +} + +static void apply_video_consumer_limitations(int req_format, uint64_t *consumer_runtime_mask) +{ + if (is_android_yuv_format(req_format)) + { + if (vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD) + { + *consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; + } + } + else + { + *consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; + } +} + +/* + * NOTE: this code assumes that all layers that don't have AFBC disabled are pre-rotated. + * */ +static void apply_display_consumer_limitations(int req_format, int buffer_size, uint64_t *display_consumer_runtime_mask) +{ + /* Disable AFBC based on buffer dimensions */ bool afbc_allowed = false; (void)buffer_size; +#if MALI_DISPLAY_VERSION == 550 || MALI_DISPLAY_VERSION == 650 #if GRALLOC_DISP_W != 0 && GRALLOC_DISP_H != 0 afbc_allowed = ((buffer_size * 100) / (GRALLOC_DISP_W * GRALLOC_DISP_H)) >= GRALLOC_AFBC_MIN_SIZE; @@ -166,13 +202,31 @@ static bool is_afbc_allowed(int buffer_size) afbc_allowed = true; #endif +#else + /* For cetus, always allow AFBC */ + afbc_allowed = true; +#endif - return afbc_allowed; -} - -static bool is_afbc_format(uint64_t internal_format) -{ - return (internal_format & MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK) != 0; + if (!afbc_allowed) + { + *display_consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; + } + else if (is_android_yuv_format(req_format)) + { + /* YUV formats don't support split or wide block. */ + *display_consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; + *display_consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK; + } + else + { + /* Some RGB formats don't support split block. */ + switch(req_format) + { + case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565: + *display_consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; + break; + } + } } static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type producer, @@ -196,22 +250,51 @@ static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type gpu_mask &= consumer_runtime_mask; dpu_mask &= consumer_runtime_mask; + if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC && + dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) + { + internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC; + } + + /* For pre-Cetus displays split block will be selected without wide block + * as this is preferred. For Cetus, wide block and split block will be enabled + * together. When in future, wide block is disabled for layers that may + * not be pre-rotated, split block should also be disabled. */ if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK && dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK) { internal_format |= MALI_GRALLOC_INTFMT_AFBC_SPLITBLK; } - else if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC && - dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) + + if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK && + dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK) { - internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC; + internal_format |= MALI_GRALLOC_INTFMT_AFBC_WIDEBLK; + } - if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS && - dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) - { - internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; - } + if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS && + dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) + { + internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; + } + +#if PLATFORM_SDK_VERSION >= 26 + /* + * Ensure requested format is supported by producer/consumer. + * GPU composition must always be supported in case of fallback from DPU. + * It is therefore not necessary to enforce DPU support. + */ + if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 && + (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0) + { + internal_format = 0; } + else if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 && + (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0) + { + internal_format = 0; + } +#endif } else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL) { @@ -227,6 +310,20 @@ static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type { internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; } + +#if PLATFORM_SDK_VERSION >= 26 + /* Reject unsupported formats */ + if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 && + (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0) + { + internal_format = 0; + } + else if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 && + (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0) + { + internal_format = 0; + } +#endif } else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER) { @@ -246,6 +343,22 @@ static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; } } + +#if PLATFORM_SDK_VERSION >= 26 + /* Reject unsupported formats */ + if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 && + ((gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0 || + (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0)) + { + internal_format = 0; + } + else if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 && + ((gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0 || + (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0)) + { + internal_format = 0; + } +#endif } } else if (producer == MALI_GRALLOC_PRODUCER_VIDEO_DECODER && @@ -274,6 +387,26 @@ static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; } } + +#if PLATFORM_SDK_VERSION >= 26 + /* + * Ensure requested format is supported by producer/consumer. + * GPU composition must always be supported in case of fallback from DPU. + * It is therefore not necessary to enforce DPU support. + */ + if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 && + ((vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0 || + (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0)) + { + internal_format = 0; + } + else if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 && + ((vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0 || + (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0 )) + { + internal_format = 0; + } +#endif } else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL) { @@ -293,10 +426,40 @@ static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; } } + +#if PLATFORM_SDK_VERSION >= 26 + /* Reject unsupported formats */ + if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 && + ((gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0 || + (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0)) + { + internal_format = 0; + } + else if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 && + ((gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0 || + (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0)) + { + internal_format = 0; + } +#endif } else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER) { /* Fall-through. To be decided.*/ + +#if PLATFORM_SDK_VERSION >= 26 + /* Reject unsupported formats */ + if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 && + (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0) + { + internal_format = 0; + } + else if (req_format == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616 && + (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0) + { + internal_format = 0; + } +#endif } } else if (producer == MALI_GRALLOC_PRODUCER_CAMERA && @@ -315,6 +478,25 @@ static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type /* Fall-through. To be decided.*/ } } + else if (producer == MALI_GRALLOC_PRODUCER_DISPLAY_AEU && + consumer == MALI_GRALLOC_CONSUMER_DISPLAY_EXCL && + dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) + { + dpu_mask &= producer_runtime_mask; + dpu_mask &= consumer_runtime_mask; + + if (dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) + { + internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC; + if (dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) + { + internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; + } + } + } + /* For MALI_GRALLOC_PRODUCER_DISPLAY or MALI_GRALLOC_PRODUCER_GPU_OR_DISPLAY + * the requested format without AFBC is used, so no extra flags need to be set. + */ return internal_format; } @@ -337,15 +519,6 @@ static uint64_t decode_internal_format(uint64_t req_format, mali_gralloc_format_ goto out; } - me_mask = internal_format & MALI_GRALLOC_INTFMT_ME_EXT_MASK; - - if (me_mask > 0 && ((me_mask - 1) & me_mask) != 0) - { - ALOGE("Internal format contains multiple mutually exclusive modifier bits: %" PRIx64, internal_format); - internal_format = 0; - goto out; - } - base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; /* Even though private format allocations are intended to be for specific @@ -362,6 +535,10 @@ static uint64_t decode_internal_format(uint64_t req_format, mali_gralloc_format_ case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888: case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565: case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888: +#if PLATFORM_SDK_VERSION >= 26 + case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102: + case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616: +#endif case MALI_GRALLOC_FORMAT_INTERNAL_YV12: case MALI_GRALLOC_FORMAT_INTERNAL_Y8: case MALI_GRALLOC_FORMAT_INTERNAL_Y16: @@ -377,6 +554,8 @@ static uint64_t decode_internal_format(uint64_t req_format, mali_gralloc_format_ case MALI_GRALLOC_FORMAT_INTERNAL_P210: case MALI_GRALLOC_FORMAT_INTERNAL_Y210: case MALI_GRALLOC_FORMAT_INTERNAL_Y410: + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: if (mapped_base_format != base_format) { internal_format = (internal_format & MALI_GRALLOC_INTFMT_EXT_MASK) | mapped_base_format; @@ -394,8 +573,7 @@ out: return internal_format; } -static bool determine_producer(mali_gralloc_producer_type *producer, uint64_t *producer_runtime_mask, int req_format, - int usage) +static bool determine_producer(mali_gralloc_producer_type *producer, int usage) { bool rval = true; @@ -405,23 +583,17 @@ static bool determine_producer(mali_gralloc_producer_type *producer, uint64_t *p if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { rval = false; + *producer = MALI_GRALLOC_PRODUCER_CPU; + } + /* This is a specific case where GRALLOC_USAGE_HW_COMPOSER can indicate display as a producer. + * This is the case because video encoder is assumed to be the only consumer. */ + else if ((usage & (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) == + (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) + { + *producer = MALI_GRALLOC_PRODUCER_GPU_OR_DISPLAY; } else if (usage & GRALLOC_USAGE_HW_RENDER) { - if (is_android_yuv_format(req_format)) - { - if (gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE) - { - *producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; - } - else - { - /* All GPUs that can write YUV AFBC can only do it in 16x16, optionally with tiled */ - *producer_runtime_mask &= - ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK); - } - } - *producer = MALI_GRALLOC_PRODUCER_GPU; } else if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) @@ -436,12 +608,19 @@ static bool determine_producer(mali_gralloc_producer_type *producer, uint64_t *p { *producer = MALI_GRALLOC_PRODUCER_VIDEO_DECODER; } - + else if ((usage & (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) == + (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) + { + *producer = MALI_GRALLOC_PRODUCER_DISPLAY; + } + else if (usage == GRALLOC_USAGE_HW_COMPOSER) + { + *producer = MALI_GRALLOC_PRODUCER_DISPLAY_AEU; + } return rval; } -static bool determine_consumer(mali_gralloc_consumer_type *consumer, uint64_t *consumer_runtime_mask, int req_format, - int usage) +static bool determine_consumer(mali_gralloc_consumer_type *consumer, int usage) { bool rval = true; @@ -451,6 +630,7 @@ static bool determine_consumer(mali_gralloc_consumer_type *consumer, uint64_t *c if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { rval = false; + *consumer = MALI_GRALLOC_CONSUMER_CPU; } /* When usage explicitly targets a consumer, as it does with GRALLOC_USAGE_HW_FB, * we pick DPU even if there are no runtime capabilities present. @@ -461,15 +641,6 @@ static bool determine_consumer(mali_gralloc_consumer_type *consumer, uint64_t *c } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) { - if (is_android_yuv_format(req_format)) - { - if (vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD) - *consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; - } - else - { - *consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; - } *consumer = MALI_GRALLOC_CONSUMER_VIDEO_ENCODER; } /* GRALLOC_USAGE_HW_COMPOSER is by default applied by SurfaceFlinger so we can't exclusively rely on it @@ -486,6 +657,10 @@ static bool determine_consumer(mali_gralloc_consumer_type *consumer, uint64_t *c { *consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL; } + else if (usage == GRALLOC_USAGE_HW_COMPOSER) + { + *consumer = MALI_GRALLOC_CONSUMER_DISPLAY_EXCL; + } return rval; } @@ -513,8 +688,9 @@ static void determine_format_capabilities() memset((void *)&cam_runtime_caps, 0, sizeof(cam_runtime_caps)); /* Determine DPU format capabilities */ - if (!get_block_capabilities(true, "hwcomposer", &dpu_runtime_caps)) + if (!get_block_capabilities(MALI_GRALLOC_DPU_LIBRARY_PATH MALI_GRALLOC_DPU_LIB_NAME, &dpu_runtime_caps)) { + dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE; #if MALI_DISPLAY_VERSION >= 500 dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; @@ -523,16 +699,25 @@ static void determine_format_capabilities() dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; #endif #endif +#if MALI_DISPLAY_VERSION == 71 + /* Cetus adds support for wide block and tiled headers. */ + 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_SPLITBLK; + dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK; + dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS; + dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK_YUV_DISABLE; +#endif } /* Determine GPU format capabilities */ if (access(MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, R_OK) == 0) { - get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps); + 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(false, MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps); + 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) @@ -568,18 +753,21 @@ static void determine_format_capabilities() #endif /* MALI_GPU_SUPPORT_AFBC_BASIC == 1 */ } + if (!get_block_capabilities(MALI_GRALLOC_VPU_LIBRARY_PATH MALI_GRALLOC_VPU_LIB_NAME, &vpu_runtime_caps)) + { /* Determine VPU format capabilities */ #if MALI_VIDEO_VERSION == 500 || MALI_VIDEO_VERSION == 550 - 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_NOREAD; + 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_NOREAD; #endif #if MALI_VIDEO_VERSION == 61 - 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_TILED_HEADERS; + 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_TILED_HEADERS; #endif + } /* Build specific capability changes */ #if GRALLOC_ARM_NO_EXTERNAL_AFBC == 1 @@ -602,6 +790,75 @@ already_init: ALOGV("CAM format capabilities 0x%" PRIx64, cam_runtime_caps.caps_mask); } + +bool mali_gralloc_adjust_dimensions(const uint64_t internal_format, + const int usage, + const AllocType type, + const uint32_t width, + const uint32_t height, + int * const internal_width, + int * const internal_height) +{ + bool rval = true; + mali_gralloc_consumer_type consumer; + mali_gralloc_producer_type producer; + + if (!runtime_caps_read) + { + /* + * It is better to initialize these when needed because + * not all processes allocates memory. + */ + determine_format_capabilities(); + } + + /* Determine producer/consumer */ + determine_producer(&producer, usage); + determine_consumer(&consumer, usage); + + /* + * Default: define internal dimensions the same as public. + */ + *internal_width = width; + *internal_height = height; + + /* + * Pad video buffer height with AFBC superblock size. + * Cropping will be applied to internal dimensions to fit the public size. + */ + if (producer == MALI_GRALLOC_PRODUCER_VIDEO_DECODER) + { + if (internal_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) + { + switch (internal_format & MALI_GRALLOC_INTFMT_FMT_MASK) + { + /* 8-bit/10-bit YUV420 formats. */ + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case MALI_GRALLOC_FORMAT_INTERNAL_YV12: + case MALI_GRALLOC_FORMAT_INTERNAL_NV12: + case MALI_GRALLOC_FORMAT_INTERNAL_NV21: + case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2: + *internal_height += 16; + break; + + default: + break; + } + } + } + + get_afbc_alignment(*internal_width, *internal_height, type, + internal_width, internal_height); + +out: + ALOGV("%s: internal_format=0x%" PRIx64 " usage=0x%08x" + " width=%u, height=%u, internal_width=%d, internal_height=%d", + __FUNCTION__, internal_format, usage, width, height, *internal_width, *internal_height); + + return rval; +} + + uint64_t mali_gralloc_select_format(uint64_t req_format, mali_gralloc_format_type type, uint64_t usage, int buffer_size) { uint64_t internal_format = 0; @@ -631,8 +888,8 @@ uint64_t mali_gralloc_select_format(uint64_t req_format, mali_gralloc_format_typ req_format_mapped = map_flex_formats(req_format); /* Determine producer/consumer */ - if (!determine_producer(&producer, &producer_runtime_mask, req_format, usage) || - !determine_consumer(&consumer, &consumer_runtime_mask, req_format, usage)) + if (!determine_producer(&producer, usage) || + !determine_consumer(&consumer, usage)) { /* Failing to determine producer/consumer usually means * client has requested sw rendering. @@ -659,14 +916,28 @@ uint64_t mali_gralloc_select_format(uint64_t req_format, mali_gralloc_format_typ producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; } - /* Disable AFBC based on buffer dimensions */ - else if (!is_afbc_allowed(buffer_size)) + else if (!is_afbc_supported(req_format_mapped)) { producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; } - else if (!is_afbc_supported(req_format_mapped)) + else { - producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; + /* Check producer limitations and modify runtime mask.*/ + if (producer == MALI_GRALLOC_PRODUCER_GPU || producer == MALI_GRALLOC_PRODUCER_GPU_OR_DISPLAY) + { + apply_gpu_producer_limitations(req_format, &producer_runtime_mask); + } + + /* Check consumer limitations and modify runtime mask. */ + if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER) + { + apply_video_consumer_limitations(req_format, &consumer_runtime_mask); + } + else if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY || + consumer == MALI_GRALLOC_CONSUMER_DISPLAY_EXCL) + { + apply_display_consumer_limitations(req_format, buffer_size, &consumer_runtime_mask); + } } /* Automatically select format in case producer/consumer identified */ @@ -681,17 +952,23 @@ out: return internal_format; } +/* This is used by the unit tests to get the capabilities for each IP. */ extern "C" { -void mali_gralloc_get_gpu_caps(struct mali_gralloc_format_caps *gpu_caps) +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) { - if (gpu_caps != NULL) { if (!runtime_caps_read) { determine_format_capabilities(); } - memcpy(gpu_caps, (void *)&gpu_runtime_caps, sizeof(struct mali_gralloc_format_caps)); + 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/gralloc/src/mali_gralloc_formats.h b/gralloc/src/mali_gralloc_formats.h index 928dc2a..77c1494 100644 --- a/gralloc/src/mali_gralloc_formats.h +++ b/gralloc/src/mali_gralloc_formats.h @@ -20,6 +20,7 @@ #define MALI_GRALLOC_FORMATS_H_ #include <system/graphics.h> +#include <log/log.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. @@ -30,10 +31,8 @@ typedef uint64_t mali_gralloc_internal_format; /* Internal format masks */ -#define MALI_GRALLOC_INTFMT_FMT_MASK 0x00000000ffffffffULL -#define MALI_GRALLOC_INTFMT_EXT_MASK 0xffffffff00000000ULL -#define MALI_GRALLOC_INTFMT_ME_EXT_MASK 0x0000ffff00000000ULL -#define MALI_GRALLOC_INTFMT_REG_EXT_MASK 0xffff000000000000ULL +#define MALI_GRALLOC_INTFMT_FMT_MASK 0x00000000ffffffffULL +#define MALI_GRALLOC_INTFMT_EXT_MASK 0xffffffff00000000ULL /* Internal base formats */ @@ -56,6 +55,10 @@ 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, + 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, @@ -98,30 +101,28 @@ typedef enum } mali_gralloc_pixel_format; /* Format Modifier Bits Locations */ -#define MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START 32 -#define MALI_GRALLOC_INTFMT_EXTENSION_BIT_START (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 16) +#define MALI_GRALLOC_INTFMT_EXTENSION_BIT_START 32 -/* Mutually Exclusive Modifier Bits */ +/* Modifier Bits - these are now independent. */ /* This format will use AFBC */ -#define MALI_GRALLOC_INTFMT_AFBC_BASIC (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 0)) +#define MALI_GRALLOC_INTFMT_AFBC_BASIC (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 0)) /* This format uses AFBC split block mode */ -#define MALI_GRALLOC_INTFMT_AFBC_SPLITBLK (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 1)) - -#define MALI_GRALLOC_INTFMT_UNUSED (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 2)) +#define MALI_GRALLOC_INTFMT_AFBC_SPLITBLK (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 1)) /* This format uses AFBC wide block mode */ -#define MALI_GRALLOC_INTFMT_AFBC_WIDEBLK (1ULL << (MALI_GRALLOC_INTFMT_ME_EXTENSION_BIT_START + 3)) +#define MALI_GRALLOC_INTFMT_AFBC_WIDEBLK (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 2)) + +/* This format uses AFBC tiled headers */ +#define MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 3)) -/* Regular Modifier Bits */ -#define MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 0)) +/* This format uses AFBC extra wide superblocks. */ +#define MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK (1ULL << (MALI_GRALLOC_INTFMT_EXTENSION_BIT_START + 4)) -/* This mask should be used to check or clear support for AFBC for an internal format - * These bits are mutually exclusive so this mask should not be used to enable support +/* 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 | MALI_GRALLOC_INTFMT_AFBC_SPLITBLK | MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)) +#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. @@ -130,8 +131,7 @@ typedef enum * Packing: * * Bits 15-0: mali_gralloc_pixel_format format - * Bits 23-16: mutually exclusive modifier bits - * Bits 31-24: regular modifier bits + * Bits 31-16: modifier bits */ static inline int mali_gralloc_format_wrapper(int format, int modifiers) { @@ -157,14 +157,19 @@ static inline int mali_gralloc_format_wrapper(int format, int modifiers) format = MALI_GRALLOC_FORMAT_INTERNAL_Y16_WRAP; } + if (format & ~0xffff) + { + format &= 0xffff; + ALOGE("Format is too large for private format wrapping"); + } + return (modifiers | format); } static inline uint64_t mali_gralloc_format_unwrap(int x) { - uint64_t internal_format = (uint64_t)(((((uint64_t)(x)) & 0xff000000) << 24) | // Regular modifier bits - ((((uint64_t)(x)) & 0x00ff0000) << 16) | // Mutually exclusive modifier bits - (((uint64_t)(x)) & 0x0000ffff)); // Private format + uint64_t internal_format = (uint64_t)(((((uint64_t)(x)) & 0xffff0000) << 16) | // Modifier bits + (((uint64_t)(x)) & 0x0000ffff)); // Private format uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; uint64_t modifiers = internal_format & MALI_GRALLOC_INTFMT_EXT_MASK; @@ -175,7 +180,7 @@ static inline uint64_t mali_gralloc_format_unwrap(int x) } else if (base_format == MALI_GRALLOC_FORMAT_INTERNAL_Y8_WRAP) { - base_format = MALI_GRALLOC_FORMAT_INTERNAL_Y8; + base_format = MALI_GRALLOC_FORMAT_INTERNAL_Y8; } else if (base_format == MALI_GRALLOC_FORMAT_INTERNAL_Y16_WRAP) { @@ -185,29 +190,64 @@ static inline uint64_t mali_gralloc_format_unwrap(int x) return (modifiers | base_format); } + #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 >> 16))) + #define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_SPLITBLK(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> 16))) + (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> 16 | \ + (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))) + #define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDEBLK(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16))) + (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16 | \ + (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))) + +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_WIDE_SPLIT(x) \ + (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16 | \ + (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> 16) | \ + (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))) + #define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_BASIC(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 24) | \ + (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 16) | \ (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16))) + #define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_WIDE(x) \ - (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 24) | \ - (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16))) + (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 16 | \ + (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16) | \ + (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))) + +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_SPLIT(x) \ + (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 16 | \ + (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> 16) | \ + (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))) + +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_TILED_HEADERS_WIDE_SPLIT(x) \ + (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 16 | \ + (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK >> 16) | \ + (MALI_GRALLOC_INTFMT_AFBC_SPLITBLK >> 16) | \ + (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16)))) + +#define GRALLOC_PRIVATE_FORMAT_WRAPPER_AFBC_EXTRAWIDEBLK(x) \ + (mali_gralloc_format_wrapper(x, (MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS >> 16 | \ + (MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK >> 16 | \ + (MALI_GRALLOC_INTFMT_AFBC_BASIC >> 16))))) + #define GRALLOC_PRIVATE_FORMAT_UNWRAP(x) mali_gralloc_format_unwrap(x) /* IP block capability masks */ -#define MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT ((uint64_t)(1 << 0)) -#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_WIDEBLK_YUV_DISABLE ((uint64_t)(1 << 4)) -#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD ((uint64_t)(1 << 5)) -#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE ((uint64_t)(1 << 6)) -#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS ((uint64_t)(1 << 7)) +#define MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT ((uint64_t)1 << 0) +#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_WIDEBLK_YUV_DISABLE ((uint64_t)1 << 4) +#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD ((uint64_t)1 << 5) +#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE ((uint64_t)1 << 6) +#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS ((uint64_t)1 << 7) +#define MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_EXTRAWIDEBLK ((uint64_t)1 << 8) + +#define MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102 ((uint64_t)1 << 32) +#define MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616 ((uint64_t)1 << 33) #define MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK \ ((uint64_t)(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | \ @@ -225,13 +265,32 @@ typedef struct mali_gralloc_format_caps mali_gralloc_format_caps; /* Producer and Consumer definitions */ typedef enum { + /* + * CPU producer demands strict adherence to the requested + * pixel format and overrides any other possible consumer + * optimisations. + */ + MALI_GRALLOC_PRODUCER_CPU, MALI_GRALLOC_PRODUCER_VIDEO_DECODER, MALI_GRALLOC_PRODUCER_GPU, MALI_GRALLOC_PRODUCER_CAMERA, + MALI_GRALLOC_PRODUCER_DISPLAY, + MALI_GRALLOC_PRODUCER_GPU_OR_DISPLAY, + /* This is used for the AFBC Encoder Unit in the display, which + * is used to convert non-AFBC layers to AFBC for rotation. + * The consumer is always the display. + */ + MALI_GRALLOC_PRODUCER_DISPLAY_AEU, } mali_gralloc_producer_type; typedef enum { + /* + * CPU consumer demands strict adherence to the requested + * pixel format and overrides any other possible consumer + * optimisations. + */ + MALI_GRALLOC_CONSUMER_CPU, /* For surface composition in SurfaceFlinger a producer * will not know what consumer will process a buffer. @@ -247,10 +306,41 @@ typedef enum * For example, HDLCD/CLCD would be such a dpu. */ MALI_GRALLOC_CONSUMER_GPU_EXCL, + /* Used for buffers produced by the AEU. */ + MALI_GRALLOC_CONSUMER_DISPLAY_EXCL } mali_gralloc_consumer_type; /* Internal prototypes */ #if defined(GRALLOC_LIBRARY_BUILD) + +/* + * Type of allocation + */ +enum AllocType +{ + UNCOMPRESSED = 0, + AFBC, + /* AFBC_WIDEBLK mode requires buffer to have 32 * 16 pixels alignment */ + AFBC_WIDEBLK, + /* An AFBC buffer with additional padding to ensure a 64-byte alignment + * for each row of blocks in the header */ + AFBC_PADDED, + /* AFBC_TILED_HEADERS_AFBC_BASIC mode requires buffer to have 128*128 pixels alignment(16x16 superblocks) */ + AFBC_TILED_HEADERS_BASIC, + /* AFBC_TILED_HEADERS_AFBC_WIDEBLK mode requires buffer to have 256*64 pixels alignment(32x8 superblocks) */ + AFBC_TILED_HEADERS_WIDEBLK, + /* AFBC_EXTRAWIDEBLK mode requires buffer to have 512*32 pixels alignment (64x4 superblocks) as tiled headers is mandatory. */ + AFBC_EXTRAWIDEBLK, +}; + +bool mali_gralloc_adjust_dimensions(uint64_t internal_format, + int usage, + AllocType type, + uint32_t width, + uint32_t height, + int * internal_width, + int * internal_height); + uint64_t mali_gralloc_select_format(uint64_t req_format, mali_gralloc_format_type type, uint64_t usage, int buffer_size); #endif @@ -259,8 +349,10 @@ uint64_t mali_gralloc_select_format(uint64_t req_format, mali_gralloc_format_typ extern "C" { #endif -void mali_gralloc_get_gpu_caps(struct mali_gralloc_format_caps *gpu_caps); - +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/gralloc/src/mali_gralloc_ion.cpp b/gralloc/src/mali_gralloc_ion.cpp index 6838133..5604973 100644 --- a/gralloc/src/mali_gralloc_ion.cpp +++ b/gralloc/src/mali_gralloc_ion.cpp @@ -20,12 +20,17 @@ #include <errno.h> #include <inttypes.h> #include <pthread.h> +#include <stdlib.h> +#include <limits.h> -#include <cutils/log.h> +#include <log/log.h> #include <cutils/atomic.h> -#include <linux/ion.h> #include <ion/ion.h> +#if GRALLOC_USE_LEGACY_ION_API == 0 +#include <ion/ion_4.12.h> +#include <vector> +#endif #include <sys/ioctl.h> #include <hardware/hardware.h> @@ -44,230 +49,280 @@ #include "mali_gralloc_formats.h" #include "mali_gralloc_usages.h" #include "mali_gralloc_bufferdescriptor.h" +#include "mali_gralloc_bufferallocation.h" + +#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); + +/* Must be removed once ION_HEAP_SECURE_MASK no longer signals an enabled secure heap. */ +#if GRALLOC_ENABLE_ION_SECURE_HEAP && defined(ION_HEAP_SECURE_MASK) +static const enum ion_heap_type ION_HEAP_TYPE_SECURE = (enum ion_heap_type)(((unsigned int)ION_HEAP_TYPE_CUSTOM) + 1); +#endif static void mali_gralloc_ion_free_internal(buffer_handle_t *pHandle, uint32_t num_hnds); +static void set_ion_flags(enum ion_heap_type heap_type, uint64_t usage, + unsigned int *priv_heap_flag, unsigned int *ion_flags); -static void init_afbc(uint8_t *buf, uint64_t internal_format, int w, int h) +/* + * Identifies a heap and retrieves file descriptor from ION for allocation + * + * @param m [in] Gralloc module. + * @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(mali_gralloc_module *m, uint64_t usage, size_t size, + enum ion_heap_type heap_type, unsigned int flags, + int *min_pgsz) { - uint32_t n_headers = (w * h) / 64; - uint32_t body_offset = n_headers * 16; - uint32_t headers[][4] = { - { body_offset, 0x1, 0x0, 0x0 }, /* Layouts 0, 3, 4 */ - { (body_offset + (1 << 28)), 0x200040, 0x4000, 0x80 } /* Layouts 1, 5 */ - }; - uint32_t i, layout; - - /* map format if necessary (also removes internal extension bits) */ - uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; - - switch (base_format) - { - case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888: - case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888: - case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888: - case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565: - case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888: - layout = 0; - break; - - case MALI_GRALLOC_FORMAT_INTERNAL_YV12: - case MALI_GRALLOC_FORMAT_INTERNAL_NV12: - case MALI_GRALLOC_FORMAT_INTERNAL_NV21: - layout = 1; - break; + int shared_fd = -1; + int ret = -1; - default: - layout = 0; + if ((m->ion_client < 0) || (size <= 0) || (heap_type == ION_HEAP_TYPE_INVALID) || + (min_pgsz == NULL)) + { + return -1; } - ALOGV("Writing AFBC header layout %d for format %" PRIu64, layout, base_format); +#if GRALLOC_USE_LEGACY_ION_API != 1 + bool system_heap_exist = false; - for (i = 0; i < n_headers; i++) + if (m->use_legacy_ion == false) { - memcpy(buf, headers[layout], sizeof(headers[layout])); - buf += sizeof(headers[layout]); - } -} + int i = 0; + bool is_heap_matched = false; -static int alloc_from_ion_heap(int ion_fd, size_t size, unsigned int heap_mask, unsigned int flags, int *min_pgsz) -{ - ion_user_handle_t ion_hnd = -1; - int shared_fd, ret; + /* Attempt to allocate memory from each matching heap type (of + * enumerated heaps) until successful + */ + do + { + if (heap_type == m->heap_info[i].type) + { + is_heap_matched = true; + ret = ion_alloc_fd(m->ion_client, size, 0, + HEAP_MASK_FROM_ID(m->heap_info[i].heap_id), + flags, &shared_fd); + } + + if (m->heap_info[i].type == ION_HEAP_TYPE_SYSTEM) + { + system_heap_exist = true; + } + + i++; + } while ((ret < 0) && (i < m->heap_cnt)); - if ((ion_fd < 0) || (size <= 0) || (heap_mask == 0) || (min_pgsz == NULL)) + if (is_heap_matched == false) + { + AERR("Failed to find matching ION heap. Trying to fall back on system heap"); + } + } +#endif + + if (m->use_legacy_ion == true) { - return -1; + /* This assumes that when the heaps were defined, the heap ids were + * defined as (1 << type) and that ION interprets the heap_mask as + * (1 << type). + */ + unsigned int heap_mask = HEAP_MASK_FROM_TYPE(heap_type); + + ret = ion_alloc_fd(m->ion_client, size, 0, heap_mask, flags, &shared_fd); } - /** - * step 1: ion_alloc new ion_hnd - * step 2: ion_share from ion_hnd and get shared_fd - * step 3: ion free the given ion_hnd - * step 4: when we need to free this ion buffer, just close the shared_fd, - * kernel will count the reference of file struct, so it's safe to - * be transfered between processes. + /* Check if allocation from selected heap failed and fall back to system + * heap if possible. */ - ret = ion_alloc(ion_fd, size, 0, heap_mask, flags, &ion_hnd); - if (ret < 0) { +#if GRALLOC_ENABLE_ION_SECURE_HEAP + /* This extra check for ION_HEAP_SECURE_MASK must be removed once + * ION_HEAP_SECURE_MASK no longer signals an enabled secure heap. + */ #if defined(ION_HEAP_SECURE_MASK) - - if (heap_mask == ION_HEAP_SECURE_MASK) + /* Don't allow falling back to sytem heap if secure was requested. */ + if (heap_type == ION_HEAP_TYPE_SECURE) { return -1; } - else #endif +#endif + /* Can't fall back to system heap if system heap was the heap that + * already failed + */ + if (heap_type == ION_HEAP_TYPE_SYSTEM) { - /* If everything else failed try system heap */ - flags = 0; /* Fallback option flags are not longer valid */ - heap_mask = ION_HEAP_SYSTEM_MASK; - ret = ion_alloc(ion_fd, size, 0, heap_mask, flags, &ion_hnd); + AERR("%s: Allocation failed on on system heap. Cannot fallback.", __func__); + return -1; } - } - ret = ion_share(ion_fd, ion_hnd, &shared_fd); + heap_type = ION_HEAP_TYPE_SYSTEM; - if (ret != 0) - { - AERR("ion_share( %d ) failed", ion_fd); - shared_fd = -1; - } + /* Set ION flags for system heap allocation */ + set_ion_flags(heap_type, usage, NULL, &flags); - ret = ion_free(ion_fd, ion_hnd); +#if GRALLOC_USE_LEGACY_ION_API != 1 + if (m->use_legacy_ion == false) + { + int i = 0; - if (0 != ret) - { - AERR("ion_free( %d ) failed", ion_fd); - close(shared_fd); - shared_fd = -1; - } + if (system_heap_exist == false) + { + AERR("%s: System heap not available for fallback", __func__); + return -1; + } - if (ret >= 0) - { - switch (heap_mask) - { - case ION_HEAP_SYSTEM_MASK: - *min_pgsz = SZ_4K; - break; + /* Attempt to allocate memory from each system heap type (of + * enumerated heaps) until successful + */ + do + { + if (m->heap_info[i].type == ION_HEAP_TYPE_SYSTEM) + { + ret = ion_alloc_fd(m->ion_client, size, 0, + HEAP_MASK_FROM_ID(m->heap_info[i].heap_id), + flags, &shared_fd); + } - case ION_HEAP_SYSTEM_CONTIG_MASK: - case ION_HEAP_CARVEOUT_MASK: -#ifdef ION_HEAP_TYPE_DMA_MASK - case ION_HEAP_TYPE_DMA_MASK: + i++; + } while ((ret < 0) && (i < m->heap_cnt)); + } + else /* Use legacy ION API */ #endif - *min_pgsz = size; - break; -#ifdef ION_HEAP_CHUNK_MASK + { + ret = ion_alloc_fd(m->ion_client, size, 0, + HEAP_MASK_FROM_TYPE(heap_type), + flags, &shared_fd); + } - /* NOTE: if have this heap make sure your ION chunk size is 2M*/ - case ION_HEAP_CHUNK_MASK: - *min_pgsz = SZ_2M; - break; -#endif -#ifdef ION_HEAP_COMPOUND_PAGE_MASK + if (ret != 0) + { + AERR("Fallback ion_alloc_fd(%d, %zd, %d, %u, %p) failed", + m->ion_client, size, 0, flags, &shared_fd); + return -1; + } + } - case ION_HEAP_COMPOUND_PAGE_MASK: - *min_pgsz = SZ_2M; - break; -#endif -/* If have customized heap please set the suitable pg type according to - * the customized ION implementation - */ -#ifdef ION_HEAP_CUSTOM_MASK + switch (heap_type) + { + case ION_HEAP_TYPE_SYSTEM: + *min_pgsz = SZ_4K; + break; - case ION_HEAP_CUSTOM_MASK: - *min_pgsz = SZ_4K; - break; + case ION_HEAP_TYPE_SYSTEM_CONTIG: + case ION_HEAP_TYPE_CARVEOUT: +#if GRALLOC_USE_ION_DMA_HEAP + case ION_HEAP_TYPE_DMA: + *min_pgsz = size; + break; #endif - - default: - *min_pgsz = SZ_4K; - break; - } +#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; } -unsigned int pick_ion_heap(uint64_t usage) +static enum ion_heap_type pick_ion_heap(uint64_t usage) { - unsigned int heap_mask; + enum ion_heap_type heap_type; if (usage & GRALLOC_USAGE_PROTECTED) { +#if GRALLOC_ENABLE_ION_SECURE_HEAP +/* Remove this #if condition once ION_HEAP_SECURE_MASK no longer signals an enabled secure heap. */ #if defined(ION_HEAP_SECURE_MASK) - heap_mask = ION_HEAP_SECURE_MASK; + if (HEAP_MASK_FROM_TYPE(ION_HEAP_TYPE_SECURE) != ION_HEAP_SECURE_MASK) + { + ALOGE("ION_HEAP_TYPE_SECURE has wrong value. ION_HEAP_TYPE_SECURE: 0x%x ION_HEAP_SECURE_MASK: 0x%x", ION_HEAP_TYPE_SECURE, ION_HEAP_SECURE_MASK); + } + heap_type = ION_HEAP_TYPE_SECURE; +/* Remove the following #else block once ION_HEAP_SECURE_MASK no longer signals an enabled secure heap. */ #else AERR("Protected ION memory is not supported on this platform."); - return 0; + return ION_HEAP_TYPE_INVALID; +#endif +/*-------*/ +#else + AERR("Protected ION memory is not supported on this platform."); + return ION_HEAP_TYPE_INVALID; #endif } - -#if defined(ION_HEAP_TYPE_COMPOUND_PAGE_MASK) && GRALLOC_USE_ION_COMPOUND_PAGE_HEAP - else if (!(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER))) - { - heap_mask = ION_HEAP_TYPE_COMPOUND_PAGE_MASK; - } - -#elif defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP else if (!(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER))) { - heap_mask = ION_HEAP_TYPE_DMA_MASK; - } - +#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_mask = ION_HEAP_SYSTEM_MASK; + heap_type = ION_HEAP_TYPE_SYSTEM; } - return heap_mask; + return heap_type; } -void set_ion_flags(unsigned int heap_mask, uint64_t usage, unsigned int *priv_heap_flag, int *ion_flags) +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_mask); + GRALLOC_UNUSED(heap_type); #endif if (priv_heap_flag) { -#if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP - - if (heap_mask == ION_HEAP_TYPE_DMA_MASK) +#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 defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP - - if (heap_mask != ION_HEAP_TYPE_DMA_MASK) +#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 | ION_FLAG_CACHED_NEEDS_SYNC; } - -#if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP +#if GRALLOC_USE_ION_DMA_HEAP } - #endif } } static bool check_buffers_sharable(const gralloc_buffer_descriptor_t *descriptors, uint32_t numDescriptors) { - unsigned int shared_backend_heap_mask = 0; - int shared_ion_flags = 0; + enum ion_heap_type shared_backend_heap_type = ION_HEAP_TYPE_INVALID; + unsigned int shared_ion_flags = 0; uint64_t usage; uint32_t i; @@ -278,30 +333,31 @@ static bool check_buffers_sharable(const gralloc_buffer_descriptor_t *descriptor for (i = 0; i < numDescriptors; i++) { - unsigned int heap_mask; - int ion_flags; + 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_mask = pick_ion_heap(usage); - if (0 == heap_mask) + heap_type = pick_ion_heap(usage); + if (heap_type == ION_HEAP_TYPE_INVALID) { return false; } - set_ion_flags(heap_mask, usage, NULL, &ion_flags); + set_ion_flags(heap_type, usage, NULL, &ion_flags); - if (0 != shared_backend_heap_mask) + if (shared_backend_heap_type != ION_HEAP_TYPE_INVALID) { - if (shared_backend_heap_mask != heap_mask || shared_ion_flags != ion_flags) + if (shared_backend_heap_type != heap_type || shared_ion_flags != ion_flags) { return false; } } else { - shared_backend_heap_mask = heap_mask; + shared_backend_heap_type = heap_type; shared_ion_flags = ion_flags; } } @@ -328,25 +384,111 @@ static int get_max_buffer_descriptor_index(const gralloc_buffer_descriptor_t *de return max_buffer_index; } -int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors, - uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend) +/* + * Opens the ION module. Queries heap information and stores it for later use + * + * @param m [inout] Gralloc private module + * + * @return 0 in case of success + * -1 for all error cases + */ +static int open_and_query_ion(mali_gralloc_module *m) +{ + int ret = -1; + + m->ion_client = ion_open(); + if (m->ion_client < 0) + { + AERR("ion_open failed with %s", strerror(errno)); + return -1; + } + +#if GRALLOC_USE_LEGACY_ION_API == 1 + m->use_legacy_ion = true; +#else + int heap_cnt = 0; + + m->heap_cnt = 0; + m->use_legacy_ion = (ion_is_legacy(m->ion_client) != 0); + + if (m->use_legacy_ion == false) + { + ret = ion_query_heap_cnt(m->ion_client, &heap_cnt); + if (ret == 0) + { + if (heap_cnt > (int)ION_NUM_HEAP_IDS) + { + AERR("Retrieved heap count %d is more than maximun heaps %zu on ion", + heap_cnt, ION_NUM_HEAP_IDS); + return -1; + } + + std::vector<struct ion_heap_data> heap_data(heap_cnt); + ret = ion_query_get_heaps(m->ion_client, heap_cnt, heap_data.data()); + if (ret == 0) + { + int heap_info_idx = 0; + for (std::vector<struct ion_heap_data>::iterator heap = heap_data.begin(); + heap != heap_data.end(); heap++) + { + if (heap_info_idx >= (int)ION_NUM_HEAP_IDS) + { + AERR("Iterator exceeding max index, cannot cache heap information"); + return -1; + } + + m->heap_info[heap_info_idx] = *heap; + heap_info_idx++; + } + } + } + if (ret < 0) + { + AERR("%s: Failed to query ION heaps.", __func__); + return ret; + } + + m->heap_cnt = heap_cnt; + } +#endif + + return 0; +} + +/* + * Allocates ION buffers + * + * @param m [in] Gralloc module. + * @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(mali_gralloc_module *m, + const gralloc_buffer_descriptor_t *descriptors, + uint32_t numDescriptors, buffer_handle_t *pHandle, + bool *shared_backend) { static int support_protected = 1; /* initially, assume we support protected memory */ - unsigned int heap_mask, priv_heap_flag = 0; + unsigned int priv_heap_flag = 0; + enum ion_heap_type heap_type; unsigned char *cpu_ptr = NULL; uint64_t usage; uint32_t i, max_buffer_index = 0; - int shared_fd, ret, ion_flags = 0; + int shared_fd; + unsigned int ion_flags = 0; int min_pgsz = 0; if (m->ion_client < 0) { - m->ion_client = ion_open(); - - if (m->ion_client < 0) + int status = 0; + status = open_and_query_ion(m); + if (status < 0) { - AERR("ion_open failed with %s", strerror(errno)); - return -1; + return status; } } @@ -360,17 +502,16 @@ int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descr max_bufDescriptor = (buffer_descriptor_t *)(descriptors[max_buffer_index]); usage = max_bufDescriptor->consumer_usage | max_bufDescriptor->producer_usage; - heap_mask = pick_ion_heap(usage); - - if (heap_mask == 0) + 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_mask, usage, &priv_heap_flag, &ion_flags); + set_ion_flags(heap_type, usage, &priv_heap_flag, &ion_flags); - shared_fd = alloc_from_ion_heap(m->ion_client, max_bufDescriptor->size, heap_mask, ion_flags, &min_pgsz); + shared_fd = alloc_from_ion_heap(m, usage, max_bufDescriptor->size, heap_type, ion_flags, &min_pgsz); if (shared_fd < 0) { @@ -389,7 +530,17 @@ int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descr if (tmp_fd < 0) { - /* need to free already allocated memory. */ + 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; } @@ -404,10 +555,23 @@ int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descr bufDescriptor->consumer_usage, bufDescriptor->producer_usage, tmp_fd, bufDescriptor->hal_format, bufDescriptor->internal_format, bufDescriptor->byte_stride, bufDescriptor->width, bufDescriptor->height, bufDescriptor->pixel_stride, bufDescriptor->internalWidth, bufDescriptor->internalHeight, - max_bufDescriptor->size); + max_bufDescriptor->size, bufDescriptor->layer_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; } @@ -422,18 +586,18 @@ int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descr buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]); usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage; - heap_mask = pick_ion_heap(usage); - if (heap_mask == 0) + 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_mask, usage, &priv_heap_flag, &ion_flags); + set_ion_flags(heap_type, usage, &priv_heap_flag, &ion_flags); - shared_fd = alloc_from_ion_heap(m->ion_client, bufDescriptor->size, heap_mask, ion_flags, &min_pgsz); + shared_fd = alloc_from_ion_heap(m, usage, bufDescriptor->size, heap_type, ion_flags, &min_pgsz); if (shared_fd < 0) { @@ -450,10 +614,14 @@ int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descr bufDescriptor->consumer_usage, bufDescriptor->producer_usage, shared_fd, bufDescriptor->hal_format, bufDescriptor->internal_format, bufDescriptor->byte_stride, bufDescriptor->width, bufDescriptor->height, bufDescriptor->pixel_stride, bufDescriptor->internalWidth, bufDescriptor->internalHeight, - bufDescriptor->size); + bufDescriptor->size, bufDescriptor->layer_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; } @@ -485,7 +653,7 @@ int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descr if ((bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) && (!(*shared_backend))) { - init_afbc(cpu_ptr, bufDescriptor->internal_format, bufDescriptor->width, bufDescriptor->height); + init_afbc(cpu_ptr, bufDescriptor->internal_format, bufDescriptor->internalWidth, bufDescriptor->internalHeight, usage); } #endif @@ -580,13 +748,11 @@ int mali_gralloc_ion_map(private_handle_t *hnd) if (m->ion_client <= 0) { /* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/ - m->ion_client = ion_open(); - - if (m->ion_client < 0) + int status = 0; + status = open_and_query_ion(m); + if (status < 0) { - AERR("Could not open ion device for handle: %p", hnd); - retval = -errno; - break; + return status; } } diff --git a/gralloc/src/mali_gralloc_module.cpp b/gralloc/src/mali_gralloc_module.cpp index c3bf4c8..5c395aa 100644 --- a/gralloc/src/mali_gralloc_module.cpp +++ b/gralloc/src/mali_gralloc_module.cpp @@ -20,7 +20,7 @@ #include <pthread.h> #include <inttypes.h> -#include <cutils/log.h> +#include <log/log.h> #include <cutils/atomic.h> #include <system/window.h> #include <hardware/hardware.h> @@ -183,6 +183,12 @@ private_module_t::private_module_t() fps = 0.0f; swapInterval = 1; ion_client = -1; + use_legacy_ion = true; + +#if GRALLOC_USE_LEGACY_ION_API != 1 + heap_cnt = 0; + INIT_ZERO(heap_info); +#endif #undef INIT_ZERO }; diff --git a/gralloc/src/mali_gralloc_module.h b/gralloc/src/mali_gralloc_module.h index b861565..ef0c6bf 100644 --- a/gralloc/src/mali_gralloc_module.h +++ b/gralloc/src/mali_gralloc_module.h @@ -22,6 +22,10 @@ #include <linux/fb.h> #include <pthread.h> +#if GRALLOC_USE_LEGACY_ION_API != 1 +#include <ion/ion_4.12.h> +#endif + typedef enum { MALI_DPY_TYPE_UNKNOWN = 0, @@ -83,6 +87,14 @@ struct private_module_t float ydpi; float fps; int swapInterval; + bool use_legacy_ion; + +#if GRALLOC_USE_LEGACY_ION_API != 1 + /* Cache the heap types / IDs information to avoid repeated IOCTL calls + * Assumption: Heap types / IDs would not change after boot up. */ + int heap_cnt; + ion_heap_data heap_info[ION_NUM_HEAP_IDS]; +#endif #ifdef __cplusplus /* Never intended to be used from C code */ diff --git a/gralloc/src/mali_gralloc_private_interface_types.h b/gralloc/src/mali_gralloc_private_interface_types.h index 47ac597..eb644a6 100644 --- a/gralloc/src/mali_gralloc_private_interface_types.h +++ b/gralloc/src/mali_gralloc_private_interface_types.h @@ -19,6 +19,36 @@ #ifndef MALI_GRALLOC_PRIVATE_INTERFACE_TYPES_H_ #define MALI_GRALLOC_PRIVATE_INTERFACE_TYPES_H_ +#define GRALLOC_ARM_BUFFER_ATTR_HDR_INFO_SUPPORT + +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 + mali_transfer_function eotf; +} mali_hdr_info; + enum { /* CROP_RECT and YUV_TRANS are intended to be @@ -35,6 +65,10 @@ enum /* Set if the AFBC format uses sparse allocation */ GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC = 3, + + /* HDR Informations*/ + GRALLOC_ARM_BUFFER_ATTR_HDR_INFO = 4, + GRALLOC_ARM_BUFFER_ATTR_LAST }; diff --git a/gralloc/src/mali_gralloc_public_interface.cpp b/gralloc/src/mali_gralloc_public_interface.cpp index 9475d82..8be1169 100644 --- a/gralloc/src/mali_gralloc_public_interface.cpp +++ b/gralloc/src/mali_gralloc_public_interface.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 ARM Limited. All rights reserved. + * Copyright (C) 2016, 2018 ARM Limited. All rights reserved. * * Copyright (C) 2008 The Android Open Source Project * @@ -186,10 +186,12 @@ static int32_t mali_gralloc_allocate(gralloc1_device_t *device, uint32_t numDesc height = bufDescriptor->height; #if GRALLOC_FB_SWAP_RED_BLUE == 1 -#ifdef GRALLOC_16_BITS +#if GRALLOC_FB_BPP == 16 format = HAL_PIXEL_FORMAT_RGB_565; -#else +#elif GRALLOC_FB_BPP == 32 format = HAL_PIXEL_FORMAT_BGRA_8888; +#else +#error "Invalid framebuffer bit depth" #endif #endif @@ -358,6 +360,26 @@ static int32_t mali_gralloc1_unlock_async(gralloc1_device_t *device, buffer_hand 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 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 }, @@ -379,6 +401,10 @@ static const mali_gralloc_func mali_gralloc_func_list[] = { { 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_INVALID has to be the last descriptor on the list. */ { GRALLOC1_FUNCTION_INVALID, NULL } @@ -387,12 +413,23 @@ static const mali_gralloc_func mali_gralloc_func_list[] = { static void mali_gralloc_getCapabilities(gralloc1_device_t *dev, uint32_t *outCount, int32_t *outCapabilities) { GRALLOC_UNUSED(dev); - GRALLOC_UNUSED(outCapabilities); +#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) diff --git a/gralloc/src/mali_gralloc_usages.h b/gralloc/src/mali_gralloc_usages.h index 4f034eb..e7dee76 100644 --- a/gralloc/src/mali_gralloc_usages.h +++ b/gralloc/src/mali_gralloc_usages.h @@ -1,5 +1,5 @@ /* - * (C) COPYRIGHT 2017 ARM Limited. All rights reserved. + * 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"); diff --git a/init.juno.rc b/init.juno.rc index 3001b15..13a3253 100644 --- a/init.juno.rc +++ b/init.juno.rc @@ -61,13 +61,13 @@ on boot # enable test harness setprop ro.test_harness true -service tee-supplicant /system/bin/tee-supplicant - class main - user root - oneshot - -service gatord /system/bin/gatord -c /data/misc/gatord/configuration.xml - class main - user root - oneshot - seclabel u:r:gatord:s0 +#service tee-supplicant /system/bin/tee-supplicant +# class main +# user root +# oneshot + +#service gatord /system/bin/gatord -c /data/misc/gatord/configuration.xml +# class main +# user root +# oneshot +# seclabel u:r:gatord:s0 diff --git a/libmemtrack/Android.mk b/libmemtrack/Android.mk index 9a38b58..0d83389 100644 --- a/libmemtrack/Android.mk +++ b/libmemtrack/Android.mk @@ -23,7 +23,7 @@ LOCAL_PROPRIETARY_MODULE := true LOCAL_C_INCLUDES += hardware/libhardware/include LOCAL_CFLAGS := -Wconversion -Wall -Werror -Wno-sign-conversion LOCAL_CLANG := true -LOCAL_SHARED_LIBRARIES := liblog +LOCAL_SHARED_LIBRARIES := liblog libhardware LOCAL_SRC_FILES := memtrack_juno.c LOCAL_MODULE := memtrack.default #LOCAL_MODULE := memtrack.$(TARGET_BOARD_PLATFORM) diff --git a/manifest.xml b/manifest.xml index d31236a..4805f08 100644 --- a/manifest.xml +++ b/manifest.xml @@ -51,7 +51,7 @@ </hal> <hal format="hidl"> <name>android.hardware.graphics.composer</name> - <transport arch="32+64">passthrough</transport> + <transport>hwbinder</transport> <version>2.1</version> <interface> <name>IComposer</name> @@ -78,7 +78,7 @@ </hal> <hal format="hidl"> <name>android.hardware.power</name> - <transport arch="32+64">passthrough</transport> + <transport>hwbinder</transport> <version>1.0</version> <interface> <name>IPower</name> @@ -94,15 +94,6 @@ <instance>default</instance> </interface> </hal> - <hal format="hidl"> - <name>android.hardware.wifi.supplicant</name> - <transport>hwbinder</transport> - <version>1.0</version> - <interface> - <name>ISupplicant</name> - <instance>default</instance> - </interface> - </hal> <hal format="hidl"> <name>android.hardware.audio.effect</name> <transport>hwbinder</transport> diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml index 029bdec..85cf474 100644 --- a/overlay/frameworks/base/core/res/res/values/config.xml +++ b/overlay/frameworks/base/core/res/res/values/config.xml @@ -38,8 +38,6 @@ does not require auto-restore. --> <!-- the 6th element indicates boot-time dependency-met value. --> <string-array translatable="false" name="networkAttributes"> - <item>"wifi,1,1,1,-1,true"</item> - <item>"wifi_p2p,13,1,0,-1,true"</item> <item>"ethernet,9,9,2,-1,true"</item> </string-array> diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts index ff9b061..e63b016 100644 --- a/sepolicy/file_contexts +++ b/sepolicy/file_contexts @@ -5,4 +5,6 @@ /vendor/bin/tee-supplicant u:object_r:tee_exec:s0 /dev/teepriv[0-9]* u:object_r:tee_device:s0 /dev/tee[0-9]* u:object_r:tee_device:s0 -/data/tee(/.*)? u:object_r:tee_data_file:s0 +#/data/tee(/.*)? u:object_r:tee_data_file:s0 +/dev/graphics/fb0 u:object_r:graphics_device:s0 + diff --git a/sepolicy/hal_graphics_allocator_default.te b/sepolicy/hal_graphics_allocator_default.te new file mode 100644 index 0000000..b17dc7d --- /dev/null +++ b/sepolicy/hal_graphics_allocator_default.te @@ -0,0 +1,2 @@ +allow hal_graphics_allocator_default graphics_device:dir search; +allow hal_graphics_allocator_default graphics_device:chr_file { open read write ioctl map rw_file_perms}; diff --git a/sepolicy/hal_graphics_composer_default.te b/sepolicy/hal_graphics_composer_default.te new file mode 100644 index 0000000..4184ab0 --- /dev/null +++ b/sepolicy/hal_graphics_composer_default.te @@ -0,0 +1 @@ +vndbinder_use(hal_graphics_composer_default) diff --git a/sepolicy/tee.te b/sepolicy/tee.te deleted file mode 100644 index 8f73909..0000000 --- a/sepolicy/tee.te +++ /dev/null @@ -1,19 +0,0 @@ -# allow run xtest as shell -domain_auto_trans(shell, tee_exec, tee); -allow shell tee_exec:file { getattr execute read open execute_no_trans }; -allow shell tee_data_file:file { create write open getattr unlink read }; -allow shell tee_data_file:dir { write add_name remove_name rename search }; -allow shell tee_data_file:chr_file { read write open ioctl }; -allow tee console_device:chr_file { getattr read write ioctl }; -allow tee shell:fd { use }; - -allow tee tee_data_file:dir { create rmdir rename }; -allow tee system_data_file:dir { write remove_name }; - -# For xtest 200x tests -allow tee tee:tcp_socket { create connect read write getopt setopt }; -allow tee tee:udp_socket { create connect read write getopt getattr }; -allow tee tee:capability { net_raw }; -allow tee fwmarkd_socket:sock_file { write }; -#allow tee netd:unix_stream_socket { connectto }; -allow tee port:tcp_socket { name_connect }; |