throttle screen redraw via cooldown, setting 10/30 largely eliminates dropped bytes

pull/111/merge
Ondřej Hruška 7 years ago
parent beda5e67c0
commit 73c943bb97
  1. 5
      html_orig/lang/en.php
  2. 6
      html_orig/pages/cfg_term.php
  3. 2
      libesphttpd
  4. 47
      user/cgi_sockets.c
  5. 20
      user/cgi_term_cfg.c
  6. 27
      user/screen.c
  7. 9
      user/screen.h
  8. 2
      user/syscfg.c
  9. 2
      user/syscfg.h
  10. 2
      user/wifimgr.c
  11. 3
      user/wifimgr.h

@ -42,8 +42,9 @@ return [
'term.buttons' => 'Button labels',
'term.theme' => 'Color scheme',
'term.parser_tout_ms' => 'Parser timeout',
'term.display_tout_ms' => 'Redraw timeout',
'term.fn_alt_mode' => 'Xterm Fn keys',
'term.display_tout_ms' => 'Redraw delay',
'term.display_cooldown_ms' => 'Redraw cooldown',
'term.fn_alt_mode' => 'SS3 Fn keys',
// terminal color labels
'color.0' => 'Black',

@ -116,6 +116,12 @@
<span class="mq-no-phone">&nbsp;ms</span>
</div>
<div class="Row">
<label for="display_cooldown_ms"><?= tr('term.display_cooldown_ms') ?><span class="mq-phone">&nbsp;(ms)</span></label>
<input type="number" step=1 min=0 name="display_cooldown_ms" id="display_cooldown_ms" value="%display_cooldown_ms%" required>
<span class="mq-no-phone">&nbsp;ms</span>
</div>
<div class="Row checkbox" >
<label><?= tr('term.fn_alt_mode') ?></label><!--
--><span class="box" tabindex=0 role=checkbox></span>

@ -1 +1 @@
Subproject commit 3237c6f8fb9fd91b22980116b89768e1ca21cf66
Subproject commit 566e95af0c892576825903303ca7c65710cbbb5e

@ -11,25 +11,36 @@
static char sock_buff[SOCK_BUF_LEN];
volatile bool notify_available = true;
volatile bool notify_cooldown = false;
static ETSTimer notifyTim;
static ETSTimer notifyTim2;
static ETSTimer notifyContentTim;
static ETSTimer notifyLabelsTim;
static ETSTimer notifyCooldownTim;
// we're trying to do a kind of mutex here, without the actual primitives
// this might glitch, very rarely.
// it's recommended to put some delay between setting labels and updating the screen.
/**
* Cooldown delay is over
* @param arg
*/
static void ICACHE_FLASH_ATTR
notifyCooldownTimCb(void *arg)
{
notify_cooldown = false;
}
static void ICACHE_FLASH_ATTR
notifyTimCb(void *arg) {
notifyContentTimCb(void *arg)
{
void *data = NULL;
int max_bl, total_bl;
cgiWebsockMeasureBacklog(URL_WS_UPDATE, &max_bl, &total_bl);
if (!notify_available || (max_bl > 2048)) { // do not send if we have anything significant backlogged
if (!notify_available || notify_cooldown || (max_bl > 2048)) { // do not send if we have anything significant backlogged
// postpone a little
os_timer_disarm(&notifyTim);
os_timer_setfn(&notifyTim, notifyTimCb, NULL);
os_timer_arm(&notifyTim, 5, 0);
TIMER_START(&notifyContentTim, notifyContentTimCb, 5, 0);
return;
}
notify_available = false;
@ -46,17 +57,18 @@ notifyTimCb(void *arg) {
// cleanup
screenSerializeToBuffer(NULL, SOCK_BUF_LEN, &data);
notify_cooldown = true;
notify_available = true;
TIMER_START(&notifyCooldownTim, notifyCooldownTimCb, termconf->display_cooldown_ms, 0);
}
static void ICACHE_FLASH_ATTR
notifyLabelsTimCb(void *arg)
{
if (!notify_available) {
if (!notify_available || notify_cooldown) {
// postpone a little
os_timer_disarm(&notifyTim2);
os_timer_setfn(&notifyTim2, notifyLabelsTimCb, NULL);
os_timer_arm(&notifyTim2, 1, 0);
TIMER_START(&notifyLabelsTim, notifyLabelsTimCb, 1, 0);
return;
}
notify_available = false;
@ -64,7 +76,10 @@ notifyLabelsTimCb(void *arg)
screenSerializeLabelsToBuffer(sock_buff, SOCK_BUF_LEN);
cgiWebsockBroadcast(URL_WS_UPDATE, sock_buff, (int) strlen(sock_buff), 0);
notify_cooldown = true;
notify_available = true;
TIMER_START(&notifyCooldownTim, notifyCooldownTimCb, termconf->display_cooldown_ms, 0);
}
/** Beep */
@ -87,17 +102,15 @@ void ICACHE_FLASH_ATTR screen_notifyChange(ScreenNotifyChangeTopic topic)
// PRs are welcome for a nicer update "queue" solution
if (termconf->display_tout_ms == 0) termconf->display_tout_ms = SCR_DEF_DISPLAY_TOUT_MS;
// NOTE: the timers are restarted if already running
if (topic == CHANGE_LABELS) {
// separate timer from content change timer, to avoid losing that update
os_timer_disarm(&notifyTim2);
os_timer_setfn(&notifyTim2, notifyLabelsTimCb, NULL);
os_timer_arm(&notifyTim2, termconf->display_tout_ms, 0);
TIMER_START(&notifyLabelsTim, notifyLabelsTimCb, termconf->display_tout_ms, 0);
}
else if (topic == CHANGE_CONTENT) {
// throttle delay
os_timer_disarm(&notifyTim);
os_timer_setfn(&notifyTim, notifyTimCb, NULL);
os_timer_arm(&notifyTim, termconf->display_tout_ms, 0);
TIMER_START(&notifyContentTim, notifyContentTimCb, termconf->display_tout_ms, 0);
}
}

@ -87,7 +87,7 @@ cgiTermCfgSetParams(HttpdConnData *connData)
if (n >= 0) {
termconf->parser_tout_ms = n;
} else {
warn("Bad timeout %s", buff);
warn("Bad parser timeout %s", buff);
redir_url += sprintf(redir_url, "parser_tout_ms,");
}
}
@ -95,14 +95,25 @@ cgiTermCfgSetParams(HttpdConnData *connData)
if (GET_ARG("display_tout_ms")) {
dbg("Display update idle timeout: %s ms", buff);
n = atoi(buff);
if (n >= 0) {
if (n > 0) {
termconf->display_tout_ms = n;
} else {
warn("Bad timeout %s", buff);
warn("Bad update timeout %s", buff);
redir_url += sprintf(redir_url, "display_tout_ms,");
}
}
if (GET_ARG("display_cooldown_ms")) {
dbg("Display update cooldown: %s ms", buff);
n = atoi(buff);
if (n > 0) {
termconf->display_cooldown_ms = n;
} else {
warn("Bad cooldown %s", buff);
redir_url += sprintf(redir_url, "display_cooldown_ms,");
}
}
if (GET_ARG("fn_alt_mode")) {
dbg("FN alt mode: %s", buff);
n = atoi(buff);
@ -195,6 +206,9 @@ tplTermCfg(HttpdConnData *connData, char *token, void **arg)
else if (streq(token, "display_tout_ms")) {
sprintf(buff, "%d", termconf->display_tout_ms);
}
else if (streq(token, "display_cooldown_ms")) {
sprintf(buff, "%d", termconf->display_cooldown_ms);
}
else if (streq(token, "fn_alt_mode")) {
sprintf(buff, "%d", (int)termconf->fn_alt_mode);
}

@ -137,17 +137,40 @@ void terminal_apply_settings(void)
/** this is used when changing terminal settings that do not affect the screen size */
void terminal_apply_settings_noclear(void)
{
if (termconf->display_tout_ms == 0) termconf->display_tout_ms = SCR_DEF_DISPLAY_TOUT_MS;
bool changed = false;
// Migrate to v1
if (termconf->config_version < 1) {
dbg("termconf: Updating to version 1");
termconf->display_cooldown_ms = SCR_DEF_DISPLAY_COOLDOWN_MS;
changed = 1;
}
termconf->config_version = TERMCONF_VERSION;
// Validation...
if (termconf->display_tout_ms == 0) {
termconf->display_tout_ms = SCR_DEF_DISPLAY_TOUT_MS;
changed = 1;
}
if (termconf->display_cooldown_ms == 0) {
termconf->display_cooldown_ms = SCR_DEF_DISPLAY_COOLDOWN_MS;
changed = 1;
}
memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle));
if (W*H > MAX_SCREEN_SIZE) {
error("BAD SCREEN SIZE: %d rows x %d cols", H, W);
error("reverting terminal settings to default");
terminal_restore_defaults();
persist_store();
changed = true;
memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle));
screen_init();
}
if (changed) {
persist_store();
}
}
//endregion

@ -41,7 +41,8 @@
#define TERM_BTN_LEN 10
#define TERM_TITLE_LEN 64
#define SCR_DEF_DISPLAY_TOUT_MS 20
#define SCR_DEF_DISPLAY_TOUT_MS 10
#define SCR_DEF_DISPLAY_COOLDOWN_MS 30
#define SCR_DEF_PARSER_TOUT_MS 10
#define SCR_DEF_FN_ALT_MODE false
#define SCR_DEF_WIDTH 26
@ -49,7 +50,9 @@
#define SCR_DEF_TITLE "ESPTerm"
/** Maximum screen size (determines size of the static data array) */
#define MAX_SCREEN_SIZE (80*25)
#define MAX_SCREEN_SIZE (80*26)
#define TERMCONF_VERSION 1
// --- Persistent Settings ---
@ -64,6 +67,8 @@ typedef struct {
u32 parser_tout_ms;
u32 display_tout_ms;
bool fn_alt_mode; // xterm compatibility mode (alternate codes for some FN keys)
u8 config_version;
u32 display_cooldown_ms;
} TerminalConfigBundle;
// Live config

@ -12,6 +12,8 @@ SystemConfigBundle * const sysconf = &persist.current.sysconf;
void ICACHE_FLASH_ATTR
sysconf_apply_settings(void)
{
// !!! Update to current version !!!
serialInit();
}

@ -10,11 +10,13 @@
// Size designed for the wifi config structure
// Must be constant to avoid corrupting user config after upgrade
#define SYSCONF_SIZE 200
#define SYSCONF_VERSION 0
typedef struct {
u32 uart_baudrate;
u8 uart_parity;
u8 uart_stopbits;
u8 config_version;
} SystemConfigBundle;
extern SystemConfigBundle * const sysconf;

@ -156,6 +156,8 @@ wifimgr_apply_settings(void)
{
info("[WiFi] Initializing...");
// !!! Update to current version !!!
// Force wifi cycle
// Disconnect - may not be needed?
WIFI_MODE opmode = wifi_get_opmode();

@ -17,6 +17,8 @@
// Must be constant to avoid corrupting user config after upgrade
#define WIFICONF_SIZE 340
#define WIFICONF_VERSION 0
/**
* A structure holding all configured WiFi parameters
* and the active state.
@ -42,6 +44,7 @@ typedef struct {
u8 sta_password[PASSWORD_LEN];
bool sta_dhcp_enable;
struct ip_info sta_addr;
u8 config_version;
} WiFiConfigBundle;
typedef struct {

Loading…
Cancel
Save