mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-21 17:20:01 +00:00
fix: improve display health on shutdown
Two extra full refreshes, masquerading as a "shutting down" screen. One is drawn white-on-black, to really shake the pixels up.
This commit is contained in:
parent
97b36f3783
commit
c0fb6dd6bb
@ -799,7 +799,7 @@ uint16_t InkHUD::Applet::getLogoHeight(uint16_t limitWidth, uint16_t limitHeight
|
|||||||
// // \\
|
// // \\
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void InkHUD::Applet::drawLogo(int16_t centerX, int16_t centerY, uint16_t width, uint16_t height)
|
void InkHUD::Applet::drawLogo(int16_t centerX, int16_t centerY, uint16_t width, uint16_t height, Color color)
|
||||||
{
|
{
|
||||||
struct Point {
|
struct Point {
|
||||||
int x;
|
int x;
|
||||||
@ -905,24 +905,24 @@ void InkHUD::Applet::drawLogo(int16_t centerX, int16_t centerY, uint16_t width,
|
|||||||
Point aq2{a2.x - fromPath.x, a2.y - fromPath.y};
|
Point aq2{a2.x - fromPath.x, a2.y - fromPath.y};
|
||||||
Point aq3{a2.x + fromPath.x, a2.y + fromPath.y};
|
Point aq3{a2.x + fromPath.x, a2.y + fromPath.y};
|
||||||
Point aq4{a1.x + fromPath.x, a1.y + fromPath.y};
|
Point aq4{a1.x + fromPath.x, a1.y + fromPath.y};
|
||||||
fillTriangle(aq1.x, aq1.y, aq2.x, aq2.y, aq3.x, aq3.y, BLACK);
|
fillTriangle(aq1.x, aq1.y, aq2.x, aq2.y, aq3.x, aq3.y, color);
|
||||||
fillTriangle(aq1.x, aq1.y, aq3.x, aq3.y, aq4.x, aq4.y, BLACK);
|
fillTriangle(aq1.x, aq1.y, aq3.x, aq3.y, aq4.x, aq4.y, color);
|
||||||
|
|
||||||
// Make the path thick: path b becomes quad b
|
// Make the path thick: path b becomes quad b
|
||||||
Point bq1{b1.x - fromPath.x, b1.y - fromPath.y};
|
Point bq1{b1.x - fromPath.x, b1.y - fromPath.y};
|
||||||
Point bq2{b2.x - fromPath.x, b2.y - fromPath.y};
|
Point bq2{b2.x - fromPath.x, b2.y - fromPath.y};
|
||||||
Point bq3{b2.x + fromPath.x, b2.y + fromPath.y};
|
Point bq3{b2.x + fromPath.x, b2.y + fromPath.y};
|
||||||
Point bq4{b1.x + fromPath.x, b1.y + fromPath.y};
|
Point bq4{b1.x + fromPath.x, b1.y + fromPath.y};
|
||||||
fillTriangle(bq1.x, bq1.y, bq2.x, bq2.y, bq3.x, bq3.y, BLACK);
|
fillTriangle(bq1.x, bq1.y, bq2.x, bq2.y, bq3.x, bq3.y, color);
|
||||||
fillTriangle(bq1.x, bq1.y, bq3.x, bq3.y, bq4.x, bq4.y, BLACK);
|
fillTriangle(bq1.x, bq1.y, bq3.x, bq3.y, bq4.x, bq4.y, color);
|
||||||
|
|
||||||
// Make the path thick: path c becomes quad c
|
// Make the path thick: path c becomes quad c
|
||||||
Point cq1{c1.x - fromPath.x, c1.y + fromPath.y};
|
Point cq1{c1.x - fromPath.x, c1.y + fromPath.y};
|
||||||
Point cq2{c2.x - fromPath.x, c2.y + fromPath.y};
|
Point cq2{c2.x - fromPath.x, c2.y + fromPath.y};
|
||||||
Point cq3{c2.x + fromPath.x, c2.y - fromPath.y};
|
Point cq3{c2.x + fromPath.x, c2.y - fromPath.y};
|
||||||
Point cq4{c1.x + fromPath.x, c1.y - fromPath.y};
|
Point cq4{c1.x + fromPath.x, c1.y - fromPath.y};
|
||||||
fillTriangle(cq1.x, cq1.y, cq2.x, cq2.y, cq3.x, cq3.y, BLACK);
|
fillTriangle(cq1.x, cq1.y, cq2.x, cq2.y, cq3.x, cq3.y, color);
|
||||||
fillTriangle(cq1.x, cq1.y, cq3.x, cq3.y, cq4.x, cq4.y, BLACK);
|
fillTriangle(cq1.x, cq1.y, cq3.x, cq3.y, cq4.x, cq4.y, color);
|
||||||
|
|
||||||
// Radius the intersection of quad b and quad c
|
// Radius the intersection of quad b and quad c
|
||||||
/*
|
/*
|
||||||
@ -941,7 +941,7 @@ void InkHUD::Applet::drawLogo(int16_t centerX, int16_t centerY, uint16_t width,
|
|||||||
// The radius for the cap *should* be the same as logoTh, but it's not, due to accumulated rounding
|
// The radius for the cap *should* be the same as logoTh, but it's not, due to accumulated rounding
|
||||||
// We get better results just re-deriving it
|
// We get better results just re-deriving it
|
||||||
int16_t capRad = sqrt(pow(fromPath.x, 2) + pow(fromPath.y, 2));
|
int16_t capRad = sqrt(pow(fromPath.x, 2) + pow(fromPath.y, 2));
|
||||||
fillCircle(b2.x, b2.y, capRad, BLACK);
|
fillCircle(b2.x, b2.y, capRad, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,8 @@ class Applet : public GFX
|
|||||||
static constexpr float LOGO_ASPECT_RATIO = 1.9; // Width:Height for drawing the Meshtastic logo
|
static constexpr float LOGO_ASPECT_RATIO = 1.9; // Width:Height for drawing the Meshtastic logo
|
||||||
uint16_t getLogoWidth(uint16_t limitWidth, uint16_t limitHeight); // Size Meshtastic logo to fit within region
|
uint16_t getLogoWidth(uint16_t limitWidth, uint16_t limitHeight); // Size Meshtastic logo to fit within region
|
||||||
uint16_t getLogoHeight(uint16_t limitWidth, uint16_t limitHeight); // Size Meshtastic logo to fit within region
|
uint16_t getLogoHeight(uint16_t limitWidth, uint16_t limitHeight); // Size Meshtastic logo to fit within region
|
||||||
void drawLogo(int16_t centerX, int16_t centerY, uint16_t width, uint16_t height); // Draw the meshtastic logo
|
void drawLogo(int16_t centerX, int16_t centerY, uint16_t width, uint16_t height,
|
||||||
|
Color color = BLACK); // Draw the Meshtastic logo
|
||||||
|
|
||||||
std::string hexifyNodeNum(NodeNum num); // Style as !0123abdc
|
std::string hexifyNodeNum(NodeNum num); // Style as !0123abdc
|
||||||
SignalStrength getSignalStrength(float snr, float rssi); // Interpret SNR and RSSI, as an easy to understand value
|
SignalStrength getSignalStrength(float snr, float rssi); // Interpret SNR and RSSI, as an easy to understand value
|
||||||
|
@ -34,7 +34,15 @@ void InkHUD::LogoApplet::onRender()
|
|||||||
int16_t logoCX = X(0.5);
|
int16_t logoCX = X(0.5);
|
||||||
int16_t logoCY = Y(0.5 - 0.05);
|
int16_t logoCY = Y(0.5 - 0.05);
|
||||||
|
|
||||||
drawLogo(logoCX, logoCY, logoW, logoH);
|
// Invert colors if black-on-white
|
||||||
|
// Used during shutdown, to resport display health
|
||||||
|
// Todo: handle this in InkHUD::Renderer instead
|
||||||
|
if (inverted) {
|
||||||
|
fillScreen(BLACK);
|
||||||
|
setTextColor(WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawLogo(logoCX, logoCY, logoW, logoH, inverted ? WHITE : BLACK);
|
||||||
|
|
||||||
if (!textLeft.empty()) {
|
if (!textLeft.empty()) {
|
||||||
setFont(fontSmall);
|
setFont(fontSmall);
|
||||||
@ -74,13 +82,30 @@ void InkHUD::LogoApplet::onBackground()
|
|||||||
// Begin displaying the screen which is shown at shutdown
|
// Begin displaying the screen which is shown at shutdown
|
||||||
void InkHUD::LogoApplet::onShutdown()
|
void InkHUD::LogoApplet::onShutdown()
|
||||||
{
|
{
|
||||||
|
bringToForeground();
|
||||||
|
|
||||||
|
textLeft = "";
|
||||||
|
textRight = "";
|
||||||
|
textTitle = "Shutting Down...";
|
||||||
|
fontTitle = fontSmall;
|
||||||
|
|
||||||
|
// Draw a shutting down screen, twice.
|
||||||
|
// Once white on black, once black on white.
|
||||||
|
// Intention is to restore display health.
|
||||||
|
|
||||||
|
inverted = true;
|
||||||
|
inkhud->forceUpdate(Drivers::EInk::FULL, false);
|
||||||
|
inverted = false;
|
||||||
|
inkhud->forceUpdate(Drivers::EInk::FULL, false);
|
||||||
|
|
||||||
|
// Prepare for the powered-off screen now
|
||||||
|
// We can change these values because the initial "shutting down" screen has already rendered at this point
|
||||||
textLeft = "";
|
textLeft = "";
|
||||||
textRight = "";
|
textRight = "";
|
||||||
textTitle = owner.short_name;
|
textTitle = owner.short_name;
|
||||||
fontTitle = fontLarge;
|
fontTitle = fontLarge;
|
||||||
|
|
||||||
bringToForeground();
|
// This is then drawn by InkHUD::Events::onShutdown, with a blocking FULL update, after InkHUD's flash write is complete
|
||||||
// This is then drawn by InkHUD::Events::onShutdown, with a blocking FULL update
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t InkHUD::LogoApplet::runOnce()
|
int32_t InkHUD::LogoApplet::runOnce()
|
||||||
|
@ -33,6 +33,7 @@ class LogoApplet : public SystemApplet, public concurrency::OSThread
|
|||||||
std::string textRight;
|
std::string textRight;
|
||||||
std::string textTitle;
|
std::string textTitle;
|
||||||
AppletFont fontTitle;
|
AppletFont fontTitle;
|
||||||
|
bool inverted = false; // Invert colors. Used during shutdown, to restore display health.
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace NicheGraphics::InkHUD
|
} // namespace NicheGraphics::InkHUD
|
||||||
|
@ -70,6 +70,9 @@ void InkHUD::Events::onButtonLong()
|
|||||||
// Returns 0 to signal that we agree to sleep now
|
// Returns 0 to signal that we agree to sleep now
|
||||||
int InkHUD::Events::beforeDeepSleep(void *unused)
|
int InkHUD::Events::beforeDeepSleep(void *unused)
|
||||||
{
|
{
|
||||||
|
// If a previous display update is in progress, wait for it to complete.
|
||||||
|
inkhud->awaitUpdate();
|
||||||
|
|
||||||
// Notify all applets that we're shutting down
|
// Notify all applets that we're shutting down
|
||||||
for (Applet *ua : inkhud->userApplets) {
|
for (Applet *ua : inkhud->userApplets) {
|
||||||
ua->onDeactivate();
|
ua->onDeactivate();
|
||||||
@ -87,8 +90,10 @@ int InkHUD::Events::beforeDeepSleep(void *unused)
|
|||||||
inkhud->persistence->saveSettings();
|
inkhud->persistence->saveSettings();
|
||||||
inkhud->persistence->saveLatestMessage();
|
inkhud->persistence->saveLatestMessage();
|
||||||
|
|
||||||
// LogoApplet::onShutdown will have requested an update, to draw the shutdown screen
|
// LogoApplet::onShutdown attempted to heal the display by drawing a "shutting down" screen twice,
|
||||||
// Draw that now, and wait here until the update is complete
|
// then prepared a final powered-off screen for us, which shows device shortname.
|
||||||
|
// We're updating to show that one now.
|
||||||
|
|
||||||
inkhud->forceUpdate(Drivers::EInk::UpdateTypes::FULL, false);
|
inkhud->forceUpdate(Drivers::EInk::UpdateTypes::FULL, false);
|
||||||
|
|
||||||
return 0; // We agree: deep sleep now
|
return 0; // We agree: deep sleep now
|
||||||
|
Loading…
Reference in New Issue
Block a user