emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

scratch/se-matrix d9d7310810f: Comments and some cleanup


From: Gerd Moellmann
Subject: scratch/se-matrix d9d7310810f: Comments and some cleanup
Date: Sun, 19 Jan 2025 07:25:01 -0500 (EST)

branch: scratch/se-matrix
commit d9d7310810f316801f0da5b8118400a3f4fea84f
Author: Gerd Möllmann <gerd@gnu.org>
Commit: Gerd Möllmann <gerd@gnu.org>

    Comments and some cleanup
---
 src/dispnew.c | 126 ++++++++++++++++++++++++++++++++++++++++++----------------
 src/frame.h   |  19 +++++----
 2 files changed, 103 insertions(+), 42 deletions(-)

diff --git a/src/dispnew.c b/src/dispnew.c
index 3635423f10c..a3165417362 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3978,27 +3978,27 @@ terminal_cursor_magic (struct frame *root, struct frame 
*topmost_child)
     }
 }
 
+/* Make a copy of glyph pool FROM in *TO.  */
+
 static void
-copy_pool (struct glyph_pool *from, struct glyph_pool **to)
+copy_pool (struct glyph_pool **to, struct glyph_pool *from)
 {
-  if (*to == NULL)
-    *to = new_glyph_pool ();
-  struct glyph_pool *p = *to;
-  struct glyph *glyphs = p->glyphs;
+  eassert (*to == NULL);
+  struct glyph_pool *p = new_glyph_pool ();
   *p = *from;
-  size_t nbytes = p->nglyphs * sizeof *glyphs;
-  p->glyphs = xrealloc (glyphs, nbytes);
-  memset (p->glyphs, 0, nbytes);
+  p->glyphs = xzalloc (p->nglyphs * sizeof *p->glyphs);
+  *to = p;
 }
 
+/* Copy glyph row with index I from FROM_MATRIX to TO_MATRIX.  */
+
 static void
-copy_row (struct glyph_matrix *from_matrix, struct glyph_matrix *to_matrix,
-         int i)
+copy_row (struct glyph_matrix *to_matrix,
+         struct glyph_matrix *from_matrix, int i)
 {
   struct glyph_row *from = from_matrix->rows + i;
   struct glyph_row *to = to_matrix->rows + i;
   *to = *from;
-
   struct glyph_pool *p = to_matrix->pool;
   struct glyph *start = p->glyphs + i * p->ncolumns;
   struct glyph *end = start + p->ncolumns;
@@ -4006,30 +4006,31 @@ copy_row (struct glyph_matrix *from_matrix, struct 
glyph_matrix *to_matrix,
   to->glyphs[TEXT_AREA] = start;
   to->glyphs[RIGHT_MARGIN_AREA] = end;
   to->glyphs[LAST_AREA] = end;
-
   memcpy (start, from->glyphs[0], p->ncolumns * sizeof *start);
 }
 
+/* Copy glyph matrix FROM to *TO and give *TO the pool POOL.  */
+
 static void
-copy_matrix (struct glyph_matrix *from, struct glyph_matrix **to,
+copy_matrix (struct glyph_matrix **to, struct glyph_matrix *from,
             struct glyph_pool *pool)
 {
-  if (*to == NULL)
-    *to = new_glyph_matrix (pool);
+  eassert (*to == NULL);
+  *to = new_glyph_matrix (pool);
   struct glyph_matrix *m = *to;
   struct glyph_row *rows = m->rows;
   *m = *from;
   m->pool = pool;
-  size_t nbytes = m->rows_allocated * sizeof *rows;
-  m->rows = xrealloc (rows, nbytes);
-  memset (m->rows, 0, nbytes);
+  m->rows = xzalloc (m->rows_allocated * sizeof *rows);
   for (int i = 0; i < m->rows_allocated; ++i)
-    copy_row (from, m, i);
+    copy_row (m, from, i);
 }
 
+/* Copy row I from desired matrix FROM_MATRIX to TO_MATRIX.  */
+
 static void
-copy_desired_row (struct glyph_matrix *from_matrix,
-                 struct glyph_matrix *to_matrix, int i)
+copy_desired_row (struct glyph_matrix *to_matrix,
+                 struct glyph_matrix *from_matrix, int i)
 {
   struct glyph_row *from = from_matrix->rows + i;
   struct glyph_row *to = to_matrix->rows + i;
@@ -4040,6 +4041,9 @@ copy_desired_row (struct glyph_matrix *from_matrix,
          to_matrix->matrix_w * sizeof (struct glyph));
 }
 
+/* Copy the desired frame matrix of frame ROOT to its desired
+   terminal matrix.  */
+
 static void
 copy_frame_desired_matrix (struct frame *root)
 {
@@ -4055,18 +4059,23 @@ copy_frame_desired_matrix (struct frame *root)
 
   for (int i = 0; i < to->rows_allocated; ++i)
     if (from->rows[i].enabled_p)
-      copy_desired_row (from, to, i);
+      copy_desired_row (to, from, i);
 }
 
+/* Copy a glyph matrix FROM.  */
+
 static void
 copy_pool_and_matrix (struct glyph_matrix *from,
                      struct glyph_pool **to_pool,
                      struct glyph_matrix **to_matrix)
 {
-  copy_pool (from->pool, to_pool);
-  copy_matrix (from, to_matrix, *to_pool);
+  copy_pool (to_pool, from->pool);
+  copy_matrix (to_matrix, from, *to_pool);
 }
 
+/* Create terminal matrices for frame ROOT on demand. This creates
+   terminal matrices and pools and copies frame matrices.  */
+
 static void
 make_terminal_matrices (struct frame *root)
 {
@@ -4076,12 +4085,18 @@ make_terminal_matrices (struct frame *root)
                        &root->terminal_desired_matrix);
 }
 
+/* Value is true if ROOT uses terminal matrices.  */
+
 static bool
 is_using_terminal_matrices (struct frame *root)
 {
   return root->frame_current_matrix != NULL;
 }
 
+/* Restore ROOT_FRAME current and desired matrix pointers to frame
+   matrices as needed.  This function is registered to be called once we
+   unwind by choose_frame_or_terminal_matrices.  */
+
 static void
 unwind_restore_matrices (Lisp_Object root_frame)
 {
@@ -4094,19 +4109,31 @@ unwind_restore_matrices (Lisp_Object root_frame)
     }
 }
 
+/* Decide if we should switch to terminal matrices or not.  ROOT is the
+   frame, and Z_ORDER is the list of visible child frame on ROOT.  We
+   switch to terminal frames once a child frame has been used.  We never
+   switch back because once a child frame has been used, it will likely
+   happen again, so we avoid the additional complexity of implementing
+   the switching back to frame matrices.  */
+
 static void
 choose_frame_or_terminal_matrices (struct frame *root, Lisp_Object z_order)
 {
-  /* Once we have used child frames once, we will likely again, so there
-     is no point in switching back to frame matrices. */
   const bool visible_child = CONSP (XCDR (z_order));
   if (visible_child && !is_using_terminal_matrices (root))
     {
+      /* Make terminal matrices on demand, the first time
+        we switch to using terminal matrices.  */
       make_terminal_matrices (root);
+
+      /* Save away the frame matrices.  */
       root->frame_current_matrix = root->current_matrix;
       root->frame_desired_matrix = root->desired_matrix;
     }
 
+  /* If using terminal matrices, temporarily the current and desired
+     matrices of ROOT to them, and arrange for them to be set to
+     frame matrices again when we are done updating.  */
   if (is_using_terminal_matrices (root))
     {
       root->current_matrix = root->terminal_current_matrix;
@@ -4117,24 +4144,52 @@ choose_frame_or_terminal_matrices (struct frame *root, 
Lisp_Object z_order)
     }
 }
 
+/* Combine updates of all frames on the root frame of F.
+   INHIBT_SCROLLING true means don't try to use scrolling.
+
+   In a call tree containing combine_updates, everything above the call
+   to combine_updates and everything after it returns uses frame
+   matrices, as it always was.  All tty frames, roots or children, are
+   completely independent of each other, and know nothing about each
+   others display, whether they are partially obscured by other frames
+   or anything like that.  It is as if each of these frames was running
+   in a separate terminal. This is appealing because the complexity is
+   for the most part localized.
+
+   To achieve this, combine_updates creates a second pair of glyph
+   matrices in addition to the existing frame matrices, which are called
+   called terminal matrices. These terminal matrices are created the
+   first time combine_updates finds a visible child frame that must be
+   displayed,
+
+   From then on, terminal matrices are used for the update by setting
+   the frame's current and desired matrix to the terminal
+   matrices.  After the update things are restored to "normal".
+
+   What is displayed on the terminal in found in the terminal current
+   matrix, and what should be displayed is in the terminal desired
+   matrix.  The construction of the terminal
+   desired matrix requires copying the frame desired matrix to the
+   terminal desired matrix (the part that is enabled_p). That includes a
+   memcpy of the glyphs.  */
+
 void
 combine_updates_for_frame (struct frame *f, bool inhibit_scrolling)
 {
   struct frame *root = root_frame (f);
   eassert (FRAME_VISIBLE_P (root));
-
   specpdl_ref count = SPECPDL_INDEX ();
+
+  /* Get the list of visible frames in reverse z-order, and
+     decide if we need to switch to terminal frames.  */
   Lisp_Object z_order = frames_in_reverse_z_order (root, true);
   choose_frame_or_terminal_matrices (root, z_order);
 
-  /* FIXME: use frame_desired_matrix directly. Problem: making
-     make_matrix_current would make the terminal current matrix
-     have pointers to frame_desired_pool. Is this bad? */
+  /* If using terminal matrices, copy the desired frame matrix
+     to the desired terminal matrix because we will use that as
+     a basis for updating the display.  */
   if (is_using_terminal_matrices (root))
-    {
-      inhibit_scrolling = true;
-      copy_frame_desired_matrix (root);
-    }
+    copy_frame_desired_matrix (root);
 
   /* Process child frames in reverse z-order, topmost last.  For each
      child, copy what we need to the root's desired matrix.  */
@@ -4157,7 +4212,8 @@ combine_updates_for_frame (struct frame *f, bool 
inhibit_scrolling)
     terminal_cursor_magic (root, topmost_child);
   flush_terminal (root);
 
-  /* Restore frame matrices, make frame current matrix current. */
+  /* Restore current and desired matrix of the frame to use frame
+     matrices again, and make the desired frame current. */
   unbind_to (count, Qnil);
 
   for (Lisp_Object tail = z_order; CONSP (tail); tail = XCDR (tail))
diff --git a/src/frame.h b/src/frame.h
index 0e33ede47b4..326406bfd0d 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -315,19 +315,24 @@ struct frame
   char *shell_position;
 #endif
 
-  /* Glyph pool and matrix.  */
-  struct glyph_pool *current_pool;
+  /* Normally, the current and desired frame matrix.  On tty root
+     frames, these matrices can be temporarily set to terminal matrices
+     (see below) while updating the display. */
   struct glyph_matrix *current_matrix;
-  struct glyph_pool *desired_pool;
   struct glyph_matrix *desired_matrix;
+  struct glyph_pool *current_pool;
+  struct glyph_pool *desired_pool;
 
-  /* Used only on ttys.  Represent what is displayed and what should be
-     displayed on a terminal when child windows are present.  */
-  struct glyph_pool *terminal_current_pool;
+  /* Used only for ttys root frames.  Represent what is displayed and
+     what should be displayed on a terminal when child frames are
+     present.  */
   struct glyph_matrix *terminal_current_matrix;
-  struct glyph_pool *terminal_desired_pool;
   struct glyph_matrix *terminal_desired_matrix;
+  struct glyph_pool *terminal_current_pool;
+  struct glyph_pool *terminal_desired_pool;
 
+  /* When using the terminal matrices above, these are the corresponding
+     frame matrices.  NULL if not using terminal frames.  */
   struct glyph_matrix *frame_current_matrix;
   struct glyph_matrix *frame_desired_matrix;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]