]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve tracking of modified regions on Haiku
authorPo Lu <luangruo@yahoo.com>
Fri, 25 Feb 2022 08:05:11 +0000 (08:05 +0000)
committerPo Lu <luangruo@yahoo.com>
Fri, 25 Feb 2022 08:08:06 +0000 (08:08 +0000)
* src/haiku_support.cc (class EmacsView): New field
`invalid_region'.
(FlipBuffers): Only invalidate that region.
(SetUpDoubleBuffering): Clear that region.
(BView_draw_lock): New parameters for denoting the region
to invalidate.
(BView_invalidate_region): New function.
* src/haiku_support.h: Update prototypes.
* src/haikufns.c (haiku_set_background_color):
* src/haikumenu.c (digest_menu_items):
* src/haikuterm.c (haiku_clip_to_string):
(haiku_flip_buffers):
(haiku_clear_frame_area):
(haiku_clear_frame):
(haiku_draw_glyph_string):
(haiku_after_update_window_line):
(haiku_draw_window_cursor):
(haiku_draw_vertical_window_border):
(haiku_draw_window_divider):
(haiku_draw_fringe_bitmap):
(haiku_scroll_run):
(haiku_read_socket):
(haiku_flash):
(haiku_clear_under_internal_border): Mark appropriate region as
invalid before buffer flip.

src/haiku_support.cc
src/haiku_support.h
src/haikufns.c
src/haikumenu.c
src/haikuterm.c

index 9aeb03c4c90ecff3025ff719ec3969206bd808fc..43b996b7959f6ec626ebd3524fa6386258521889 100644 (file)
@@ -1197,6 +1197,7 @@ public:
   uint32_t previous_buttons = 0;
   int looper_locked_count = 0;
   BRegion sb_region;
+  BRegion invalid_region;
 
   BView *offscreen_draw_view = NULL;
   BBitmap *offscreen_draw_bitmap_1 = NULL;
@@ -1403,7 +1404,8 @@ public:
     SetViewBitmap (copy_bitmap,
                   Frame (), Frame (), B_FOLLOW_NONE, 0);
 
-    Invalidate ();
+    Invalidate (&invalid_region);
+    invalid_region.MakeEmpty ();
     UnlockLooper ();
     return;
   }
@@ -1431,6 +1433,7 @@ public:
          gui_abort ("Failed to lock bitmap after double buffering was set up");
       }
 
+    invalid_region.MakeEmpty ();
     UnlockLooper ();
     Invalidate ();
   }
@@ -2147,14 +2150,23 @@ BView_invalidate (void *view)
 
 /* Lock VIEW in preparation for drawing operations.  This should be
    called before any attempt to draw onto VIEW or to lock it for Cairo
-   drawing.  `BView_draw_unlock' should be called afterwards.  */
+   drawing.  `BView_draw_unlock' should be called afterwards.
+
+   If any drawing is going to take place, INVALID_REGION should be
+   true, and X, Y, WIDTH, HEIGHT should specify a rectangle in which
+   the drawing will take place.  */
 void
-BView_draw_lock (void *view)
+BView_draw_lock (void *view, bool invalidate_region,
+                int x, int y, int width, int height)
 {
   EmacsView *vw = (EmacsView *) view;
   if (vw->looper_locked_count)
     {
       vw->looper_locked_count++;
+
+      if (invalidate_region && vw->offscreen_draw_view)
+       vw->invalid_region.Include (BRect (x, y, x + width - 1,
+                                          y + height - 1));
       return;
     }
   BView *v = (BView *) find_appropriate_view_for_draw (vw);
@@ -2168,9 +2180,23 @@ BView_draw_lock (void *view)
 
   if (v != vw && !vw->LockLooper ())
     gui_abort ("Failed to lock view while acquiring draw lock");
+
+  if (invalidate_region && vw->offscreen_draw_view)
+    vw->invalid_region.Include (BRect (x, y, x + width - 1,
+                                      y + height - 1));
   vw->looper_locked_count++;
 }
 
+void
+BView_invalidate_region (void *view, int x, int y, int width, int height)
+{
+  EmacsView *vw = (EmacsView *) view;
+
+  if (vw->offscreen_draw_view)
+    vw->invalid_region.Include (BRect (x, y, x + width - 1,
+                                      y + height - 1));
+}
+
 void
 BView_draw_unlock (void *view)
 {
index 1deb867c5f7f91ed82de772b2219fc6ec79fca4c..4de71075c0e574252f276752ef8b2f5b5fdb16c7 100644 (file)
@@ -621,7 +621,11 @@ extern "C"
   BView_invalidate (void *view);
 
   extern void
-  BView_draw_lock (void *view);
+  BView_draw_lock (void *view, bool invalidate_region,
+                  int x, int y, int width, int height);
+
+  extern void
+  BView_invalidate_region (void *view, int x, int y, int width, int height);
 
   extern void
   BView_draw_unlock (void *view);
index 69f502fb016a0d5a4099a2b7bfafb3183a77c831..ff5082030f18ee3721fdc0140f12718410b59148 100644 (file)
@@ -1374,7 +1374,7 @@ haiku_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval
     {
       struct face *defface;
 
-      BView_draw_lock (FRAME_HAIKU_VIEW (f));
+      BView_draw_lock (FRAME_HAIKU_VIEW (f), false, 0, 0, 0, 0);
       BView_SetViewColor (FRAME_HAIKU_VIEW (f), color.pixel);
       BView_draw_unlock (FRAME_HAIKU_VIEW (f));
 
index 41db0d414dd2f6dbb92ba32d4139d9a171045dfe..74328086d6fc6ae4768922d58e6a2efda4916807 100644 (file)
@@ -63,7 +63,7 @@ digest_menu_items (void *first_menu, int start, int menu_items_used,
     }
 
   if (view)
-    BView_draw_lock (view);
+    BView_draw_lock (view, false, 0, 0, 0, 0);
 
   while (i < menu_items_used)
     {
index 83330b5f638b3f00e79dd333b86539d73ac46cec..023349327a42c189d303f8fe31b9b64e30dd01df 100644 (file)
@@ -161,8 +161,12 @@ haiku_clip_to_string (struct glyph_string *s)
                          FRAME_PIXEL_HEIGHT (s->f),
                          10, 10);
       else
-       BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[0].x,
-                         r[0].y, r[0].width, r[0].height);
+       {
+         BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[0].x,
+                           r[0].y, r[0].width, r[0].height);
+         BView_invalidate_region (FRAME_HAIKU_VIEW (s->f), r[0].x,
+                                  r[0].y, r[0].width, r[0].height);
+       }
     }
 
   if (n > 1)
@@ -175,8 +179,12 @@ haiku_clip_to_string (struct glyph_string *s)
                          FRAME_PIXEL_HEIGHT (s->f),
                          10, 10);
       else
-       BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[1].x, r[1].y,
-                         r[1].width, r[1].height);
+       {
+         BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[1].x, r[1].y,
+                           r[1].width, r[1].height);
+         BView_invalidate_region (FRAME_HAIKU_VIEW (s->f), r[1].x,
+                                  r[1].y, r[1].width, r[1].height);
+       }
     }
 }
 
@@ -193,7 +201,7 @@ haiku_flip_buffers (struct frame *f)
   void *view = FRAME_OUTPUT_DATA (f)->view;
   block_input ();
 
-  BView_draw_lock (view);
+  BView_draw_lock (view, false, 0, 0, 0, 0);
   FRAME_DIRTY_P (f) = 0;
   EmacsView_flip_and_blit (view);
   BView_draw_unlock (view);
@@ -224,7 +232,7 @@ haiku_clear_frame_area (struct frame *f, int x, int y,
 {
   void *vw = FRAME_HAIKU_VIEW (f);
   block_input ();
-  BView_draw_lock (vw);
+  BView_draw_lock (vw, true, x, y, width, height);
   BView_StartClip (vw);
   BView_ClipToRect (vw, x, y, width, height);
   BView_SetHighColor (vw, FRAME_BACKGROUND_PIXEL (f));
@@ -242,7 +250,8 @@ haiku_clear_frame (struct frame *f)
   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
 
   block_input ();
-  BView_draw_lock (view);
+  BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f),
+                  FRAME_PIXEL_HEIGHT (f));
   BView_StartClip (view);
   BView_ClipToRect (view, 0, 0, FRAME_PIXEL_WIDTH (f),
                    FRAME_PIXEL_HEIGHT (f));
@@ -1462,7 +1471,7 @@ haiku_draw_glyph_string (struct glyph_string *s)
 
   block_input ();
   view = FRAME_HAIKU_VIEW (s->f);
-  BView_draw_lock (view);
+  BView_draw_lock (view, false, 0, 0, 0, 0);
   prepare_face_for_display (s->f, s->face);
 
   struct face *face = s->face;
@@ -1645,13 +1654,17 @@ haiku_after_update_window_line (struct window *w,
       if (face)
        {
          void *view = FRAME_HAIKU_VIEW (f);
-         BView_draw_lock (view);
+         BView_draw_lock (view, false, 0, 0, 0, 0);
          BView_StartClip (view);
          BView_SetHighColor (view, face->background_defaulted_p ?
                              FRAME_BACKGROUND_PIXEL (f) : face->background);
          BView_FillRectangle (view, 0, y, width, height);
          BView_FillRectangle (view, FRAME_PIXEL_WIDTH (f) - width,
                               y, width, height);
+         BView_invalidate_region (FRAME_HAIKU_VIEW (f),
+                                  0, y, width, height);
+         BView_invalidate_region (view, FRAME_PIXEL_WIDTH (f) - width,
+                                  y, width, height);
          BView_EndClip (view);
          BView_draw_unlock (view);
        }
@@ -1739,7 +1752,7 @@ haiku_draw_window_cursor (struct window *w,
       h = cursor_height;
     }
 
-  BView_draw_lock (view);
+  BView_draw_lock (view, false, 0, 0, 0, 0);
   BView_StartClip (view);
 
   if (cursor_type == BAR_CURSOR)
@@ -1771,13 +1784,20 @@ haiku_draw_window_cursor (struct window *w,
       break;
     case HBAR_CURSOR:
       BView_FillRectangle (view, fx, fy, w->phys_cursor_width, h);
+      BView_invalidate_region (view, fx, fy, w->phys_cursor_width, h);
       break;
     case BAR_CURSOR:
       if (cursor_glyph->resolved_level & 1)
-       BView_FillRectangle (view, fx + cursor_glyph->pixel_width - w->phys_cursor_width,
-                            fy, w->phys_cursor_width, h);
+       {
+         BView_FillRectangle (view, fx + cursor_glyph->pixel_width - w->phys_cursor_width,
+                              fy, w->phys_cursor_width, h);
+         BView_invalidate_region (view, fx + cursor_glyph->pixel_width - w->phys_cursor_width,
+                                  fy, w->phys_cursor_width, h);
+       }
       else
        BView_FillRectangle (view, fx, fy, w->phys_cursor_width, h);
+
+      BView_invalidate_region (view, fx, fy, w->phys_cursor_width, h);
       break;
     case HOLLOW_BOX_CURSOR:
       if (phys_cursor_glyph->type != IMAGE_GLYPH)
@@ -1787,6 +1807,8 @@ haiku_draw_window_cursor (struct window *w,
        }
       else
        draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+
+      BView_invalidate_region (view, fx, fy, w->phys_cursor_width, h);
       break;
     case FILLED_BOX_CURSOR:
       draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
@@ -1865,7 +1887,7 @@ haiku_draw_vertical_window_border (struct window *w,
 
   face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
   void *view = FRAME_HAIKU_VIEW (f);
-  BView_draw_lock (view);
+  BView_draw_lock (view, true, x, y_0, 1, y_1);
   BView_StartClip (view);
   if (face)
     BView_SetHighColor (view, face->foreground);
@@ -1910,7 +1932,7 @@ haiku_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
                              : FRAME_FOREGROUND_PIXEL (f));
   void *view = FRAME_HAIKU_VIEW (f);
 
-  BView_draw_lock (view);
+  BView_draw_lock (view, true, x0, y0, x1 - x0 + 1, y1 - y0 + 1);
   BView_StartClip (view);
 
   if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
@@ -2240,7 +2262,7 @@ haiku_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
   struct face *face = p->face;
 
   block_input ();
-  BView_draw_lock (view);
+  BView_draw_lock (view, true, p->x, p->y, p->wd, p->h);
   BView_StartClip (view);
 
   haiku_clip_to_row (w, row, ANY_AREA);
@@ -2345,7 +2367,7 @@ haiku_scroll_run (struct window *w, struct run *run)
   block_input ();
   gui_clear_cursor (w);
 
-  BView_draw_lock (view);
+  BView_draw_lock (view, true, x, to_y, width, height);
   BView_StartClip (view);
   BView_CopyBits (view, x, from_y, width, height,
                  x, to_y, width, height);
@@ -2630,7 +2652,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
                continue;
              }
 
-           BView_draw_lock (FRAME_HAIKU_VIEW (f));
+           BView_draw_lock (FRAME_HAIKU_VIEW (f), false, 0, 0, 0, 0);
            BView_resize_to (FRAME_HAIKU_VIEW (f), width, height);
            BView_draw_unlock (FRAME_HAIKU_VIEW (f));
 
@@ -3222,7 +3244,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
                   menu bar.  */
                if (!b->no_lock)
                  {
-                   BView_draw_lock (FRAME_HAIKU_VIEW (f));
+                   BView_draw_lock (FRAME_HAIKU_VIEW (f), false, 0, 0, 0, 0);
                    /* This shouldn't be here, but nsmenu does it, so
                       it should probably be safe.  */
                    int was_waiting_for_input_p = waiting_for_input;
@@ -3440,7 +3462,8 @@ haiku_flash (struct frame *f)
   delay = make_timespec (0, 150 * 1000 * 1000);
   wakeup = timespec_add (current_timespec (), delay);
 
-  BView_draw_lock (view);
+  BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f),
+                  FRAME_PIXEL_HEIGHT (f));
   BView_StartClip (view);
   /* If window is tall, flash top and bottom line.  */
   if (height > 3 * FRAME_LINE_HEIGHT (f))
@@ -3484,7 +3507,8 @@ haiku_flash (struct frame *f)
       pselect (0, NULL, NULL, NULL, &timeout, NULL);
     }
 
-  BView_draw_lock (view);
+  BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f),
+                  FRAME_PIXEL_HEIGHT (f));
   BView_StartClip (view);
   /* If window is tall, flash top and bottom line.  */
   if (height > 3 * FRAME_LINE_HEIGHT (f))
@@ -3709,7 +3733,8 @@ haiku_clear_under_internal_border (struct frame *f)
       struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
       void *view = FRAME_HAIKU_VIEW (f);
       block_input ();
-      BView_draw_lock (view);
+      BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f),
+                      FRAME_PIXEL_HEIGHT (f));
       BView_StartClip (view);
       BView_ClipToRect (view, 0, 0, FRAME_PIXEL_WIDTH (f),
                        FRAME_PIXEL_HEIGHT (f));