Skip to content

Commit 0183c38

Browse files
Jeff Walshfejfighter
authored andcommitted
Bring pgtk more inline with X11-cairo builds
- 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()
1 parent 30cc5b8 commit 0183c38

File tree

3 files changed

+53
-105
lines changed

3 files changed

+53
-105
lines changed

src/image.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
3434
#include <c-ctype.h>
3535
#include <flexmember.h>
3636

37-
#ifdef HAVE_PGTK
38-
#include <cairo.h>
39-
#endif
40-
4137
#include "lisp.h"
4238
#include "frame.h"
4339
#include "process.h"
@@ -406,7 +402,8 @@ static cairo_pattern_t *
406402
image_create_pattern_from_pixbuf (struct frame *f, GdkPixbuf *pixbuf)
407403
{
408404
GdkPixbuf *pb = gdk_pixbuf_add_alpha (pixbuf, TRUE, 255, 255, 255);
409-
cairo_surface_t *surface = cairo_surface_create_similar_image (f->output_data.pgtk->cr_surface,
405+
cairo_surface_t *surface = cairo_surface_create_similar_image (cairo_get_target(
406+
f->output_data.pgtk->cr_context),
410407
CAIRO_FORMAT_A1,
411408
gdk_pixbuf_get_width (pb),
412409
gdk_pixbuf_get_height (pb));

src/pgtkterm.c

Lines changed: 48 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
6161

6262
#define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0)
6363

64-
#define FRAME_CR_CONTEXT(f) ((f)->output_data.pgtk->cr_context)
65-
#define FRAME_CR_SURFACE(f) ((f)->output_data.pgtk->cr_surface)
64+
#define FRAME_CR_CONTEXT(f) ((f)->output_data.pgtk->cr_context)
65+
#define FRAME_CR_ACTIVE_CONTEXT(f) ((f)->output_data.pgtk->cr_active)
66+
#define FRAME_CR_SURFACE(f) (cairo_get_target(FRAME_CR_CONTEXT(f)))
6667
#define FRAME_CR_SURFACE_DESIRED_WIDTH(f) \
6768
((f)->output_data.pgtk->cr_surface_desired_width)
6869
#define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \
@@ -95,6 +96,22 @@ static void pgtk_clip_to_row (struct window *w, struct glyph_row *row,
9596
static struct frame *
9697
pgtk_any_window_to_frame (GdkWindow *window);
9798

99+
static void flip_cr_context(struct frame *f)
100+
{
101+
APGTK_TRACE("flip_cr_context");
102+
cairo_t * cr = FRAME_CR_ACTIVE_CONTEXT(f);
103+
104+
block_input();
105+
if ( cr != FRAME_CR_CONTEXT(f))
106+
{
107+
cairo_destroy(cr);
108+
FRAME_CR_ACTIVE_CONTEXT(f) = cairo_reference(FRAME_CR_CONTEXT(f));
109+
110+
}
111+
unblock_input();
112+
}
113+
114+
98115
static void evq_enqueue(union buffered_input_event *ev)
99116
{
100117
struct event_queue_t *evq = &event_q;
@@ -2665,8 +2682,6 @@ pgtk_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
26652682
xic_set_preeditarea (w, x, y);
26662683
#endif
26672684
}
2668-
2669-
gtk_widget_queue_draw(FRAME_GTK_WIDGET(f));
26702685
}
26712686

26722687
static void
@@ -2769,24 +2784,6 @@ pgtk_scroll_run (struct window *w, struct run *run)
27692784
static void
27702785
pgtk_update_begin (struct frame *f)
27712786
{
2772-
if (! NILP (tip_frame) && XFRAME (tip_frame) == f
2773-
&& ! FRAME_VISIBLE_P (f))
2774-
return;
2775-
2776-
if (! FRAME_CR_SURFACE (f))
2777-
{
2778-
int width = FRAME_PIXEL_WIDTH (f);
2779-
int height = FRAME_PIXEL_HEIGHT (f);
2780-
2781-
if (width > 0 && height > 0)
2782-
{
2783-
block_input();
2784-
FRAME_CR_SURFACE (f) = cairo_image_surface_create
2785-
(CAIRO_FORMAT_ARGB32, width, height);
2786-
unblock_input();
2787-
}
2788-
}
2789-
27902787
pgtk_clear_under_internal_border (f);
27912788
}
27922789

@@ -2949,8 +2946,12 @@ pgtk_update_window_end (struct window *w, bool cursor_on_p,
29492946
static void
29502947
pgtk_update_end (struct frame *f)
29512948
{
2949+
GtkWidget *widget = FRAME_GTK_WIDGET(f);
29522950
/* Mouse highlight may be displayed again. */
29532951
MOUSE_HL_INFO (f)->mouse_face_defer = false;
2952+
2953+
gtk_widget_queue_draw (widget);
2954+
flip_cr_context(f);
29542955
}
29552956

29562957
/* Return the current position of the mouse.
@@ -3123,13 +3124,10 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC *gc, cairo_pattern_t *image,
31233124
int src_x, int src_y, int width, int height,
31243125
int dest_x, int dest_y, bool overlay_p)
31253126
{
3126-
cairo_t *cr;
3127-
cairo_matrix_t matrix;
3128-
cairo_surface_t *surface;
3129-
cairo_format_t format;
3127+
cairo_t *cr = pgtk_begin_cr_clip (f);
31303128

31313129
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);
3132-
cr = pgtk_begin_cr_clip (f);
3130+
31333131
if (overlay_p)
31343132
cairo_rectangle (cr, dest_x, dest_y, width, height);
31353133
else
@@ -3138,42 +3136,24 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC *gc, cairo_pattern_t *image,
31383136
cairo_rectangle (cr, dest_x, dest_y, width, height);
31393137
cairo_fill_preserve (cr);
31403138
}
3141-
cairo_clip (cr);
3142-
cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
3143-
cairo_pattern_set_matrix (image, &matrix);
3139+
cairo_translate (cr, dest_x - src_x, dest_y - src_y);
3140+
3141+
cairo_surface_t *surface;
31443142
cairo_pattern_get_surface (image, &surface);
3145-
format = cairo_image_surface_get_format (surface);
3143+
cairo_format_t format = cairo_image_surface_get_format (surface);
31463144
if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
31473145
{
3148-
PGTK_TRACE("other format.");
31493146
cairo_set_source (cr, image);
31503147
cairo_fill (cr);
31513148
}
31523149
else
31533150
{
3154-
if (format == CAIRO_FORMAT_A8)
3155-
PGTK_TRACE("format A8.");
3156-
else if (format == CAIRO_FORMAT_A1)
3157-
PGTK_TRACE("format A1.");
3158-
else
3159-
PGTK_TRACE("format ??.");
31603151
pgtk_set_cr_source_with_gc_foreground (f, gc);
3161-
cairo_rectangle_list_t *rects = cairo_copy_clip_rectangle_list(cr);
3162-
PGTK_TRACE("rects:");
3163-
PGTK_TRACE(" status: %u", rects->status);
3164-
PGTK_TRACE(" rectangles:");
3165-
for (int i = 0; i < rects->num_rectangles; i++) {
3166-
PGTK_TRACE(" %fx%f+%f+%f",
3167-
rects->rectangles[i].width,
3168-
rects->rectangles[i].height,
3169-
rects->rectangles[i].x,
3170-
rects->rectangles[i].y);
3171-
}
3172-
cairo_rectangle_list_destroy(rects);
3152+
cairo_clip (cr);
31733153
cairo_mask (cr, image);
31743154
}
3155+
31753156
pgtk_end_cr_clip (f);
3176-
PGTK_TRACE("pgtk_cr_draw_image: 9.");
31773157
}
31783158

31793159
static void
@@ -3358,8 +3338,6 @@ recover_from_visible_bell(struct atimer *timer)
33583338

33593339
if (FRAME_X_OUTPUT(f)->atimer_visible_bell != NULL)
33603340
FRAME_X_OUTPUT(f)->atimer_visible_bell = NULL;
3361-
3362-
gtk_widget_queue_draw(FRAME_GTK_WIDGET(f));
33633341
}
33643342

33653343
static void
@@ -3419,8 +3397,6 @@ pgtk_flash (struct frame *f)
34193397
width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
34203398

34213399
FRAME_X_OUTPUT(f)->cr_surface_visible_bell = surface;
3422-
gtk_widget_queue_draw(FRAME_GTK_WIDGET(f));
3423-
34243400
{
34253401
struct timespec delay = make_timespec (0, 50 * 1000 * 1000);
34263402
if (FRAME_X_OUTPUT(f)->atimer_visible_bell != NULL) {
@@ -4828,12 +4804,12 @@ pgtk_handle_draw(GtkWidget *widget, cairo_t *cr, gpointer *data)
48284804
PGTK_TRACE(" f=%p", f);
48294805
if (f != NULL) {
48304806
src = FRAME_X_OUTPUT(f)->cr_surface_visible_bell;
4831-
if (src == NULL)
4832-
src = FRAME_CR_SURFACE(f);
4807+
if (src == NULL && FRAME_CR_ACTIVE_CONTEXT(f) != NULL)
4808+
src = cairo_get_target(FRAME_CR_ACTIVE_CONTEXT(f));
48334809
}
4834-
PGTK_TRACE(" surface=%p", src);
4810+
APGTK_TRACE(" surface=%p", src);
48354811
if (src != NULL) {
4836-
PGTK_TRACE(" resized_p=%d", f->resized_p);
4812+
APGTK_TRACE(" resized_p=%d", f->resized_p);
48374813
PGTK_TRACE(" garbaged=%d", f->garbaged);
48384814
PGTK_TRACE(" scroll_bar_width=%f", (double) PGTK_SCROLL_BAR_WIDTH(f));
48394815
// PGTK_TRACE(" scroll_bar_adjust=%d", PGTK_SCROLL_BAR_ADJUST(f));
@@ -6580,27 +6556,10 @@ pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height)
65806556
if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width
65816557
|| FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height)
65826558
{
6583-
cairo_surface_t *old_surface = FRAME_CR_SURFACE(f);
6584-
cairo_t *cr = NULL;
6585-
cairo_t *old_cr = FRAME_CR_CONTEXT(f);
6586-
FRAME_CR_SURFACE(f) = gdk_window_create_similar_surface(gtk_widget_get_window(FRAME_GTK_WIDGET(f)),
6587-
CAIRO_CONTENT_COLOR_ALPHA,
6588-
width,
6589-
height);
6590-
6591-
if (old_surface){
6592-
cr = cairo_create(FRAME_CR_SURFACE(f));
6593-
cairo_set_source_surface (cr, old_surface, 0, 0);
6594-
6595-
cairo_paint(cr);
6596-
FRAME_CR_CONTEXT (f) = cr;
6597-
6598-
cairo_destroy(old_cr);
6599-
cairo_surface_destroy (old_surface);
6600-
}
6601-
gtk_widget_queue_draw(FRAME_GTK_WIDGET(f));
6559+
pgtk_cr_destroy_frame_context(f);
66026560
FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width;
66036561
FRAME_CR_SURFACE_DESIRED_HEIGHT (f) = height;
6562+
SET_FRAME_GARBAGED(f);
66046563
}
66056564
}
66066565

@@ -6611,16 +6570,17 @@ pgtk_begin_cr_clip (struct frame *f)
66116570
cairo_t *cr = FRAME_CR_CONTEXT (f);
66126571

66136572
PGTK_TRACE("pgtk_begin_cr_clip");
6614-
if (! FRAME_CR_SURFACE (f))
6615-
{
6616-
FRAME_CR_SURFACE(f) = gdk_window_create_similar_surface(gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
6617-
CAIRO_CONTENT_COLOR_ALPHA,
6618-
FRAME_PIXEL_WIDTH (f),
6619-
FRAME_PIXEL_HEIGHT (f));
6620-
}
6621-
66226573
if (!cr)
66236574
{
6575+
cairo_surface_t *surface =
6576+
gdk_window_create_similar_surface(gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
6577+
CAIRO_CONTENT_COLOR_ALPHA,
6578+
FRAME_CR_SURFACE_DESIRED_WIDTH (f),
6579+
FRAME_CR_SURFACE_DESIRED_HEIGHT (f));
6580+
6581+
cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
6582+
cairo_surface_destroy (surface);
6583+
66246584
cr = cairo_create (FRAME_CR_SURFACE (f));
66256585
FRAME_CR_CONTEXT (f) = cr;
66266586
}
@@ -6635,9 +6595,6 @@ pgtk_end_cr_clip (struct frame *f)
66356595
{
66366596
PGTK_TRACE("pgtk_end_cr_clip");
66376597
cairo_restore (FRAME_CR_CONTEXT (f));
6638-
6639-
GtkWidget *widget = FRAME_GTK_WIDGET(f);
6640-
gtk_widget_queue_draw(widget);
66416598
}
66426599

66436600
void
@@ -6674,18 +6631,13 @@ pgtk_cr_draw_frame (cairo_t *cr, struct frame *f)
66746631
}
66756632

66766633
void
6677-
pgtk_cr_destroy_surface(struct frame *f)
6634+
pgtk_cr_destroy_frame_context(struct frame *f)
66786635
{
6679-
PGTK_TRACE("pgtk_cr_destroy_surface");
6636+
PGTK_TRACE("pgtk_cr_destroy_frame_context");
66806637
if (FRAME_CR_CONTEXT(f) != NULL) {
66816638
cairo_destroy(FRAME_CR_CONTEXT(f));
66826639
FRAME_CR_CONTEXT(f) = NULL;
66836640
}
6684-
if (FRAME_CR_SURFACE(f) != NULL) {
6685-
cairo_surface_destroy(FRAME_CR_SURFACE(f));
6686-
FRAME_CR_SURFACE(f) = NULL;
6687-
}
6688-
SET_FRAME_GARBAGED (f);
66896641
}
66906642

66916643
void

src/pgtkterm.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,10 @@ struct pgtk_output
364364
int toolbar_left_width, toolbar_right_width;
365365

366366
#ifdef USE_CAIRO
367-
/* Cairo drawing context. */
368-
cairo_t *cr_context;
367+
/* Cairo drawing contexts. */
368+
cairo_t *cr_context, *cr_active;
369369
int cr_surface_desired_width, cr_surface_desired_height;
370370
/* Cairo surface for double buffering */
371-
cairo_surface_t *cr_surface;
372371
cairo_surface_t *cr_surface_visible_bell;
373372
#endif
374373
struct atimer *atimer_visible_bell;
@@ -576,7 +575,7 @@ extern void pgtk_set_cr_source_with_gc_foreground (struct frame *f, Emacs_GC *gc
576575
extern void pgtk_set_cr_source_with_gc_background (struct frame *f, Emacs_GC *gc);
577576
extern void pgtk_set_cr_source_with_color (struct frame *f, unsigned long color);
578577
extern void pgtk_cr_draw_frame (cairo_t *cr, struct frame *f);
579-
extern void pgtk_cr_destroy_surface(struct frame *f);
578+
extern void pgtk_cr_destroy_frame_context(struct frame *f);
580579

581580
/* Defined in pgtkmenu.c */
582581
extern Lisp_Object pgtk_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents);

0 commit comments

Comments
 (0)