From 555d56f32f614e88daa3922bf5e312c3a502a6bc Mon Sep 17 00:00:00 2001 From: Fabrice Weinberg <Fabrice@weinberg.me> Date: Thu, 11 Aug 2016 14:23:25 +0200 Subject: [PATCH] Improve drawing performance by using a the x bounds too --- SH1106Brzo.h | 24 ++++++++++++++++++++---- SH1106Wire.h | 20 +++++++++++++++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/SH1106Brzo.h b/SH1106Brzo.h index c1a89c4..385630b 100644 --- a/SH1106Brzo.h +++ b/SH1106Brzo.h @@ -60,6 +60,8 @@ class SH1106Brzo : public OLEDDisplay { uint8_t minBoundY = ~0; uint8_t maxBoundY = 0; + uint8_t minBoundX = ~0; + uint8_t maxBoundX = 0; uint8_t x, y; // Calculate the Y bounding box of changes @@ -70,6 +72,8 @@ class SH1106Brzo : public OLEDDisplay { if (buffer[pos] != buffer_back[pos]) { minBoundY = _min(minBoundY, y); maxBoundY = _max(maxBoundY, y); + minBoundX = _min(minBoundX, x); + maxBoundX = _max(maxBoundX, x); } buffer_back[pos] = buffer[pos]; } @@ -84,12 +88,18 @@ class SH1106Brzo : public OLEDDisplay { byte k = 0; uint8_t sendBuffer[17]; sendBuffer[0] = 0x40; + + // Calculate the colum offset + uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F; + uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 ); + brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED); + for (y = minBoundY; y <= maxBoundY; y++) { sendCommand(0xB0 + y); - sendCommand(0x02); - sendCommand(0x10); - for (x = 0; x < DISPLAY_WIDTH; x++) { + sendCommand(minBoundXp2H); + sendCommand(minBoundXp2L); + for (x = minBoundX; x <= maxBoundX; x++) { k++; sendBuffer[k] = buffer[x + y * DISPLAY_WIDTH]; if (k == 16) { @@ -97,9 +107,15 @@ class SH1106Brzo : public OLEDDisplay { k = 0; } } + if (k != 0) { + brzo_i2c_write(sendBuffer, k + 1, true); + k = 0; + } yield(); } - brzo_i2c_write(sendBuffer, k + 1, true); + if (k != 0) { + brzo_i2c_write(sendBuffer, k + 1, true); + } brzo_i2c_end_transaction(); #else #endif diff --git a/SH1106Wire.h b/SH1106Wire.h index d885fab..f0784b9 100644 --- a/SH1106Wire.h +++ b/SH1106Wire.h @@ -62,6 +62,10 @@ class SH1106Wire : public OLEDDisplay { #ifdef OLEDDISPLAY_DOUBLE_BUFFER uint8_t minBoundY = ~0; uint8_t maxBoundY = 0; + + uint8_t minBoundX = ~0; + uint8_t maxBoundX = 0; + uint8_t x, y; // Calculate the Y bounding box of changes @@ -72,6 +76,8 @@ class SH1106Wire : public OLEDDisplay { if (buffer[pos] != buffer_back[pos]) { minBoundY = _min(minBoundY, y); maxBoundY = _max(maxBoundY, y); + minBoundX = _min(minBoundX, x); + maxBoundX = _max(maxBoundX, x); } buffer_back[pos] = buffer[pos]; } @@ -83,12 +89,16 @@ class SH1106Wire : public OLEDDisplay { // holdes true for all values of pos if (minBoundY == ~0) return; + // Calculate the colum offset + uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F; + uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 ); + byte k = 0; for (y = minBoundY; y <= maxBoundY; y++) { sendCommand(0xB0 + y); - sendCommand(0x02); - sendCommand(0x10); - for (x = 0; x < DISPLAY_WIDTH; x++) { + sendCommand(minBoundXp2H); + sendCommand(minBoundXp2L); + for (x = minBoundX; x <= maxBoundX; x++) { if (k == 0) { Wire.beginTransmission(_address); Wire.write(0x40); @@ -100,6 +110,10 @@ class SH1106Wire : public OLEDDisplay { k = 0; } } + if (k != 0) { + Wire.endTransmission(); + k = 0; + } yield(); } -- GitLab