aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2013-09-24 09:42:30 +0400
committerDmitry Antipov2013-09-24 09:42:30 +0400
commitec7bc82f9c63b6ec533f7489e67b1c1b18d08dd5 (patch)
treeb5cd6d535d5593424d85e227cf565e51c8016883 /src
parent7be68de5d25998e7d15aaab800c40cad48eac846 (diff)
downloademacs-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/ChangeLog10
-rw-r--r--src/dispextern.h18
-rw-r--r--src/dispnew.c65
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 @@
12013-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
12013-09-24 Paul Eggert <eggert@cs.ucla.edu> 112013-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
797struct glyph_row 800struct 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
839static struct glyph_row null_row;
840 837
841void 838void
842clear_glyph_row (struct glyph_row *row) 839clear_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
1012static void 989static void
1013copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from) 990copy_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