refactor: use EPD-exact bgr888 palette with bulk pushImage
Replace the PALETTE_565 + writePixel loop with a bgr888_t palette whose values exactly match Panel_ED2208's internal epd_palette, pushed via a single pushImage() call. Benefits: - Eliminates ~240K individual writePixel calls per frame - Zero-distance palette values guarantee correct color mapping - Removes lossy RGB565 intermediate encoding - Remove unused paletteToColor565() helper Also adds informational comment to triggerRefresh() noting that Panel_ED2208::_exec_transfer always sends the full 400x600 frame. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,14 +2,16 @@
|
||||
#include "power_manager.h"
|
||||
#include <M5Unified.h>
|
||||
|
||||
// Map 6-color palette indices to RGB565 for M5GFX
|
||||
static const uint16_t PALETTE_565[6] = {
|
||||
0x0000, // Black
|
||||
0xFFFF, // White
|
||||
0xF800, // Red (approximate)
|
||||
0x07E0, // Green (approximate)
|
||||
0x001F, // Blue (approximate)
|
||||
0xFFE0 // Yellow (approximate)
|
||||
// EPD-exact palette: values produce distance=0 in Panel_ED2208's
|
||||
// _rgb_to_epd_color nearest-color lookup, guaranteeing correct mapping.
|
||||
// Order matches our pipeline's palette indices (0=black..5=yellow).
|
||||
static const lgfx::bgr888_t EPD_PALETTE[6] = {
|
||||
{0, 0, 0}, // Black (EPD_BLACK)
|
||||
{255, 255, 255}, // White (EPD_WHITE)
|
||||
{191, 0, 0}, // Red (EPD_RED)
|
||||
{67, 138, 28}, // Green (EPD_GREEN)
|
||||
{100, 64, 255}, // Blue (EPD_BLUE)
|
||||
{255, 243, 56} // Yellow (EPD_YELLOW)
|
||||
};
|
||||
|
||||
void DisplayManager::begin(PowerManager& power) {
|
||||
@@ -92,14 +94,10 @@ void DisplayManager::showImage(const ProcessedImage& img) {
|
||||
|
||||
Serial.println("[display] Writing framebuffer to e-ink...");
|
||||
|
||||
// Write pixel by pixel using palette-mapped colors
|
||||
// Bulk-write framebuffer using palette lookup (handles rotation internally)
|
||||
_display->startWrite();
|
||||
for (uint16_t y = 0; y < img.height; y++) {
|
||||
for (uint16_t x = 0; x < img.width; x++) {
|
||||
uint8_t colorIdx = img.framebuffer[y * img.width + x];
|
||||
_display->writePixel(x, y, PALETTE_565[colorIdx]);
|
||||
}
|
||||
}
|
||||
_display->pushImage(0, 0, img.width, img.height,
|
||||
img.framebuffer, lgfx::color_depth_t::palette_8bit, EPD_PALETTE);
|
||||
_display->endWrite();
|
||||
// Do NOT refresh here — caller should add metadata overlay then call refresh()
|
||||
}
|
||||
@@ -361,12 +359,9 @@ void DisplayManager::refresh() {
|
||||
}
|
||||
|
||||
void DisplayManager::triggerRefresh() {
|
||||
// M5GFX handles e-ink refresh internally when using the EPD panel driver
|
||||
// The display() call triggers the actual e-ink refresh cycle (10-20s)
|
||||
// Panel_ED2208::_exec_transfer always sends the full 400x600 frame
|
||||
// regardless of dirty region — the dirty rect only gates whether
|
||||
// a transfer happens at all. ~30ms at 4MHz SPI, fine for photo frame.
|
||||
_display->display();
|
||||
}
|
||||
|
||||
uint16_t DisplayManager::paletteToColor565(uint8_t index) {
|
||||
if (index >= DISPLAY_COLORS) return 0;
|
||||
return PALETTE_565[index];
|
||||
}
|
||||
|
||||
@@ -31,5 +31,4 @@ private:
|
||||
|
||||
void drawBadge(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||||
void triggerRefresh();
|
||||
uint16_t paletteToColor565(uint8_t index);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user