diff options
Diffstat (limited to 'gralloc4/src/core/mali_gralloc_bufferallocation.cpp')
-rw-r--r-- | gralloc4/src/core/mali_gralloc_bufferallocation.cpp | 174 |
1 files changed, 103 insertions, 71 deletions
diff --git a/gralloc4/src/core/mali_gralloc_bufferallocation.cpp b/gralloc4/src/core/mali_gralloc_bufferallocation.cpp index d67eeb8..54e7f2f 100644 --- a/gralloc4/src/core/mali_gralloc_bufferallocation.cpp +++ b/gralloc4/src/core/mali_gralloc_bufferallocation.cpp @@ -82,11 +82,11 @@ static uint64_t getUniqueId() return id | counter++; } -static void afbc_buffer_align(const bool is_tiled, int *size) +template<typename T> +static void afbc_buffer_align(const bool is_tiled, T *size) { - const uint16_t AFBC_BODY_BUFFER_BYTE_ALIGNMENT = 1024; - - int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; + constexpr T AFBC_BODY_BUFFER_BYTE_ALIGNMENT = 1024; + T buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT; if (is_tiled) { @@ -244,13 +244,13 @@ bool get_alloc_type(const uint64_t format_ext, */ void init_afbc(uint8_t *buf, const uint64_t alloc_format, const bool is_multi_plane, - const int w, const int h) + const uint64_t w, const uint64_t h) { ATRACE_CALL(); 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; + uint32_t body_offset = n_headers * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY; afbc_buffer_align(is_tiled, &body_offset); @@ -266,7 +266,7 @@ void init_afbc(uint8_t *buf, const uint64_t alloc_format, 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); + memset(headers[0], 0, sizeof(size_t) * 4); } /* Map base format to AFBC header layout */ @@ -295,24 +295,14 @@ void init_afbc(uint8_t *buf, const uint64_t alloc_format, } } -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, +static void get_pixel_w_h(uint64_t * const width, + uint64_t * const height, const format_info_t format, const alloc_type_t alloc_type, const uint8_t plane, @@ -345,14 +335,14 @@ static void get_pixel_w_h(uint32_t * const width, * Pixel alignment (width), * where format stride is stated in pixels. */ - int pixel_align_w = 1, pixel_align_h = 1; + uint32_t 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) + constexpr uint32_t HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS = 0; uint32_t num_sb_align = 0; if (alloc_type.is_padded && !format.is_yuv) { @@ -361,7 +351,7 @@ static void get_pixel_w_h(uint32_t * const width, */ num_sb_align = 4; } - pixel_align_w = max(HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS, num_sb_align) * sb.width; + pixel_align_w = std::max(HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS, num_sb_align) * sb.width; /* * Determine AFBC tile size when allocating tiled headers. @@ -373,13 +363,13 @@ static void get_pixel_w_h(uint32_t * const 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]: [SUB-SAMPLE] w:%" PRIu64 ", h:%" PRIu64 "\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); + MALI_GRALLOC_LOGV("Plane[%hhu]: [AFBC_TILE] w:%" PRIu64 ", h:%" PRIu64 "\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); + pixel_align_w = std::max(static_cast<uint64_t>(pixel_align_w), afbc_tile.width); + pixel_align_h = std::max(static_cast<uint64_t>(pixel_align_h), afbc_tile.height); if (AllocBaseType::AFBC_WIDEBLK == alloc_type.primary_type && !alloc_type.is_tiled) { @@ -391,18 +381,17 @@ static void get_pixel_w_h(uint32_t * const width, * 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); + pixel_align_h = std::max(pixel_align_h, 16u); } } - *width = GRALLOC_ALIGN(*width, max(1, pixel_align_w, format.tile_size)); - *height = GRALLOC_ALIGN(*height, max(1, pixel_align_h, format.tile_size)); + *width = GRALLOC_ALIGN(*width, std::max({1u, pixel_align_w, static_cast<uint32_t>(format.tile_size)})); + *height = GRALLOC_ALIGN(*height, std::max({1u, pixel_align_h, static_cast<uint32_t>(format.tile_size)})); } - - -static uint32_t gcd(uint32_t a, uint32_t b) +template<typename T> +static T gcd(T a, T b) { - uint32_t r, t; + T r, t; if (a == b) { @@ -425,14 +414,15 @@ static uint32_t gcd(uint32_t a, uint32_t b) return a; } -uint32_t lcm(uint32_t a, uint32_t b) +template<typename T> +T lcm(T a, T b) { if (a != 0 && b != 0) { return (a * b) / gcd(a, b); } - return max(a, b); + return std::max(a, b); } @@ -447,9 +437,9 @@ uint32_t lcm(uint32_t a, uint32_t b) * constraints, the luma stride must be doubled. */ static void update_yv12_stride(int8_t plane, - uint32_t luma_stride, + size_t luma_stride, uint32_t stride_align, - uint32_t * byte_stride) + uint64_t * byte_stride) { // https://developer.android.com/reference/android/graphics/ImageFormat#YV12 if (plane == 0) { @@ -464,23 +454,66 @@ static void update_yv12_stride(int8_t plane, #endif /* - * Logs and returns true if deprecated usage bits are found + * Logs and returns false 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) { +static bool log_obsolete_usage_flags(uint64_t usage) { if (usage & DEPRECATED_MALI_GRALLOC_USAGE_FRONTBUFFER) { MALI_GRALLOC_LOGW("Using deprecated FRONTBUFFER usage bit, please upgrade to BufferUsage::FRONT_BUFFER"); - return true; + return false; + } + if (usage & UNSUPPORTED_MALI_GRALLOC_USAGE_CUBE_MAP) { + MALI_GRALLOC_LOGW("BufferUsage::GPU_CUBE_MAP is unsupported"); + return false; + } + if (usage & UNSUPPORTED_MALI_GRALLOC_USAGE_MIPMAP_COMPLETE) { + MALI_GRALLOC_LOGW("BufferUsage::GPU_MIPMAP_COMPLETE is unsupported"); + return false; + } + + return true; +} + +static bool validate_size(uint32_t layer_count, uint32_t width, uint32_t height) { + // The max size of an image can be from camera (50 Megapixels) and considering the max + // depth of 4 bytes per pixel, we get an image of size 200MB. + // We can keep twice the margin for a max size of 400MB. + uint64_t overflow_limit = 400 * (1 << 20); + + // Maximum 4 bytes per pixel buffers are supported (RGBA). This does not take care of + // alignment, but 400MB is already very generous, so there should not be an issue. + overflow_limit /= 4; + overflow_limit /= layer_count; + + if (width > overflow_limit) { + MALI_GRALLOC_LOGE("Parameters layer: %" PRIu32 ", width: %" PRIu32 ", height: %" PRIu32 " are too big", layer_count, width, height); + return false; + } + overflow_limit /= width; + + if (height > overflow_limit) { + MALI_GRALLOC_LOGE("Parameters layer: %" PRIu32 ", width: %" PRIu32 ", height: %" PRIu32 " are too big", layer_count, width, height); + return false; } - return false; + return true; +} + +static bool validate_descriptor(buffer_descriptor_t * const bufDescriptor) { + if (!log_obsolete_usage_flags(bufDescriptor->producer_usage | bufDescriptor->consumer_usage)) { + return false; + } + + // BLOB formats are used for some ML models whose size can be really large (up to 2GB) + if (bufDescriptor->hal_format != MALI_GRALLOC_FORMAT_INTERNAL_BLOB && + !validate_size(bufDescriptor->layer_count, bufDescriptor->width, bufDescriptor->height)) { + return false; + } + + return true; } /* @@ -505,7 +538,7 @@ static uint64_t update_usage_for_BIG(uint64_t usage) { return usage; } -static void align_plane_stride(plane_info_t *plane_info, int plane, const format_info_t format, uint32_t stride_align) +static void align_plane_stride(plane_info_t *plane_info, uint8_t 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]; @@ -540,8 +573,8 @@ static void calc_allocation_size(const int width, const bool has_gpu_usage, const bool has_BIG_usage, const bool has_camera_usage, - int * const pixel_stride, - uint64_t * const size, + uint64_t * 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 */ @@ -563,7 +596,7 @@ static void calc_allocation_size(const int width, alloc_type, plane, has_cpu_usage); - MALI_GRALLOC_LOGV("Aligned w=%d, h=%d (in pixels)", + MALI_GRALLOC_LOGV("Aligned w=%" PRIu64 ", h=%" PRIu64 " (in pixels)", plane_info[plane].alloc_width, plane_info[plane].alloc_height); /* @@ -577,7 +610,7 @@ static void calc_allocation_size(const int width, else { assert((plane_info[plane].alloc_width * format.bpp[plane]) % 8 == 0); - plane_info[plane].byte_stride = (static_cast<uint64_t>(plane_info[plane].alloc_width) * format.bpp[plane]) / 8; + plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp[plane]) / 8; /* * Align byte stride (uncompressed allocations only). @@ -588,7 +621,7 @@ static void calc_allocation_size(const int width, * * NOTE: Pixel stride is defined as multiple of 'align_w_cpu'. */ - uint16_t hw_align = 0; + uint32_t hw_align = 0; if (has_hw_usage) { static_assert(is_power2(YUV_BYTE_ALIGN_DEFAULT), @@ -609,7 +642,7 @@ static void calc_allocation_size(const int width, /* * The GPU requires stricter alignment on YUV and raw formats. */ - hw_align = std::max(hw_align, static_cast<uint16_t>(GPU_BYTE_ALIGN_DEFAULT)); + hw_align = std::max(hw_align, static_cast<uint32_t>(GPU_BYTE_ALIGN_DEFAULT)); } #ifdef SOC_ZUMA @@ -619,13 +652,13 @@ static void calc_allocation_size(const int width, /* * Camera ISP requires RAW buffers to have 32-byte aligned stride */ - hw_align = std::max(hw_align, static_cast<uint16_t>(CAMERA_RAW_BUFFER_BYTE_ALIGN)); + hw_align = std::max(hw_align, static_cast<uint32_t>(CAMERA_RAW_BUFFER_BYTE_ALIGN)); } #endif if (has_BIG_usage) { assert(has_hw_usage); - hw_align = lcm(hw_align, static_cast<uint16_t>(BIG_BYTE_ALIGN_DEFAULT)); + hw_align = lcm(hw_align, static_cast<uint32_t>(BIG_BYTE_ALIGN_DEFAULT)); } uint32_t cpu_align = 0; @@ -661,7 +694,7 @@ static void calc_allocation_size(const int width, } #endif } - MALI_GRALLOC_LOGV("Byte stride: %d", plane_info[plane].byte_stride); + MALI_GRALLOC_LOGV("Byte stride: %" PRIu64, plane_info[plane].byte_stride); const uint32_t sb_num = (plane_info[plane].alloc_width * plane_info[plane].alloc_height) / AFBC_PIXELS_PER_BLOCK; @@ -669,11 +702,11 @@ static void calc_allocation_size(const int width, /* * Calculate body size (per plane). */ - int body_size = 0; + size_t 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); + const size_t 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, @@ -685,7 +718,7 @@ static void calc_allocation_size(const int width, if (alloc_type.is_frontbuffer_safe) { - int back_buffer_size = body_size; + size_t back_buffer_size = body_size; afbc_buffer_align(alloc_type.is_tiled, &back_buffer_size); body_size += back_buffer_size; } @@ -701,13 +734,13 @@ static void calc_allocation_size(const int width, } body_size = plane_info[plane].byte_stride * plane_info[plane].alloc_height; } - MALI_GRALLOC_LOGV("Body size: %d", body_size); + MALI_GRALLOC_LOGV("Body size: %zu", body_size); /* * Calculate header size (per plane). */ - int header_size = 0; + size_t header_size = 0; if (alloc_type.is_afbc()) { /* As this is AFBC, calculate header size for this plane. @@ -716,7 +749,7 @@ static void calc_allocation_size(const int width, 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); + MALI_GRALLOC_LOGV("AFBC Header size: %zu", header_size); /* * Set offset for separate chroma planes. @@ -942,7 +975,7 @@ static int prepare_descriptor_exynos_formats( { MALI_GRALLOC_LOGE("buffer with format (%s %" PRIx64 ") has size %" PRIu64 - " != byte_stride %" PRIu32 " * alloc_height %" PRIu32, + " != byte_stride %" PRIu64 " * alloc_height %" PRIu64, format_name(bufDescriptor->alloc_format), bufDescriptor->alloc_format, plane[pidx].size, plane[pidx].byte_stride, plane[pidx].alloc_height); @@ -987,10 +1020,14 @@ int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescripto ATRACE_CALL(); alloc_type_t alloc_type{}; - int alloc_width = bufDescriptor->width; - int alloc_height = bufDescriptor->height; + uint64_t alloc_width = bufDescriptor->width; + uint64_t alloc_height = bufDescriptor->height; uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage; + if (!validate_descriptor(bufDescriptor)) { + return -EINVAL; + } + /* * Select optimal internal pixel format based upon * usage and requested format. @@ -1126,7 +1163,7 @@ int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescripto int mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t *descriptors, uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend, - int fd) + bool use_placeholder) { std::string atrace_log = __FUNCTION__; if (ATRACE_ENABLED()) { @@ -1156,11 +1193,6 @@ int mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t *descriptors, bufDescriptor->consumer_usage = usage; } - if (log_deprecated_usage_flags(usage)) - { - return -EINVAL; - } - /* Derive the buffer size from descriptor parameters */ err = mali_gralloc_derive_format_and_size(bufDescriptor); if (err != 0) @@ -1170,7 +1202,7 @@ int mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t *descriptors, } /* Allocate ION backing store memory */ - err = mali_gralloc_ion_allocate(descriptors, numDescriptors, pHandle, &shared, fd); + err = mali_gralloc_ion_allocate(descriptors, numDescriptors, pHandle, &shared, use_placeholder); if (err < 0) { return err; |