Implement 4-quadrant dirty rectangle optimization and 30 FPS limiting for ST7796
Add intelligent partial screen update system using bitwise XOR change detection and 4-quadrant tracking (top-left, top-right, bottom-left, bottom-right). Each changed pixel is routed to its quadrant, with sophisticated merge logic that combines adjacent rectangles when beneficial (<40% overhead). This dramatically reduces SPI bandwidth for UIs with scattered updates (e.g., corners, sidebars). Key changes: - 4-quadrant dirty rectangle tracking with automatic merging - XOR-based change detection for fast byte-level comparison - Expose st7796_set_window() for partial region updates - 30 FPS frame rate limiter (33ms per frame) to prevent excessive refreshes - Smart sleep timing when frame rate limit is active Performance: Up to 99% reduction in SPI traffic for corner-based UIs (e.g., 4 small regions vs full 480x320 screen updates). Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -268,7 +268,7 @@ static void write_command_with_data(uint8_t cmd, const uint8_t *data, size_t len
|
||||
* This compensates for displays where the physical screen doesn't align
|
||||
* with the controller's framebuffer (common with ST7789/ST7796).
|
||||
*/
|
||||
static void set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
void st7796_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
uint8_t data[4];
|
||||
|
||||
// Add offsets for display positioning
|
||||
@@ -475,7 +475,7 @@ void st7796_init(const struct st7796_config *c, uint16_t w, uint16_t h) {
|
||||
* @param color RGB565 color value (0x0000=black, 0xFFFF=white)
|
||||
*/
|
||||
void st7796_fill(uint16_t color) {
|
||||
set_window(0, 0, width - 1, height - 1);
|
||||
st7796_set_window(0, 0, width - 1, height - 1);
|
||||
|
||||
dc_data();
|
||||
cs_select();
|
||||
@@ -535,7 +535,7 @@ void st7796_put(uint16_t color) {
|
||||
* @param y Starting Y coordinate
|
||||
*/
|
||||
void st7796_set_cursor(uint16_t x, uint16_t y) {
|
||||
set_window(x, y, width - 1, height - 1);
|
||||
st7796_set_window(x, y, width - 1, height - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -614,8 +614,8 @@ void st7796_write_raw(const uint8_t *data, size_t len) {
|
||||
*/
|
||||
void st7796_draw_pixel(uint16_t x, uint16_t y, uint16_t color) {
|
||||
if (x >= width || y >= height) return; // Bounds check
|
||||
|
||||
set_window(x, y, x, y); // 1x1 window
|
||||
|
||||
st7796_set_window(x, y, x, y); // 1x1 window
|
||||
|
||||
uint8_t data[2] = {(color >> 8) & 0xFF, color & 0xFF};
|
||||
dc_data();
|
||||
@@ -676,8 +676,8 @@ void st7796_fill_rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t c
|
||||
if (x >= width || y >= height) return;
|
||||
if (x + w > width) w = width - x;
|
||||
if (y + h > height) h = height - y;
|
||||
|
||||
set_window(x, y, x + w - 1, y + h - 1);
|
||||
|
||||
st7796_set_window(x, y, x + w - 1, y + h - 1);
|
||||
|
||||
dc_data();
|
||||
cs_select();
|
||||
|
||||
Reference in New Issue
Block a user