Bug 1595767 - Don't use rayon for glyph rasterization unless there is a lot of glyphs to rasterize r=nical
authorBert Peers <bpeers@mozilla.com>
Tue, 07 Jan 2020 17:30:14 +0000
changeset 509145 29584a35d69ae2c8bb157702be402733fc0ce176
parent 509144 1a8dc8ffd7374ca12ad36d92abc0bca3e06c9eaa
child 509146 23d862866f3a55716b89230e5440213ae56df178
push id36993
push userdluca@mozilla.com
push dateWed, 08 Jan 2020 09:41:58 +0000
treeherdermozilla-central@12fb5e522dd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1595767
milestone74.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1595767 - Don't use rayon for glyph rasterization unless there is a lot of glyphs to rasterize r=nical Differential Revision: https://phabricator.services.mozilla.com/D57005
gfx/wr/webrender/src/glyph_rasterizer/mod.rs
--- a/gfx/wr/webrender/src/glyph_rasterizer/mod.rs
+++ b/gfx/wr/webrender/src/glyph_rasterizer/mod.rs
@@ -107,65 +107,76 @@ impl GlyphRasterizer {
 
         self.request_glyphs_from_backend(font, new_glyphs);
     }
 
     pub(in super) fn request_glyphs_from_backend(&mut self, font: FontInstance, glyphs: Vec<GlyphKey>) {
         let font_contexts = Arc::clone(&self.font_contexts);
         let glyph_tx = self.glyph_tx.clone();
 
-        // spawn an async task to get off of the render backend thread as early as
-        // possible and in that task use rayon's fork join dispatch to rasterize the
-        // glyphs in the thread pool.
-        self.workers.spawn(move || {
-            let jobs = glyphs
-                .par_iter()
-                .map(|key: &GlyphKey| {
-                    profile_scope!("glyph-raster");
-                    let mut context = font_contexts.lock_current_context();
-                    let mut job = GlyphRasterJob {
-                        key: key.clone(),
-                        result: context.rasterize_glyph(&font, key),
-                    };
+        fn process_glyph(key: &GlyphKey, font_contexts: &FontContexts, font: &FontInstance) -> GlyphRasterJob {
+            profile_scope!("glyph-raster");
+            let mut context = font_contexts.lock_current_context();
+            let mut job = GlyphRasterJob {
+                key: key.clone(),
+                result: context.rasterize_glyph(&font, key),
+            };
 
-                    if let Ok(ref mut glyph) = job.result {
-                        // Sanity check.
-                        let bpp = 4; // We always render glyphs in 32 bits RGBA format.
-                        assert_eq!(
-                            glyph.bytes.len(),
-                            bpp * (glyph.width * glyph.height) as usize
-                        );
+            if let Ok(ref mut glyph) = job.result {
+                // Sanity check.
+                let bpp = 4; // We always render glyphs in 32 bits RGBA format.
+                assert_eq!(
+                    glyph.bytes.len(),
+                    bpp * (glyph.width * glyph.height) as usize
+                );
+
+                // a quick-and-dirty monochrome over
+                fn over(dst: u8, src: u8) -> u8 {
+                    let a = src as u32;
+                    let a = 256 - a;
+                    let dst = ((dst as u32 * a) >> 8) as u8;
+                    src + dst
+                }
 
-                        // a quick-and-dirty monochrome over
-                        fn over(dst: u8, src: u8) -> u8 {
-                            let a = src as u32;
-                            let a = 256 - a;
-                            let dst = ((dst as u32 * a) >> 8) as u8;
-                            src + dst
-                        }
+                if GLYPH_FLASHING.load(Ordering::Relaxed) {
+                    let color = (random() & 0xff) as u8;
+                    for i in &mut glyph.bytes {
+                        *i = over(*i, color);
+                    }
+                }
+
+                assert_eq!((glyph.left.fract(), glyph.top.fract()), (0.0, 0.0));
+
+                // Check if the glyph has a bitmap that needs to be downscaled.
+                glyph.downscale_bitmap_if_required(&font);
+            }
+
+            job
+        }
 
-                        if GLYPH_FLASHING.load(Ordering::Relaxed) {
-                            let color = (random() & 0xff) as u8;
-                            for i in &mut glyph.bytes {
-                                *i = over(*i, color);
-                            }
-                        }
-
-                        assert_eq!((glyph.left.fract(), glyph.top.fract()), (0.0, 0.0));
+        // if the number of glyphs is small, do it inline to avoid the threading overhead;
+        // send the result into glyph_tx so downstream code can't tell the difference.
+        if glyphs.len() < 8 {
+            let jobs = glyphs.iter()
+                             .map(|key: &GlyphKey| process_glyph(key, &font_contexts, &font))
+                             .collect();
+            glyph_tx.send(GlyphRasterJobs { font, jobs }).unwrap();
+        } else {
+            // spawn an async task to get off of the render backend thread as early as
+            // possible and in that task use rayon's fork join dispatch to rasterize the
+            // glyphs in the thread pool.
+            self.workers.spawn(move || {
+                let jobs = glyphs
+                    .par_iter()
+                    .map(|key: &GlyphKey| process_glyph(key, &font_contexts, &font))
+                    .collect();
 
-                        // Check if the glyph has a bitmap that needs to be downscaled.
-                        glyph.downscale_bitmap_if_required(&font);
-                    }
-
-                    job
-                })
-                .collect();
-
-            glyph_tx.send(GlyphRasterJobs { font, jobs }).unwrap();
-        });
+                glyph_tx.send(GlyphRasterJobs { font, jobs }).unwrap();
+            });
+        }
     }
 
     pub fn resolve_glyphs(
         &mut self,
         glyph_cache: &mut GlyphCache,
         texture_cache: &mut TextureCache,
         gpu_cache: &mut GpuCache,
         _: &mut RenderTaskCache,