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