diff options
author | Daniel Colascione <dancol@dancol.org> | 2016-10-20 20:34:36 -0700 |
---|---|---|
committer | Daniel Colascione <dancol@dancol.org> | 2016-10-28 19:21:39 -0700 |
commit | c29071587c64efb30792bd72248d3c791abd9337 (patch) | |
tree | a38c726630104997b7d63cbba56056ed1f8d19fa /src/xftfont.c | |
parent | f5543ffcf5b2974fa8fc6cf007e9109fa8e9051e (diff) | |
download | emacs-c29071587c64efb30792bd72248d3c791abd9337.tar.gz emacs-c29071587c64efb30792bd72248d3c791abd9337.tar.bz2 emacs-c29071587c64efb30792bd72248d3c791abd9337.zip |
Add double-buffering support to reduce flicker
* src/dispextern.h (struct glyph_string): Remove window member
(block_buffer_flips, unblock_buffer_flips)
(buffer_flipping_blocked_p): Declare.
* src/xterm.h (struct x_display_info): New member supports_xdbe.
(struct x_output): New members draw_desc and need_buffer_flip.
(FRAME_X_DRAWABLE, FRAME_X_RAW_DRAWABLE)
(FRAME_X_DOUBLE_BUFFERED_P)
(FRAME_X_NEED_BUFFER_FLIP): New macros.
(set_up_x_back_buffer, tear_down_x_back_buffer)
(initial_set_up_x_back_buffer): Declare.
* src/xterm.c: Include Xdbe.h.
(x_begin_cr_clip, x_fill_rectangle, x_draw_rectangle)
(x_draw_vertical_window_border, x_update_end)
(x_setup_relief_color, x_draw_relief_rect)
(x_draw_fringe_bitmap, x_shift_glyphs_for_insert)
(x_scroll_run, x_draw_hollow_cursor, x_draw_bar_cursor): Use
FRAME_X_DRAWABLE instead of FRAME_X_WINDOW; rename local
variables appropriately; substitute calls to XClearArea with
x_clear_area, which DTRT for double buffering.
(x_clear_window, x_clear_area): In double-buffering mode, use
rect-drawing X functions instead of XClearWindow and
XClearArea, which always operate on the front buffer.
(show_back_buffer): New function.
(XTframe_up_to_date): Call show_back_buffer when done.
(x_clear_frame, x_clear_frame_area): Remove obsolete calls to
gtk_widget_queue_draw to refresh scroll bars; scroll bars are
now independent X windows.
(handle_one_xevent): Call font_drop_xrender_surfaces when
XftDraw might need regenerating; perform buffer flip when
responding to Expose events; issue front-buffer clearing
commands as stopgap while we wait for redisplay.
Call flush_dirty_back_buffers.
(x_make_frame_visible): Un-bitrot comment; move XSETFRAME
earlier in function.
(x_free_frame_resources): Call tear_down_x_back_buffer when
destroying frame.
(x_term_init): Attempt to initialize double buffer extension.
(x_flip_and_flush): New function.
(x_redisplay_interface): Point to x_flip_and_flush instead of
x_flip directly.
(flush_dirty_back_buffers): New function.
(x_create_terminal): Register buffer_flipping_unblocked_hook.
* src/xftfont.c (xftfont_drop_xrender_surfaces): Use
FRAME_X_DRAWABLE instead of FRAME_X_WINDOW.
(xftfont_draw): Call x_mark_frame_dirty.
(xftfont_drop_xrender_surfaces): New function.
(syms_of_xftfont): Register it.
* src/xfont.c (xfont_draw): Use FRAME_X_DRAWABLE instead of
FRAME_X_WINDOW.
* src/xfns.c: Include Xdbe.h.
(x_set_inhibit_double_buffering, set_up_x_back_buffer)
(Fx_double_buffered_p): New functions.
(x_window): Call initial_set_up_x_back_buffer.
(x_make_gc): Use FRAME_X_DRAWABLE instead of FRAME_X_WINDOW.
(Fx_create_frame): Configure `inhibit-double-buffering'
frame parameter.
(x_create_tip_frame): Call initial_set_up_x_back_buffer.
(x_frame_parm_handlers): Register
x_set_inhibit_double_buffering.
(syms_of_xfns): Register Sx_double_buffered_p.
(x_mark_frame_dirty): Define.
* src/xfaces.c (x_create_gc): Use FRAME_X_DRAWABLE instead of
FRAME_X_WINDOW.
* src/xdisp.c (remember_mouse_glyph, init_glyph_string): Use
FRAME_X_DRAWABLE instead of FRAME_X_WINDOW.
(redisplay_internal): Restart redisplay if a frame is garbaged
during updating; explain why. Block buffer flips
during redisplay.
(redisplay_preserve_echo_area): Block buffer flip during call
to redisplay_internal.
(buffer_flip_blocked_depth): New variable.
(block_buffer_flips, unblock_buffer_flips)
(buffer_flipping_blocked_p): New functions.
(init_glyph_string): Stop setting window member of struct
glyph_string.
* src/w32fns.c (w32_frame_parm_handlers): Add placeholder for
x_set_inhibit_double_buffering.
* src/termhooks.h (struct terminal): Add
buffer_flipping_unblocked_hook.
* src/nsfns.m (ns_frame_parm_handlers): Add placeholder for
x_set_inhibit_double_buffering.
* src/image.c (x_create_bitmap_from_data)
(x_create_bitmap_from_file, x_create_x_image_and_pixmap)
(Create_Pixmap_From_Bitmap_Data)
(x_create_bitmap_from_xpm_data, xpm_load, gs_load): Use
FRAME_X_DRAWABLE instead of FRAME_X_WINDOW; rename local
variables appropriately.
* src/gtkutil.c: Include Xdbe.h.
(xg_get_widget_from_map): Forward declare.
(xg_clear_under_internal_border): Remove obsolete calls to
refresh scroll bars.
(xg_create_frame_widgets): Call initial_set_up_x_back_buffer.
(xg_free_frame_widgets): Call tear_down_x_back_buffer; reset
FRAME_X_DRAWABLE as well as FRAME_X_WINDOW and for the
same reason.
(xg_set_background_color): Set scroll bar background colors.
(xg_finish_scroll_bar_creation): New function with common
logic of xg_create_scroll_bar, xg_create_horizontal_scroll_bar. Force
scroll bars to be real X11 windows.
(xg_create_scroll_bar, xg_create_horizontal_scroll_bar): Call
xg_finish_scroll_bar_creation.
(xg_update_scrollbar_pos, xg_update_horizontal_scrollbar_pos):
Remove obsolete calls to refresh scroll bars; fix comments.
* src/ftxfont.c (ftxfont_get_gcs, ftxfont_draw_bitmap,
(ftxfont_draw_background): Use FRAME_X_DRAWABLE instead of
FRAME_X_WINDOW.
* src/frame.c (frame_parms): Add table entry for new
`inhibit-double-buffering' frame parameter
(syms_of_frame): Register Qinhibit_double_buffering.
* src/font.h (struct font_driver): Add new `flush_frame_caches' hook.
(font_drop_xrender_surfaces): Declare.
* src/font.c (font_drop_xrender_surfaces): New function.
* src/Makefile.in (XDBE_LIBS, XDBE_CFLAGS): Substitute.
* etc/NEWS: Mention use of double buffering
* doc/lispref/frames.texi (Management Parameters): Document
`inhibit-double-buffering' frame parameters.
(Visibility of Frames): Document `x-double-buffered-p'.
* configure.ac: Check for the X double buffer extension
Diffstat (limited to 'src/xftfont.c')
-rw-r--r-- | src/xftfont.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/xftfont.c b/src/xftfont.c index 34c6f7d3e42..861ad80da5c 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -586,7 +586,7 @@ xftfont_get_xft_draw (struct frame *f) { block_input (); xft_draw= XftDrawCreate (FRAME_X_DISPLAY (f), - FRAME_X_WINDOW (f), + FRAME_X_DRAWABLE (f), FRAME_X_VISUAL (f), FRAME_X_COLORMAP (f)); unblock_input (); @@ -600,6 +600,8 @@ static int xftfont_draw (struct glyph_string *s, int from, int to, int x, int y, bool with_background) { + block_input (); + struct frame *f = s->f; struct face *face = s->face; struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font; @@ -614,7 +616,6 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y, xftface_info = (struct xftface_info *) face->extra; xftfont_get_colors (f, face, s->gc, xftface_info, &fg, with_background ? &bg : NULL); - block_input (); if (s->num_clips > 0) XftDrawSetClipRectangles (xft_draw, 0, 0, s->clip, s->num_clips); else @@ -652,9 +653,12 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y, x + i, y, code + i, 1); else XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont, - x, y, code, len); + x, y, code, len); + /* Need to explicitly mark the frame dirty because we didn't call + FRAME_X_DRAWABLE in order to draw: we cached the drawable in the + XftDraw structure. */ + x_mark_frame_dirty (f); unblock_input (); - return len; } @@ -678,13 +682,10 @@ xftfont_shape (Lisp_Object lgstring) static int xftfont_end_for_frame (struct frame *f) { + block_input (); XftDraw *xft_draw; - /* Don't do anything if display is dead */ - if (FRAME_X_DISPLAY (f) == NULL) return 0; - xft_draw = font_get_frame_data (f, Qxft); - if (xft_draw) { block_input (); @@ -692,9 +693,19 @@ xftfont_end_for_frame (struct frame *f) unblock_input (); font_put_frame_data (f, Qxft, NULL); } + unblock_input (); return 0; } +static void +xftfont_drop_xrender_surfaces (struct frame *f) +{ + block_input (); + if (FRAME_X_DOUBLE_BUFFERED_P (f)) + xftfont_end_for_frame (f); + unblock_input (); +} + static bool xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object, Lisp_Object entity) @@ -777,6 +788,10 @@ This is needed with some fonts to correct vertical overlap of glyphs. */); #if defined (HAVE_M17N_FLT) && defined (HAVE_LIBOTF) xftfont_driver.shape = xftfont_shape; #endif + /* When using X double buffering, the XftDraw structure we build + seems to be useless once a frame is resized, so recreate it on + ConfigureNotify and in some other cases. */ + xftfont_driver.drop_xrender_surfaces = xftfont_drop_xrender_surfaces; register_font_driver (&xftfont_driver, NULL); } |