From d35c4ee10a549deb613f0ab2f99244e0240c4b60 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 3 Feb 2022 07:50:36 +0000 Subject: [PATCH] Stop creating cairo contexts in haiku_begin_cr_clip * src/haikufont.c (haikufont_draw): * src/ftcrfont.c (ftcrfont_draw): Stop holding the draw lock. * src/haiku_support.cc (class EmacsView): New field `cairo_context'. (DetachCairoSurface): Destroy cairo_context. (AttachCairoSurface): Create cairo_context from the surface. (EmacsView_cairo_surface): Delete function. (EmacsView_cairo_context): New function. * src/haiku_support.h: Update prototypes. * src/haikuterm.c (haiku_begin_cr_clip): (haiku_end_cr_clip): Retrieve the existing cairo context instead of creating a new one. * src/haikuterm.h (FRAME_CR_CONTEXT): New macro. --- src/ftcrfont.c | 5 ++--- src/haiku_support.cc | 15 +++++++++++---- src/haiku_support.h | 4 ++-- src/haikufont.c | 5 +++-- src/haikuterm.c | 14 +++++++++----- src/haikuterm.h | 6 ++++-- 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/ftcrfont.c b/src/ftcrfont.c index c327146ba28..7d192697ca1 100644 --- a/src/ftcrfont.c +++ b/src/ftcrfont.c @@ -538,12 +538,12 @@ ftcrfont_draw (struct glyph_string *s, cr = pgtk_begin_cr_clip (f); #endif #else - BView_draw_lock (FRAME_HAIKU_VIEW (f)); + /* Presumably the draw lock is already held by + haiku_draw_glyph_string. */ EmacsWindow_begin_cr_critical_section (FRAME_HAIKU_WINDOW (f)); cr = haiku_begin_cr_clip (f, s); if (!cr) { - BView_draw_unlock (FRAME_HAIKU_VIEW (f)); EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f)); unblock_input (); return 0; @@ -610,7 +610,6 @@ ftcrfont_draw (struct glyph_string *s, #else haiku_end_cr_clip (cr); EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f)); - BView_draw_unlock (FRAME_HAIKU_VIEW (f)); #endif unblock_input (); diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 8ab82170916..fad2b466544 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1184,6 +1184,7 @@ public: #ifdef USE_BE_CAIRO cairo_surface_t *cr_surface = NULL; + cairo_t *cr_context = NULL; BLocker cr_surface_lock; #endif @@ -1215,8 +1216,10 @@ public: gui_abort ("Could not lock cr surface during detachment"); if (!cr_surface) gui_abort ("Trying to detach window cr surface when none exists"); + cairo_destroy (cr_context); cairo_surface_destroy (cr_surface); cr_surface = NULL; + cr_context = NULL; cr_surface_lock.Unlock (); } @@ -1236,6 +1239,10 @@ public: offscreen_draw_bitmap_1->BytesPerRow ()); if (!cr_surface) gui_abort ("Cr surface allocation failed for double-buffered view"); + + cr_context = cairo_create (cr_surface); + if (!cr_context) + gui_abort ("cairo_t allocation failed for double-buffered view"); cr_surface_lock.Unlock (); } #endif @@ -3178,12 +3185,12 @@ BView_show_tooltip (void *view) #ifdef USE_BE_CAIRO -/* Return VIEW's cairo surface. */ -cairo_surface_t * -EmacsView_cairo_surface (void *view) +/* Return VIEW's cairo context. */ +cairo_t * +EmacsView_cairo_context (void *view) { EmacsView *vw = (EmacsView *) view; - return vw->cr_surface; + return vw->cr_context; } /* Transfer each clip rectangle in VIEW to the cairo context diff --git a/src/haiku_support.h b/src/haiku_support.h index b98fa56415b..ea34ccb435c 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -827,8 +827,8 @@ extern "C" BView_show_tooltip (void *view); #ifdef USE_BE_CAIRO - extern cairo_surface_t * - EmacsView_cairo_surface (void *view); + extern cairo_t * + EmacsView_cairo_context (void *view); extern void BView_cr_dump_clipping (void *view, cairo_t *ctx); diff --git a/src/haikufont.c b/src/haikufont.c index e08792be4b3..67b1113e44c 100644 --- a/src/haikufont.c +++ b/src/haikufont.c @@ -955,7 +955,8 @@ haikufont_draw (struct glyph_string *s, int from, int to, block_input (); prepare_face_for_display (s->f, face); - BView_draw_lock (view); + /* Presumably the draw lock is already held by + haiku_draw_glyph_string; */ if (with_background) { int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font); @@ -1014,7 +1015,7 @@ haikufont_draw (struct glyph_string *s, int from, int to, BView_DrawString (view, b, b_len); xfree (b); } - BView_draw_unlock (view); + unblock_input (); return 1; } diff --git a/src/haikuterm.c b/src/haikuterm.c index ac0540b77f8..e8c734d6711 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -3618,18 +3618,22 @@ haiku_set_offset (struct frame *frame, int x, int y, cairo_t * haiku_begin_cr_clip (struct frame *f, struct glyph_string *s) { - cairo_surface_t *surface = FRAME_CR_SURFACE (f); - if (!surface) + cairo_t *cr = FRAME_CR_CONTEXT (f); + + if (!cr) return NULL; - cairo_t *context = cairo_create (surface); - return context; + cairo_save (cr); + return cr; } void haiku_end_cr_clip (cairo_t *cr) { - cairo_destroy (cr); + if (!cr) + return NULL; + + cairo_restore (cr); } #endif diff --git a/src/haikuterm.h b/src/haikuterm.h index de607e6dc51..2dbdb6aafcb 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h @@ -231,8 +231,10 @@ struct scroll_bar #define FRAME_CURSOR_COLOR(f) (FRAME_OUTPUT_DATA (f)->cursor_color) #ifdef USE_BE_CAIRO -#define FRAME_CR_SURFACE(f) \ - (FRAME_HAIKU_VIEW (f) ? EmacsView_cairo_surface (FRAME_HAIKU_VIEW (f)) : 0); +#define FRAME_CR_CONTEXT(f) \ + (FRAME_HAIKU_VIEW (f) \ + ? EmacsView_cairo_context (FRAME_HAIKU_VIEW (f)) \ + : NULL) #endif extern void syms_of_haikuterm (void); -- 2.39.5