diff --git a/components/esp_driver_ppa/test_apps/main/CMakeLists.txt b/components/esp_driver_ppa/test_apps/main/CMakeLists.txt index 25e3680685..5988460a63 100644 --- a/components/esp_driver_ppa/test_apps/main/CMakeLists.txt +++ b/components/esp_driver_ppa/test_apps/main/CMakeLists.txt @@ -5,5 +5,5 @@ set(srcs "test_app_main.c" # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} INCLUDE_DIRS "." - PRIV_REQUIRES esp_driver_ppa esp_psram unity + PRIV_REQUIRES esp_driver_ppa esp_psram unity esp_mm WHOLE_ARCHIVE) diff --git a/components/esp_driver_ppa/test_apps/main/test_ppa.c b/components/esp_driver_ppa/test_apps/main/test_ppa.c index 0dd676c664..b1ce989141 100644 --- a/components/esp_driver_ppa/test_apps/main/test_ppa.c +++ b/components/esp_driver_ppa/test_apps/main/test_ppa.c @@ -16,6 +16,7 @@ #include "esp_err.h" #include "ccomp_timer.h" #include "hal/color_hal.h" +#include "esp_cache.h" #define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) @@ -35,9 +36,9 @@ TEST_CASE("ppa_client_do_ppa_operation", "[PPA]") uint32_t buf_1_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(buf_1_cm) / 8, 64); uint32_t buf_2_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(buf_2_cm) / 8, 64); - uint8_t *buf_1 = heap_caps_aligned_calloc(64, buf_1_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *buf_1 = heap_caps_aligned_calloc(4, buf_1_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); // cache alignment is implicited by MALLOC_CAP_DMA TEST_ASSERT_NOT_NULL(buf_1); - uint8_t *buf_2 = heap_caps_aligned_calloc(64, buf_2_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *buf_2 = heap_caps_aligned_calloc(4, buf_2_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(buf_2); // Register different types of PPA clients @@ -167,7 +168,7 @@ TEST_CASE("ppa_pending_transactions_in_queue", "[PPA]") const uint32_t w = 1920; const uint32_t h = 1080; const uint32_t buf_1_color_type_id = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888); - const uint32_t buf_2_color_type_id = COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888); + const uint32_t buf_2_color_type_id = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420); color_space_pixel_format_t buf_1_cm = { .color_type_id = buf_1_color_type_id, @@ -178,9 +179,9 @@ TEST_CASE("ppa_pending_transactions_in_queue", "[PPA]") uint32_t buf_1_size = w * h * color_hal_pixel_format_get_bit_depth(buf_1_cm) / 8; uint32_t buf_2_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(buf_2_cm) / 8, 64); - uint8_t *buf_1 = heap_caps_aligned_calloc(64, buf_1_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *buf_1 = heap_caps_aligned_calloc(4, buf_1_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(buf_1); - uint8_t *buf_2 = heap_caps_aligned_calloc(64, buf_2_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *buf_2 = heap_caps_aligned_calloc(4, buf_2_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(buf_2); // Register two PPA SRM clients with different max_pending_trans_num @@ -261,14 +262,304 @@ TEST_CASE("ppa_pending_transactions_in_queue", "[PPA]") free(buf_2); } -TEST_CASE("ppa_srm_performance", "[PPA][ignore]") +TEST_CASE("ppa_srm_basic_data_correctness_check", "[PPA]") { + const uint32_t w = 4; + const uint32_t h = 4; + const uint32_t block_w = 3; + const uint32_t block_h = 3; + const uint32_t in_block_offset_x = 1; + const uint32_t in_block_offset_y = 1; + const uint32_t out_block_offset_x = 1; + const uint32_t out_block_offset_y = 0; + const ppa_srm_color_mode_t cm = PPA_SRM_COLOR_MODE_RGB565; + const ppa_srm_rotation_angle_t rotation = PPA_SRM_ROTATION_ANGLE_90; // CCW + const float scale_x = 1.0; + const float scale_y = 1.0; + + color_space_pixel_format_t buf_cm = { + .color_type_id = cm, + }; + const uint32_t buf_len = w * h * color_hal_pixel_format_get_bit_depth(buf_cm) / 8; // 32 + uint32_t out_buf_size = ALIGN_UP(buf_len, 64); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(out_buf); + esp_cache_msync((void *)out_buf, out_buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M); + const uint16_t in_buf[16] = { + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + // /*******************************/ + 0xFFFF, /**/ 0x8080, 0x8080, 0x8080, /**/ + 0xFFFF, /**/ 0x8F80, 0x8F80, 0x8F80, /**/ + 0xFFFF, /**/ 0xFF80, 0xFF80, 0xFF80, /**/ + // /*******************************/ + }; + // Expected SRM output + const uint16_t out_buf_expected[16] = { + // /*******************************/ + 0x0000, /**/ 0x8080, 0x8F80, 0xFF80, /**/ + 0x0000, /**/ 0x8080, 0x8F80, 0xFF80, /**/ + 0x0000, /**/ 0x8080, 0x8F80, 0xFF80, /**/ + // /*******************************/ + 0x0000, 0x0000, 0x0000, 0x0000 + }; + + ppa_client_handle_t ppa_client_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_SRM, + .max_pending_trans_num = 1, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_handle)); + + ppa_srm_oper_config_t oper_config = { + .in.buffer = in_buf, + .in.pic_w = w, + .in.pic_h = h, + .in.block_w = block_w, + .in.block_h = block_h, + .in.block_offset_x = in_block_offset_x, + .in.block_offset_y = in_block_offset_y, + .in.srm_cm = cm, + + .out.buffer = out_buf, + .out.buffer_size = out_buf_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = out_block_offset_x, + .out.block_offset_y = out_block_offset_y, + .out.srm_cm = cm, + + .rotation_angle = rotation, + .scale_x = scale_x, + .scale_y = scale_y, + + .rgb_swap = 0, + .byte_swap = 0, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_handle, &oper_config)); + + // Check result + for (int i = 0; i < buf_len; i++) { + if (i % 8 == 0) { + printf("\n"); + } + printf("0x%02X ", out_buf[i]); + } + printf("\n"); + TEST_ASSERT_EQUAL_UINT8_ARRAY((void *)out_buf_expected, (void *)out_buf, buf_len); + + TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); + + free(out_buf); +} + +TEST_CASE("ppa_blend_basic_data_correctness_check", "[PPA]") +{ + const uint32_t w = 2; + const uint32_t h = 2; + const uint32_t block_w = 1; + const uint32_t block_h = 1; + const uint32_t block_offset_x = 1; + const uint32_t block_offset_y = 1; + const ppa_blend_color_mode_t in_bg_cm = PPA_BLEND_COLOR_MODE_RGB888; + const ppa_blend_color_mode_t in_fg_cm = PPA_BLEND_COLOR_MODE_ARGB8888; + const ppa_blend_color_mode_t out_cm = PPA_BLEND_COLOR_MODE_ARGB8888; + + color_space_pixel_format_t bg_buf_cm = { + .color_type_id = in_bg_cm, + }; + const uint32_t bg_buf_len __attribute__((unused)) = w * h * color_hal_pixel_format_get_bit_depth(bg_buf_cm) / 8; // 12 + color_space_pixel_format_t fg_buf_cm = { + .color_type_id = in_fg_cm, + }; + const uint32_t fg_buf_len __attribute__((unused)) = w * h * color_hal_pixel_format_get_bit_depth(fg_buf_cm) / 8; // 16 + const uint32_t out_buf_len = fg_buf_len; // 16 + // We will make the output write to the in_fg_buffer, therefore, it has cache line alignment requirement + const uint32_t out_buf_size = 64; + + // Alpha of BG will be scaled by 0.8 + // Alpha of FG will be inverted + const float bg_alpha_scale_ratio = 0.8; + const uint8_t in_bg_buf[12] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // /*************************/ + 0xFF, 0xFF, 0xFF, /**/ 0x80, 0x40, 0xA0, /**/ + // /*************************/ + }; + uint8_t in_fg_buf[64] __attribute__((aligned(64))) = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // /*******************************/ + 0xFF, 0xFF, 0xFF, 0xFF, /**/ 0x00, 0x80, 0x80, 0xC0, /**/ + // /* (B) (G) (R) (A) */ + // /*******************************/ + [16 ... 63] = 0, + }; + uint8_t *out_buf = in_fg_buf; + // Expected blend output + // Alpha Blending calculation: + // A_bg' = (255 * 0.8) / 255 = 0.8, A_fg' = (255 - 0xC0) / 255 = 0.247 + // A_out = 0.8 + 0.247 - 0.8 * 0.247 = 0.849 (216 -> 0xD8) + // C_out_b = (0x80 * 0.8 * (1 - 0.247) + 0x00 * 0.247) / 0.849 = 91 -> 0x5B + // C_out_g = (0x40 * 0.8 * (1 - 0.247) + 0x80 * 0.247) / 0.849 = 83 -> 0x53 + // C_out_g = (0xA0 * 0.8 * (1 - 0.247) + 0x80 * 0.247) / 0.849 = 150 -> 0x96 + const uint8_t out_buf_expected[16] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + // /*******************************/ + 0xFF, 0xFF, 0xFF, 0xFF, /**/ 0x5B, 0x53, 0x96, 0xD8, /**/ + // /*******************************/ + }; + + ppa_client_handle_t ppa_client_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_BLEND, + .max_pending_trans_num = 1, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_handle)); + + ppa_blend_oper_config_t oper_config = { + .in_bg.buffer = in_bg_buf, + .in_bg.pic_w = w, + .in_bg.pic_h = h, + .in_bg.block_w = block_w, + .in_bg.block_h = block_h, + .in_bg.block_offset_x = block_offset_x, + .in_bg.block_offset_y = block_offset_y, + .in_bg.blend_cm = in_bg_cm, + + .in_fg.buffer = in_fg_buf, + .in_fg.pic_w = w, + .in_fg.pic_h = h, + .in_fg.block_w = block_w, + .in_fg.block_h = block_h, + .in_fg.block_offset_x = block_offset_x, + .in_fg.block_offset_y = block_offset_y, + .in_fg.blend_cm = in_fg_cm, + + .out.buffer = out_buf, + .out.buffer_size = out_buf_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = block_offset_x, + .out.block_offset_y = block_offset_y, + .out.blend_cm = out_cm, + + .bg_alpha_update_mode = PPA_ALPHA_SCALE, + .bg_alpha_scale_ratio = bg_alpha_scale_ratio, + + .fg_alpha_update_mode = PPA_ALPHA_INVERT, + + .bg_ck_en = false, + .fg_ck_en = false, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + TEST_ESP_OK(ppa_do_blend(ppa_client_handle, &oper_config)); + + // Check result + for (int i = 0; i < out_buf_len; i++) { + if (i % 8 == 0) { + printf("\n"); + } + printf("0x%02X ", out_buf[i]); + } + printf("\n"); + TEST_ASSERT_EQUAL_UINT8_ARRAY((void *)out_buf_expected, (void *)out_buf, out_buf_len); + + TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); +} + +TEST_CASE("ppa_fill_basic_data_correctness_check", "[PPA]") +{ + const uint32_t w = 80; + const uint32_t h = 120; + const uint32_t block_w = 80; + const uint32_t block_h = 80; + const uint32_t block_offset_x = 0; + const uint32_t block_offset_y = 40; + const ppa_fill_color_mode_t out_cm = PPA_FILL_COLOR_MODE_RGB565; + const color_pixel_argb8888_data_t fill_color = {.a = 0x80, .r = 0xFF, .g = 0x55, .b = 0xAA}; + + color_space_pixel_format_t out_pixel_format = { + .color_type_id = out_cm, + }; + + uint32_t out_pixel_depth = color_hal_pixel_format_get_bit_depth(out_pixel_format); // bits + uint32_t out_buf_len = w * h * out_pixel_depth / 8; + uint32_t out_buf_size = ALIGN_UP(out_buf_len, 64); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(out_buf); + + memset(out_buf, 0xFF, out_buf_len); + + ppa_client_handle_t ppa_client_handle; + ppa_client_config_t ppa_client_config = { + .oper_type = PPA_OPERATION_FILL, + .max_pending_trans_num = 1, + }; + TEST_ESP_OK(ppa_register_client(&ppa_client_config, &ppa_client_handle)); + + ppa_fill_oper_config_t oper_config = { + .out.buffer = out_buf, + .out.buffer_size = out_buf_size, + .out.pic_w = w, + .out.pic_h = h, + .out.block_offset_x = block_offset_x, + .out.block_offset_y = block_offset_y, + .out.fill_cm = out_cm, + + .fill_block_w = block_w, + .fill_block_h = block_h, + .fill_argb_color = fill_color, + + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + TEST_ESP_OK(ppa_do_fill(ppa_client_handle, &oper_config)); + + // Check result + const color_pixel_rgb565_data_t fill_pixel_expected = {.r = fill_color.r >> 3, + .g = fill_color.g >> 2, + .b = fill_color.b >> 3, + }; + TEST_ASSERT_EACH_EQUAL_UINT16(fill_pixel_expected.val, (void *)((uint32_t)out_buf + w * block_offset_y * out_pixel_depth / 8), block_w * block_h); + + TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); + + free(out_buf); +} + +/* All performance tests are tested under the following situations: + * - Testing PPA speed where in_buffer(s) and out_buffer all located in PSRAM + * - Only 2D-DMA is using PSRAM + * - 2D-DMA burst length is at maximum 128B + * - Input and output color mode is ARGB8888 (maximizing 2D-DMA data transafer amount) + * + * The time spend (T) to complete a PPA transaction is proportional to the amount of pixels (x) need to be processed. + * T = k * x + b + * k = (T - b) / x + */ + +#define PPA_SRM_MIN_PERFORMANCE_PX_PER_SEC (21000 * 1000) // k_min +#define PPA_SRM_TIME_OFFSET (-26000) // b_approx + +#define PPA_BLEND_MIN_PERFORMANCE_PX_PER_SEC (31500 * 1000) // k_min +#define PPA_BLEND_TIME_OFFSET (-37150) // b_approx + +#define PPA_FILL_MIN_PERFORMANCE_PX_PER_SEC (150000 * 1000) // k_min +#define PPA_FILL_TIME_OFFSET (-106000) // b_approx + +TEST_CASE("ppa_srm_performance", "[PPA]") +{ + // Configurable parameters const uint32_t w = 1920; // 1920 / 1280 / 800 / 640 const uint32_t h = 1080; // 1080 / 720 / 480 const uint32_t block_w = w; const uint32_t block_h = h; const ppa_srm_color_mode_t in_cm = PPA_SRM_COLOR_MODE_ARGB8888; - const ppa_srm_color_mode_t out_cm = PPA_SRM_COLOR_MODE_YUV420; + const ppa_srm_color_mode_t out_cm = PPA_SRM_COLOR_MODE_ARGB8888; const ppa_srm_rotation_angle_t rotation = PPA_SRM_ROTATION_ANGLE_0; const float scale_x = 1.0; const float scale_y = 1.0; @@ -282,9 +573,9 @@ TEST_CASE("ppa_srm_performance", "[PPA][ignore]") uint32_t in_buf_size = w * h * color_hal_pixel_format_get_bit_depth(in_pixel_format) / 8; uint32_t out_buf_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(out_pixel_format) / 8, 64); - uint8_t *out_buf = heap_caps_aligned_calloc(64, out_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(out_buf); - uint8_t *in_buf = heap_caps_aligned_calloc(64, in_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *in_buf = heap_caps_aligned_calloc(4, in_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(in_buf); uint8_t *ptr = in_buf; @@ -333,8 +624,14 @@ TEST_CASE("ppa_srm_performance", "[PPA][ignore]") TEST_ESP_OK(ppa_do_scale_rotate_mirror(ppa_client_handle, &oper_config)); - int64_t oper_time = ccomp_timer_stop(); - printf("Time passed: %lld us\n", oper_time); + int64_t oper_time = ccomp_timer_stop(); // us + printf("PPA SRM - Process Time: %lld us\n", oper_time); + + // Check performance + uint64_t num_pixels_processed = block_w * block_h; + uint64_t px_per_second = (num_pixels_processed - PPA_SRM_TIME_OFFSET) * 1000 * 1000 / oper_time; + printf("PPA SRM performance = %lld pixels/sec\n", px_per_second); + TEST_ASSERT_GREATER_THAN(PPA_SRM_MIN_PERFORMANCE_PX_PER_SEC, px_per_second); TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); @@ -342,8 +639,9 @@ TEST_CASE("ppa_srm_performance", "[PPA][ignore]") free(out_buf); } -TEST_CASE("ppa_blend_performance", "[PPA][ignore]") +TEST_CASE("ppa_blend_performance", "[PPA]") { + // Configurable parameters const uint32_t w = 1280; const uint32_t h = 720; const uint32_t block_w = w; @@ -365,11 +663,11 @@ TEST_CASE("ppa_blend_performance", "[PPA][ignore]") uint32_t in_bg_buf_size = w * h * color_hal_pixel_format_get_bit_depth(in_bg_pixel_format) / 8; uint32_t in_fg_buf_size = w * h * color_hal_pixel_format_get_bit_depth(in_fg_pixel_format) / 8; uint32_t out_buf_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(out_pixel_format) / 8, 64); - uint8_t *out_buf = heap_caps_aligned_calloc(64, out_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(out_buf); - uint8_t *in_bg_buf = heap_caps_aligned_calloc(64, in_bg_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *in_bg_buf = heap_caps_aligned_calloc(4, in_bg_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(in_bg_buf); - uint8_t *in_fg_buf = heap_caps_aligned_calloc(64, in_fg_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *in_fg_buf = heap_caps_aligned_calloc(4, in_fg_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(in_fg_buf); uint8_t *ptr = in_bg_buf; @@ -426,7 +724,13 @@ TEST_CASE("ppa_blend_performance", "[PPA][ignore]") TEST_ESP_OK(ppa_do_blend(ppa_client_handle, &oper_config)); int64_t oper_time = ccomp_timer_stop(); - printf("Time passed: %lld us\n", oper_time); + printf("PPA Blend - Process Time: %lld us\n", oper_time); + + // Check performance + uint64_t num_pixels_processed = block_w * block_h; + uint64_t px_per_second = (num_pixels_processed - PPA_BLEND_TIME_OFFSET) * 1000 * 1000 / oper_time; + printf("PPA Blend performance = %lld pixels/sec\n", px_per_second); + TEST_ASSERT_GREATER_THAN(PPA_BLEND_MIN_PERFORMANCE_PX_PER_SEC, px_per_second); TEST_ESP_OK(ppa_unregister_client(ppa_client_handle)); @@ -435,8 +739,9 @@ TEST_CASE("ppa_blend_performance", "[PPA][ignore]") free(out_buf); } -TEST_CASE("ppa_fill_performance", "[PPA][ignore]") +TEST_CASE("ppa_fill_performance", "[PPA]") { + // Configurable parameters const uint32_t w = 1280; const uint32_t h = 720; const uint32_t block_w = 800; @@ -448,7 +753,7 @@ TEST_CASE("ppa_fill_performance", "[PPA][ignore]") }; uint32_t out_buf_size = ALIGN_UP(w * h * color_hal_pixel_format_get_bit_depth(out_pixel_format) / 8, 64); - uint8_t *out_buf = heap_caps_aligned_calloc(64, out_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM); + uint8_t *out_buf = heap_caps_aligned_calloc(4, out_buf_size, sizeof(uint8_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(out_buf); ppa_client_handle_t ppa_client_handle; @@ -481,7 +786,13 @@ TEST_CASE("ppa_fill_performance", "[PPA][ignore]") TEST_ESP_OK(ppa_do_fill(ppa_client_handle, &oper_config)); int64_t oper_time = ccomp_timer_stop(); - printf("Time passed: %lld us\n", oper_time); + printf("PPA Fill - Process Time: %lld us\n", oper_time); + + // Check performance + uint64_t num_pixels_processed = block_w * block_h; + uint64_t px_per_second = (num_pixels_processed - PPA_FILL_TIME_OFFSET) * 1000 * 1000 / oper_time; + printf("PPA Blend performance = %lld pixels/sec\n", px_per_second); + TEST_ASSERT_GREATER_THAN(PPA_FILL_MIN_PERFORMANCE_PX_PER_SEC, px_per_second); TEST_ESP_OK(ppa_unregister_client(ppa_client_handle));