summaryrefslogtreecommitdiff
path: root/src/xftfont.c
diff options
context:
space:
mode:
authorDaniel Colascione <dancol@dancol.org>2016-10-20 20:34:36 -0700
committerDaniel Colascione <dancol@dancol.org>2016-10-28 19:21:39 -0700
commitc29071587c64efb30792bd72248d3c791abd9337 (patch)
treea38c726630104997b7d63cbba56056ed1f8d19fa /src/xftfont.c
parentf5543ffcf5b2974fa8fc6cf007e9109fa8e9051e (diff)
downloademacs-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.c31
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);
}