mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
perf(oled): skip I2C flush when the frame is unchanged
The SH1106 path always pushed the full 1 KB buffer over I2C every endFrame, even on static screens (clock, home) that don't change between updates. Hash the GFX buffer (FNV-1a, no external dep — the CRC32 lib is only wired into e-ink builds) and skip display.display() when it matches the last frame pushed. _force_redraw forces a flush on the first frame and after turnOn()/clear() so a post-wake or post-clear frame can't be wrongly skipped. Mirrors the existing e-ink CRC-skip. Builds green: WioTrackerL1_companion_solo_dual. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@ void SH1106Display::turnOn()
|
||||
display.oled_commandList(pre, 2);
|
||||
display.setContrast(_contrast);
|
||||
_isOn = true;
|
||||
_force_redraw = true; // panel was off — guarantee the next endFrame() flushes
|
||||
}
|
||||
|
||||
void SH1106Display::turnOff()
|
||||
@@ -35,6 +36,7 @@ void SH1106Display::clear()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.display();
|
||||
_force_redraw = true; // next endFrame() must flush even if its CRC matches a pre-clear frame
|
||||
}
|
||||
|
||||
void SH1106Display::startFrame(Color bkg)
|
||||
@@ -189,5 +191,17 @@ void SH1106Display::setBrightness(uint8_t level)
|
||||
|
||||
void SH1106Display::endFrame()
|
||||
{
|
||||
// Skip the I²C flush when the frame is byte-identical to the last one pushed.
|
||||
// The most-shown screens (clock, home) are static between updates, so this
|
||||
// cuts redundant display() traffic and a little power. FNV-1a over the 1 KB
|
||||
// GFX buffer (~1k xor+mul, cheap); _force_redraw guarantees the first frame
|
||||
// and the frame after wake/clear.
|
||||
const uint8_t* buf = display.getBuffer();
|
||||
uint16_t n = (uint16_t)((width() * height()) / 8);
|
||||
uint32_t h = 2166136261u;
|
||||
for (uint16_t i = 0; i < n; i++) { h ^= buf[i]; h *= 16777619u; }
|
||||
if (!_force_redraw && h == _last_frame_hash) return;
|
||||
_force_redraw = false;
|
||||
_last_frame_hash = h;
|
||||
display.display();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,12 @@ class SH1106Display : public DisplayDriver
|
||||
uint8_t _precharge;
|
||||
bool _use_lemon = false;
|
||||
int _text_sz;
|
||||
// Frame-skip: endFrame() hashes the GFX buffer (FNV-1a, no external dep — the
|
||||
// CRC32 lib is only wired into e-ink builds) and skips the I²C flush when it's
|
||||
// byte-identical to the last one pushed. _force_redraw guarantees the first
|
||||
// frame and the frame after turnOn()/clear() always flush.
|
||||
uint32_t _last_frame_hash = 0;
|
||||
bool _force_redraw = true;
|
||||
|
||||
bool i2c_probe(TwoWire &wire, uint8_t addr);
|
||||
int16_t drawLemonChar(int16_t x, int16_t y, uint32_t cp);
|
||||
|
||||
Reference in New Issue
Block a user