aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConfuSomu2021-03-04 21:35:34 -0500
committerConfuSomu2021-03-04 21:35:34 -0500
commite864e2efdda9ae977a049bc5491495b421028902 (patch)
treeb941ccc86cb7114907d9573e67f787a4b50d7fa3
parent250b15a5196efa4658fc637fe0c3896cb9c57c9a (diff)
downloadpico-watch-e864e2efdda9ae977a049bc5491495b421028902.tar
pico-watch-e864e2efdda9ae977a049bc5491495b421028902.tar.gz
pico-watch-e864e2efdda9ae977a049bc5491495b421028902.zip
Dump display backbuffer only once
This reduces display flickering and might help in having a longer battery life.
-rw-r--r--api.cpp26
-rw-r--r--api.hpp3
-rw-r--r--pico-watch.cpp4
3 files changed, 23 insertions, 10 deletions
diff --git a/api.cpp b/api.cpp
index a79b0f3..0d04772 100644
--- a/api.cpp
+++ b/api.cpp
@@ -27,7 +27,8 @@ void Api::display_power(bool mode) {
}
int Api::display_write_string(int iScrollX, int x, int y, char *szMsg, int iSize, int bInvert, int bRender) {
- return oledWriteString(&m_oled, iScrollX, x, y, szMsg, iSize, bInvert, bRender);
+ oledWriteString(&m_oled, iScrollX, x, y, szMsg, iSize, bInvert, 0);
+ m_writebb_needed = true;
}
void Api::display_fill(unsigned char ucData, int bRender) {
@@ -35,23 +36,30 @@ void Api::display_fill(unsigned char ucData, int bRender) {
}
void Api::display_draw_line(int x1, int y1, int x2, int y2, int bRender) {
- oledDrawLine(&m_oled, x1, y1, x2, y2, bRender);
+ oledDrawLine(&m_oled, x1, y1, x2, y2, 0);
+ m_writebb_needed = true;
}
void Api::display_draw_rectange(int x1, int y1, int x2, int y2, uint8_t ucColor, uint8_t bFilled) {
oledRectangle(&m_oled, x1, y1, x2, y2, ucColor, bFilled);
- oledDumpBuffer(&m_oled, m_ucBuffer); // Write the back buffer, after experimentation, seems to be required when drawing this shape
+ m_writebb_needed = true; // Write the back buffer, after experimentation, seems to be required when drawing this shape
}
void Api::display_draw_ellipse(int iCenterX, int iCenterY, int32_t iRadiusX, int32_t iRadiusY, uint8_t ucColor, uint8_t bFilled) {
oledEllipse(&m_oled, iCenterX, iCenterY, iRadiusX, iRadiusY, ucColor, bFilled);
- oledDumpBuffer(&m_oled, m_ucBuffer);
+ m_writebb_needed = true;
}
void Api::display_write_buffer(uint8_t *pBuffer) {
oledDumpBuffer(&m_oled, pBuffer);
}
+void Api::display_write_backbuffer() {
+ if (m_writebb_needed)
+ oledDumpBuffer(&m_oled, m_ucBuffer);
+ m_writebb_needed = false;
+}
+
int Api::display_write_pixel(int x, int y, unsigned char ucColor, int bRender) {
return oledSetPixel(&m_oled, x, y, ucColor, bRender);
}
@@ -64,7 +72,7 @@ bool Api::gui_popup_text(std::string title, std::string body){
oledRectangle(&m_oled, 9,7, 119,63, 0, 1); // Background
oledRectangle(&m_oled, 9,7, 119,63, 1, 0); // Popup border
oledRectangle(&m_oled, 9,7, 119,16, 1, 1); // Title background, FIXME pixel bleeding
- oledDumpBuffer(&m_oled, m_ucBuffer); // Display rectangle
+ m_writebb_needed = true; this->display_write_backbuffer(); // Display rectangle and anything else behind it (drawn before)
// Truncate longer strings to avoid wasting time in for loop and drawing on OLED
if (title.size() > 13)
@@ -108,9 +116,9 @@ bool Api::gui_footer_text(std::string text, int offset_x, int offset_row, bool i
if (!no_bg) {
oledRectangle(&m_oled, 0,56-offset_row*8, 127,64-offset_row*8, invert, 1);
- oledDumpBuffer(&m_oled, m_ucBuffer);
+ m_writebb_needed = true;
}
- oledWriteString(&m_oled, 0,offset_x,7-offset_row, &text[0], font, invert, 1);
+ oledWriteString(&m_oled, 0,offset_x,7-offset_row, &text[0], font, invert, 0);
}
bool Api::gui_header_text(std::string text, int offset_x, int offset_row, bool invert, bool no_bg) {
@@ -129,9 +137,9 @@ bool Api::gui_header_text(std::string text, int offset_x, int offset_row, bool i
if (!no_bg) {
oledRectangle(&m_oled, 0,0+offset_row*8, 127,8+offset_row*8, invert, 1);
- oledDumpBuffer(&m_oled, m_ucBuffer);
+ m_writebb_needed = true;
}
- oledWriteString(&m_oled, 0,offset_x,0+offset_row, &text[0], font, invert, 1);
+ oledWriteString(&m_oled, 0,offset_x,0+offset_row, &text[0], font, invert, 0);
}
bool Api::performance_set(int perf) {
diff --git a/api.hpp b/api.hpp
index 37a8c0c..d6f551e 100644
--- a/api.hpp
+++ b/api.hpp
@@ -11,6 +11,7 @@ class Api {
private:
SSOLED m_oled;
u_char m_init_done = 0;
+ bool m_writebb_needed = false; // Do we need to write the internal backbuffer?
uint8_t m_ucBuffer[1024] = {0};
uint m_button_last_pressed = 0;
int m_app_render_interval = 500;
@@ -33,6 +34,8 @@ class Api {
void display_draw_rectange(int x1, int y1, int x2, int y2, uint8_t ucColor, uint8_t bFilled);
void display_draw_ellipse(int iCenterX, int iCenterY, int32_t iRadiusX, int32_t iRadiusY, uint8_t ucColor, uint8_t bFilled);
void display_write_buffer(uint8_t *pBuffer);
+ // Write the internal backbuffer to the display. Should be called when after all drawing calls. One call is done to avoid flickering of the display.
+ void display_write_backbuffer();
int display_write_pixel(int x, int y, unsigned char ucColor, int bRender);
// Display a popup over the current view and wait for select button to be pressed.
// This is a blocking function and should be used only in the app's render method.
diff --git a/pico-watch.cpp b/pico-watch.cpp
index 9e22687..1dee093 100644
--- a/pico-watch.cpp
+++ b/pico-watch.cpp
@@ -95,8 +95,10 @@ int main() {
app_init(current_app);
while (1) {
- if (app_ready && !is_sleeping)
+ if (app_ready && !is_sleeping) {
app_render(current_app); // FIXME: This may cause race conditions when switching app
+ app_api.display_write_backbuffer();
+ }
sleep_ms(app_api.performance_render_interval_get());
}
return 0;