ui/ncurses: Reduce unnecessary calls to redrawwin
authorSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Wed, 4 Feb 2015 01:02:23 +0000 (12:02 +1100)
committerSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Mon, 16 Feb 2015 03:25:23 +0000 (14:25 +1100)
All current *_post() methods in ui/ncurses call redrawwin() and
wrefresh() together. wrefresh() updates any lines on the screen that
have been marked as changed or invalid. However redrawwin() marks the
entire screen as invalid unconditionally. We can reduce the amount of
data written to the screen by avoiding calls to redrawwin().

Screen transitions are the primary use case of redrawwin(), where the
whole screen must be invalidated to avoid stale data remaining on
screen. All other 'in-screen' updates such as changes to widgets or
changing focus do not require a call to redrawwin(). The most noticeable
performance improvement is in nc-menu, which makes an unnecssary call to
redrawwin() after every addition to the boot option menu.

eg. The number of bytes written to STDOUT in the main menu:
# Boot options | Before | After
--------------------------------
8 | 5488   | 1149
133 | 422454 | 4652

Signed-off-by: Samuel Mendoza-Jonas <sam.mj@au1.ibm.com>
ui/ncurses/nc-add-url.c
ui/ncurses/nc-boot-editor.c
ui/ncurses/nc-config.c
ui/ncurses/nc-lang.c
ui/ncurses/nc-menu.c

index 386d813264af64e25a257b3a30b5db33f2061744..cf55b03a104df725fcb9c2207c816cda87df1b5a 100644 (file)
@@ -43,6 +43,7 @@ struct add_url_screen {
 
        bool                    exit;
        bool                    show_help;
 
        bool                    exit;
        bool                    show_help;
+       bool                    need_redraw;
        void                    (*on_exit)(struct cui *);
 
        int                     label_x;
        void                    (*on_exit)(struct cui *);
 
        int                     label_x;
@@ -93,6 +94,7 @@ static void add_url_screen_process_key(struct nc_scr *scr, int key)
 
        } else if (screen->show_help) {
                screen->show_help = false;
 
        } else if (screen->show_help) {
                screen->show_help = false;
+               screen->need_redraw = true;
                cui_show_help(screen->cui, _("Retrieve Config"),
                        &add_url_help_text);
 
                cui_show_help(screen->cui, _("Retrieve Config"),
                        &add_url_help_text);
 
@@ -106,7 +108,10 @@ static int add_url_screen_post(struct nc_scr *scr)
        struct add_url_screen *screen = add_url_screen_from_scr(scr);
        widgetset_post(screen->widgetset);
        nc_scr_frame_draw(scr);
        struct add_url_screen *screen = add_url_screen_from_scr(scr);
        widgetset_post(screen->widgetset);
        nc_scr_frame_draw(scr);
-       redrawwin(scr->main_ncw);
+       if (screen->need_redraw) {
+               redrawwin(scr->main_ncw);
+               screen->need_redraw = false;
+       }
        wrefresh(screen->scr.main_ncw);
        return 0;
 }
        wrefresh(screen->scr.main_ncw);
        return 0;
 }
@@ -224,6 +229,7 @@ struct add_url_screen *add_url_screen_init(struct cui *cui,
        screen->on_exit = on_exit;
        screen->label_x = 2;
        screen->field_x = 25;
        screen->on_exit = on_exit;
        screen->label_x = 2;
        screen->field_x = 25;
+       screen->need_redraw = false;
 
        nc_scr_init(&screen->scr, pb_add_url_screen_sig, 0,
                cui, add_url_screen_process_key,
 
        nc_scr_init(&screen->scr, pb_add_url_screen_sig, 0,
                cui, add_url_screen_process_key,
index f78da5611e5838ea3c75050fb5121853fb2f0513..274bd9d2fa1b4df079eb050c10524bc46abad5b1 100644 (file)
@@ -44,6 +44,7 @@ struct boot_editor {
        void                    (*on_exit)(struct cui *cui,
                                        struct pmenu_item *item,
                                        struct pb_boot_data *bd);
        void                    (*on_exit)(struct cui *cui,
                                        struct pmenu_item *item,
                                        struct pb_boot_data *bd);
+       bool                    need_redraw;
 
        int                     label_x;
        int                     field_x;
 
        int                     label_x;
        int                     field_x;
@@ -111,7 +112,10 @@ static int boot_editor_post(struct nc_scr *scr)
        struct boot_editor *boot_editor = boot_editor_from_scr(scr);
        widgetset_post(boot_editor->widgetset);
        nc_scr_frame_draw(scr);
        struct boot_editor *boot_editor = boot_editor_from_scr(scr);
        widgetset_post(boot_editor->widgetset);
        nc_scr_frame_draw(scr);
-       redrawwin(scr->main_ncw);
+       if (boot_editor->need_redraw) {
+               redrawwin(scr->main_ncw);
+               boot_editor->need_redraw = false;
+       }
        wrefresh(boot_editor->scr.main_ncw);
        pad_refresh(boot_editor);
        return 0;
        wrefresh(boot_editor->scr.main_ncw);
        pad_refresh(boot_editor);
        return 0;
@@ -231,6 +235,7 @@ static void boot_editor_process_key(struct nc_scr *scr, int key)
                break;
        case STATE_HELP:
                boot_editor->state = STATE_EDIT;
                break;
        case STATE_HELP:
                boot_editor->state = STATE_EDIT;
+               boot_editor->need_redraw = true;
                cui_show_help(boot_editor->cui, _("Boot Option Editor"),
                                &boot_editor_help_text);
                break;
                cui_show_help(boot_editor->cui, _("Boot Option Editor"),
                                &boot_editor_help_text);
                break;
@@ -568,6 +573,7 @@ struct boot_editor *boot_editor_init(struct cui *cui,
        boot_editor->item = item;
        boot_editor->on_exit = on_exit;
        boot_editor->state = STATE_EDIT;
        boot_editor->item = item;
        boot_editor->on_exit = on_exit;
        boot_editor->state = STATE_EDIT;
+       boot_editor->need_redraw = false;
 
        int ncols1 = strncols(_("Device tree:"));
        int ncols2 = strncols(_("Boot arguments:"));
 
        int ncols1 = strncols(_("Device tree:"));
        int ncols2 = strncols(_("Boot arguments:"));
index 17cc380172cb15394fb0b3bb73b84cfd270d8d4d..c45df34e9afce17f5d641206bade8923e3bff252 100644 (file)
@@ -57,6 +57,7 @@ struct config_screen {
 
        bool                    exit;
        bool                    show_help;
 
        bool                    exit;
        bool                    show_help;
+       bool                    need_redraw;
        void                    (*on_exit)(struct cui *);
 
        int                     scroll_y;
        void                    (*on_exit)(struct cui *);
 
        int                     scroll_y;
@@ -146,6 +147,7 @@ static void config_screen_process_key(struct nc_scr *scr, int key)
 
        } else if (screen->show_help) {
                screen->show_help = false;
 
        } else if (screen->show_help) {
                screen->show_help = false;
+               screen->need_redraw = true;
                cui_show_help(screen->cui, _("System Configuration"),
                                &config_help_text);
 
                cui_show_help(screen->cui, _("System Configuration"),
                                &config_help_text);
 
@@ -165,7 +167,10 @@ static int config_screen_post(struct nc_scr *scr)
        struct config_screen *screen = config_screen_from_scr(scr);
        widgetset_post(screen->widgetset);
        nc_scr_frame_draw(scr);
        struct config_screen *screen = config_screen_from_scr(scr);
        widgetset_post(screen->widgetset);
        nc_scr_frame_draw(scr);
-       redrawwin(scr->main_ncw);
+       if (screen->need_redraw) {
+               redrawwin(scr->main_ncw);
+               screen->need_redraw = false;
+       }
        wrefresh(screen->scr.main_ncw);
        pad_refresh(screen);
        return 0;
        wrefresh(screen->scr.main_ncw);
        pad_refresh(screen);
        return 0;
@@ -859,6 +864,7 @@ struct config_screen *config_screen_init(struct cui *cui,
 
        screen->cui = cui;
        screen->on_exit = on_exit;
 
        screen->cui = cui;
        screen->on_exit = on_exit;
+       screen->need_redraw = false;
        screen->label_x = 2;
        screen->field_x = 17;
 
        screen->label_x = 2;
        screen->field_x = 17;
 
index 0422ebba7531e4a2cd7db87b5319c708f7084b99..0b871566aa83fbeda61e02da393f6fb204be36ed 100644 (file)
@@ -131,7 +131,6 @@ static int lang_screen_post(struct nc_scr *scr)
        struct lang_screen *screen = lang_screen_from_scr(scr);
        widgetset_post(screen->widgetset);
        nc_scr_frame_draw(scr);
        struct lang_screen *screen = lang_screen_from_scr(scr);
        widgetset_post(screen->widgetset);
        nc_scr_frame_draw(scr);
-       redrawwin(scr->main_ncw);
        wrefresh(screen->scr.main_ncw);
        pad_refresh(screen);
        return 0;
        wrefresh(screen->scr.main_ncw);
        pad_refresh(screen);
        return 0;
index 7ff2468cb1c47d3b1caae9cf3180523ad920f939..b8f9a35e0cddcd7ac16bbd330e73104ee8a0a3e4 100644 (file)
@@ -62,7 +62,6 @@ static int pmenu_post(struct nc_scr *scr)
        result = post_menu(menu->ncm);
 
        nc_scr_frame_draw(scr);
        result = post_menu(menu->ncm);
 
        nc_scr_frame_draw(scr);
-       redrawwin(menu->scr.main_ncw);
        wrefresh(menu->scr.main_ncw);
 
        return result;
        wrefresh(menu->scr.main_ncw);
 
        return result;