From c452ffe4c28da21991f1f98007fbe1d66c7e0538 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 31 Dec 2021 07:29:30 +0000 Subject: [PATCH] Prevent double buffering from being disabled on USE_BE_CAIRO builds The direct rendering code used in that situation never completely worked, and the BDirectWindow destructor is also buggy. Completely remove that code in order to let us inherit from BWindow, so as to prevent the buggy destructor from being run. * src/haiku_support.cc (cairo_format_from_color_space): Delete function. (class EmacsWindow): Inherit from BWindow. (EmacsWindow): Call BWindow constructor instead. (MessageReceived): (DispatchMessage): (FrameResized): (FrameMoved): (Zoom): Call BWindow functions instead. (EmacsView_cairo_surface): Stop looking for surfaces in the window. (EmacsWindow_begin_cr_critical_section): (EmacsWindow_end_cr_critical_section): Stop locking the window. * src/haikufns.c (haiku_set_inhibit_double_buffering): Always enable double buffering on Cairo builds. --- src/haiku_support.cc | 104 +++++-------------------------------------- src/haikufns.c | 4 ++ 2 files changed, 16 insertions(+), 92 deletions(-) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index b8f6e84d2c3..d211f1157d3 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -104,28 +104,6 @@ gui_abort (const char *msg) emacs_abort (); } -#ifdef USE_BE_CAIRO -static cairo_format_t -cairo_format_from_color_space (color_space space) -{ - switch (space) - { - case B_RGBA32: - return CAIRO_FORMAT_ARGB32; - case B_RGB32: - return CAIRO_FORMAT_RGB24; - case B_RGB16: - return CAIRO_FORMAT_RGB16_565; - case B_GRAY8: - return CAIRO_FORMAT_A8; - case B_GRAY1: - return CAIRO_FORMAT_A1; - default: - gui_abort ("Unsupported color space"); - } -} -#endif - static void map_key (char *chars, int32 offset, uint32_t *c) { @@ -242,7 +220,7 @@ public: } }; -class EmacsWindow : public BDirectWindow +class EmacsWindow : public BWindow { public: struct child_frame @@ -261,13 +239,8 @@ public: int zoomed_p = 0; int shown_flag = 0; -#ifdef USE_BE_CAIRO - BLocker surface_lock; - cairo_surface_t *cr_surface = NULL; -#endif - - EmacsWindow () : BDirectWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK, - B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS) + EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK, + B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS) { } @@ -284,17 +257,6 @@ public: if (this->parent) UnparentAndUnlink (); - -#ifdef USE_BE_CAIRO - if (!surface_lock.Lock ()) - gui_abort ("Failed to lock cairo surface"); - if (cr_surface) - { - cairo_surface_destroy (cr_surface); - cr_surface = NULL; - } - surface_lock.Unlock (); -#endif } void @@ -457,43 +419,6 @@ public: haiku_write (ACTIVATION, &rq); } - void - DirectConnected (direct_buffer_info *info) - { -#ifdef USE_BE_CAIRO - if (!surface_lock.Lock ()) - gui_abort ("Failed to lock window direct cr surface"); - if (cr_surface) - { - cairo_surface_destroy (cr_surface); - cr_surface = NULL; - } - - if (info->buffer_state != B_DIRECT_STOP) - { - int left, top, right, bottom; - left = info->clip_bounds.left; - top = info->clip_bounds.top; - right = info->clip_bounds.right; - bottom = info->clip_bounds.bottom; - - unsigned char *bits = (unsigned char *) info->bits; - if ((info->bits_per_pixel % 8) == 0) - { - bits += info->bytes_per_row * top; - bits += (left * info->bits_per_pixel / 8); - cr_surface = cairo_image_surface_create_for_data - (bits, - cairo_format_from_color_space (info->pixel_format), - right - left + 1, - bottom - top + 1, - info->bytes_per_row); - } - } - surface_lock.Unlock (); -#endif - } - void MessageReceived (BMessage *msg) { @@ -567,7 +492,7 @@ public: haiku_write (FILE_PANEL_EVENT, &rq); } else - BDirectWindow::MessageReceived (msg); + BWindow::MessageReceived (msg); } void @@ -638,7 +563,7 @@ public: }; } else - BDirectWindow::DispatchMessage (msg, handler); + BWindow::DispatchMessage (msg, handler); } void @@ -668,7 +593,7 @@ public: rq.px_widthf = newWidth + 1.0f; haiku_write (FRAME_RESIZED, &rq); - BDirectWindow::FrameResized (newWidth, newHeight); + BWindow::FrameResized (newWidth, newHeight); } void @@ -684,7 +609,7 @@ public: for (struct child_frame *f = subset_windows; f; f = f->next) DoMove (f); - BDirectWindow::FrameMoved (newPosition); + BWindow::FrameMoved (newPosition); } void @@ -716,7 +641,7 @@ public: void Minimize (bool minimized_p) { - BDirectWindow::Minimize (minimized_p); + BWindow::Minimize (minimized_p); struct haiku_iconification_event rq; rq.window = this; rq.iconified_p = !parent && minimized_p; @@ -776,7 +701,7 @@ public: x_before_zoom = y_before_zoom = INT_MIN; } - BDirectWindow::Zoom (o, w, h); + BWindow::Zoom (o, w, h); } void @@ -2816,8 +2741,7 @@ cairo_surface_t * EmacsView_cairo_surface (void *view) { EmacsView *vw = (EmacsView *) view; - EmacsWindow *wn = (EmacsWindow *) vw->Window (); - return vw->cr_surface ? vw->cr_surface : wn->cr_surface; + return vw->cr_surface; } /* Transfer each clip rectangle in VIEW to the cairo context @@ -2843,10 +2767,7 @@ BView_cr_dump_clipping (void *view, cairo_t *ctx) void EmacsWindow_begin_cr_critical_section (void *window) { - EmacsWindow *w = (EmacsWindow *) window; - if (!w->surface_lock.Lock ()) - gui_abort ("Couldn't lock cairo surface"); - + BWindow *w = (BWindow *) window; BView *vw = (BView *) w->FindView ("Emacs"); EmacsView *ev = dynamic_cast (vw); if (ev && !ev->cr_surface_lock.Lock ()) @@ -2857,8 +2778,7 @@ EmacsWindow_begin_cr_critical_section (void *window) void EmacsWindow_end_cr_critical_section (void *window) { - EmacsWindow *w = (EmacsWindow *) window; - w->surface_lock.Unlock (); + BWindow *w = (BWindow *) window; BView *vw = (BView *) w->FindView ("Emacs"); EmacsView *ev = dynamic_cast (vw); if (ev) diff --git a/src/haikufns.c b/src/haikufns.c index 737b0338994..b9198e9d445 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -1510,20 +1510,24 @@ haiku_set_inhibit_double_buffering (struct frame *f, Lisp_Object old_value) { block_input (); +#ifndef USE_BE_CAIRO if (FRAME_HAIKU_WINDOW (f)) { if (NILP (new_value)) { +#endif EmacsView_set_up_double_buffering (FRAME_HAIKU_VIEW (f)); if (!NILP (old_value)) { SET_FRAME_GARBAGED (f); expose_frame (f, 0, 0, 0, 0); } +#ifndef USE_BE_CAIRO } else EmacsView_disable_double_buffering (FRAME_HAIKU_VIEW (f)); } +#endif unblock_input (); } -- 2.39.2