emacs-diffs
[Top][All Lists]
Advanced

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

feature/pgtk 9752896 042/100: Bring pgtk more inline with X11-cairo buil


From: Yuuki Harano
Subject: feature/pgtk 9752896 042/100: Bring pgtk more inline with X11-cairo builds
Date: Tue, 24 Nov 2020 08:02:33 -0500 (EST)

branch: feature/pgtk
commit 975289663f353f830d121058320150ff099e809a
Author: Jeff Walsh <jawalsh@localhost.localdomain>
Commit: Jeff Walsh <jeff.walsh@drtusers-MacBook-Pro.local>

    Bring pgtk more inline with X11-cairo builds
    
    * src/pgtkterm.h (struct pgtk_output):
    
    * src/pgtkterm.c (FRAME_CR_ACTIVE_CONTEXT, flip_cr_context)
    (x_draw_bar_cursor, pgtk_scroll_run, pgtk_update_end)
    (pgtk_cr_draw_image, pgtk_flash, pgtk_handle_draw)
    (pgtk_cr_update_surface_desired_size, pgtk_begin_cr_clip)
    (pgtk_cr_destroy_frame_context):
    
    * src/image.c (image_create_pattern_from_pixbuf):
    
    - Don't create a context each time, just hold a reference
    
    - Pull in a few cairo image changes from master
    
    - Remove redundant code in pgtk_update_begin()
---
 src/image.c    |   3 +-
 src/pgtkterm.c | 157 +++++++++++++++++----------------------------------------
 src/pgtkterm.h |   7 ++-
 3 files changed, 52 insertions(+), 115 deletions(-)

diff --git a/src/image.c b/src/image.c
index 0b85cf8..c7ae3b9 100644
--- a/src/image.c
+++ b/src/image.c
@@ -405,7 +405,8 @@ static cairo_pattern_t *
 image_create_pattern_from_pixbuf (struct frame *f, GdkPixbuf *pixbuf)
 {
   GdkPixbuf *pb = gdk_pixbuf_add_alpha (pixbuf, TRUE, 255, 255, 255);
-  cairo_surface_t *surface = cairo_surface_create_similar_image 
(f->output_data.pgtk->cr_surface,
+  cairo_surface_t *surface = cairo_surface_create_similar_image 
(cairo_get_target(
+                                                                  
f->output_data.pgtk->cr_context),
                                                                 
CAIRO_FORMAT_A1,
                                                                 
gdk_pixbuf_get_width (pb),
                                                                 
gdk_pixbuf_get_height (pb));
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index fbfc295..e214cc2 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -62,8 +62,9 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0)
 
-#define FRAME_CR_CONTEXT(f)    ((f)->output_data.pgtk->cr_context)
-#define FRAME_CR_SURFACE(f)    ((f)->output_data.pgtk->cr_surface)
+#define FRAME_CR_CONTEXT(f) ((f)->output_data.pgtk->cr_context)
+#define FRAME_CR_ACTIVE_CONTEXT(f)     ((f)->output_data.pgtk->cr_active)
+#define FRAME_CR_SURFACE(f) (cairo_get_target(FRAME_CR_CONTEXT(f)))
 #define FRAME_CR_SURFACE_DESIRED_WIDTH(f)              \
   ((f)->output_data.pgtk->cr_surface_desired_width)
 #define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \
@@ -96,6 +97,21 @@ static void pgtk_clip_to_row (struct window *w, struct 
glyph_row *row,
 static struct frame *
 pgtk_any_window_to_frame (GdkWindow *window);
 
+static void flip_cr_context(struct frame *f)
+{
+  PGTK_TRACE("flip_cr_context");
+  cairo_t * cr = FRAME_CR_ACTIVE_CONTEXT(f);
+
+  block_input();
+  if ( cr != FRAME_CR_CONTEXT(f))
+    {
+      cairo_destroy(cr);
+      FRAME_CR_ACTIVE_CONTEXT(f) = cairo_reference(FRAME_CR_CONTEXT(f));
+
+    }
+  unblock_input();
+}
+
 
 static void evq_enqueue(union buffered_input_event *ev)
 {
@@ -2667,8 +2683,6 @@ pgtk_draw_window_cursor (struct window *w, struct 
glyph_row *glyph_row, int x,
          xic_set_preeditarea (w, x, y);
 #endif
     }
-
-  gtk_widget_queue_draw(FRAME_GTK_WIDGET(f));
 }
 
 static void
@@ -2771,38 +2785,6 @@ pgtk_scroll_run (struct window *w, struct run *run)
 static void
 pgtk_update_begin (struct frame *f)
 {
-  if (! NILP (tip_frame) && XFRAME (tip_frame) == f
-      && ! FRAME_VISIBLE_P (f))
-    return;
-
-  if (! FRAME_CR_SURFACE (f))
-    {
-      int width, height;
-      if (FRAME_GTK_WIDGET (f))
-       {
-         GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
-         width = gdk_window_get_width (w);
-         height = gdk_window_get_height (w);
-       }
-      else
-       {
-         width = FRAME_PIXEL_WIDTH (f);
-         height = FRAME_PIXEL_HEIGHT (f);
-         if (! FRAME_EXTERNAL_TOOL_BAR (f))
-           height += FRAME_TOOL_BAR_HEIGHT (f);
-         if (! FRAME_EXTERNAL_MENU_BAR (f))
-           height += FRAME_MENU_BAR_HEIGHT (f);
-       }
-
-      if (width > 0 && height > 0)
-       {
-         block_input();
-         FRAME_CR_SURFACE (f) = cairo_image_surface_create
-           (CAIRO_FORMAT_ARGB32, width, height);
-         unblock_input();
-       }
-    }
-
   pgtk_clear_under_internal_border (f);
 }
 
@@ -2965,8 +2947,12 @@ pgtk_update_window_end (struct window *w, bool 
cursor_on_p,
 static void
 pgtk_update_end (struct frame *f)
 {
+  GtkWidget *widget = FRAME_GTK_WIDGET(f);
   /* Mouse highlight may be displayed again.  */
   MOUSE_HL_INFO (f)->mouse_face_defer = false;
+
+  gtk_widget_queue_draw (widget);
+  flip_cr_context(f);
 }
 
 /* Return the current position of the mouse.
@@ -3139,13 +3125,10 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC *gc, 
cairo_pattern_t *image,
                 int src_x, int src_y, int width, int height,
                 int dest_x, int dest_y, bool overlay_p)
 {
-  cairo_t *cr;
-  cairo_matrix_t matrix;
-  cairo_surface_t *surface;
-  cairo_format_t format;
+  cairo_t *cr = pgtk_begin_cr_clip (f);
 
   PGTK_TRACE("pgtk_cr_draw_image: 0: %d,%d,%d,%d,%d,%d,%d.", src_x, src_y, 
width, height, dest_x, dest_y, overlay_p);
-  cr = pgtk_begin_cr_clip (f);
+
   if (overlay_p)
     cairo_rectangle (cr, dest_x, dest_y, width, height);
   else
@@ -3154,42 +3137,24 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC *gc, 
cairo_pattern_t *image,
       cairo_rectangle (cr, dest_x, dest_y, width, height);
       cairo_fill_preserve (cr);
     }
-  cairo_clip (cr);
-  cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
-  cairo_pattern_set_matrix (image, &matrix);
+  cairo_translate (cr, dest_x - src_x, dest_y - src_y);
+
+  cairo_surface_t *surface;
   cairo_pattern_get_surface (image, &surface);
-  format = cairo_image_surface_get_format (surface);
+  cairo_format_t format = cairo_image_surface_get_format (surface);
   if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
     {
-      PGTK_TRACE("other format.");
       cairo_set_source (cr, image);
       cairo_fill (cr);
     }
   else
     {
-      if (format == CAIRO_FORMAT_A8)
-       PGTK_TRACE("format A8.");
-      else if (format == CAIRO_FORMAT_A1)
-       PGTK_TRACE("format A1.");
-      else
-       PGTK_TRACE("format ??.");
       pgtk_set_cr_source_with_gc_foreground (f, gc);
-      cairo_rectangle_list_t *rects = cairo_copy_clip_rectangle_list(cr);
-      PGTK_TRACE("rects:");
-      PGTK_TRACE(" status: %u", rects->status);
-      PGTK_TRACE(" rectangles:");
-      for (int i = 0; i < rects->num_rectangles; i++) {
-       PGTK_TRACE("  %fx%f+%f+%f",
-               rects->rectangles[i].width,
-               rects->rectangles[i].height,
-               rects->rectangles[i].x,
-               rects->rectangles[i].y);
-      }
-      cairo_rectangle_list_destroy(rects);
+      cairo_clip (cr);
       cairo_mask (cr, image);
     }
+
   pgtk_end_cr_clip (f);
-  PGTK_TRACE("pgtk_cr_draw_image: 9.");
 }
 
 static void
@@ -3375,8 +3340,6 @@ recover_from_visible_bell(struct atimer *timer)
 
   if (FRAME_X_OUTPUT(f)->atimer_visible_bell != NULL)
     FRAME_X_OUTPUT(f)->atimer_visible_bell = NULL;
-
-  gtk_widget_queue_draw(FRAME_GTK_WIDGET(f));
 }
 
 static void
@@ -3436,8 +3399,6 @@ pgtk_flash (struct frame *f)
                        width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 
       FRAME_X_OUTPUT(f)->cr_surface_visible_bell = surface;
-      gtk_widget_queue_draw(FRAME_GTK_WIDGET(f));
-
       {
        struct timespec delay = make_timespec (0, 50 * 1000 * 1000);
        if (FRAME_X_OUTPUT(f)->atimer_visible_bell != NULL) {
@@ -4843,12 +4804,12 @@ pgtk_handle_draw(GtkWidget *widget, cairo_t *cr, 
gpointer *data)
     PGTK_TRACE("  f=%p", f);
     if (f != NULL) {
       src = FRAME_X_OUTPUT(f)->cr_surface_visible_bell;
-      if (src == NULL)
-       src = FRAME_CR_SURFACE(f);
+      if (src == NULL && FRAME_CR_ACTIVE_CONTEXT(f) != NULL)
+       src = cairo_get_target(FRAME_CR_ACTIVE_CONTEXT(f));
     }
-    PGTK_TRACE("  surface=%p", src);
+    APGTK_TRACE("  surface=%p", src);
     if (src != NULL) {
-      PGTK_TRACE("  resized_p=%d", f->resized_p);
+      APGTK_TRACE("  resized_p=%d", f->resized_p);
       PGTK_TRACE("  garbaged=%d", f->garbaged);
       PGTK_TRACE("  scroll_bar_width=%f", (double) PGTK_SCROLL_BAR_WIDTH(f));
       // PGTK_TRACE("  scroll_bar_adjust=%d", PGTK_SCROLL_BAR_ADJUST(f));
@@ -6596,27 +6557,10 @@ pgtk_cr_update_surface_desired_size (struct frame *f, 
int width, int height)
   if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width
       || FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height)
     {
-      cairo_surface_t *old_surface = FRAME_CR_SURFACE(f);
-      cairo_t *cr = NULL;
-      cairo_t *old_cr = FRAME_CR_CONTEXT(f);
-      FRAME_CR_SURFACE(f) = 
gdk_window_create_similar_surface(gtk_widget_get_window(FRAME_GTK_WIDGET(f)),
-                                                             
CAIRO_CONTENT_COLOR_ALPHA,
-                                                             width,
-                                                             height);
-
-      if (old_surface){
-       cr = cairo_create(FRAME_CR_SURFACE(f));
-       cairo_set_source_surface (cr, old_surface, 0, 0);
-
-       cairo_paint(cr);
-       FRAME_CR_CONTEXT (f) = cr;
-
-        cairo_destroy(old_cr);
-       cairo_surface_destroy (old_surface);
-      }
-      gtk_widget_queue_draw(FRAME_GTK_WIDGET(f));
+      pgtk_cr_destroy_frame_context(f);
       FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width;
       FRAME_CR_SURFACE_DESIRED_HEIGHT (f) = height;
+      SET_FRAME_GARBAGED(f);
     }
 }
 
@@ -6627,16 +6571,17 @@ pgtk_begin_cr_clip (struct frame *f)
   cairo_t *cr = FRAME_CR_CONTEXT (f);
 
   PGTK_TRACE("pgtk_begin_cr_clip");
-  if (! FRAME_CR_SURFACE (f))
-    {
-      FRAME_CR_SURFACE(f) = 
gdk_window_create_similar_surface(gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
-                                                             
CAIRO_CONTENT_COLOR_ALPHA,
-                                                             FRAME_PIXEL_WIDTH 
(f),
-                                                             
FRAME_PIXEL_HEIGHT (f));
-    }
-
   if (!cr)
     {
+      cairo_surface_t *surface =
+       gdk_window_create_similar_surface(gtk_widget_get_window 
(FRAME_GTK_WIDGET (f)),
+                                         CAIRO_CONTENT_COLOR_ALPHA,
+                                         FRAME_CR_SURFACE_DESIRED_WIDTH (f),
+                                         FRAME_CR_SURFACE_DESIRED_HEIGHT (f));
+
+      cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
+      cairo_surface_destroy (surface);
+
       cr = cairo_create (FRAME_CR_SURFACE (f));
       FRAME_CR_CONTEXT (f) = cr;
     }
@@ -6651,9 +6596,6 @@ pgtk_end_cr_clip (struct frame *f)
 {
   PGTK_TRACE("pgtk_end_cr_clip");
   cairo_restore (FRAME_CR_CONTEXT (f));
-
-  GtkWidget *widget = FRAME_GTK_WIDGET(f);
-  gtk_widget_queue_draw(widget);
 }
 
 void
@@ -6690,18 +6632,13 @@ pgtk_cr_draw_frame (cairo_t *cr, struct frame *f)
 }
 
 void
-pgtk_cr_destroy_surface(struct frame *f)
+pgtk_cr_destroy_frame_context(struct frame *f)
 {
-  PGTK_TRACE("pgtk_cr_destroy_surface");
+  PGTK_TRACE("pgtk_cr_destroy_frame_context");
   if (FRAME_CR_CONTEXT(f) != NULL) {
     cairo_destroy(FRAME_CR_CONTEXT(f));
     FRAME_CR_CONTEXT(f) = NULL;
   }
-  if (FRAME_CR_SURFACE(f) != NULL) {
-    cairo_surface_destroy(FRAME_CR_SURFACE(f));
-    FRAME_CR_SURFACE(f) = NULL;
-  }
-  SET_FRAME_GARBAGED (f);
 }
 
 void
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index 7bc0f0d..5c59d5e 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -364,11 +364,10 @@ struct pgtk_output
   int toolbar_left_width, toolbar_right_width;
 
 #ifdef USE_CAIRO
-  /* Cairo drawing context.  */
-  cairo_t *cr_context;
+  /* Cairo drawing contexts.  */
+  cairo_t *cr_context, *cr_active;
   int cr_surface_desired_width, cr_surface_desired_height;
   /* Cairo surface for double buffering */
-  cairo_surface_t *cr_surface;
   cairo_surface_t *cr_surface_visible_bell;
 #endif
   struct atimer *atimer_visible_bell;
@@ -576,7 +575,7 @@ extern void pgtk_set_cr_source_with_gc_foreground (struct 
frame *f, Emacs_GC *gc
 extern void pgtk_set_cr_source_with_gc_background (struct frame *f, Emacs_GC 
*gc);
 extern void pgtk_set_cr_source_with_color (struct frame *f, unsigned long 
color);
 extern void pgtk_cr_draw_frame (cairo_t *cr, struct frame *f);
-extern void pgtk_cr_destroy_surface(struct frame *f);
+extern void pgtk_cr_destroy_frame_context(struct frame *f);
 
 /* Defined in pgtkmenu.c */
 extern Lisp_Object pgtk_popup_dialog (struct frame *f, Lisp_Object header, 
Lisp_Object contents);



reply via email to

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