Bug 1420275 - Cherry-pick WR PR 2094 to fix frequent crasher. r?kats draft
authorLee Salzman <lsalzman@mozilla.com>
Thu, 23 Nov 2017 16:23:04 -0500
changeset 702876 14cfba97017fa68eb95bb8a12fef716375e1a8b4
parent 702875 d4779e0fdbbba3291ca8c858a051fc979c5b7a3f
child 741590 454fb82b41b6bc0bda567a7eee1d26754dffb931
push id90622
push userkgupta@mozilla.com
push dateThu, 23 Nov 2017 22:05:12 +0000
reviewerskats
bugs1420275
milestone59.0a1
Bug 1420275 - Cherry-pick WR PR 2094 to fix frequent crasher. r?kats MozReview-Commit-ID: EMczYB1JzlF
gfx/webrender/src/frame_builder.rs
gfx/webrender/src/prim_store.rs
gfx/webrender/src/tiling.rs
--- a/gfx/webrender/src/frame_builder.rs
+++ b/gfx/webrender/src/frame_builder.rs
@@ -20,17 +20,17 @@ use clip_scroll_tree::ClipScrollTree;
 use euclid::{SideOffsets2D, vec2};
 use frame::FrameId;
 use glyph_rasterizer::FontInstance;
 use gpu_cache::GpuCache;
 use internal_types::{FastHashMap, FastHashSet};
 use picture::{PictureCompositeMode, PictureKind, PicturePrimitive, RasterizationSpace};
 use prim_store::{TexelRect, YuvImagePrimitiveCpu};
 use prim_store::{GradientPrimitiveCpu, ImagePrimitiveCpu, LinePrimitive, PrimitiveKind};
-use prim_store::{PrimitiveContainer, PrimitiveIndex};
+use prim_store::{PrimitiveContainer, PrimitiveIndex, SpecificPrimitiveIndex};
 use prim_store::{PrimitiveStore, RadialGradientPrimitiveCpu};
 use prim_store::{RectangleContent, RectanglePrimitive, TextRunPrimitiveCpu};
 use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters};
 use render_task::{ClearMode, RenderTask, RenderTaskId, RenderTaskTree};
 use resource_cache::ResourceCache;
 use scene::{ScenePipeline, SceneProperties};
 use std::{mem, usize, f32};
 use tiling::{CompositeOps, Frame};
@@ -1577,16 +1577,17 @@ impl FrameBuilder {
             clip_scroll_tree,
             pipelines,
             &root_prim_context,
             true,
             &mut child_tasks,
             profile_counters,
             None,
             scene_properties,
+            SpecificPrimitiveIndex(0),
         );
 
         let pic = &mut self.prim_store.cpu_pictures[0];
         pic.runs = prim_run_cmds;
 
         let root_render_task = RenderTask::new_picture(
             None,
             PrimitiveIndex(0),
--- a/gfx/webrender/src/prim_store.rs
+++ b/gfx/webrender/src/prim_store.rs
@@ -11,17 +11,17 @@ use api::{ClipId, LayerTransform, Pipeli
 use border::BorderCornerInstance;
 use clip_scroll_tree::ClipScrollTree;
 use clip::{ClipSourcesHandle, ClipStore};
 use frame_builder::PrimitiveContext;
 use glyph_rasterizer::{FontInstance, FontTransform};
 use internal_types::FastHashMap;
 use gpu_cache::{GpuBlockData, GpuCache, GpuCacheAddress, GpuCacheHandle, GpuDataRequest,
                 ToGpuBlocks};
-use picture::{PictureKind, PicturePrimitive};
+use picture::{PictureKind, PicturePrimitive, RasterizationSpace};
 use profiler::FrameProfileCounters;
 use render_task::{ClipWorkItem, ClipChainNode};
 use render_task::{RenderTask, RenderTaskId, RenderTaskTree};
 use renderer::MAX_VERTEX_TEXTURE_WIDTH;
 use resource_cache::{ImageProperties, ResourceCache};
 use scene::{ScenePipeline, SceneProperties};
 use std::{mem, usize};
 use std::rc::Rc;
@@ -590,38 +590,43 @@ pub struct TextRunPrimitiveCpu {
 }
 
 
 impl TextRunPrimitiveCpu {
     pub fn get_font(
         &self,
         device_pixel_ratio: f32,
         transform: &LayerToWorldTransform,
+        rasterization_kind: RasterizationSpace,
     ) -> FontInstance {
         let mut font = self.font.clone();
         font.size = font.size.scale_by(device_pixel_ratio);
-        if font.render_mode == FontRenderMode::Subpixel {
-            if transform.has_perspective_component() || !transform.has_2d_inverse() {
-                font.render_mode = FontRenderMode::Alpha;
-            } else {
-                font.transform = FontTransform::from(transform).quantize();
+        match (font.render_mode, rasterization_kind) {
+            (FontRenderMode::Subpixel, RasterizationSpace::Screen) => {
+                if transform.has_perspective_component() || !transform.has_2d_inverse() {
+                    font.render_mode = FontRenderMode::Alpha;
+                } else {
+                    font.transform = FontTransform::from(transform).quantize();
+                }
             }
+            _ => {}
         }
         font
     }
 
     fn prepare_for_render(
         &mut self,
         resource_cache: &mut ResourceCache,
         device_pixel_ratio: f32,
         transform: &LayerToWorldTransform,
         display_list: &BuiltDisplayList,
         gpu_cache: &mut GpuCache,
+        rasterization_kind: RasterizationSpace,
     ) {
-        let font = self.get_font(device_pixel_ratio, transform);
+        let font = self.get_font(device_pixel_ratio, transform, rasterization_kind);
 
         // Cache the glyph positions, if not in the cache already.
         // TODO(gw): In the future, remove `glyph_instances`
         //           completely, and just reference the glyphs
         //           directly from the display list.
         if self.glyph_keys.is_empty() {
             let subpx_dir = font.subpx_dir.limit_by(font.render_mode);
             let src_glyphs = display_list.get(self.glyph_range);
@@ -1097,39 +1102,42 @@ impl PrimitiveStore {
         &mut self,
         prim_index: PrimitiveIndex,
         prim_context: &PrimitiveContext,
         resource_cache: &mut ResourceCache,
         gpu_cache: &mut GpuCache,
         render_tasks: &mut RenderTaskTree,
         child_tasks: Vec<RenderTaskId>,
         parent_tasks: &mut Vec<RenderTaskId>,
+        pic_index: SpecificPrimitiveIndex,
     ) {
         let metadata = &mut self.cpu_metadata[prim_index.0];
         match metadata.prim_kind {
             PrimitiveKind::Rectangle | PrimitiveKind::Border | PrimitiveKind::Line => {}
             PrimitiveKind::Picture => {
                 self.cpu_pictures[metadata.cpu_prim_index.0]
                     .prepare_for_render(
                         prim_index,
                         prim_context,
                         render_tasks,
                         metadata.screen_rect.as_ref().expect("bug: trying to draw an off-screen picture!?"),
                         child_tasks,
                         parent_tasks,
                     );
             }
             PrimitiveKind::TextRun => {
+                let pic = &self.cpu_pictures[pic_index.0];
                 let text = &mut self.cpu_text_runs[metadata.cpu_prim_index.0];
                 text.prepare_for_render(
                     resource_cache,
                     prim_context.device_pixel_ratio,
                     &prim_context.scroll_node.world_content_transform,
                     prim_context.display_list,
                     gpu_cache,
+                    pic.rasterization_kind,
                 );
             }
             PrimitiveKind::Image => {
                 let image_cpu = &mut self.cpu_images[metadata.cpu_prim_index.0];
 
                 resource_cache.request_image(
                     image_cpu.image_key,
                     image_cpu.image_rendering,
@@ -1310,16 +1318,17 @@ impl PrimitiveStore {
         render_tasks: &mut RenderTaskTree,
         clip_store: &mut ClipStore,
         clip_scroll_tree: &ClipScrollTree,
         pipelines: &FastHashMap<PipelineId, ScenePipeline>,
         perform_culling: bool,
         parent_tasks: &mut Vec<RenderTaskId>,
         scene_properties: &SceneProperties,
         profile_counters: &mut FrameProfileCounters,
+        pic_index: SpecificPrimitiveIndex,
     ) -> Option<LayerRect> {
         // Reset the visibility of this primitive.
         // Do some basic checks first, that can early out
         // without even knowing the local rect.
         let (cpu_prim_index, dependencies, cull_children) = {
             let metadata = &mut self.cpu_metadata[prim_index.0];
             metadata.screen_rect = None;
 
@@ -1368,16 +1377,17 @@ impl PrimitiveStore {
                 clip_scroll_tree,
                 pipelines,
                 prim_context,
                 cull_children,
                 &mut child_tasks,
                 profile_counters,
                 rfid,
                 scene_properties,
+                cpu_prim_index,
             );
 
             let metadata = &mut self.cpu_metadata[prim_index.0];
 
             // Restore the dependencies (borrow check dance)
             let pic = &mut self.cpu_pictures[cpu_prim_index.0];
             pic.runs = dependencies;
 
@@ -1445,16 +1455,17 @@ impl PrimitiveStore {
         self.prepare_prim_for_render_inner(
             prim_index,
             prim_context,
             resource_cache,
             gpu_cache,
             render_tasks,
             child_tasks,
             parent_tasks,
+            pic_index,
         );
 
         Some(local_rect)
     }
 
     // TODO(gw): Make this simpler / more efficient by tidying
     //           up the logic that early outs from prepare_prim_for_render.
     pub fn reset_prim_visibility(&mut self) {
@@ -1474,16 +1485,17 @@ impl PrimitiveStore {
         clip_scroll_tree: &ClipScrollTree,
         pipelines: &FastHashMap<PipelineId, ScenePipeline>,
         parent_prim_context: &PrimitiveContext,
         perform_culling: bool,
         parent_tasks: &mut Vec<RenderTaskId>,
         profile_counters: &mut FrameProfileCounters,
         original_reference_frame_id: Option<ClipId>,
         scene_properties: &SceneProperties,
+        pic_index: SpecificPrimitiveIndex,
     ) -> PrimitiveRunLocalRect {
         let mut result = PrimitiveRunLocalRect {
             local_rect_in_actual_parent_space: LayerRect::zero(),
             local_rect_in_original_parent_space: LayerRect::zero(),
         };
 
         for run in runs {
             // TODO(gw): Perhaps we can restructure this to not need to create
@@ -1539,16 +1551,17 @@ impl PrimitiveStore {
                     render_tasks,
                     clip_store,
                     clip_scroll_tree,
                     pipelines,
                     perform_culling,
                     parent_tasks,
                     scene_properties,
                     profile_counters,
+                    pic_index,
                 ) {
                     profile_counters.visible_primitives.inc();
 
                     if let Some(ref matrix) = original_relative_transform {
                         let bounds = get_local_bounding_rect(&prim_local_rect, matrix);
                         result.local_rect_in_original_parent_space =
                             result.local_rect_in_original_parent_space.union(&bounds);
                     }
--- a/gfx/webrender/src/tiling.rs
+++ b/gfx/webrender/src/tiling.rs
@@ -15,17 +15,17 @@ use device::Texture;
 use euclid::{TypedTransform3D, vec3};
 use glyph_rasterizer::GlyphFormat;
 use gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle, GpuCacheUpdateList};
 use gpu_types::{BlurDirection, BlurInstance, BrushInstance, BrushImageKind, ClipMaskInstance};
 use gpu_types::{CompositePrimitiveInstance, PrimitiveInstance, SimplePrimitiveInstance};
 use gpu_types::{ClipScrollNodeIndex, ClipScrollNodeData};
 use internal_types::{FastHashMap, SourceTexture};
 use internal_types::BatchTextures;
-use picture::{PictureCompositeMode, PictureKind, PicturePrimitive};
+use picture::{PictureCompositeMode, PictureKind, PicturePrimitive, RasterizationSpace};
 use plane_split::{BspSplitter, Polygon, Splitter};
 use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore};
 use prim_store::{BrushMaskKind, BrushKind, DeferredResolve, PrimitiveRun, RectangleContent};
 use profiler::FrameProfileCounters;
 use render_task::{ClipWorkItem, MaskGeometryKind, MaskSegment};
 use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskKey, RenderTaskKind};
 use render_task::{BlurTask, ClearMode, RenderTaskLocation, RenderTaskTree};
 use renderer::BlendMode;
@@ -542,16 +542,17 @@ fn add_to_batch(
         }
         PrimitiveKind::TextRun => {
             let text_cpu =
                 &ctx.prim_store.cpu_text_runs[prim_metadata.cpu_prim_index.0];
 
             let font = text_cpu.get_font(
                 ctx.device_pixel_ratio,
                 &scroll_node.transform,
+                RasterizationSpace::Screen,
             );
 
             ctx.resource_cache.fetch_glyphs(
                 font,
                 &text_cpu.glyph_keys,
                 glyph_fetch_buffer,
                 gpu_cache,
                 |texture_id, glyph_format, glyphs| {
@@ -1478,16 +1479,17 @@ impl RenderTarget for ColorRenderTarget 
                                                 // the shader to fetch the shadow parameters.
                                                 let text = &ctx.prim_store.cpu_text_runs
                                                     [sub_metadata.cpu_prim_index.0];
                                                 let text_run_cache_prims = &mut self.text_run_cache_prims;
 
                                                 let font = text.get_font(
                                                     ctx.device_pixel_ratio,
                                                     &LayerToWorldTransform::identity(),
+                                                    RasterizationSpace::Local,
                                                 );
 
                                                 ctx.resource_cache.fetch_glyphs(
                                                     font,
                                                     &text.glyph_keys,
                                                     &mut self.glyph_fetch_buffer,
                                                     gpu_cache,
                                                     |texture_id, _glyph_format, glyphs| {