Skip to content

Commit c207927

Browse files
OmniLab Teamcopybara-github
authored andcommitted
Internal change
PiperOrigin-RevId: 952138474
1 parent cc633a2 commit c207927

1 file changed

Lines changed: 46 additions & 12 deletions

File tree

  • src/devtools/recoverbot/firmware/src

src/devtools/recoverbot/firmware/src/ui.cpp

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,19 @@ static size_t g_screenLogCount = 0;
3232
static char g_logText[LOG_TEXT_CAP];
3333
static size_t g_logTextLen = 0;
3434
static uint32_t g_lastLvglTickMs = 0;
35+
static uint32_t g_lastLvglHandlerMs = 0;
36+
static uint32_t g_logDirtySinceMs = 0;
37+
static bool g_logDirty = false;
38+
static bool g_forceFollowPending = false;
3539
static bool g_logoShown = false;
3640

41+
// Keep display work out of the servo command path. Log messages are appended
42+
// to the in-memory ring immediately, then coalesced into one LVGL update after
43+
// a short quiet window. LVGL itself only needs a modest service rate because
44+
// this UI has no latency-sensitive animations.
45+
static const uint32_t LOG_FLUSH_DEBOUNCE_MS = 50;
46+
static const uint32_t LVGL_HANDLER_INTERVAL_MS = 20;
47+
3748
void lvglDisplayFlush(lv_disp_drv_t* disp, const lv_area_t* area,
3849
lv_color_t* colorP) {
3950
uint32_t w = static_cast<uint32_t>(area->x2 - area->x1 + 1);
@@ -109,16 +120,29 @@ void scrollLogToBottom() {
109120
lv_obj_scroll_to_y(g_logPanel, LV_COORD_MAX, LV_ANIM_OFF);
110121
}
111122

112-
void appendLogToUi(const char* line, bool forceFollow) {
113-
if (!g_logLabel) return;
114-
if (!recoverbot::shouldShowLineOnScreen(line)) return;
123+
void flushPendingLogUi() {
124+
if (!g_logDirty || !g_logLabel) return;
115125

116126
bool wasAtBottom = true;
117127
if (g_logPanel) {
118128
lv_obj_update_layout(g_logPanel);
119129
wasAtBottom = lv_obj_get_scroll_bottom(g_logPanel) <= 6;
120130
}
121131

132+
rebuildLogText();
133+
lv_label_set_text_static(g_logLabel, g_logText);
134+
updateStatusLabel();
135+
136+
if (g_forceFollowPending || wasAtBottom) scrollLogToBottom();
137+
138+
g_logDirty = false;
139+
g_forceFollowPending = false;
140+
}
141+
142+
void appendLogToUi(const char* line, bool forceFollow) {
143+
if (!g_logLabel) return;
144+
if (!recoverbot::shouldShowLineOnScreen(line)) return;
145+
122146
size_t idx;
123147
if (g_screenLogCount < SCREEN_LOG_LINES) {
124148
idx = screenLogPhysicalIndex(g_screenLogCount);
@@ -129,12 +153,9 @@ void appendLogToUi(const char* line, bool forceFollow) {
129153
}
130154

131155
snprintf(g_screenLog[idx], SCREEN_LOG_LINE_CHARS, "%s", line);
132-
rebuildLogText();
133-
134-
lv_label_set_text_static(g_logLabel, g_logText);
135-
updateStatusLabel();
136-
137-
if (forceFollow || wasAtBottom) scrollLogToBottom();
156+
if (!g_logDirty) g_logDirtySinceMs = millis();
157+
g_logDirty = true;
158+
g_forceFollowPending = g_forceFollowPending || forceFollow;
138159
}
139160

140161
bool isLogoShown() { return g_logoShown; }
@@ -149,8 +170,9 @@ bool prepareLogUiForMessage() {
149170

150171
void finishLogUiMessage(bool wasLogoShown) {
151172
if (!wasLogoShown) return;
152-
lv_obj_invalidate(lv_scr_act());
153-
lv_timer_handler();
173+
// The pending log flush will restore the LVGL screen. Avoid a synchronous
174+
// render here because logMsg() is also called by press/release operations.
175+
g_forceFollowPending = true;
154176
}
155177

156178
void initLogUi() {
@@ -216,6 +238,7 @@ void initLogUi() {
216238
lv_label_set_text_static(g_logLabel, g_logText);
217239

218240
g_lastLvglTickMs = millis();
241+
g_lastLvglHandlerMs = g_lastLvglTickMs;
219242
lv_timer_handler();
220243
}
221244

@@ -224,7 +247,18 @@ void serviceLogUi() {
224247
lv_tick_inc(now - g_lastLvglTickMs);
225248
g_lastLvglTickMs = now;
226249

227-
if (!g_logoShown) lv_timer_handler();
250+
if (g_logoShown) return;
251+
252+
bool flushed = false;
253+
if (g_logDirty && (now - g_logDirtySinceMs) >= LOG_FLUSH_DEBOUNCE_MS) {
254+
flushPendingLogUi();
255+
flushed = true;
256+
}
257+
258+
if (flushed || (now - g_lastLvglHandlerMs) >= LVGL_HANDLER_INTERVAL_MS) {
259+
lv_timer_handler();
260+
g_lastLvglHandlerMs = now;
261+
}
228262
}
229263

230264
void showLogoScreen() {

0 commit comments

Comments
 (0)