After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 687882 - loads and parses CSS background/border/etc. images in the main thread
loads and parses CSS background/border/etc. images in the main thread
Status: RESOLVED OBSOLETE
Product: gnome-shell
Classification: Core
Component: st
3.6.x
Other Linux
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on:
Blocks: 687362
 
 
Reported: 2012-11-07 20:24 UTC by Simon McVittie
Modified: 2021-07-05 14:03 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Simon McVittie 2012-11-07 20:24:05 UTC
+++ This bug was initially created as a clone of Bug #687362 +++

St loads resources referenced by CSS in the main thread:

31106 1352317144.712156 access("GLib-GIO-START: g_local_file_read: /home/jhbuild/usr/share/gnome-shell/theme/panel-button-highlight-wide.svg", F_OK) = -1 ENOENT (No such file or directory) <0.000029>
31106 1352317144.712254 open("/home/jhbuild/usr/share/gnome-shell/theme/panel-button-highlight-wide.svg", O_RDONLY) = 23 <0.000030>
31106 1352317144.712342 fstat(23, {st_mode=S_IFREG|0644, st_size=3580, ...}) = 0 <0.000025>
31106 1352317144.712434 access("GLib-GIO-END: g_local_file_read: /home/jhbuild/usr/share/gnome-shell/theme/panel-button-highlight-wide.svg", F_OK) = -1 ENOENT (No such file or directory) <0.000027>
31106 1352317144.712536 access("GLib-GIO-START: g_local_file_input_stream_read: 0x4446f00", F_OK) = -1 ENOENT (No such file or directory) <0.000031>
31106 1352317144.712624 read(23, "<?xml version=\"1.0\" encoding=\"UT"..., 8192) = 3580 <0.000033>
31106 1352317144.712711 access("GLib-GIO-END: g_local_file_input_stream_read: 0x4446f00 -> 3580", F_OK) = -1 ENOENT (No such file or directory) <0.000029>
31106 1352317144.712801 access("GLib-GIO-START: g_local_file_input_stream_read: 0x4446f00", F_OK) = -1 ENOENT (No such file or directory) <0.000027>
31106 1352317144.712883 read(23, "", 8192) = 0 <0.000025>
31106 1352317144.712959 access("GLib-GIO-END: g_local_file_input_stream_read: 0x4446f00 -> 0", F_OK) = -1 ENOENT (No such file or directory) <0.000029>
31106 1352317144.713047 access("GLib-GIO-START: g_local_file_input_stream_close: 0x4446f00", F_OK) = -1 ENOENT (No such file or directory) <0.000030>
31106 1352317144.713132 close(23)       = 0 <0.000026>
31106 1352317144.713205 access("GLib-GIO-END: g_local_file_input_stream_close: 0x4446f00 -> success", F_OK) = -1 ENOENT (No such file or directory) <0.000029>

(This example is from strace'ing Bug #687465.)

I don't see any mutex contention here, so I suspect that it's also parsing and rendering these SVGs in the main thread.

It would be nice if the compositor didn't have to become unresponsive while waiting for I/O. I realise that fixing this is non-trivial, because the compositor needs to draw things, and to do that, it needs these images to be ready...
Comment 1 Simon McVittie 2012-11-07 20:35:26 UTC
Complicating factors:

* Until we use the image, we don't know whether it's going to have to be
  a Cairo surface or a COGL texture. I assume having each image in
  both formats is probably a bad move?

* Presumably only the main thread can upload textures to the GPU? which
  would mean we could load (and render) the images as pixbufs from a
  worker thread, but then we'd have to pass those into the main thread
  to turn them into Cairo surfaces and/or COGL textures. We presumably
  don't want to keep the pixbuf afterwards, unless we later realise
  that we really wanted this particular texture in both formats.

* When the main thread draws (e.g.) a menu, it wants all the images
  needed for that menu, synchronously - so if we loaded the textures
  "idly", we'd need a mechanism for "wait for at least this set of textures",
  and possibly "prioritize these textures".

* We could solve many of those by precaching every image referenced by the
  CSS before drawing our first frame - but that hurts the "time to log in"
  metric, which I also want to try to improve.
Comment 2 Jasper St. Pierre (not reading bugmail) 2012-11-07 21:28:12 UTC
We can't punt SVG rendering to a separate worker thread yet, until pango becomes thread-safe.
Comment 3 Simon McVittie 2012-11-08 11:12:15 UTC
(In reply to comment #2)
> We can't punt SVG rendering to a separate worker thread yet

Thanks, that's useful to know.

Blocking on I/O and rendering during Shell startup still seems like a possibility: it would hurt startup time (I'll try to benchmark how much), but would prevent unexpected blocking later.

Another possible way to load the images before they're needed would be to do the I/O in a thread, and pass the file's contents to the main thread to be rendered and turned into a texture/surface in an idle (which would spread out the blocking over multiple frames, at least). The actual I/O could even continue to block, and happen in an idle in the same way, if necessary? What I'm mainly trying to avoid is "user does something, Shell becomes unresponsive for half a second while it thinks about it".
Comment 4 Jasper St. Pierre (not reading bugmail) 2012-12-06 06:41:09 UTC
(In reply to comment #1)
> Complicating factors:
> 
> * Until we use the image, we don't know whether it's going to have to be
>   a Cairo surface or a COGL texture. I assume having each image in
>   both formats is probably a bad move?

Not quite true. We know based on the complications of the CSS. It's probably also possible to put more things on the GPU, right now we just have a slow cairo fallback for simplicity. It's also entirely possible through things like hover states to have to render the texture as both cogl and cairo othertimes. We should detect these cases so we hold onto both.

> * Presumably only the main thread can upload textures to the GPU? which
>   would mean we could load (and render) the images as pixbufs from a
>   worker thread, but then we'd have to pass those into the main thread
>   to turn them into Cairo surfaces and/or COGL textures. We presumably
>   don't want to keep the pixbuf afterwards, unless we later realise
>   that we really wanted this particular texture in both formats.

Owen would have to be the expert on this, and how much uploading textures to the GPU "costs" in terms of perf. As said above, we want to keep the pixbuf if we know about cairo usage, so we don't have to reload switching between cairo / cogl usage.

> * When the main thread draws (e.g.) a menu, it wants all the images
>   needed for that menu, synchronously - so if we loaded the textures
>   "idly", we'd need a mechanism for "wait for at least this set of textures",
>   and possibly "prioritize these textures".

Yeah. What do we show until the image is loaded? Blank nothing that we fill in later? Should we render simple borders and backgrounds, or just leave the entire thing blank?
Comment 5 Jasper St. Pierre (not reading bugmail) 2013-08-05 04:45:23 UTC
Another option is to take the GTK+ approach and prerender all theme assets as compressed data in a gresource.
Comment 6 GNOME Infrastructure Team 2021-07-05 14:03:41 UTC
GNOME is going to shut down bugzilla.gnome.org in favor of  gitlab.gnome.org.
As part of that, we are mass-closing older open tickets in bugzilla.gnome.org
which have not seen updates for a longer time (resources are unfortunately
quite limited so not every ticket can get handled).

If you can still reproduce the situation described in this ticket in a recent
and supported software version, then please follow
  https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines
and create a new ticket at
  https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/

Thank you for your understanding and your help.