I’ve ported my logic to a custom Teensy 4.x (Micromod) with 32MB SDRAM and use of the eLCDIF LCD controller
I have a 5" TFT wired up on 16 data lines and the eLCDIF configured the same (16 bit bus/16 bit words)
I’ve set my waveform to be 800px wide by 164px high, but the framerate has dropped to 2-3FPS
with lv_benchmark I get a min of 15FPS and a max of 60ish FPS
I know the issue here is of a few reasons:
- I am reading data points from a waveform buffer in SDRAM, writing them into an lv_canvas buffer in SDRAM, copied over to one of the full screen sized frame buffers in SDRAM
- My routine for drawing the waveform is not fully optimized
I’ve done some work to try make it a bit better:
#define BLUE_COLOR 0x0000FF // Example color value for blue
#define WAVEFORM_WIDTH 320
#define WAVEFORM_HEIGHT 64
EXTMEM static uint8_t waveformbuffer[WAVEFORM_WIDTH * WAVEFORM_HEIGHT * 2];
/*
void lv_draw_vline(uint16_t x, uint16_t y, uint8_t length, lv_color_t color){
// Loop from y downwards by `length` pixels
for(int i = y; i < y + length; i++){
lv_canvas_set_px(waveform_canvas, x, i, color, LV_OPA_100);
}
}
*/
// Modified lv_draw_vline function
void lv_draw_vline(uint16_t x, uint16_t y, uint8_t length, lv_color_t color, lv_color_t bg_color) {
// Draw background color from top (y = 0) to the start of the line
for (int i = 0; i < y; i++) {
lv_canvas_set_px(waveform_canvas, x, i, bg_color, LV_OPA_100);
}
// Draw the line with the waveform color
for (int i = y; i < y + length && i < WAVEFORM_HEIGHT; i++) {
lv_canvas_set_px(waveform_canvas, x, i, color, LV_OPA_100);
}
// Draw background color from the end of the line to the bottom (y = WAVEFORM_HEIGHT)
for (int i = y + length; i < WAVEFORM_HEIGHT; i++) {
lv_canvas_set_px(waveform_canvas, x, i, bg_color, LV_OPA_100);
}
}
void DrawDynamicWaveform(uint16_t *WFORMDYNAMIC, uint32_t position, uint8_t DynamicWaveformZOOM) {
//static uint32_t _position = 0xFFFFFFFF;
//if(position == _position) return;
//_position = position;
uint32_t adr;
uint8_t amplitude, rms;
uint16_t i, j;
lv_layer_t layer;
position = position/DynamicWaveformZOOM;
//memset(waveformbuffer, 0xFFFF, WAVEFORM_WIDTH*WAVEFORM_HEIGHT*2);
//lv_canvas_init_layer(waveform_canvas, &layer);
for (i = 0; i < WAVEFORM_WIDTH; i++) {
adr = DynamicWaveformZOOM * (i + position - (WAVEFORM_WIDTH/2));
if(adr<=all_long){
lv_color_t color = lv_palette_main(LV_PALETTE_BLUE);
amplitude = WFORMDYNAMIC[adr]>>8;
rms = WFORMDYNAMIC[adr]&0xFF;
if (DynamicWaveformZOOM == 1) {
lv_draw_vline(i,(WAVEFORM_HEIGHT/2)-amplitude-1, 2+(2*amplitude),color, lv_color_black());
//lv_draw_vline(i,(WAVEFORM_HEIGHT/2)-rms-1, 2+(2*rms), lv_color_white());
}
else {
uint8_t amplitude_z = WFORMDYNAMIC[adr]>>8;
uint8_t rms_z = WFORMDYNAMIC[adr]&0xFF;
for (j = 0; j < DynamicWaveformZOOM-1; j++) {
if (WFORMDYNAMIC[adr+j+1] > amplitude_z) {
amplitude_z = WFORMDYNAMIC[adr+j+1] >>8;
}
if(WFORMDYNAMIC[adr]&0xFF > rms_z){
rms_z = WFORMDYNAMIC[adr+j+1]&0xFF;
}
}
lv_draw_vline(i,(WAVEFORM_HEIGHT/2)-amplitude_z-1, 2+(2*amplitude_z), color, lv_color_black());
//lv_draw_vline(i,(WAVEFORM_HEIGHT/2)-rms_z-1, 2+(2*rms_z), lv_color_white());
}
}
else{
lv_canvas_set_px(waveform_canvas, i, (WAVEFORM_HEIGHT/2) - 1, lv_palette_main(LV_PALETTE_BLUE) , LV_OPA_100);
lv_canvas_set_px(waveform_canvas, i, WAVEFORM_HEIGHT/2, lv_palette_main(LV_PALETTE_BLUE) , LV_OPA_100);
}
}
lv_draw_vline(WAVEFORM_WIDTH/2-1, 0, WAVEFORM_HEIGHT-1, lv_color_hex(0xFF0000), lv_color_black());
lv_draw_vline(WAVEFORM_WIDTH/2, 0, WAVEFORM_HEIGHT-1, lv_color_hex(0xFF0000), lv_color_black());
//lv_canvas_finish_layer(waveform_canvas, &layer);
}
void createDynamicWaveform(){
waveform_canvas = lv_canvas_create(screen);
lv_obj_set_size(waveform_canvas, WAVEFORM_WIDTH, WAVEFORM_HEIGHT);
lv_canvas_set_buffer(waveform_canvas, &waveformbuffer, WAVEFORM_WIDTH, WAVEFORM_HEIGHT, LV_COLOR_FORMAT_RGB565);
lv_canvas_fill_bg(waveform_canvas, lv_color_black(), LV_OPA_100);
lv_obj_center(waveform_canvas);
}
But I think ideally, I need to drop the lv_canvas buffer and somehow draw directly into the current working frame buffer
@kisvegabor do you have any suggestion on how to speed things up here?