bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

classic Classic list List threaded Threaded
36 messages Options
12
Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Robert Pluim
>>>>> On Thu, 03 Sep 2020 16:48:04 +0200, Andreas Schwab <[hidden email]> said:

    Andreas> On Sep 03 2020, Robert Pluim wrote:
    >> Does it go away if you set font-backend . ftcrhb in your frame
    >> parameters (assuming youʼre using Cairo)?

    Andreas> That completely removes the delay.

So the solution is easy: just deprecate and remove the 'x' backend :-)

Robert



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Alexander Shukaev-2
On 03/09/2020 17:10, Robert Pluim wrote:

>>>>>> On Thu, 03 Sep 2020 16:48:04 +0200, Andreas Schwab <[hidden email]> said:
>
>      Andreas> On Sep 03 2020, Robert Pluim wrote:
>      >> Does it go away if you set font-backend . ftcrhb in your frame
>      >> parameters (assuming youʼre using Cairo)?
>
>      Andreas> That completely removes the delay.
>
> So the solution is easy: just deprecate and remove the 'x' backend :-)
>
> Robert
>

Love that tip, man!  Confirming the speed up.  Thanks a lot!



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Eli Zaretskii
In reply to this post by Robert Pluim
> From: Andreas Schwab <[hidden email]>
> Cc: Robert Pluim <[hidden email]>,  [hidden email],
>   [hidden email]
> Date: Thu, 03 Sep 2020 19:51:17 +0200
>
> On Sep 03 2020, Eli Zaretskii wrote:
>
> > Do we understand why including the x backend produces such a huge
> > delay?  Where is most of that time spent, and why?
>
> My guess would be that probing fonts via the x backend is expensive due
> to round trips to the X server (and the X server is quite busy during
> that time).

If that is the reason, I guess we should try to minimize the number of
fonts for which this is done.  Like, for example, set up some data
structure to be consulted when a deciding whether a given font should
be used with the x backend.  After all, the number of fonts for which
that backend is needed is quite small, basically bitmapped fonts.



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Alexander Shukaev-2
In reply to this post by Alexander Shukaev-2
On 03/09/2020 18:39, Alexander Shukaev wrote:

> On 03/09/2020 17:10, Robert Pluim wrote:
>>>>>>> On Thu, 03 Sep 2020 16:48:04 +0200, Andreas Schwab
>>>>>>> <[hidden email]> said:
>>
>>      Andreas> On Sep 03 2020, Robert Pluim wrote:
>>      >> Does it go away if you set font-backend . ftcrhb in your frame
>>      >> parameters (assuming youʼre using Cairo)?
>>
>>      Andreas> That completely removes the delay.
>>
>> So the solution is easy: just deprecate and remove the 'x' backend :-)
>>
>> Robert
>>
>
> Love that tip, man!  Confirming the speed up.  Thanks a lot!

For future visitors and for completeness sake, my per-frame font setup
function now looks like this:

   (defun init-frame-font-setup
       (&optional frame)
     (unless frame (setq frame (selected-frame)))
     (with-selected-frame frame
       (when (and (not noninteractive) (init-display-graphic-p))
         (let ((font-backend (assoc 'font-backend default-frame-alist)))
           (if font-backend
               (when (eq frame frame-initial-frame)
                 (modify-frame-parameters frame
                                          `((font-backend . ,font-backend)))
                 (unless noninteractive
                   (message "Font Backend: `%s'" font-backend)))
             (when (and (> emacs-major-version 26)
                        (boundp 'cairo-version-string))
               (setq font-backend "ftcrhb"))
             (when font-backend
               (add-to-list 'default-frame-alist
                            `(font-backend . ,font-backend))
               (modify-frame-parameters frame
                                        `((font-backend . ,font-backend)))
               (unless noninteractive
                 (message "Font Backend: `%s'" font-backend)))))
         (let ((font (assoc 'font default-frame-alist)))
           (if font
               (when (eq frame frame-initial-frame)
                 (set-frame-font font t t)
                 (unless noninteractive
                   (message "Font: `%s'" font)))
             (let ((font-family (catch 'break
                                  (dolist (font-family init-font-families)
                                    (when (member font-family
                                                  (font-family-list))
                                      (throw 'break font-family))))))
               (setq font (when font-family
                            (format "%s-%d" font-family init-font-size))))
             (when font
               (add-to-list 'default-frame-alist `(font . ,font))
               (set-frame-font font t t)
               (unless noninteractive
                 (message "Font: `%s'" font))))))))

Typical usage is to add the following stanza to Emacs Lisp
initialization file(s):


   (unless (or noninteractive (daemonp))
     (when (init-display-graphic-p)
       (init-frame-font-setup)))

   (dolist (hook '(after-make-frame-functions focus-in-hook))
     (add-hook hook #'init-frame-font-setup))



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Eli Zaretskii
> From: Alexander Shukaev <[hidden email]>
> Date: Thu, 3 Sep 2020 21:47:41 +0200
> Cc: [hidden email]
>
> >> So the solution is easy: just deprecate and remove the 'x' backend :-)
> >>
> >> Robert
> >>
> >
> > Love that tip, man!  Confirming the speed up.  Thanks a lot!
>
> For future visitors and for completeness sake, my per-frame font setup
> function now looks like this:

For those same future visitors, a word of warning: removing the x font
backend will make some (rarely used) fonts unavailable to Emacs.
Caveat emptor!



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Robert Pluim
In reply to this post by Eli Zaretskii
>>>>> On Thu, 03 Sep 2020 21:24:24 +0300, Eli Zaretskii <[hidden email]> said:

    >> From: Andreas Schwab <[hidden email]>
    >> Cc: Robert Pluim <[hidden email]>,  [hidden email],
    >> [hidden email]
    >> Date: Thu, 03 Sep 2020 19:51:17 +0200
    >>
    >> On Sep 03 2020, Eli Zaretskii wrote:
    >>
    >> > Do we understand why including the x backend produces such a huge
    >> > delay?  Where is most of that time spent, and why?
    >>
    >> My guess would be that probing fonts via the x backend is expensive due
    >> to round trips to the X server (and the X server is quite busy during
    >> that time).

    Eli> If that is the reason, I guess we should try to minimize the number of
    Eli> fonts for which this is done.  Like, for example, set up some data
    Eli> structure to be consulted when a deciding whether a given font should
    Eli> be used with the x backend.  After all, the number of fonts for which
    Eli> that backend is needed is quite small, basically bitmapped fonts.

xfont_supported_scripts already skips opening a font if itʼs for
Japanese or Korean. Perhaps we should add tai-viet to that list?

<time passes>

Perhaps we should flip the default of scalable-fonts-allowed to nil
under GNU/Linux? [1]
(unless the only available font-backend is 'x', which can only happen
if the user explicitly sets it that way)?

Robert


Footnotes:
[1]  I only see that variable being checked in xfont.c, but ns-win.el
     refers to it, so I might have missed something.




Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Eli Zaretskii
> From: Robert Pluim <[hidden email]>
> Cc: Andreas Schwab <[hidden email]>,  [hidden email],
>   [hidden email]
> Date: Fri, 04 Sep 2020 09:45:37 +0200
>
>     >> My guess would be that probing fonts via the x backend is expensive due
>     >> to round trips to the X server (and the X server is quite busy during
>     >> that time).
>
>     Eli> If that is the reason, I guess we should try to minimize the number of
>     Eli> fonts for which this is done.  Like, for example, set up some data
>     Eli> structure to be consulted when a deciding whether a given font should
>     Eli> be used with the x backend.  After all, the number of fonts for which
>     Eli> that backend is needed is quite small, basically bitmapped fonts.
>
> xfont_supported_scripts already skips opening a font if itʼs for
> Japanese or Korean. Perhaps we should add tai-viet to that list?

I don't think this would help, because most scripts don't specify
language properties like 'ja' or 'ko', which is what
xfont_supported_scripts uses.

> Perhaps we should flip the default of scalable-fonts-allowed to nil
> under GNU/Linux? [1]
> (unless the only available font-backend is 'x', which can only happen
> if the user explicitly sets it that way)?

That'd be backward-incompatible.  Besides, I think it's too late.  I
think we should do this in font.c, where the 'list' method of each
font backend is called.  There, we should not call the 'x' backend
unless the no fonts were found by the backend called before it.  This
should be controlled by a variable exposed to Lisp, of course.

Does that make sense?



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Robert Pluim
>>>>> On Fri, 04 Sep 2020 15:22:58 +0300, Eli Zaretskii <[hidden email]> said:
    Eli> I don't think this would help, because most scripts don't specify
    Eli> language properties like 'ja' or 'ko', which is what
    Eli> xfont_supported_scripts uses.

ok

    >> Perhaps we should flip the default of scalable-fonts-allowed to nil
    >> under GNU/Linux? [1]
    >> (unless the only available font-backend is 'x', which can only happen
    >> if the user explicitly sets it that way)?

    Eli> That'd be backward-incompatible.  Besides, I think it's too late.  I
    Eli> think we should do this in font.c, where the 'list' method of each
    Eli> font backend is called.  There, we should not call the 'x' backend
    Eli> unless the no fonts were found by the backend called before it.  This
    Eli> should be controlled by a variable exposed to Lisp, of course.

    Eli> Does that make sense?

Yes. Something like the following works, and makes displaying
etc/HELLO quite a bit faster.

diff --git a/src/font.c b/src/font.c
index 2786a772dc..6bff3a7362 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2810,7 +2810,13 @@ font_list_entities (struct frame *f, Lisp_Object spec)
  || ! NILP (Vface_ignored_fonts)))
   val = font_delete_unmatched (val, need_filtering ? spec : Qnil, size);
  if (ASIZE (val) > 0)
-  list = Fcons (val, list);
+          {
+            list = Fcons (val, list);
+            /* Querying further backends can be very slow, so we only do
+               it if the user has explicitly requested it (Bug#43177).  */
+            if (query_all_font_backends == false)
+              break;
+          }
       }
 
   list = Fnreverse (list);
@@ -5527,6 +5533,13 @@ syms_of_font (void)
 cause Xft crashes.  Only has an effect in Xft builds.  */);
   xft_ignore_color_fonts = true;
 
+  DEFVAR_BOOL ("query-all-font-backends", query_all_font_backends,
+               doc: /*
+Non-nil means attempt to query all available font backends when
+looking up a font, otherwise stop as soon as a suitable font has been
+found.  */);
+  query_all_font_backends = false;
+
 #ifdef HAVE_WINDOW_SYSTEM
 #ifdef HAVE_FREETYPE
   syms_of_ftfont ();





Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Eli Zaretskii
> From: Robert Pluim <[hidden email]>
> Cc: [hidden email],  [hidden email],
>   [hidden email]
> Date: Fri, 04 Sep 2020 15:05:52 +0200
>
> +          {
> +            list = Fcons (val, list);
> +            /* Querying further backends can be very slow, so we only do
> +               it if the user has explicitly requested it (Bug#43177).  */
> +            if (query_all_font_backends == false)
> +              break;
> +          }

Shouldn't we query those other backends if the first one couldn't find
a font, even if the variable is nil?  Otherwise, this change could
cause regressions in some (hopefully rare) cases, whereby some
characters will display as hex codes where previously they were shown
using some font.



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Robert Pluim
>>>>> On Fri, 04 Sep 2020 16:30:41 +0300, Eli Zaretskii <[hidden email]> said:

    >> From: Robert Pluim <[hidden email]>
    >> Cc: [hidden email],  [hidden email],
    >> [hidden email]
    >> Date: Fri, 04 Sep 2020 15:05:52 +0200
    >>
    >> +          {
    >> +            list = Fcons (val, list);
    >> +            /* Querying further backends can be very slow, so we only do
    >> +               it if the user has explicitly requested it (Bug#43177).  */
    >> +            if (query_all_font_backends == false)
    >> +              break;
    >> +          }

    Eli> Shouldn't we query those other backends if the first one couldn't find
    Eli> a font, even if the variable is nil?  Otherwise, this change could
    Eli> cause regressions in some (hopefully rare) cases, whereby some
    Eli> characters will display as hex codes where previously they were shown
    Eli> using some font.

Thatʼs what this does. The variable is only checked if (ASIZE(val) >
0), if we find zero fonts we go to the next backend.

I tested it before I sent the patch :-)

Hereʼs what I get for Cantonese in etc/HELLO:

              display: by this font (glyph code)
    ftcrhb:-GOOG-Noto Sans CJK KR-normal-normal-normal-*-13-*-*-*-*-0-iso10646-1 (#x4F01)

And hereʼs what I get for Korean:

              display: by this font (glyph code)
    x:-daewoo-mincho-medium-r-normal--16-120-100-100-c-160-ksc5601.1987-0
    (#x3E4

Robert



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Eli Zaretskii
> From: Robert Pluim <[hidden email]>
> Cc: [hidden email],  [hidden email],
>   [hidden email]
> Date: Fri, 04 Sep 2020 16:04:35 +0200
>
>     Eli> Shouldn't we query those other backends if the first one couldn't find
>     Eli> a font, even if the variable is nil?  Otherwise, this change could
>     Eli> cause regressions in some (hopefully rare) cases, whereby some
>     Eli> characters will display as hex codes where previously they were shown
>     Eli> using some font.
>
> Thatʼs what this does.

Then I guess we should install it.



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Robert Pluim
>>>>> On Fri, 04 Sep 2020 20:26:15 +0300, Eli Zaretskii <[hidden email]> said:

    >> From: Robert Pluim <[hidden email]>
    >> Cc: [hidden email],  [hidden email],
    >> [hidden email]
    >> Date: Fri, 04 Sep 2020 16:04:35 +0200
    >>
    Eli> Shouldn't we query those other backends if the first one couldn't find
    Eli> a font, even if the variable is nil?  Otherwise, this change could
    Eli> cause regressions in some (hopefully rare) cases, whereby some
    Eli> characters will display as hex codes where previously they were shown
    Eli> using some font.
    >>
    >> Thatʼs what this does.

    Eli> Then I guess we should install it.

If anyone wants me to change the name or the verbiage, speak up,
otherwise Iʼll push this tomorrow.

diff --git a/etc/NEWS b/etc/NEWS
index f0644c8ea9..f45cb86175 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -98,7 +98,14 @@ specify 'cursor-type' to be '(box . SIZE)', the cursor becomes a hollow
 box if the point is on an image larger than 'SIZE' pixels in any
 dimension.
 
-+++
+** Fonts are no longer always searched for in all available backends.
+Previously, when looking for a matching font, Emacs would check all
+the available font backends, even if it had already found a match.
+This could cause slowdowns with large numbers of fonts installed, and
+in most cases the font found by later backends was never used.  This
+behavior can be changed by setting 'font-query-all-backends' to t.
+
++++
 ** New user option 'word-wrap-by-category'.
 When word-wrap is enabled, and this option is non-nil, that allows
 Emacs to break lines after more characters than just whitespace
diff --git a/src/font.c b/src/font.c
index 2786a772dc..779b852096 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2810,7 +2810,13 @@ font_list_entities (struct frame *f, Lisp_Object spec)
  || ! NILP (Vface_ignored_fonts)))
   val = font_delete_unmatched (val, need_filtering ? spec : Qnil, size);
  if (ASIZE (val) > 0)
-  list = Fcons (val, list);
+          {
+            list = Fcons (val, list);
+            /* Querying further backends can be very slow, so we only do
+               it if the user has explicitly requested it (Bug#43177).  */
+            if (query_all_font_backends == false)
+              break;
+          }
       }
 
   list = Fnreverse (list);
@@ -5527,6 +5533,13 @@ syms_of_font (void)
 cause Xft crashes.  Only has an effect in Xft builds.  */);
   xft_ignore_color_fonts = true;
 
+  DEFVAR_BOOL ("query-all-font-backends", query_all_font_backends,
+               doc: /*
+If non-nil attempt to query all available font backends.
+By default Emacs will stop searching for a matching font at the first
+match.  */);
+  query_all_font_backends = false;
+
 #ifdef HAVE_WINDOW_SYSTEM
 #ifdef HAVE_FREETYPE
   syms_of_ftfont ();



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Robert Pluim
>>>>> On Mon, 7 Sep 2020 14:41:13 +0000, Pip Cet <[hidden email]> said:
    >> +in most cases the font found by later backends was never used.  This
    >> +behavior can be changed by setting 'font-query-all-backends' to t.

    Pip> It says "font-query-all-backends" here ...

    >> +  DEFVAR_BOOL ("query-all-font-backends", query_all_font_backends,

    Pip> ... but "query-all-font-backends" here.

Thanks, fixed (who was it that said that the way to get the right
answer to a question was to post the wrong one to the Internet?)

Robert



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Eli Zaretskii
In reply to this post by Robert Pluim
> From: Robert Pluim <[hidden email]>
> Cc: [hidden email],  [hidden email],
>   [hidden email]
> Date: Mon, 07 Sep 2020 16:18:07 +0200
>
>     Eli> Then I guess we should install it.
>
> If anyone wants me to change the name or the verbiage, speak up,
> otherwise Iʼll push this tomorrow.

Speaking up:

> +** Fonts are no longer always searched for in all available backends.
> +Previously, when looking for a matching font, Emacs would check all
> +the available font backends, even if it had already found a match.
> +This could cause slowdowns with large numbers of fonts installed, and
> +in most cases the font found by later backends was never used.  This
> +behavior can be changed by setting 'font-query-all-backends' to t.

Please include in the text the description of the new behavior.  It is
hinted by what the text says, but I'd rather we said that explicitly.
Also, the last sentence would be more clear, IMO, if it started with
"To get back the old behavior, set ...".

And finally, I think you can mark this entry with "---", as I don't
think it should be in the manual.

Thanks.



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Robert Pluim
>>>>> On Mon, 07 Sep 2020 17:49:24 +0300, Eli Zaretskii <[hidden email]> said:
    Eli> Please include in the text the description of the new behavior.  It is
    Eli> hinted by what the text says, but I'd rather we said that explicitly.
    Eli> Also, the last sentence would be more clear, IMO, if it started with
    Eli> "To get back the old behavior, set ...".

Yes, that does read better. Fixed

    Eli> And finally, I think you can mark this entry with "---", as I don't
    Eli> think it should be in the manual.

Done

Robert



Reply | Threaded
Open this post in threaded view
|

bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

Robert Pluim
>>>>> On Mon, 07 Sep 2020 17:06:03 +0200, Robert Pluim <[hidden email]> said:

>>>>> On Mon, 07 Sep 2020 17:49:24 +0300, Eli Zaretskii <[hidden email]> said:
    Eli> Please include in the text the description of the new behavior.  It is
    Eli> hinted by what the text says, but I'd rather we said that explicitly.
    Eli> Also, the last sentence would be more clear, IMO, if it started with
    Eli> "To get back the old behavior, set ...".

    Robert> Yes, that does read better. Fixed

    Eli> And finally, I think you can mark this entry with "---", as I don't
    Eli> think it should be in the manual.

    Robert> Done

And now pushed to master as 20d13e424f

Closing (I donʼt think we can do anything about the Adobe font issue
in Emacs).



12