summaryrefslogtreecommitdiff
path: root/GrallocHAL/src/core/mali_gralloc_bufferallocation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'GrallocHAL/src/core/mali_gralloc_bufferallocation.cpp')
-rw-r--r--GrallocHAL/src/core/mali_gralloc_bufferallocation.cpp1179
1 files changed, 0 insertions, 1179 deletions
diff --git a/GrallocHAL/src/core/mali_gralloc_bufferallocation.cpp b/GrallocHAL/src/core/mali_gralloc_bufferallocation.cpp
deleted file mode 100644
index a570723..0000000
--- a/GrallocHAL/src/core/mali_gralloc_bufferallocation.cpp
+++ /dev/null
@@ -1,1179 +0,0 @@
-/*
- * Copyright (C) 2016-2020 ARM Limited. All rights reserved.
- *
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <inttypes.h>
-#include <assert.h>
-#include <atomic>
-#include <algorithm>
-
-#include <hardware/hardware.h>
-#include <hardware/gralloc1.h>
-
-#include "mali_gralloc_bufferallocation.h"
-#include "allocator/mali_gralloc_ion.h"
-#include "allocator/mali_gralloc_shared_memory.h"
-#include "mali_gralloc_buffer.h"
-#include "mali_gralloc_bufferdescriptor.h"
-#include "mali_gralloc_debug.h"
-#include "mali_gralloc_log.h"
-#include "format_info.h"
-#include <exynos_format.h>
-#include "exynos_format_allocation.h"
-
-#define EXT_SIZE 256
-
-/* Default align values for Exynos */
-#define YUV_BYTE_ALIGN_DEFAULT 16
-#define RGB_BYTE_ALIGN_DEFAULT 64
-
-/* IP-specific align values */
-#define GPU_BYTE_ALIGN_DEFAULT 64
-
-/* Always CPU align for Exynos */
-#define CAN_SKIP_CPU_ALIGN 0
-
-/* Realign YV12 format so that chroma stride is half of luma stride */
-#define REALIGN_YV12 1
-
-/* TODO: set S10B format align in BoardConfig.mk */
-#define BOARD_EXYNOS_S10B_FORMAT_ALIGN 64
-#if 0
-ifeq ($(BOARD_EXYNOS_S10B_FORMAT_ALIGN), 64)
-LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=$(BOARD_EXYNOS_S10B_FORMAT_ALIGN)
-else
-LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=16
-endif
-#endif
-
-#define AFBC_PIXELS_PER_BLOCK 256
-#define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY 16
-
-bool afbc_format_fallback(uint32_t * const format_idx, const uint64_t usage, bool force);
-
-
-/*
- * Get a global unique ID
- */
-static uint64_t getUniqueId()
-{
- static std::atomic<uint32_t> counter(0);
- uint64_t id = static_cast<uint64_t>(getpid()) << 32;
- return id | counter++;
-}
-
-static void afbc_buffer_align(const bool is_tiled, int *size)
-{
- const uint16_t AFBC_BODY_BUFFER_BYTE_ALIGNMENT = 1024;
-
- int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
-
- if (is_tiled)
- {
- buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
- }
-
- *size = GRALLOC_ALIGN(*size, buffer_byte_alignment);
-}
-
-/*
- * Obtain AFBC superblock dimensions from type.
- */
-static rect_t get_afbc_sb_size(AllocBaseType alloc_base_type)
-{
- const uint16_t AFBC_BASIC_BLOCK_WIDTH = 16;
- const uint16_t AFBC_BASIC_BLOCK_HEIGHT = 16;
- const uint16_t AFBC_WIDE_BLOCK_WIDTH = 32;
- const uint16_t AFBC_WIDE_BLOCK_HEIGHT = 8;
- const uint16_t AFBC_EXTRAWIDE_BLOCK_WIDTH = 64;
- const uint16_t AFBC_EXTRAWIDE_BLOCK_HEIGHT = 4;
-
- rect_t sb = {0, 0};
-
- switch(alloc_base_type)
- {
- case AllocBaseType::AFBC:
- sb.width = AFBC_BASIC_BLOCK_WIDTH;
- sb.height = AFBC_BASIC_BLOCK_HEIGHT;
- break;
- case AllocBaseType::AFBC_WIDEBLK:
- sb.width = AFBC_WIDE_BLOCK_WIDTH;
- sb.height = AFBC_WIDE_BLOCK_HEIGHT;
- break;
- case AllocBaseType::AFBC_EXTRAWIDEBLK:
- sb.width = AFBC_EXTRAWIDE_BLOCK_WIDTH;
- sb.height = AFBC_EXTRAWIDE_BLOCK_HEIGHT;
- break;
- default:
- break;
- }
- return sb;
-}
-
-/*
- * Obtain AFBC superblock dimensions for specific plane.
- *
- * See alloc_type_t for more information.
- */
-static rect_t get_afbc_sb_size(alloc_type_t alloc_type, const uint8_t plane)
-{
- if (plane > 0 && alloc_type.is_afbc() && alloc_type.is_multi_plane)
- {
- return get_afbc_sb_size(AllocBaseType::AFBC_EXTRAWIDEBLK);
- }
- else
- {
- return get_afbc_sb_size(alloc_type.primary_type);
- }
-}
-
-bool get_alloc_type(const uint64_t format_ext,
- const uint32_t format_idx,
- const uint64_t usage,
- alloc_type_t * const alloc_type)
-{
- alloc_type->primary_type = AllocBaseType::UNCOMPRESSED;
- alloc_type->is_multi_plane = formats[format_idx].npln > 1;
- alloc_type->is_tiled = false;
- alloc_type->is_padded = false;
- alloc_type->is_frontbuffer_safe = false;
-
- /* Determine AFBC type for this format. This is used to decide alignment.
- Split block does not affect alignment, and therefore doesn't affect the allocation type. */
- if (format_ext & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
- {
- /* YUV transform shall not be enabled for a YUV format */
- if ((formats[format_idx].is_yuv == true) && (format_ext & MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM))
- {
- MALI_GRALLOC_LOGW("YUV Transform is incorrectly enabled for format = (%s 0x%x). Extended internal format = (%s 0x%" PRIx64 ")\n",
- format_name(formats[format_idx].id), formats[format_idx].id, format_name(format_ext), format_ext);
- }
-
- /* Determine primary AFBC (superblock) type. */
- alloc_type->primary_type = AllocBaseType::AFBC;
- if (format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
- {
- alloc_type->primary_type = AllocBaseType::AFBC_WIDEBLK;
- }
- else if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)
- {
- alloc_type->primary_type = AllocBaseType::AFBC_EXTRAWIDEBLK;
- }
-
- if (format_ext & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
- {
- alloc_type->is_tiled = true;
-
- if (formats[format_idx].npln > 1 &&
- (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) == 0)
- {
- MALI_GRALLOC_LOGW("Extra-wide AFBC must be signalled for multi-plane formats. "
- "Falling back to single plane AFBC.");
- alloc_type->is_multi_plane = false;
- }
-
- if (format_ext & MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY)
- {
- alloc_type->is_frontbuffer_safe = true;
- }
- }
- else
- {
- if (formats[format_idx].npln > 1)
- {
- MALI_GRALLOC_LOGW("Multi-plane AFBC is not supported without tiling. "
- "Falling back to single plane AFBC.");
- }
- alloc_type->is_multi_plane = false;
- }
-
- if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK &&
- !alloc_type->is_tiled)
- {
- /* Headers must be tiled for extra-wide. */
- MALI_GRALLOC_LOGE("ERROR: Invalid to specify extra-wide block without tiled headers.");
- return false;
- }
-
- if (alloc_type->is_frontbuffer_safe &&
- (format_ext & (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK | MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)))
- {
- MALI_GRALLOC_LOGE("ERROR: Front-buffer safe not supported with wide/extra-wide block.");
- }
-
- if (formats[format_idx].npln == 1 &&
- format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK &&
- format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)
- {
- /* "Wide + Extra-wide" implicitly means "multi-plane". */
- MALI_GRALLOC_LOGE("ERROR: Invalid to specify multiplane AFBC with single plane format.");
- return false;
- }
-
- if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING)
- {
- alloc_type->is_padded = true;
- }
- }
- return true;
-}
-
-/*
- * Initialise AFBC header based on superblock layout.
- * Width and height should already be AFBC aligned.
- */
-void init_afbc(uint8_t *buf, const uint64_t alloc_format,
- const bool is_multi_plane,
- const int w, const int h)
-{
- const bool is_tiled = ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
- == MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS);
- const uint32_t n_headers = (w * h) / AFBC_PIXELS_PER_BLOCK;
- int body_offset = n_headers * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY;
-
- afbc_buffer_align(is_tiled, &body_offset);
-
- /*
- * Declare the AFBC header initialisation values for each superblock layout.
- * Tiled headers (AFBC 1.2) can be initialised to zero for non-subsampled formats
- * (SB layouts: 0, 3, 4, 7).
- */
- uint32_t headers[][4] = {
- { (uint32_t)body_offset, 0x1, 0x10000, 0x0 }, /* Layouts 0, 3, 4, 7 */
- { ((uint32_t)body_offset + (1 << 28)), 0x80200040, 0x1004000, 0x20080 } /* Layouts 1, 5 */
- };
- if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS))
- {
- /* Zero out body_offset for non-subsampled formats. */
- memset(headers[0], 0, sizeof(uint32_t) * 4);
- }
-
- /* Map base format to AFBC header layout */
- const uint32_t base_format = alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK;
-
- /* Sub-sampled formats use layouts 1 and 5 which is index 1 in the headers array.
- * 1 = 4:2:0 16x16, 5 = 4:2:0 32x8.
- *
- * Non-subsampled use layouts 0, 3, 4 and 7, which is index 0.
- * 0 = 16x16, 3 = 32x8 + split, 4 = 32x8, 7 = 64x4.
- *
- * When using separated planes for YUV formats, the header layout is the non-subsampled one
- * as there is a header per-plane and there is no sub-sampling within the plane.
- * Separated plane only supports 32x8 or 64x4 for the luma plane, so the first plane must be 4 or 7.
- * Seperated plane only supports 64x4 for subsequent planes, so these must be header layout 7.
- */
- const uint32_t layout = is_subsampled_yuv(base_format) && !is_multi_plane ? 1 : 0;
-
- MALI_GRALLOC_LOGV("Writing AFBC header layout %d for format (%s %" PRIx32 ")",
- layout, format_name(base_format), base_format);
-
- for (uint32_t i = 0; i < n_headers; i++)
- {
- memcpy(buf, headers[layout], sizeof(headers[layout]));
- buf += sizeof(headers[layout]);
- }
-}
-
-static int max(int a, int b)
-{
- return a > b ? a : b;
-}
-
-static int max(int a, int b, int c)
-{
- return c > max(a, b) ? c : max(a, b);
-}
-
-/*
- * Obtain plane allocation dimensions (in pixels).
- *
- * NOTE: pixel stride, where defined for format, is
- * incorporated into allocation dimensions.
- */
-static void get_pixel_w_h(uint32_t * const width,
- uint32_t * const height,
- const format_info_t format,
- const alloc_type_t alloc_type,
- const uint8_t plane,
- bool has_cpu_usage)
-{
- const rect_t sb = get_afbc_sb_size(alloc_type, plane);
- const bool is_primary_plane = (plane == 0 || !format.planes_contiguous);
-
- /*
- * Round-up plane dimensions, to multiple of:
- * - Samples for all channels (sub-sampled formats)
- * - Memory bytes/words (some packed formats)
- */
- if (is_primary_plane)
- {
- *width = GRALLOC_ALIGN(*width, format.align_w);
- *height = GRALLOC_ALIGN(*height, format.align_h);
- }
-
- /*
- * Sub-sample (sub-sampled) planes.
- */
- if (plane > 0)
- {
- *width /= format.hsub;
- *height /= format.vsub;
- }
-
- /*
- * Pixel alignment (width),
- * where format stride is stated in pixels.
- */
- int pixel_align_w = 1, pixel_align_h = 1;
- if (has_cpu_usage && is_primary_plane)
- {
- pixel_align_w = format.align_w_cpu;
- }
- else if (alloc_type.is_afbc())
- {
-#define HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS (0)
- uint32_t num_sb_align = 0;
- if (alloc_type.is_padded && !format.is_yuv)
- {
- /* Align to 4 superblocks in width --> 64-byte,
- * assuming 16-byte header per superblock.
- */
- num_sb_align = 4;
- }
- pixel_align_w = max(HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS, num_sb_align) * sb.width;
-
- /*
- * Determine AFBC tile size when allocating tiled headers.
- */
- rect_t afbc_tile = sb;
- if (alloc_type.is_tiled)
- {
- afbc_tile.width = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.width : 8 * afbc_tile.width;
- afbc_tile.height = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.height : 8 * afbc_tile.height;
- }
-
- MALI_GRALLOC_LOGV("Plane[%hhu]: [SUB-SAMPLE] w:%d, h:%d\n", plane, *width, *height);
- MALI_GRALLOC_LOGV("Plane[%hhu]: [PIXEL_ALIGN] w:%d\n", plane, pixel_align_w);
- MALI_GRALLOC_LOGV("Plane[%hhu]: [LINEAR_TILE] w:%" PRIu16 "\n", plane, format.tile_size);
- MALI_GRALLOC_LOGV("Plane[%hhu]: [AFBC_TILE] w:%" PRIu16 ", h:%" PRIu16 "\n", plane, afbc_tile.width, afbc_tile.height);
-
- pixel_align_w = max(pixel_align_w, afbc_tile.width);
- pixel_align_h = max(pixel_align_h, afbc_tile.height);
-
- if (AllocBaseType::AFBC_WIDEBLK == alloc_type.primary_type && !alloc_type.is_tiled)
- {
- /*
- * Special case for wide block (32x8) AFBC with linear (non-tiled)
- * headers: hardware reads and writes 32x16 blocks so we need to
- * pad the body buffer accordingly.
- *
- * Note that this branch will not be taken for multi-plane AFBC
- * since that requires tiled headers.
- */
- pixel_align_h = max(pixel_align_h, 16);
- }
- }
- *width = GRALLOC_ALIGN(*width, max(1, pixel_align_w, format.tile_size));
- *height = GRALLOC_ALIGN(*height, max(1, pixel_align_h, format.tile_size));
-}
-
-
-
-static uint32_t gcd(uint32_t a, uint32_t b)
-{
- uint32_t r, t;
-
- if (a == b)
- {
- return a;
- }
- else if (a < b)
- {
- t = a;
- a = b;
- b = t;
- }
-
- while (b != 0)
- {
- r = a % b;
- a = b;
- b = r;
- }
-
- return a;
-}
-
-uint32_t lcm(uint32_t a, uint32_t b)
-{
- if (a != 0 && b != 0)
- {
- return (a * b) / gcd(a, b);
- }
-
- return max(a, b);
-}
-
-
-#if REALIGN_YV12 == 1
-/*
- * YV12 stride has additional complexity since chroma stride
- * must conform to the following:
- *
- * c_stride = ALIGN(stride/2, 16)
- *
- * Since the stride alignment must satisfy both CPU and HW
- * constraints, the luma stride must be doubled.
- */
-static void update_yv12_stride(int8_t plane,
- uint32_t luma_stride,
- uint32_t stride_align,
- uint32_t * byte_stride)
-{
- if (plane == 0)
- {
- *byte_stride = GRALLOC_ALIGN(luma_stride, GRALLOC_ALIGN(stride_align, 32));
- }
- else
- {
- /*
- * Derive chroma stride from luma and verify it is:
- * 1. Aligned to "1/2*lcm(hw_align, cpu_align)"
- * 2. Multiple of 16px (16 bytes)
- */
- *byte_stride = luma_stride / 2;
- assert(*byte_stride == GRALLOC_ALIGN(*byte_stride, GRALLOC_ALIGN(stride_align / 2, 16)));
- assert(*byte_stride & 15 == 0);
- }
-}
-#endif
-
-/*
- * Logs and returns true if deprecated usage bits are found
- *
- * At times, framework introduces new usage flags which are identical to what
- * vendor has been using internally. This method logs those bits and returns
- * true if there is any deprecated usage bit.
- *
- * TODO(layog@): This check is also performed again during format deduction. At
- * that point, the allocation is not aborted, just a log is printed to ALOGE
- * (matched against `VALID_USAGE`). These should be aligned.
- */
-static bool log_deprecated_usage_flags(uint64_t usage) {
- if (usage & MALI_GRALLOC_USAGE_FRONTBUFFER) {
- MALI_GRALLOC_LOGW("Using deprecated FRONTBUFFER usage bit, please upgrade to BufferUsage::FRONT_BUFFER");
- return true;
- }
-
- return false;
-}
-
-/*
- * Modify usage flag when BO is the producer
- *
- * BO cannot use the flags CPU_READ_RARELY as Codec layer redefines those flags
- * for some internal usage. So, when BO is sending CPU_READ_OFTEN, it still
- * expects to allocate an uncached buffer and this procedure convers the OFTEN
- * flag to RARELY.
- */
-static uint64_t update_usage_for_BO(uint64_t usage) {
- MALI_GRALLOC_LOGV("Hacking CPU RW flags for BO");
- if (usage & hidl_common::BufferUsage::CPU_READ_OFTEN) {
- usage &= ~(static_cast<uint64_t>(hidl_common::BufferUsage::CPU_READ_OFTEN));
- usage |= hidl_common::BufferUsage::CPU_READ_RARELY;
- }
-
- if (usage & hidl_common::BufferUsage::CPU_WRITE_OFTEN) {
- usage &= ~(static_cast<uint64_t>(hidl_common::BufferUsage::CPU_WRITE_OFTEN));
- usage |= hidl_common::BufferUsage::CPU_WRITE_RARELY;
- }
- return usage;
-}
-
-static void align_plane_stride(plane_info_t *plane_info, int plane, const format_info_t format, uint32_t stride_align)
-{
- plane_info[plane].byte_stride = GRALLOC_ALIGN(plane_info[plane].byte_stride * format.tile_size, stride_align) / format.tile_size;
- plane_info[plane].alloc_width = plane_info[plane].byte_stride * 8 / format.bpp[plane];
-}
-
-/*
- * Calculate allocation size.
- *
- * Determine the width and height of each plane based on pixel alignment for
- * both uncompressed and AFBC allocations.
- *
- * @param width [in] Buffer width.
- * @param height [in] Buffer height.
- * @param alloc_type [in] Allocation type inc. whether tiled and/or multi-plane.
- * @param format [in] Pixel format.
- * @param has_cpu_usage [in] CPU usage requested (in addition to any other).
- * @param pixel_stride [out] Calculated pixel stride.
- * @param size [out] Total calculated buffer size including all planes.
- * @param plane_info [out] Array of calculated information for each plane. Includes
- * offset, byte stride and allocation width and height.
- */
-static void calc_allocation_size(const int width,
- const int height,
- const alloc_type_t alloc_type,
- const format_info_t format,
- const bool has_cpu_usage,
- const bool has_hw_usage,
- const bool has_gpu_usage,
- int * const pixel_stride,
- uint64_t * const size,
- plane_info_t plane_info[MAX_PLANES])
-{
- /* pixel_stride is set outside this function after this function is called */
- GRALLOC_UNUSED(pixel_stride);
-
- plane_info[0].offset = 0;
-
- *size = 0;
- for (uint8_t plane = 0; plane < format.npln; plane++)
- {
- plane_info[plane].alloc_width = width;
- plane_info[plane].alloc_height = height;
- get_pixel_w_h(&plane_info[plane].alloc_width,
- &plane_info[plane].alloc_height,
- format,
- alloc_type,
- plane,
- has_cpu_usage);
- MALI_GRALLOC_LOGV("Aligned w=%d, h=%d (in pixels)",
- plane_info[plane].alloc_width, plane_info[plane].alloc_height);
-
- /*
- * Calculate byte stride (per plane).
- */
- if (alloc_type.is_afbc())
- {
- assert((plane_info[plane].alloc_width * format.bpp_afbc[plane]) % 8 == 0);
- plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp_afbc[plane]) / 8;
- }
- else
- {
- assert((plane_info[plane].alloc_width * format.bpp[plane]) % 8 == 0);
- plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp[plane]) / 8;
-
- /*
- * Align byte stride (uncompressed allocations only).
- *
- * Find the lowest-common-multiple of:
- * 1. hw_align: Minimum byte stride alignment for HW IP (has_hw_usage == true)
- * 2. cpu_align: Byte equivalent of 'align_w_cpu' (has_cpu_usage == true)
- *
- * NOTE: Pixel stride is defined as multiple of 'align_w_cpu'.
- */
- uint16_t hw_align = 0;
- if (has_hw_usage)
- {
- static_assert(is_power2(YUV_BYTE_ALIGN_DEFAULT),
- "YUV_BYTE_ALIGN_DEFAULT is not a power of 2");
- static_assert(is_power2(RGB_BYTE_ALIGN_DEFAULT),
- "RGB_BYTE_ALIGN_DEFAULT is not a power of 2");
-
- hw_align = format.is_yuv ?
- YUV_BYTE_ALIGN_DEFAULT :
- (format.is_rgb ? RGB_BYTE_ALIGN_DEFAULT : 0);
- }
-
- if (has_gpu_usage)
- {
- static_assert(is_power2(GPU_BYTE_ALIGN_DEFAULT),
- "RGB_BYTE_ALIGN_DEFAULT is not a power of 2");
-
- /*
- * The GPU requires stricter alignment on YUV and raw formats.
- */
- hw_align = std::max(hw_align, static_cast<uint16_t>(GPU_BYTE_ALIGN_DEFAULT));
- }
-
- uint32_t cpu_align = 0;
-
-#if CAN_SKIP_CPU_ALIGN == 1
- if (has_cpu_usage)
-#endif
- {
- assert((format.bpp[plane] * format.align_w_cpu) % 8 == 0);
- const bool is_primary_plane = (plane == 0 || !format.planes_contiguous);
- if (is_primary_plane)
- {
- cpu_align = (format.bpp[plane] * format.align_w_cpu) / 8;
- }
- }
-
- uint32_t stride_align = lcm(hw_align, cpu_align);
- if (stride_align)
- {
- align_plane_stride(plane_info, plane, format, stride_align);
- }
-
-#if REALIGN_YV12 == 1
- /*
- * Update YV12 stride with both CPU & HW usage due to constraint of chroma stride.
- * Width is anyway aligned to 16px for luma and chroma (has_cpu_usage).
- *
- * Note: To prevent luma stride misalignment with GPU stride alignment.
- * The luma plane will maintain the same `stride` size, and the chroma plane
- * will align to `stride/2`.
- */
- if (format.id == MALI_GRALLOC_FORMAT_INTERNAL_YV12 && has_hw_usage && has_cpu_usage)
- {
- update_yv12_stride(plane,
- plane_info[0].byte_stride,
- stride_align,
- &plane_info[plane].byte_stride);
- }
-#endif
- }
- MALI_GRALLOC_LOGV("Byte stride: %d", plane_info[plane].byte_stride);
-
- const uint32_t sb_num = (plane_info[plane].alloc_width * plane_info[plane].alloc_height)
- / AFBC_PIXELS_PER_BLOCK;
-
- /*
- * Calculate body size (per plane).
- */
- int body_size = 0;
- if (alloc_type.is_afbc())
- {
- const rect_t sb = get_afbc_sb_size(alloc_type, plane);
- const int sb_bytes = GRALLOC_ALIGN((format.bpp_afbc[plane] * sb.width * sb.height) / 8, 128);
- body_size = sb_num * sb_bytes;
-
- /* When AFBC planes are stored in separate buffers and this is not the last plane,
- also align the body buffer to make the subsequent header aligned. */
- if (format.npln > 1 && plane < 2)
- {
- afbc_buffer_align(alloc_type.is_tiled, &body_size);
- }
-
- if (alloc_type.is_frontbuffer_safe)
- {
- int back_buffer_size = body_size;
- afbc_buffer_align(alloc_type.is_tiled, &back_buffer_size);
- body_size += back_buffer_size;
- }
- }
- else
- {
- body_size = plane_info[plane].byte_stride * plane_info[plane].alloc_height;
- }
- MALI_GRALLOC_LOGV("Body size: %d", body_size);
-
-
- /*
- * Calculate header size (per plane).
- */
- int header_size = 0;
- if (alloc_type.is_afbc())
- {
- /* As this is AFBC, calculate header size for this plane.
- * Always align the header, which will make the body buffer aligned.
- */
- header_size = sb_num * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY;
- afbc_buffer_align(alloc_type.is_tiled, &header_size);
- }
- MALI_GRALLOC_LOGV("AFBC Header size: %d", header_size);
-
- /*
- * Set offset for separate chroma planes.
- */
- if (plane > 0)
- {
- plane_info[plane].offset = *size;
- }
-
- /*
- * Set overall size.
- * Size must be updated after offset.
- */
- *size += body_size + header_size;
- MALI_GRALLOC_LOGV("size=%" PRIu64, *size);
- }
-}
-
-
-
-/*
- * Validate selected format against requested.
- * Return true if valid, false otherwise.
- */
-static bool validate_format(const format_info_t * const format,
- const alloc_type_t alloc_type,
- const buffer_descriptor_t * const bufDescriptor)
-{
- if (alloc_type.is_afbc())
- {
- /*
- * Validate format is supported by AFBC specification and gralloc.
- */
- if (format->afbc == false)
- {
- MALI_GRALLOC_LOGE("ERROR: AFBC selected but not supported for base format: (%s 0x%" PRIx32")",
- format_name(format->id), format->id);
- return false;
- }
-
- /*
- * Enforce consistency between number of format planes and
- * request for single/multi-plane AFBC.
- */
- if (((format->npln == 1 && alloc_type.is_multi_plane) ||
- (format->npln > 1 && !alloc_type.is_multi_plane)))
- {
- MALI_GRALLOC_LOGE("ERROR: Format ((%s %" PRIx32 "), num planes: %u) is incompatible with %s-plane AFBC request",
- format_name(format->id), format->id, format->npln, (alloc_type.is_multi_plane) ? "multi" : "single");
- return false;
- }
- }
- else
- {
- if (format->linear == false)
- {
- MALI_GRALLOC_LOGE("ERROR: Uncompressed format requested but not supported for base format: (%s %" PRIx32 ")",
- format_name(format->id), format->id);
- return false;
- }
- }
-
- if (format->id == MALI_GRALLOC_FORMAT_INTERNAL_BLOB &&
- bufDescriptor->height != 1)
- {
- MALI_GRALLOC_LOGE("ERROR: Height for format BLOB must be 1.");
- return false;
- }
-
- return true;
-}
-
-static int prepare_descriptor_exynos_formats(
- buffer_descriptor_t *bufDescriptor,
- format_info_t format_info)
-{
- int fd_count = 1;
- int w = bufDescriptor->width;
- int h = bufDescriptor->height;
- uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage;
- int plane_count = 2;
- int format = MALI_GRALLOC_INTFMT_FMT_MASK & bufDescriptor->alloc_format;
-
- if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_HW_VIDEO_DECODER))
- {
- usage |= GRALLOC_USAGE_VIDEO_PRIVATE_DATA;
- bufDescriptor->producer_usage |= GRALLOC_USAGE_VIDEO_PRIVATE_DATA;
- bufDescriptor->consumer_usage |= GRALLOC_USAGE_VIDEO_PRIVATE_DATA;
- }
-
- /* set SBWC format fd_count */
- fd_count = 1;
- switch (format)
- {
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
- fd_count = 2;
- break;
- }
-
- /* SWBC Formats have special size requirements */
- switch (format)
- {
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
- plane_count = setup_sbwc_420_sp(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
- plane_count = setup_sbwc_420_sp_10bit(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
- plane_count = setup_sbwc_420_sp_lossy(w, h, 50, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
- plane_count = setup_sbwc_420_sp_lossy(w, h, 75, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
- plane_count = setup_sbwc_420_sp_10bit_lossy(w, h, 40, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
- plane_count = setup_sbwc_420_sp_10bit_lossy(w, h, 60, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
- plane_count = setup_sbwc_420_sp_10bit_lossy(w, h, 80, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- fd_count = 1;
- h = GRALLOC_ALIGN(h, 2);
- plane_count = setup_420_sp(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
- w = GRALLOC_ALIGN(w, 32);
- h = GRALLOC_ALIGN(h, 16);
- fd_count = 3;
- plane_count = setup_420_p(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
- w = GRALLOC_ALIGN(w, 16);
- h = GRALLOC_ALIGN(h, 32);
- fd_count = 2;
- plane_count = setup_420_sp_tiled(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
- w = GRALLOC_ALIGN(w, 16);
- fd_count = 1;
- plane_count = setup_420_p(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
- case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
- w = GRALLOC_ALIGN(w, 16);
- h = GRALLOC_ALIGN(h, 32);
- fd_count = 2;
- plane_count = setup_420_sp(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
- w = GRALLOC_ALIGN(w, 16);
- h = GRALLOC_ALIGN(h, 16);
- fd_count = 1;
- plane_count = setup_420_sp(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
- /* This is 64 pixel align for now */
- w = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN);
- h = GRALLOC_ALIGN(h, 16);
- fd_count = 2;
- plane_count = setup_420_sp_s10b(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
- w = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN);
- h = GRALLOC_ALIGN(h, 16);
- fd_count = 1;
- plane_count = setup_420_sp_s10b(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
- w = GRALLOC_ALIGN(w, 16);
- h = GRALLOC_ALIGN(h, 16);
- fd_count = 2;
- plane_count = setup_p010_sp(w, h, fd_count, bufDescriptor->plane_info);
- break;
-
- default:
- MALI_GRALLOC_LOGE("invalid yuv format (%s %" PRIx64 ")", format_name(bufDescriptor->alloc_format),
- bufDescriptor->alloc_format);
- return -1;
- }
-
- plane_info_t *plane = bufDescriptor->plane_info;
-
- if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER))
- {
- if (is_sbwc_format(format))
- {
- MALI_GRALLOC_LOGE("using SBWC format (%s %" PRIx64 ") with GPU is invalid",
- format_name(bufDescriptor->alloc_format),
- bufDescriptor->alloc_format);
- return -1;
- }
- else
- {
- /*
- * The GPU requires stricter alignment on YUV formats.
- */
- for (int pidx = 0; pidx < plane_count; ++pidx)
- {
- if (plane[pidx].size == plane[pidx].byte_stride * plane[pidx].alloc_height)
- {
- align_plane_stride(plane, pidx, format_info, GPU_BYTE_ALIGN_DEFAULT);
- plane[pidx].size = plane[pidx].byte_stride * plane[pidx].alloc_height;
- }
- else
- {
- MALI_GRALLOC_LOGE("buffer with format (%s %" PRIx64
- ") has size %" PRIu64
- " != byte_stride %" PRIu32 " * alloc_height %" PRIu32,
- format_name(bufDescriptor->alloc_format),
- bufDescriptor->alloc_format,
- plane[pidx].size, plane[pidx].byte_stride, plane[pidx].alloc_height);
- }
- }
- }
- }
-
- for (int fidx = 0; fidx < fd_count; fidx++)
- {
- uint64_t size = 0;
-
- for (int pidx = 0; pidx < plane_count; pidx++)
- {
- if (plane[pidx].fd_idx == fidx)
- {
- size += plane[pidx].size;
- }
- }
-
- /* TODO(b/183073089): Removing the following size hacks make video playback
- * fail. Need to investigate more for the root cause. Copying the original
- * comment from upstream below */
- /* is there a need to check the condition for padding like in older gralloc? */
- /* Add MSCL_EXT_SIZE */
- /* MSCL_EXT_SIZE + MSCL_EXT_SIZE/2 + ext_size */
- size += 1024;
-
- size = size < SZ_4K ? SZ_4K : size;
-
- bufDescriptor->alloc_sizes[fidx] = size;
- }
-
-
- bufDescriptor->fd_count = fd_count;
- bufDescriptor->plane_count = plane_count;
-
- return 0;
-}
-
-int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescriptor)
-{
- alloc_type_t alloc_type{};
-
- int alloc_width = bufDescriptor->width;
- int alloc_height = bufDescriptor->height;
- uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage;
-
- /*
- * Select optimal internal pixel format based upon
- * usage and requested format.
- */
- bufDescriptor->alloc_format = mali_gralloc_select_format(bufDescriptor->hal_format,
- bufDescriptor->format_type,
- usage,
- bufDescriptor->width * bufDescriptor->height);
- if (bufDescriptor->alloc_format == MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED)
- {
- MALI_GRALLOC_LOGE("ERROR: Unrecognized and/or unsupported format (%s 0x%" PRIx64 ") and usage (%s 0x%" PRIx64 ")",
- format_name(bufDescriptor->hal_format), bufDescriptor->hal_format,
- describe_usage(usage).c_str(), usage);
- return -EINVAL;
- }
-
- int32_t format_idx = get_format_index(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
- if (format_idx == -1)
- {
- return -EINVAL;
- }
- MALI_GRALLOC_LOGV("alloc_format: (%s 0x%" PRIx64 ") format_idx: %d",
- format_name(bufDescriptor->alloc_format), bufDescriptor->alloc_format, format_idx);
-
- /*
- * Obtain allocation type (uncompressed, AFBC basic, etc...)
- */
- if (!get_alloc_type(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_EXT_MASK,
- format_idx, usage, &alloc_type))
- {
- return -EINVAL;
- }
-
- if (!validate_format(&formats[format_idx], alloc_type, bufDescriptor))
- {
- return -EINVAL;
- }
-
- if (is_exynos_format(bufDescriptor->alloc_format))
- {
- prepare_descriptor_exynos_formats(bufDescriptor, formats[format_idx]);
- }
- else
- {
- /*
- * Resolution of frame (allocation width and height) might require adjustment.
- * This adjustment is only based upon specific usage and pixel format.
- * If using AFBC, further adjustments to the allocation width and height will be made later
- * based on AFBC alignment requirements and, for YUV, the plane properties.
- */
- mali_gralloc_adjust_dimensions(bufDescriptor->alloc_format,
- usage,
- &alloc_width,
- &alloc_height);
-
- /* Obtain buffer size and plane information. */
- calc_allocation_size(alloc_width,
- alloc_height,
- alloc_type,
- formats[format_idx],
- usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK),
- usage & ~(GRALLOC_USAGE_PRIVATE_MASK | GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK),
- usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER),
- &bufDescriptor->pixel_stride,
- &bufDescriptor->alloc_sizes[0],
- bufDescriptor->plane_info);
- }
-
- /* Set pixel stride differently for RAW formats */
- switch (MALI_GRALLOC_INTFMT_FMT_MASK & bufDescriptor->alloc_format)
- {
- case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
- case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
- bufDescriptor->pixel_stride = bufDescriptor->plane_info[0].byte_stride;
- break;
- default:
- bufDescriptor->pixel_stride = bufDescriptor->plane_info[0].alloc_width;
- }
-
- /*
- * Each layer of a multi-layer buffer must be aligned so that
- * it is accessible by both producer and consumer. In most cases,
- * the stride alignment is also sufficient for each layer, however
- * for AFBC the header buffer alignment is more constrained (see
- * AFBC specification v3.4, section 2.15: "Alignment requirements").
- * Also update the buffer size to accommodate all layers.
- */
- if (bufDescriptor->layer_count > 1)
- {
- if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
- {
- if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
- {
- bufDescriptor->alloc_sizes[0] = GRALLOC_ALIGN(bufDescriptor->alloc_sizes[0], 4096);
- }
- else
- {
- bufDescriptor->alloc_sizes[0] = GRALLOC_ALIGN(bufDescriptor->alloc_sizes[0], 128);
- }
- }
-
- bufDescriptor->alloc_sizes[0] *= bufDescriptor->layer_count;
- }
-
- /* MFC requires EXT_SIZE padding */
- bufDescriptor->alloc_sizes[0] += EXT_SIZE;
-
- return 0;
-}
-
-
-int mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t *descriptors,
- uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend,
- int fd)
-{
- bool shared = false;
- uint64_t backing_store_id = 0x0;
- int err;
-
- for (uint32_t i = 0; i < numDescriptors; i++)
- {
- buffer_descriptor_t * const bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
-
- assert(bufDescriptor->producer_usage == bufDescriptor->consumer_usage);
- uint64_t usage = bufDescriptor->producer_usage;
- if ((usage & hidl_common::BufferUsage::VIDEO_DECODER) && (usage & GRALLOC_USAGE_GOOGLE_IP_BO)) {
- usage = update_usage_for_BO(usage);
- bufDescriptor->producer_usage = usage;
- bufDescriptor->consumer_usage = usage;
- }
-
- if (log_deprecated_usage_flags(usage)) {
- return -EINVAL;
- }
-
- /* Derive the buffer size from descriptor parameters */
- err = mali_gralloc_derive_format_and_size(bufDescriptor);
- if (err != 0)
- {
- return err;
- }
- }
-
- /* Allocate ION backing store memory */
- err = mali_gralloc_ion_allocate(descriptors, numDescriptors, pHandle, &shared, fd);
- if (err < 0)
- {
- return err;
- }
-
- if (shared)
- {
- backing_store_id = getUniqueId();
- }
-
- for (uint32_t i = 0; i < numDescriptors; i++)
- {
- private_handle_t *hnd = (private_handle_t *)pHandle[i];
-
- if (shared)
- {
- /*each buffer will share the same backing store id.*/
- hnd->backing_store_id = backing_store_id;
- }
- else
- {
- /* each buffer will have an unique backing store id.*/
- hnd->backing_store_id = getUniqueId();
- }
- }
-
- if (NULL != shared_backend)
- {
- *shared_backend = shared;
- }
-
- return 0;
-}
-
-int mali_gralloc_buffer_free(buffer_handle_t pHandle)
-{
- auto *hnd = const_cast<private_handle_t *>(
- reinterpret_cast<const private_handle_t *>(pHandle));
-
- if (hnd == nullptr)
- {
- return -1;
- }
-
- gralloc_shared_memory_free(hnd);
- mali_gralloc_ion_free(hnd);
-
- return 0;
-}