diff options
| author | Dmitry Antipov | 2013-09-24 09:42:30 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2013-09-24 09:42:30 +0400 |
| commit | ec7bc82f9c63b6ec533f7489e67b1c1b18d08dd5 (patch) | |
| tree | b5cd6d535d5593424d85e227cf565e51c8016883 /src | |
| parent | 7be68de5d25998e7d15aaab800c40cad48eac846 (diff) | |
| download | emacs-ec7bc82f9c63b6ec533f7489e67b1c1b18d08dd5.tar.gz emacs-ec7bc82f9c63b6ec533f7489e67b1c1b18d08dd5.zip | |
Optimize glyph row clearing and copying routines.
* dispextern.h (struct glyph_row): Change layout of struct
glyph_row to help copy_row_except_pointers. Adjust comment.
* dispnew.c (null_row): Remove.
(clear_glyph_row): Use offsetof and memset to find and clear
just the members that need clearing. Adjust comment.
(copy_row_except_pointers): Likewise for copying.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/dispextern.h | 18 | ||||
| -rw-r--r-- | src/dispnew.c | 65 |
3 files changed, 36 insertions, 57 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 303eb4f9176..28b4da176ae 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2013-09-24 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | Optimize glyph row clearing and copying routines. | ||
| 4 | * dispextern.h (struct glyph_row): Change layout of struct | ||
| 5 | glyph_row to help copy_row_except_pointers. Adjust comment. | ||
| 6 | * dispnew.c (null_row): Remove. | ||
| 7 | (clear_glyph_row): Use offsetof and memset to find and clear | ||
| 8 | just the members that need clearing. Adjust comment. | ||
| 9 | (copy_row_except_pointers): Likewise for copying. | ||
| 10 | |||
| 1 | 2013-09-24 Paul Eggert <eggert@cs.ucla.edu> | 11 | 2013-09-24 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 12 | ||
| 3 | Some minor cleanups of recently-added bool vector code. | 13 | Some minor cleanups of recently-added bool vector code. |
diff --git a/src/dispextern.h b/src/dispextern.h index 84111bd9958..5ddc177bcf0 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -792,7 +792,10 @@ enum glyph_row_area | |||
| 792 | Rows in window matrices on frames having no frame matrices point to | 792 | Rows in window matrices on frames having no frame matrices point to |
| 793 | glyphs allocated from the heap via xmalloc; | 793 | glyphs allocated from the heap via xmalloc; |
| 794 | glyphs[LEFT_MARGIN_AREA] is the start address of the allocated | 794 | glyphs[LEFT_MARGIN_AREA] is the start address of the allocated |
| 795 | glyph structure array. */ | 795 | glyph structure array. |
| 796 | |||
| 797 | NOTE: layout of first four members of this structure is important, | ||
| 798 | see clear_glyph_row and copy_row_except_pointers to check why. */ | ||
| 796 | 799 | ||
| 797 | struct glyph_row | 800 | struct glyph_row |
| 798 | { | 801 | { |
| @@ -812,8 +815,13 @@ struct glyph_row | |||
| 812 | removed some day, so don't use it in new code. */ | 815 | removed some day, so don't use it in new code. */ |
| 813 | struct glyph *glyphs[1 + LAST_AREA]; | 816 | struct glyph *glyphs[1 + LAST_AREA]; |
| 814 | 817 | ||
| 815 | /* Number of glyphs actually filled in areas. */ | 818 | /* Number of glyphs actually filled in areas. This could have size |
| 816 | short used[LAST_AREA]; | 819 | LAST_AREA, but it's 1 + LAST_AREA to simplify offset calculations. */ |
| 820 | short used[1 + LAST_AREA]; | ||
| 821 | |||
| 822 | /* Hash code. This hash code is available as soon as the row | ||
| 823 | is constructed, i.e. after a call to display_line. */ | ||
| 824 | unsigned hash; | ||
| 817 | 825 | ||
| 818 | /* Window-relative x and y-position of the top-left corner of this | 826 | /* Window-relative x and y-position of the top-left corner of this |
| 819 | row. If y < 0, this means that eabs (y) pixels of the row are | 827 | row. If y < 0, this means that eabs (y) pixels of the row are |
| @@ -846,10 +854,6 @@ struct glyph_row | |||
| 846 | in last row when checking if row is fully visible. */ | 854 | in last row when checking if row is fully visible. */ |
| 847 | int extra_line_spacing; | 855 | int extra_line_spacing; |
| 848 | 856 | ||
| 849 | /* Hash code. This hash code is available as soon as the row | ||
| 850 | is constructed, i.e. after a call to display_line. */ | ||
| 851 | unsigned hash; | ||
| 852 | |||
| 853 | /* First position in this row. This is the text position, including | 857 | /* First position in this row. This is the text position, including |
| 854 | overlay position information etc, where the display of this row | 858 | overlay position information etc, where the display of this row |
| 855 | started, and can thus be less than the position of the first | 859 | started, and can thus be less than the position of the first |
diff --git a/src/dispnew.c b/src/dispnew.c index 4ec989280ea..f7e3fa54441 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -832,41 +832,17 @@ clear_window_matrices (struct window *w, bool desired_p) | |||
| 832 | See dispextern.h for an overall explanation of glyph rows. | 832 | See dispextern.h for an overall explanation of glyph rows. |
| 833 | ***********************************************************************/ | 833 | ***********************************************************************/ |
| 834 | 834 | ||
| 835 | /* Clear glyph row ROW. Do it in a way that makes it robust against | 835 | /* Clear glyph row ROW. NOTE: this code relies on the current |
| 836 | changes in the glyph_row structure, i.e. addition or removal of | 836 | layout of `glyphs' and `used' fields of `struct glyph_row'. */ |
| 837 | structure members. */ | ||
| 838 | |||
| 839 | static struct glyph_row null_row; | ||
| 840 | 837 | ||
| 841 | void | 838 | void |
| 842 | clear_glyph_row (struct glyph_row *row) | 839 | clear_glyph_row (struct glyph_row *row) |
| 843 | { | 840 | { |
| 844 | struct glyph *p[1 + LAST_AREA]; | 841 | const size_t off = offsetof (struct glyph_row, used); |
| 845 | 842 | ||
| 846 | /* Save pointers. */ | 843 | eassert (off == sizeof row->glyphs); |
| 847 | p[LEFT_MARGIN_AREA] = row->glyphs[LEFT_MARGIN_AREA]; | 844 | /* Zero everything except pointers in `glyphs'. */ |
| 848 | p[TEXT_AREA] = row->glyphs[TEXT_AREA]; | 845 | memset ((char *) row + off, 0, sizeof *row - off); |
| 849 | p[RIGHT_MARGIN_AREA] = row->glyphs[RIGHT_MARGIN_AREA]; | ||
| 850 | p[LAST_AREA] = row->glyphs[LAST_AREA]; | ||
| 851 | |||
| 852 | /* Clear. */ | ||
| 853 | *row = null_row; | ||
| 854 | |||
| 855 | /* Restore pointers. */ | ||
| 856 | row->glyphs[LEFT_MARGIN_AREA] = p[LEFT_MARGIN_AREA]; | ||
| 857 | row->glyphs[TEXT_AREA] = p[TEXT_AREA]; | ||
| 858 | row->glyphs[RIGHT_MARGIN_AREA] = p[RIGHT_MARGIN_AREA]; | ||
| 859 | row->glyphs[LAST_AREA] = p[LAST_AREA]; | ||
| 860 | |||
| 861 | #if 0 /* At some point, some bit-fields of struct glyph were not set, | ||
| 862 | which made glyphs unequal when compared with GLYPH_EQUAL_P. | ||
| 863 | Redisplay outputs such glyphs, and flickering effects were | ||
| 864 | the result. This also depended on the contents of memory | ||
| 865 | returned by xmalloc. If flickering happens again, activate | ||
| 866 | the code below. If the flickering is gone with that, chances | ||
| 867 | are that the flickering has the same reason as here. */ | ||
| 868 | memset (p[0], 0, (char *) p[LAST_AREA] - (char *) p[0]); | ||
| 869 | #endif | ||
| 870 | } | 846 | } |
| 871 | 847 | ||
| 872 | 848 | ||
| @@ -1005,29 +981,18 @@ swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b) | |||
| 1005 | } | 981 | } |
| 1006 | 982 | ||
| 1007 | 983 | ||
| 1008 | /* Copy glyph row structure FROM to glyph row structure TO, except | 984 | /* Copy glyph row structure FROM to glyph row structure TO, except that |
| 1009 | that glyph pointers, the `used' counts, and the hash values in the | 985 | glyph pointers, the `used' counts, and the hash values in the structures |
| 1010 | structures are left unchanged. */ | 986 | are left unchanged. NOTE: this code relies on the current layout of |
| 987 | `glyphs', `used', `hash' and `x' fields of `struct glyph_row'. */ | ||
| 1011 | 988 | ||
| 1012 | static void | 989 | static void |
| 1013 | copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from) | 990 | copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from) |
| 1014 | { | 991 | { |
| 1015 | struct glyph *pointers[1 + LAST_AREA]; | 992 | const size_t off = offsetof (struct glyph_row, x); |
| 1016 | short used[LAST_AREA]; | 993 | |
| 1017 | unsigned hashval; | 994 | eassert (off == sizeof to->glyphs + sizeof to->used + sizeof to->hash); |
| 1018 | 995 | memcpy ((char *) to + off, (char *) from + off, sizeof *to - off); | |
| 1019 | /* Save glyph pointers of TO. */ | ||
| 1020 | memcpy (pointers, to->glyphs, sizeof to->glyphs); | ||
| 1021 | memcpy (used, to->used, sizeof to->used); | ||
| 1022 | hashval = to->hash; | ||
| 1023 | |||
| 1024 | /* Do a structure assignment. */ | ||
| 1025 | *to = *from; | ||
| 1026 | |||
| 1027 | /* Restore original pointers of TO. */ | ||
| 1028 | memcpy (to->glyphs, pointers, sizeof to->glyphs); | ||
| 1029 | memcpy (to->used, used, sizeof to->used); | ||
| 1030 | to->hash = hashval; | ||
| 1031 | } | 996 | } |
| 1032 | 997 | ||
| 1033 | 998 | ||