mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
rgb_lcd: support multi-fb with bounce buffer
This commit is contained in:
@@ -97,7 +97,8 @@ struct esp_rgb_panel_t {
|
|||||||
esp_pm_lock_handle_t pm_lock; // Power management lock
|
esp_pm_lock_handle_t pm_lock; // Power management lock
|
||||||
size_t num_dma_nodes; // Number of DMA descriptors that used to carry the frame buffer
|
size_t num_dma_nodes; // Number of DMA descriptors that used to carry the frame buffer
|
||||||
uint8_t *fbs[RGB_LCD_PANEL_MAX_FB_NUM]; // Frame buffers
|
uint8_t *fbs[RGB_LCD_PANEL_MAX_FB_NUM]; // Frame buffers
|
||||||
uint8_t cur_fb_index; // Current frame buffer index (0 or 1)
|
uint8_t cur_fb_index; // Current frame buffer index
|
||||||
|
uint8_t bb_fb_index; // Current frame buffer index which used by bounce buffer
|
||||||
size_t fb_size; // Size of frame buffer
|
size_t fb_size; // Size of frame buffer
|
||||||
int data_gpio_nums[SOC_LCD_RGB_DATA_WIDTH]; // GPIOs used for data lines, we keep these GPIOs for action like "invert_color"
|
int data_gpio_nums[SOC_LCD_RGB_DATA_WIDTH]; // GPIOs used for data lines, we keep these GPIOs for action like "invert_color"
|
||||||
uint32_t src_clk_hz; // Peripheral source clock resolution
|
uint32_t src_clk_hz; // Peripheral source clock resolution
|
||||||
@@ -165,6 +166,7 @@ static esp_err_t lcd_rgb_panel_alloc_frame_buffers(const esp_lcd_rgb_panel_confi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
rgb_panel->cur_fb_index = 0;
|
rgb_panel->cur_fb_index = 0;
|
||||||
|
rgb_panel->bb_fb_index = 0;
|
||||||
rgb_panel->flags.fb_in_psram = fb_in_psram;
|
rgb_panel->flags.fb_in_psram = fb_in_psram;
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -962,25 +964,26 @@ static IRAM_ATTR bool lcd_rgb_panel_fill_bounce_buffer(esp_rgb_panel_t *panel, u
|
|||||||
} else {
|
} else {
|
||||||
// We do have frame buffer; copy from there.
|
// We do have frame buffer; copy from there.
|
||||||
// Note: if the cache is diabled, and accessing the PSRAM by DCACHE will crash.
|
// Note: if the cache is diabled, and accessing the PSRAM by DCACHE will crash.
|
||||||
memcpy(buffer, &panel->fbs[panel->cur_fb_index][panel->bounce_pos_px * bytes_per_pixel], panel->bb_size);
|
memcpy(buffer, &panel->fbs[panel->bb_fb_index][panel->bounce_pos_px * bytes_per_pixel], panel->bb_size);
|
||||||
if (panel->flags.bb_invalidate_cache) {
|
if (panel->flags.bb_invalidate_cache) {
|
||||||
// We don't need the bytes we copied from the psram anymore
|
// We don't need the bytes we copied from the psram anymore
|
||||||
// Make sure that if anything happened to have changed (because the line already was in cache) we write the data back.
|
// Make sure that if anything happened to have changed (because the line already was in cache) we write the data back.
|
||||||
Cache_WriteBack_Addr((uint32_t)&panel->fbs[panel->cur_fb_index][panel->bounce_pos_px * bytes_per_pixel], panel->bb_size);
|
Cache_WriteBack_Addr((uint32_t)&panel->fbs[panel->bb_fb_index][panel->bounce_pos_px * bytes_per_pixel], panel->bb_size);
|
||||||
// Invalidate the data.
|
// Invalidate the data.
|
||||||
// Note: possible race: perhaps something on the other core can squeeze a write between this and the writeback,
|
// Note: possible race: perhaps something on the other core can squeeze a write between this and the writeback,
|
||||||
// in which case that data gets discarded.
|
// in which case that data gets discarded.
|
||||||
Cache_Invalidate_Addr((uint32_t)&panel->fbs[panel->cur_fb_index][panel->bounce_pos_px * bytes_per_pixel], panel->bb_size);
|
Cache_Invalidate_Addr((uint32_t)&panel->fbs[panel->bb_fb_index][panel->bounce_pos_px * bytes_per_pixel], panel->bb_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panel->bounce_pos_px += panel->bb_size / bytes_per_pixel;
|
panel->bounce_pos_px += panel->bb_size / bytes_per_pixel;
|
||||||
// If the bounce pos is larger than the frame buffer size, wrap around so the next isr starts pre-loading the next frame.
|
// If the bounce pos is larger than the frame buffer size, wrap around so the next isr starts pre-loading the next frame.
|
||||||
if (panel->bounce_pos_px >= panel->fb_size / bytes_per_pixel) {
|
if (panel->bounce_pos_px >= panel->fb_size / bytes_per_pixel) {
|
||||||
panel->bounce_pos_px = 0;
|
panel->bounce_pos_px = 0;
|
||||||
|
panel->bb_fb_index = panel->cur_fb_index;
|
||||||
}
|
}
|
||||||
if (panel->num_fbs > 0) {
|
if (panel->num_fbs > 0) {
|
||||||
// Preload the next bit of buffer from psram
|
// Preload the next bit of buffer from psram
|
||||||
Cache_Start_DCache_Preload((uint32_t)&panel->fbs[panel->cur_fb_index][panel->bounce_pos_px * bytes_per_pixel],
|
Cache_Start_DCache_Preload((uint32_t)&panel->fbs[panel->bb_fb_index][panel->bounce_pos_px * bytes_per_pixel],
|
||||||
panel->bb_size, 0);
|
panel->bb_size, 0);
|
||||||
}
|
}
|
||||||
return need_yield;
|
return need_yield;
|
||||||
|
Reference in New Issue
Block a user