From a95c43976f7cbe571bf404c24574c9a5399f235e Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 25 Feb 2022 08:05:11 +0000 Subject: [PATCH] Improve tracking of modified regions on Haiku * 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 | 32 +++++++++++++++++++-- src/haiku_support.h | 6 +++- src/haikufns.c | 2 +- src/haikumenu.c | 2 +- src/haikuterm.c | 67 ++++++++++++++++++++++++++++++-------------- 5 files changed, 82 insertions(+), 27 deletions(-) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 9aeb03c4c90..43b996b7959 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -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) { diff --git a/src/haiku_support.h b/src/haiku_support.h index 1deb867c5f7..4de71075c0e 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -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); diff --git a/src/haikufns.c b/src/haikufns.c index 69f502fb016..ff5082030f1 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -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)); diff --git a/src/haikumenu.c b/src/haikumenu.c index 41db0d414dd..74328086d6f 100644 --- a/src/haikumenu.c +++ b/src/haikumenu.c @@ -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) { diff --git a/src/haikuterm.c b/src/haikuterm.c index 83330b5f638..023349327a4 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -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)); -- 2.39.5