summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVishal Bhoj <vishal.bhoj@linaro.org>2019-01-23 10:55:00 +0000
committerVishal Bhoj <vishal.bhoj@linaro.org>2019-01-28 04:38:16 +0000
commit104697b4406e8ab0a18b80125dc66a9aa99b05f5 (patch)
tree13dbf3f27868dcfcb47b6e1ec935722bedfcc4cb
parentd536ed60a262f2f267e5c59f77f2b66b2f4d51ed (diff)
downloadjuno-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>
-rw-r--r--BoardConfig.mk16
-rw-r--r--device.mk16
-rw-r--r--gralloc/src/Android.juno.mk4
-rw-r--r--gralloc/src/Android.mk44
-rw-r--r--gralloc/src/Android.vexpress.mk4
-rw-r--r--gralloc/src/format_info.cpp114
-rw-r--r--gralloc/src/format_info.h63
-rw-r--r--gralloc/src/framebuffer_device.cpp16
-rw-r--r--gralloc/src/gralloc_buffer_priv.cpp2
-rw-r--r--gralloc/src/gralloc_buffer_priv.h11
-rw-r--r--gralloc/src/gralloc_priv.h1
-rw-r--r--gralloc/src/ion/ion_4.12.h125
-rw-r--r--gralloc/src/legacy/alloc_device.cpp16
-rw-r--r--gralloc/src/legacy/buffer_access.cpp430
-rw-r--r--gralloc/src/legacy/buffer_access.h43
-rw-r--r--gralloc/src/legacy/buffer_alloc.cpp998
-rw-r--r--gralloc/src/legacy/buffer_alloc.h72
-rw-r--r--gralloc/src/mali_gralloc_buffer.h41
-rw-r--r--gralloc/src/mali_gralloc_bufferaccess.cpp28
-rw-r--r--gralloc/src/mali_gralloc_bufferallocation.cpp599
-rw-r--r--gralloc/src/mali_gralloc_bufferallocation.h5
-rw-r--r--gralloc/src/mali_gralloc_bufferdescriptor.cpp37
-rw-r--r--gralloc/src/mali_gralloc_bufferdescriptor.h5
-rw-r--r--gralloc/src/mali_gralloc_debug.cpp2
-rw-r--r--gralloc/src/mali_gralloc_formats.cpp463
-rw-r--r--gralloc/src/mali_gralloc_formats.h170
-rw-r--r--gralloc/src/mali_gralloc_ion.cpp520
-rw-r--r--gralloc/src/mali_gralloc_module.cpp8
-rw-r--r--gralloc/src/mali_gralloc_module.h12
-rw-r--r--gralloc/src/mali_gralloc_private_interface_types.h34
-rw-r--r--gralloc/src/mali_gralloc_public_interface.cpp45
-rw-r--r--gralloc/src/mali_gralloc_usages.h2
-rw-r--r--init.juno.rc20
-rw-r--r--libmemtrack/Android.mk2
-rw-r--r--manifest.xml13
-rw-r--r--overlay/frameworks/base/core/res/res/values/config.xml2
-rw-r--r--sepolicy/file_contexts4
-rw-r--r--sepolicy/hal_graphics_allocator_default.te2
-rw-r--r--sepolicy/hal_graphics_composer_default.te1
-rw-r--r--sepolicy/tee.te19
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
diff --git a/device.mk b/device.mk
index a2fe341..ccb4988 100644
--- a/device.mk
+++ b/device.mk
@@ -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(&region->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, &region->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 };