perf(lcd): cache idle eye frames and anchor blink timing
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
from pathlib import Path
|
||||
import re, subprocess, tempfile
|
||||
src=(Path(__file__).resolve().parents[1]/'components/platform/src/lcd_direct.c').read_text()
|
||||
def extract(name):
|
||||
m=re.search(r'static [^;{}]+\b'+name+r'\([^;{}]*\)\s*\{',src)
|
||||
a=m.start();b=src.index('{',a)+1;depth=1
|
||||
while depth:
|
||||
if src[b]=='{':depth+=1
|
||||
if src[b]=='}':depth-=1
|
||||
b+=1
|
||||
return src[a:b]
|
||||
prefix='''#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#define ESP_OK 0
|
||||
#define ESP_ERR_INVALID_STATE 1
|
||||
#define LCD_DIRECT_EMOTE_STEP_MS 34U
|
||||
#define LCD_DIRECT_PRESENTATION_WAIT_POLL_MS 20U
|
||||
#define pdMS_TO_TICKS(x) ((x)/10)
|
||||
#define ESP_RETURN_ON_ERROR(expr,...) do {int e=(expr);if(e)return e;}while(0)
|
||||
typedef int esp_err_t;
|
||||
typedef uint32_t TickType_t;
|
||||
static int s_emote_handle, delays, stop_after, locks, unlocks;
|
||||
static bool stop;
|
||||
static int64_t now;
|
||||
static int64_t esp_timer_get_time(void){return now;}
|
||||
static bool lcd_direct_should_stop_idle(void){return stop;}
|
||||
static int gfx_emote_lock(int h){++locks;return 0;}
|
||||
static int gfx_emote_unlock(int h){++unlocks;return 0;}
|
||||
static int lcd_direct_emote_update_hud(bool force,bool *changed){*changed=false;return 0;}
|
||||
static int lcd_direct_emote_refresh(void){return 0;}
|
||||
static void vTaskDelay(TickType_t ticks){assert(ticks>0);now+=ticks*10000;++delays;if(stop_after && delays>=stop_after)stop=true;}
|
||||
'''
|
||||
test='''int main(void){
|
||||
for(size_t i=0;i<12;++i){
|
||||
assert(lcd_direct_emote_step_deadline(123000,i)==123000+(int64_t)(i+1)*34000);
|
||||
now+=13000;
|
||||
assert(lcd_direct_emote_wait_until(lcd_direct_emote_step_deadline(0,i))==0);
|
||||
assert(now>=(int64_t)(i+1)*34000 && now<(int64_t)(i+1)*34000+10000);
|
||||
}
|
||||
int64_t anchored=now;
|
||||
now=0;
|
||||
for(size_t i=0;i<12;++i){now+=13000;assert(lcd_direct_emote_wait(21)==0);}
|
||||
assert(anchored<418000 && now>=480000);
|
||||
now=200000;int before=delays;
|
||||
assert(lcd_direct_emote_wait_until(100000)==0 && now==200000 && delays==before);
|
||||
stop=true;assert(lcd_direct_emote_wait_until(100000)==1);
|
||||
stop=false;stop_after=delays+1;assert(lcd_direct_emote_wait_until(now+100000)==1);
|
||||
assert(locks==unlocks);
|
||||
printf("PASS: fixed deadlines, 10ms tick drift reduction (anchored=%lldus), late/stop handling and paired HUD locks\\n",(long long)anchored);
|
||||
}'''
|
||||
with tempfile.TemporaryDirectory(prefix='emote-timeline-') as tmp:
|
||||
c=Path(tmp)/'test.c';exe=Path(tmp)/'test'
|
||||
c.write_text(prefix+'\n'.join(extract(n) for n in ['lcd_direct_emote_wait_until','lcd_direct_emote_wait','lcd_direct_emote_step_deadline'])+'\n'+test)
|
||||
subprocess.run(['clang','-std=c11','-fsanitize=address,undefined',str(c),'-o',str(exe)],check=True)
|
||||
subprocess.run([str(exe)],check=True)
|
||||
Reference in New Issue
Block a user