From a096b149ea0a6a492d2c772a04b02d0ef93ec6e4 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 3 Aug 2024 19:34:55 +0300 Subject: [PATCH] misc/common: Add timing macros. Those can be used for timing functions. To enable build with PROFILE=1. --- src/Makefile | 5 +++++ src/omv/common/omv_common.h | 12 ++++++++++++ src/omv/imlib/draw.c | 2 ++ src/omv/imlib/imlib.h | 1 + src/omv/imlib/jpegd.c | 15 ++------------- src/omv/imlib/jpege.c | 17 +++-------------- src/omv/imlib/png.c | 24 ++++-------------------- src/omv/ports/stm32/jpeg.c | 26 +++++--------------------- src/omv/ports/stm32/omv_gpu.c | 20 ++++---------------- 9 files changed, 38 insertions(+), 84 deletions(-) diff --git a/src/Makefile b/src/Makefile index be51e1cbd..1919287d3 100755 --- a/src/Makefile +++ b/src/Makefile @@ -97,6 +97,11 @@ ifeq ($(FB_ALLOC_STATS), 1) CFLAGS += -DFB_ALLOC_STATS endif +# Enable timing for some functions. +ifeq ($(PROFILE), 1) +CFLAGS += -DOMV_PROFILE_ENABLE=1 +endif + # Include OpenMV board config first to set the port. include $(OMV_BOARD_CONFIG_DIR)/omv_boardconfig.mk diff --git a/src/omv/common/omv_common.h b/src/omv/common/omv_common.h index bbd379db1..af69e40ad 100644 --- a/src/omv/common/omv_common.h +++ b/src/omv/common/omv_common.h @@ -9,6 +9,7 @@ * Common macros. */ #ifndef __OMV_COMMON_H__ +#define __OMV_COMMON_H__ #define OMV_ATTR_ALIGNED(x, a) x __attribute__((aligned(a))) #define OMV_ATTR_SECTION(x, s) x __attribute__((section(s))) @@ -46,4 +47,15 @@ #define OMV_ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +#if OMV_PROFILE_ENABLE +#include +#include "py/mphal.h" + +#define OMV_PROFILE_START mp_uint_t omv_profile_ticks_start = mp_hal_ticks_us(); +#define OMV_PROFILE_END printf("%s %u us\n", __FUNCTION__, mp_hal_ticks_us() - omv_profile_ticks_start); +#else +#define OMV_PROFILE_START +#define OMV_PROFILE_END +#endif + #endif //__OMV_COMMON_H__ diff --git a/src/omv/imlib/draw.c b/src/omv/imlib/draw.c index 1914b6bfa..74a60ae33 100644 --- a/src/omv/imlib/draw.c +++ b/src/omv/imlib/draw.c @@ -2843,6 +2843,7 @@ void imlib_draw_image(image_t *dst_img, imlib_draw_row_callback_t callback, void *callback_arg, void *dst_row_override) { + OMV_PROFILE_START int dst_delta_x = 1; // positive direction if (x_scale < 0.f) { // flip X @@ -5517,6 +5518,7 @@ exit_cleanup: if (&new_src_img == src_img) { fb_free(); } + OMV_PROFILE_END } #ifdef IMLIB_ENABLE_FLOOD_FILL diff --git a/src/omv/imlib/imlib.h b/src/omv/imlib/imlib.h index 7330ab0ca..526a5e140 100644 --- a/src/omv/imlib/imlib.h +++ b/src/omv/imlib/imlib.h @@ -29,6 +29,7 @@ #include "collections.h" #include "imlib_config.h" #include "omv_boardconfig.h" +#include "omv_common.h" // Enables 38 TensorFlow Lite operators. #define IMLIB_TF_DEFAULT (1) diff --git a/src/omv/imlib/jpegd.c b/src/omv/imlib/jpegd.c index bc872561f..297a1b99f 100644 --- a/src/omv/imlib/jpegd.c +++ b/src/omv/imlib/jpegd.c @@ -16,12 +16,6 @@ #include "py/nlr.h" #include "py/runtime.h" -#define TIME_JPEG (0) -#if (TIME_JPEG == 1) -#include "py/mphal.h" -#include -#endif - #if (OMV_JPEG_CODEC_ENABLE == 0) /* Software JPEG decoder */ #define FILE_HIGHWATER 1536 @@ -2847,12 +2841,9 @@ static int DecodeJPEG(JPEGIMAGE *pJPEG) { } void jpeg_decompress(image_t *dst, image_t *src) { + OMV_PROFILE_START JPEGIMAGE jpg; - #if (TIME_JPEG == 1) - mp_uint_t start = mp_hal_ticks_ms(); - #endif - // Supports decoding baseline JPEGs only. if (!jpeg_is_valid(src)) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Non-Baseline JPEGs are not supported.")); @@ -2891,8 +2882,6 @@ void jpeg_decompress(image_t *dst, image_t *src) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("JPEG decoder failed.")); } - #if (TIME_JPEG == 1) - printf("time: %u ms\n", mp_hal_ticks_ms() - start); - #endif + OMV_PROFILE_END } #endif diff --git a/src/omv/imlib/jpege.c b/src/omv/imlib/jpege.c index 3452355ba..1983603a5 100644 --- a/src/omv/imlib/jpege.c +++ b/src/omv/imlib/jpege.c @@ -10,14 +10,8 @@ * Ported from public domain JPEG writer by Jon Olick - http://jonolick.com * DCT implementation is based on Arai, Agui, and Nakajima's algorithm for scaled DCT. */ -#include "file_utils.h" #include "imlib.h" - -#define TIME_JPEG (0) -#if (TIME_JPEG == 1) -#include -#include "py/mphal.h" -#endif +#include "file_utils.h" // Expand 4 bits to 32 for binary to grayscale - process 4 pixels at a time #if (OMV_JPEG_CODEC_ENABLE == 1) @@ -1615,9 +1609,7 @@ static void jpeg_write_headers(jpeg_buf_t *jpeg_buf, int w, int h, int bpp, jpeg } bool jpeg_compress(image_t *src, image_t *dst, int quality, bool realloc, jpeg_subsampling_t subsampling) { - #if (TIME_JPEG == 1) - mp_uint_t start = mp_hal_ticks_ms(); - #endif + OMV_PROFILE_START if (!dst->data) { uint32_t size = 0; @@ -1949,10 +1941,7 @@ bool jpeg_compress(image_t *src, image_t *dst, int quality, bool realloc, jpeg_s dst->size = jpeg_buf.idx; dst->data = jpeg_buf.buf; - #if (TIME_JPEG == 1) - printf("compress time: %u ms\n", mp_hal_ticks_ms() - start); - #endif - + OMV_PROFILE_END return false; } diff --git a/src/omv/imlib/png.c b/src/omv/imlib/png.c index 5d104dba9..12f8d3079 100644 --- a/src/omv/imlib/png.c +++ b/src/omv/imlib/png.c @@ -8,17 +8,13 @@ * * PNG CODEC */ -#include #include "imlib.h" -#include "py/mphal.h" #include "py/runtime.h" #include "file_utils.h" #if defined(IMLIB_ENABLE_PNG_ENCODER) || defined(IMLIB_ENABLE_PNG_DECODER) #include "lodepng.h" #include "umm_malloc.h" -#define TIME_PNG (0) - void *lodepng_malloc(size_t size) { return umm_malloc(size); } @@ -109,9 +105,7 @@ unsigned lodepng_convert_cb(unsigned char *out, const unsigned char *in, #if defined(IMLIB_ENABLE_PNG_ENCODER) bool png_compress(image_t *src, image_t *dst) { - #if (TIME_PNG == 1) - mp_uint_t start = mp_hal_ticks_ms(); - #endif + OMV_PROFILE_START if (src->is_compressed) { return true; @@ -183,21 +177,14 @@ bool png_compress(image_t *src, image_t *dst) { // free fb_alloc() memory used for umm_init_x(). fb_free(); // umm_init_x(); } - - #if (TIME_PNG == 1) - printf("time: %u ms\n", mp_hal_ticks_ms() - start); - #endif - + OMV_PROFILE_END return false; } #endif // IMLIB_ENABLE_PNG_ENCODER #if defined(IMLIB_ENABLE_PNG_DECODER) void png_decompress(image_t *dst, image_t *src) { - #if (TIME_PNG == 1) - mp_uint_t start = mp_hal_ticks_ms(); - #endif - + OMV_PROFILE_START umm_init_x(fb_avail()); LodePNGState state; @@ -239,10 +226,7 @@ void png_decompress(image_t *dst, image_t *src) { // free fb_alloc() memory used for umm_init_x(). fb_free(); // umm_init_x(); - - #if (TIME_PNG == 1) - printf("time: %u ms\n", mp_hal_ticks_ms() - start); - #endif + OMV_PROFILE_END } #endif // IMLIB_ENABLE_PNG_DECODER #endif // IMLIB_ENABLE_PNG_ENCODER || IMLIB_ENABLE_PNG_DECODER diff --git a/src/omv/ports/stm32/jpeg.c b/src/omv/ports/stm32/jpeg.c index 607ea7860..5caec8b62 100644 --- a/src/omv/ports/stm32/jpeg.c +++ b/src/omv/ports/stm32/jpeg.c @@ -19,11 +19,6 @@ #include "irq.h" #include "dma_utils.h" -#define TIME_JPEG (0) -#if (TIME_JPEG == 1) -#include -#endif - #define JPEG_CODEC_TIMEOUT (1000) #define JPEG_ALLOC_PADDING ((__SCB_DCACHE_LINE_SIZE) * 4) #define JPEG_OUTPUT_CHUNK_SIZE (512) // The minimum output buffer size is 2x this - so 1KB. @@ -111,10 +106,7 @@ static void jpeg_compress_data_ready(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataOu } bool jpeg_compress(image_t *src, image_t *dst, int quality, bool realloc, jpeg_subsampling_t subsampling) { - #if (TIME_JPEG == 1) - mp_uint_t start = mp_hal_ticks_ms(); - #endif - + OMV_PROFILE_START HAL_JPEG_RegisterGetDataCallback(&JPEG_state.jpeg_descr, jpeg_compress_get_data); HAL_JPEG_RegisterDataReadyCallback(&JPEG_state.jpeg_descr, jpeg_compress_data_ready); @@ -365,12 +357,7 @@ bool jpeg_compress(image_t *src, image_t *dst, int quality, bool realloc, jpeg_s // Clean trailing data after 0xFFD9 at the end of the jpeg byte stream. dst->size = jpeg_clean_trailing_bytes(dst->size, dst->data); - #if (TIME_JPEG == 1) - printf("compress time: %u ms\n", mp_hal_ticks_ms() - start); - #endif - exit_cleanup: - // Cleanup jpeg state. HAL_JPEG_Abort(&JPEG_state.jpeg_descr); HAL_JPEG_UnRegisterDataReadyCallback(&JPEG_state.jpeg_descr); @@ -378,6 +365,7 @@ exit_cleanup: fb_free(); // mcu_row_buffer (after DMA is aborted) + OMV_PROFILE_END return jpeg_overflow; } @@ -409,9 +397,7 @@ static void jpeg_decompress_data_ready(JPEG_HandleTypeDef *hjpeg, uint8_t *pData } void jpeg_decompress(image_t *dst, image_t *src) { - #if (TIME_JPEG == 1) - mp_uint_t start = mp_hal_ticks_ms(); - #endif + OMV_PROFILE_START // Verify the jpeg image is not a non-baseline jpeg image and check that is has // valid headers up to the start-of-scan header (which cannot be trivially walked). @@ -749,10 +735,6 @@ void jpeg_decompress(image_t *dst, image_t *src) { } } - #if (TIME_JPEG == 1) - printf("decompress time: %u ms\n", mp_hal_ticks_ms() - start); - #endif - exit_cleanup: // Cleanup jpeg state. @@ -769,6 +751,8 @@ exit_cleanup: if (((uint32_t) src->data) % __SCB_DCACHE_LINE_SIZE) { fb_free(); // JPEG_state.jpeg_descr.pJpegInBuffPtr (after DMA is aborted) } + + OMV_PROFILE_END } void imlib_hardware_jpeg_init() { diff --git a/src/omv/ports/stm32/omv_gpu.c b/src/omv/ports/stm32/omv_gpu.c index 1a82ca4af..27818db1e 100644 --- a/src/omv/ports/stm32/omv_gpu.c +++ b/src/omv/ports/stm32/omv_gpu.c @@ -10,17 +10,10 @@ */ #include "omv_boardconfig.h" #if (OMV_GPU_ENABLE == 1) -#include "imlib.h" - #include STM32_HAL_H +#include "imlib.h" #include "dma.h" -#define TIME_GPU (0) -#if (TIME_GPU == 1) -#include "py/mphal.h" -#include -#endif - int omv_gpu_init() { return 0; } @@ -39,6 +32,8 @@ int omv_gpu_draw_image(image_t *src_img, const uint16_t *color_palette, const uint8_t *alpha_palette, image_hint_t hint) { + OMV_PROFILE_START + // DMA2D can only draw on RGB565 buffers and the destination/source buffers must be accessible by DMA. if ((dst_img->pixfmt != PIXFORMAT_RGB565) || (!DMA_BUFFER(dst_img->data)) || (!DMA_BUFFER(src_img->data))) { return -1; @@ -69,10 +64,6 @@ int omv_gpu_draw_image(image_t *src_img, } #endif - #if (TIME_GPU == 1) - mp_uint_t start = mp_hal_ticks_ms(); - #endif - DMA2D_HandleTypeDef dma2d = {}; dma2d.Instance = DMA2D; @@ -220,10 +211,7 @@ int omv_gpu_draw_image(image_t *src_img, fb_free(); // clut } - #if (TIME_GPU == 1) - printf("draw time: %u ms\n", mp_hal_ticks_ms() - start); - #endif - + OMV_PROFILE_END return 0; } #endif // (OMV_GPU_ENABLE == 1)