feat(lcd): add boundary performance test
@@ -577,6 +577,20 @@ static void handle_log_command(size_t argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_lcd_test(void)
|
||||
{
|
||||
const domain_expression_request_t request = {
|
||||
.id = DOMAIN_EXPRESSION_LCD_BOUNDARY_TEST,
|
||||
.trigger = DOMAIN_EXPRESSION_TRIGGER_FACTORY_LCD_TEST,
|
||||
};
|
||||
esp_err_t err = domain_runtime_request_expression(&request);
|
||||
if (err != ESP_OK) {
|
||||
cli_write_error("lcd_test_failed");
|
||||
return;
|
||||
}
|
||||
cli_write_ok();
|
||||
}
|
||||
|
||||
static void handle_command_line(char *line)
|
||||
{
|
||||
trim_text(line);
|
||||
@@ -661,6 +675,8 @@ static void handle_command_line(char *line)
|
||||
handle_prepare_rotate(key_version);
|
||||
} else if (strcmp(cmd, "log") == 0) {
|
||||
handle_log_command(argc, argv);
|
||||
} else if (strcmp(cmd, "lcd_test") == 0) {
|
||||
handle_lcd_test();
|
||||
} else {
|
||||
cli_write_error("unknown_command");
|
||||
}
|
||||
|
||||
@@ -170,6 +170,7 @@ typedef enum {
|
||||
DOMAIN_EXPRESSION_WUXING,
|
||||
DOMAIN_EXPRESSION_LISTENING,
|
||||
DOMAIN_EXPRESSION_OTA_UPDATE,
|
||||
DOMAIN_EXPRESSION_LCD_BOUNDARY_TEST,
|
||||
} domain_expression_id_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -198,6 +199,7 @@ typedef enum {
|
||||
DOMAIN_EXPRESSION_TRIGGER_OTA_UPDATE,
|
||||
DOMAIN_EXPRESSION_TRIGGER_MODEL_LUCKY_COLOR,
|
||||
DOMAIN_EXPRESSION_TRIGGER_PTT_BUTTON,
|
||||
DOMAIN_EXPRESSION_TRIGGER_FACTORY_LCD_TEST,
|
||||
} domain_expression_trigger_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -81,6 +81,10 @@ static const uint8_t s_basic_face_frame_order[] = {0, 1, 2};
|
||||
static const uint8_t s_muyu_frame_order[] = {0, 1, 2, 1};
|
||||
static const uint8_t s_listening_frame_order[] = {0, 1, 2};
|
||||
static const uint8_t s_ota_update_frame_order[] = {0, 1, 2};
|
||||
static const uint8_t s_lcd_boundary_test_frame_order[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
};
|
||||
static const char *const s_chouqian_result_asset_dirs[] = {
|
||||
"chouqian_buyun",
|
||||
"chouqian_heping",
|
||||
@@ -280,6 +284,22 @@ static const domain_expression_catalog_entry_t s_expression_catalog[] = {
|
||||
.frame_ms = 200,
|
||||
},
|
||||
},
|
||||
{
|
||||
.id = DOMAIN_EXPRESSION_LCD_BOUNDARY_TEST,
|
||||
.platform_request = {
|
||||
.kind = PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE,
|
||||
.priority = 250,
|
||||
.interrupt_current = true,
|
||||
.return_to_idle = true,
|
||||
.asset_dir = "lcd_boundary_test",
|
||||
.frame_order = s_lcd_boundary_test_frame_order,
|
||||
.frame_order_count = sizeof(s_lcd_boundary_test_frame_order) /
|
||||
sizeof(s_lcd_boundary_test_frame_order[0]),
|
||||
.repeat_count = 0,
|
||||
.frame_ms = 1,
|
||||
.duration_ms = 10000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static void snapshot_domain_wifi_behavior_hooks(domain_wifi_behavior_hooks_t *out_hooks)
|
||||
|
||||
@@ -156,6 +156,22 @@ set(platform_lcd_png_assets
|
||||
charging
|
||||
lowbat
|
||||
qrcode
|
||||
lcdtest00
|
||||
lcdtest01
|
||||
lcdtest02
|
||||
lcdtest03
|
||||
lcdtest04
|
||||
lcdtest05
|
||||
lcdtest06
|
||||
lcdtest07
|
||||
lcdtest08
|
||||
lcdtest09
|
||||
lcdtest10
|
||||
lcdtest11
|
||||
lcdtest12
|
||||
lcdtest13
|
||||
lcdtest14
|
||||
lcdtest15
|
||||
)
|
||||
set(platform_lcd_png_asset_files)
|
||||
foreach(lcd_png_asset IN LISTS platform_lcd_png_assets)
|
||||
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
@@ -495,6 +495,246 @@
|
||||
"source_sha256": "a048e4e9a74ad59d8835a4a4288cee5598b0f4b96de801bdfd3a38dde4c70b72",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest00.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 2885,
|
||||
"optimized_sha256": "3ef8a1298e87bf95d438e7632c74289aff003c715daf761e28c39123321146de",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 34,
|
||||
"source_bytes": 3321,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "1e9644092b2de9edb12d03bfeaef5b5fd3ce702b5c4ef0feda2e6feed88ee92c",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest01.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 2965,
|
||||
"optimized_sha256": "635099f9f20e5debab027b6a445255aa942e785fecf8a8901c9ff9ca7e280f1a",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 40,
|
||||
"source_bytes": 3574,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "02f3915f405ce676241ff7e3cda707d01baabec1b7c5416dd48e4c3cb899f2ee",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest02.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 2982,
|
||||
"optimized_sha256": "f7db16b21b7662fcab878793658b7836887453c1ea142faebf7d54206b31b119",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 50,
|
||||
"source_bytes": 3767,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "d6deabbeebf55acb43c71d93a99fea65be1b866f0b7d63c628a86777b63f75b3",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest03.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 3043,
|
||||
"optimized_sha256": "7f8d0c54698558220925d4d8903f83b5e4572c28906b3cf7ea25983897010f02",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 54,
|
||||
"source_bytes": 3903,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "9b5fdb2ab9acf148b516596e39a3cafc7abd1cd7cb257e2ed3b03d16e0701fe6",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest04.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 2949,
|
||||
"optimized_sha256": "03d7113fdb653277b0e384905e641001ae04c5dc0047058f29765a52e8aaa576",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 43,
|
||||
"source_bytes": 3579,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "84e51f7ba6c608de7e9864e2765c0e21649a576b33db3a57e781824ae966dd7d",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest05.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 3225,
|
||||
"optimized_sha256": "c76b3e5271d17354f145a211f001f8609e592181101308fcefa553171d1d215f",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 59,
|
||||
"source_bytes": 3996,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "4ab57523735c7627330751dfae4031905bed66d34296003ca0628126eaaee11b",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest06.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 3431,
|
||||
"optimized_sha256": "148789a0e47478f59b67d55242c26df112b617fba99b9f4bd1777af31ea8e8be",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 60,
|
||||
"source_bytes": 4089,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "fc9e01e9b5f6140a3a1904ac3b31b3ed659df475c171e0edde5af0de8215bb3a",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest07.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 3369,
|
||||
"optimized_sha256": "0845948af9c1bbb2a176ca139d15b0b130df401f2c32a488781b8fdbfbd6c479",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 52,
|
||||
"source_bytes": 3753,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "c3bd1a40466269b2778f8edd84174881d9de773e15a2222974fa4ac8caf498cb",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest08.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 3299,
|
||||
"optimized_sha256": "19f355a63a6d437e2b171644a4c297ea78e9da05abbc236f14f7c94d6e7898cc",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 60,
|
||||
"source_bytes": 3860,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "a4382986103c92344afd3bf3686585e9750f7286f1c508cf42abbc4e56e9fad8",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest09.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 3458,
|
||||
"optimized_sha256": "9fbcbdca9b17fbbf116c0f0f5c7968099253543664cab4c0049f42f9cb99dc07",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 60,
|
||||
"source_bytes": 4008,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "b4b811390bc77db0f4e28ff45b102c24f77aebc50aa57ecbb4378bf440ff5008",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest10.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 3229,
|
||||
"optimized_sha256": "e37daec397eea565e1e46479ba96cdbbdb22736470d2893aadf894f857cb1265",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 40,
|
||||
"source_bytes": 3545,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "e050346ca4d6a15504ea4276a28a6bd23cb6eeab031ec4ada4dc8d65405bbd6e",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest11.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 2966,
|
||||
"optimized_sha256": "57c958dac45e46376c7419ea5c28acb8e072140d8848b49a3a9cd723da58517e",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 28,
|
||||
"source_bytes": 3169,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "bd373fbf6e41318c7767c8b877699027cb282569506262d59072c366e11fd9d6",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest12.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 2921,
|
||||
"optimized_sha256": "705d5aca100df51c8bfd13ceb6f42ef9a4305416755ea4247e5781cb12dfe4e1",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 47,
|
||||
"source_bytes": 3453,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "bce48a61a6a55d3c69e998a4907652f712a9b76d5c7a99c28a87afaad9777d5c",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest13.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 3020,
|
||||
"optimized_sha256": "fdc3b0aea5740bc4322157af16b1cc3d52fd723fa0ac7598bd3a97da9baa2741",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 54,
|
||||
"source_bytes": 3710,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "b66b4113787fd763c2b01f0213bc14bbb1d72ebc27e643126e765a70d2fe1ab0",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest14.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 2986,
|
||||
"optimized_sha256": "f8df29b876d32f2e744f5e5cb3dd386358eab42346419760b0d276d31224e36f",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 35,
|
||||
"source_bytes": 3443,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "18619fa00094c38abd445acbe99980e0b85eebad67bb559f7d63799c3594d18e",
|
||||
"width": 320
|
||||
},
|
||||
"lcdtest15.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
255
|
||||
],
|
||||
"height": 240,
|
||||
"optimized_bytes": 3033,
|
||||
"optimized_sha256": "9fa7245972c22418d8aaca38ea057c06a9991a9f617fb65cb2b1323579c4ee03",
|
||||
"output_mode": "indexed",
|
||||
"rgb565_colors": 58,
|
||||
"source_bytes": 3646,
|
||||
"source_mode": "RGB",
|
||||
"source_sha256": "3dad7138d4f1409767d29fefa7e02e948ae02c0624ebc5a9347ed30350955b4e",
|
||||
"width": 320
|
||||
},
|
||||
"listening0.png": {
|
||||
"alpha_range": [
|
||||
255,
|
||||
@@ -889,9 +1129,9 @@
|
||||
"generator": "tools/optimize_lcd_assets.py",
|
||||
"pillow_version": "12.3.0",
|
||||
"totals": {
|
||||
"asset_count": 59,
|
||||
"optimized_bytes": 381384,
|
||||
"source_bytes": 1069465
|
||||
"asset_count": 75,
|
||||
"optimized_bytes": 431145,
|
||||
"source_bytes": 1128281
|
||||
},
|
||||
"version": 1
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
@@ -27,6 +27,7 @@
|
||||
#include "esp_lcd_panel_vendor.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -49,6 +50,7 @@
|
||||
#define LCD_DIRECT_TRANSFER_TIMEOUT_MS 100U
|
||||
#define LCD_DIRECT_PREHEAT_WAIT_TIMEOUT_MS 5000U
|
||||
#define LCD_DIRECT_FRAME_CACHE_MAX 6U
|
||||
#define LCD_DIRECT_BOUNDARY_TEST_CACHE_HIT_FRAMES LCD_DIRECT_FRAME_CACHE_MAX
|
||||
#define LCD_DIRECT_PATH_MAX 96U
|
||||
#define LCD_DIRECT_CHARGING_ICON_WIDTH 50U
|
||||
#define LCD_DIRECT_CHARGING_ICON_X (LCD_DIRECT_WIDTH - LCD_DIRECT_CHARGING_ICON_WIDTH - 8U)
|
||||
@@ -116,6 +118,13 @@ typedef struct lcd_direct_decoded_image_t {
|
||||
bool pinned;
|
||||
} lcd_direct_decoded_image_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t completed_frames;
|
||||
uint64_t total_draw_us;
|
||||
uint32_t min_draw_us;
|
||||
uint32_t max_draw_us;
|
||||
} lcd_direct_sequence_perf_t;
|
||||
|
||||
typedef struct {
|
||||
lcd_direct_icon_draw_t draw;
|
||||
const lcd_direct_icon_t *icon;
|
||||
@@ -778,7 +787,8 @@ static size_t lcd_direct_append_status_icons(const lcd_direct_image_t *image,
|
||||
size_t icon_capacity)
|
||||
{
|
||||
if (image == NULL || image->path == NULL || icons == NULL ||
|
||||
icon_count >= icon_capacity || strstr(image->path, "/qrcode.png") != NULL) {
|
||||
icon_count >= icon_capacity || strstr(image->path, "/qrcode.png") != NULL ||
|
||||
strstr(image->path, "/lcdtest") != NULL) {
|
||||
return icon_count;
|
||||
}
|
||||
|
||||
@@ -1011,7 +1021,8 @@ static esp_err_t lcd_direct_draw_png_image(const lcd_direct_image_t *image,
|
||||
combined_icon_count,
|
||||
prepared_icons,
|
||||
sizeof(prepared_icons) / sizeof(prepared_icons[0]));
|
||||
const bool clock_visible = strstr(image->path, "/qrcode.png") == NULL;
|
||||
const bool clock_visible = strstr(image->path, "/qrcode.png") == NULL &&
|
||||
strstr(image->path, "/lcdtest") == NULL;
|
||||
char clock_text[LCD_DIRECT_CLOCK_TEXT_LENGTH + 1U] = {0};
|
||||
if (clock_visible) {
|
||||
lcd_direct_clock_text(clock_text);
|
||||
@@ -1193,6 +1204,9 @@ static uint32_t lcd_direct_asset_sequence_hold_ms(const lcd_direct_request_t *re
|
||||
LCD_DIRECT_BASIC_FACE_LAST_FRAME_HOLD_MS :
|
||||
LCD_DIRECT_BASIC_FACE_FRAME_HOLD_MS;
|
||||
}
|
||||
if (request != NULL && strcmp(request->asset_dir, "lcd_boundary_test") == 0) {
|
||||
return frame_ms;
|
||||
}
|
||||
if (frame_index + 1U != frame_count) {
|
||||
return frame_ms;
|
||||
}
|
||||
@@ -1204,6 +1218,9 @@ static uint32_t lcd_direct_asset_sequence_duration_ms(const lcd_direct_request_t
|
||||
if (request == NULL || request->duration_ms == 0U) {
|
||||
return 0U;
|
||||
}
|
||||
if (strcmp(request->asset_dir, "lcd_boundary_test") == 0) {
|
||||
return request->duration_ms;
|
||||
}
|
||||
|
||||
const size_t frame_count = request->frame_order_count > 0U ? request->frame_order_count : 1U;
|
||||
const uint32_t frame_ms = lcd_direct_asset_sequence_frame_ms(request);
|
||||
@@ -1284,7 +1301,8 @@ static esp_err_t lcd_direct_draw_asset_sequence_once(const lcd_direct_request_t
|
||||
|
||||
static esp_err_t lcd_direct_draw_asset_sequence_for_duration(const lcd_direct_request_t *request,
|
||||
TickType_t start_tick,
|
||||
TickType_t duration_ticks)
|
||||
TickType_t duration_ticks,
|
||||
lcd_direct_sequence_perf_t *perf)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(request != NULL,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
@@ -1312,9 +1330,21 @@ static esp_err_t lcd_direct_draw_asset_sequence_for_duration(const lcd_direct_re
|
||||
request->asset_dir,
|
||||
(unsigned)frame_index);
|
||||
|
||||
const int64_t draw_started_us = esp_timer_get_time();
|
||||
ESP_RETURN_ON_ERROR(lcd_direct_draw_png_image(frame, NULL, 0),
|
||||
TAG,
|
||||
"draw timed asset frame failed");
|
||||
const uint32_t draw_us = (uint32_t)(esp_timer_get_time() - draw_started_us);
|
||||
if (perf != NULL) {
|
||||
perf->completed_frames++;
|
||||
perf->total_draw_us += draw_us;
|
||||
if (draw_us < perf->min_draw_us) {
|
||||
perf->min_draw_us = draw_us;
|
||||
}
|
||||
if (draw_us > perf->max_draw_us) {
|
||||
perf->max_draw_us = draw_us;
|
||||
}
|
||||
}
|
||||
|
||||
const TickType_t now = xTaskGetTickCount();
|
||||
const TickType_t elapsed_ticks = now - start_tick;
|
||||
@@ -1332,6 +1362,91 @@ static esp_err_t lcd_direct_draw_asset_sequence_for_duration(const lcd_direct_re
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void lcd_direct_log_sequence_perf(const lcd_direct_request_t *request,
|
||||
const char *mode,
|
||||
const lcd_direct_sequence_perf_t *perf,
|
||||
uint64_t elapsed_us)
|
||||
{
|
||||
if (request == NULL || perf == NULL || perf->completed_frames == 0U || elapsed_us == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t fps_x100 =
|
||||
((uint64_t)perf->completed_frames * 100000000ULL) / elapsed_us;
|
||||
const uint32_t average_draw_us =
|
||||
(uint32_t)(perf->total_draw_us / perf->completed_frames);
|
||||
ESP_LOGI(TAG,
|
||||
"LCD sequence perf asset=%s mode=%s working_set=%u cache_capacity=%u "
|
||||
"frames=%u elapsed_ms=%llu fps=%llu.%02llu draw_us_avg=%u "
|
||||
"draw_us_min=%u draw_us_max=%u hold_ms=%u",
|
||||
request->asset_dir,
|
||||
mode,
|
||||
(unsigned)request->frame_order_count,
|
||||
(unsigned)LCD_DIRECT_FRAME_CACHE_MAX,
|
||||
(unsigned)perf->completed_frames,
|
||||
(unsigned long long)(elapsed_us / 1000ULL),
|
||||
(unsigned long long)(fps_x100 / 100ULL),
|
||||
(unsigned long long)(fps_x100 % 100ULL),
|
||||
(unsigned)average_draw_us,
|
||||
(unsigned)perf->min_draw_us,
|
||||
(unsigned)perf->max_draw_us,
|
||||
(unsigned)lcd_direct_asset_sequence_frame_ms(request));
|
||||
}
|
||||
|
||||
static esp_err_t lcd_direct_run_sequence_perf_stage(const lcd_direct_request_t *request,
|
||||
uint32_t duration_ms,
|
||||
const char *mode)
|
||||
{
|
||||
const TickType_t start_tick = xTaskGetTickCount();
|
||||
const TickType_t duration_ticks = pdMS_TO_TICKS(duration_ms);
|
||||
const int64_t started_us = esp_timer_get_time();
|
||||
lcd_direct_sequence_perf_t perf = {
|
||||
.min_draw_us = UINT32_MAX,
|
||||
};
|
||||
esp_err_t err = lcd_direct_draw_asset_sequence_for_duration(
|
||||
request, start_tick, duration_ticks, &perf);
|
||||
const uint64_t elapsed_us = (uint64_t)(esp_timer_get_time() - started_us);
|
||||
lcd_direct_log_sequence_perf(request, mode, &perf, elapsed_us);
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t lcd_direct_run_boundary_test(const lcd_direct_request_t *request)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(request != NULL &&
|
||||
request->frame_order_count > LCD_DIRECT_BOUNDARY_TEST_CACHE_HIT_FRAMES,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
TAG,
|
||||
"invalid LCD boundary test request");
|
||||
|
||||
lcd_direct_request_t cache_hit_request = *request;
|
||||
cache_hit_request.frame_order_count = LCD_DIRECT_BOUNDARY_TEST_CACHE_HIT_FRAMES;
|
||||
|
||||
ESP_RETURN_ON_ERROR(lcd_direct_preheat_asset_sequence(&cache_hit_request),
|
||||
TAG,
|
||||
"preheat cache-hit frames failed");
|
||||
|
||||
const uint32_t cache_hit_duration_ms = request->duration_ms / 2U;
|
||||
const uint32_t cache_thrash_duration_ms = request->duration_ms - cache_hit_duration_ms;
|
||||
ESP_RETURN_ON_ERROR(lcd_direct_run_sequence_perf_stage(
|
||||
&cache_hit_request, cache_hit_duration_ms, "cache_hit"),
|
||||
TAG,
|
||||
"cache-hit performance stage failed");
|
||||
|
||||
lcd_direct_request_t cache_thrash_preheat = *request;
|
||||
cache_thrash_preheat.frame_order_count = LCD_DIRECT_BOUNDARY_TEST_CACHE_HIT_FRAMES;
|
||||
const size_t first_preheat_frame =
|
||||
request->frame_order_count - LCD_DIRECT_BOUNDARY_TEST_CACHE_HIT_FRAMES;
|
||||
memcpy(cache_thrash_preheat.frame_order,
|
||||
&request->frame_order[first_preheat_frame],
|
||||
LCD_DIRECT_BOUNDARY_TEST_CACHE_HIT_FRAMES * sizeof(cache_thrash_preheat.frame_order[0]));
|
||||
ESP_RETURN_ON_ERROR(lcd_direct_preheat_asset_sequence(&cache_thrash_preheat),
|
||||
TAG,
|
||||
"preheat cache-thrash frames failed");
|
||||
|
||||
return lcd_direct_run_sequence_perf_stage(
|
||||
request, cache_thrash_duration_ms, "cache_thrash");
|
||||
}
|
||||
|
||||
static esp_err_t lcd_direct_play_asset_sequence(const lcd_direct_request_t *request)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(request != NULL,
|
||||
@@ -1359,9 +1474,15 @@ static esp_err_t lcd_direct_play_asset_sequence(const lcd_direct_request_t *requ
|
||||
}
|
||||
|
||||
if (request->duration_ms > 0U) {
|
||||
const TickType_t start_tick = xTaskGetTickCount();
|
||||
const TickType_t duration_ticks = pdMS_TO_TICKS(lcd_direct_asset_sequence_duration_ms(request));
|
||||
esp_err_t err = lcd_direct_draw_asset_sequence_for_duration(request, start_tick, duration_ticks);
|
||||
esp_err_t err;
|
||||
if (strcmp(request->asset_dir, "lcd_boundary_test") == 0) {
|
||||
err = lcd_direct_run_boundary_test(request);
|
||||
} else {
|
||||
err = lcd_direct_run_sequence_perf_stage(
|
||||
request,
|
||||
lcd_direct_asset_sequence_duration_ms(request),
|
||||
"normal");
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,25 @@ static const lcd_direct_image_t s_ota_frames[] = {
|
||||
{.path = LCD_ASSET_BASE_PATH "ota3.png"},
|
||||
};
|
||||
|
||||
static const lcd_direct_image_t s_lcd_boundary_test_frames[] = {
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest00.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest01.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest02.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest03.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest04.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest05.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest06.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest07.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest08.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest09.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest10.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest11.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest12.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest13.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest14.png"},
|
||||
{.path = LCD_ASSET_BASE_PATH "lcdtest15.png"},
|
||||
};
|
||||
|
||||
static const lcd_direct_image_t s_wifi_connecting_qr_frames[] = {
|
||||
{.path = LCD_ASSET_BASE_PATH "qrcode.png"},
|
||||
};
|
||||
@@ -270,6 +289,14 @@ const lcd_direct_image_t *lcd_direct_asset_frame(const char *asset_dir, uint8_t
|
||||
frame_index);
|
||||
}
|
||||
|
||||
if (strcmp(asset_dir, "lcd_boundary_test") == 0) {
|
||||
return lcd_direct_frame_from_array(
|
||||
s_lcd_boundary_test_frames,
|
||||
sizeof(s_lcd_boundary_test_frames) /
|
||||
sizeof(s_lcd_boundary_test_frames[0]),
|
||||
frame_index);
|
||||
}
|
||||
|
||||
if (strcmp(asset_dir, "wifi_connecting_qr") == 0) {
|
||||
return lcd_direct_frame_from_array(
|
||||
s_wifi_connecting_qr_frames,
|
||||
|
||||