Bug 1518840 - P1: Remove rendering blurs into texture cache. r=gw,emilio
authorDan Glastonbury <dan.glastonbury@gmail.com>
Wed, 23 Jan 2019 23:41:51 +0000
changeset 515210 48cff9538a5ef2a070b0e9e78b373ceb784aaeff
parent 515209 b94e3d7633e2dc5f3ba288a1970b2f24aaf04af1
child 515211 fdb28a194129f4c934681746ded72d8a221fd957
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw, emilio
bugs1518840
milestone66.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 1518840 - P1: Remove rendering blurs into texture cache. r=gw,emilio Caching text-shadows into texture cache was leading to rendering artifacts with missing shadows. Switch to using the picture path for all picture blurs and rely upon picture caching to reduce repetitive work. Differential Revision: https://phabricator.services.mozilla.com/D17329
gfx/wr/webrender/src/picture.rs
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -2664,148 +2664,63 @@ impl PicturePrimitive {
                 surface.tasks.extend(child_tasks);
 
                 return true;
             }
             PictureCompositeMode::Filter(FilterOp::Blur(blur_radius)) => {
                 let blur_std_deviation = blur_radius * frame_context.device_pixel_scale.0;
                 let blur_range = (blur_std_deviation * BLUR_SAMPLE_SCALE).ceil() as i32;
 
-                // We need to choose whether to cache this picture, or draw
-                // it into a temporary render target each frame. If we draw
-                // it into a persistently cached texture, then we want to
-                // draw the whole picture, without clipping it to the screen
-                // dimensions, so that it can be reused as it scrolls into
-                // view etc. However, if the unclipped size of the surface is
-                // too big, then it will be very expensive to draw, and may
-                // even be bigger than the maximum hardware render target
-                // size. In these cases, it's probably best to not cache the
-                // picture, and just draw a minimal portion of the picture
-                // (clipped to screen bounds) to a temporary target each frame.
-
-                let too_big_to_cache = unclipped.size.width > MAX_CACHE_SIZE ||
-                                       unclipped.size.height > MAX_CACHE_SIZE;
-
-                // If we can't create a valid cache key for this descriptor (e.g.
-                // due to it referencing old non-interned style primitives), then
-                // don't try to cache it.
-                let has_valid_cache_key = self.surface_desc.is_some();
-
-                if !has_valid_cache_key ||
-                   too_big_to_cache ||
-                   !pic_state_for_children.is_cacheable {
-                    // The clipped field is the part of the picture that is visible
-                    // on screen. The unclipped field is the screen-space rect of
-                    // the complete picture, if no screen / clip-chain was applied
-                    // (this includes the extra space for blur region). To ensure
-                    // that we draw a large enough part of the picture to get correct
-                    // blur results, inflate that clipped area by the blur range, and
-                    // then intersect with the total screen rect, to minimize the
-                    // allocation size.
-                    let device_rect = clipped
-                        .inflate(blur_range, blur_range)
-                        .intersection(&unclipped.to_i32())
-                        .unwrap();
-
-                    let uv_rect_kind = calculate_uv_rect_kind(
-                        &pic_rect,
-                        &transform,
-                        &device_rect,
-                        frame_context.device_pixel_scale,
-                        true,
-                    );
-
-                    let picture_task = RenderTask::new_picture(
-                        RenderTaskLocation::Dynamic(None, device_rect.size),
-                        unclipped.size,
-                        pic_index,
-                        device_rect.origin,
-                        child_tasks,
-                        uv_rect_kind,
-                        pic_context.raster_spatial_node_index,
-                        None,
-                    );
-
-                    let picture_task_id = frame_state.render_tasks.add(picture_task);
-
-                    let blur_render_task = RenderTask::new_blur(
-                        blur_std_deviation,
-                        picture_task_id,
-                        frame_state.render_tasks,
-                        RenderTargetKind::Color,
-                        ClearMode::Transparent,
-                    );
-
-                    let render_task_id = frame_state.render_tasks.add(blur_render_task);
-
-                    surfaces[surface_index.0].tasks.push(render_task_id);
-
-                    PictureSurface::RenderTask(render_task_id)
-                } else {
-                    // Request a render task that will cache the output in the
-                    // texture cache.
-                    let device_rect = unclipped.to_i32();
-
-                    let uv_rect_kind = calculate_uv_rect_kind(
-                        &pic_rect,
-                        &transform,
-                        &device_rect,
-                        frame_context.device_pixel_scale,
-                        true,
-                    );
-
-                    // TODO(gw): Probably worth changing the render task caching API
-                    //           so that we don't need to always clone the key.
-                    let cache_key = self.surface_desc
-                        .as_ref()
-                        .expect("bug: no cache key for surface")
-                        .cache_key
-                        .clone();
-
-                    let cache_item = frame_state.resource_cache.request_render_task(
-                        RenderTaskCacheKey {
-                            size: device_rect.size,
-                            kind: RenderTaskCacheKeyKind::Picture(cache_key),
-                        },
-                        frame_state.gpu_cache,
-                        frame_state.render_tasks,
-                        None,
-                        false,
-                        |render_tasks| {
-                            let picture_task = RenderTask::new_picture(
-                                RenderTaskLocation::Dynamic(None, device_rect.size),
-                                unclipped.size,
-                                pic_index,
-                                device_rect.origin,
-                                child_tasks,
-                                uv_rect_kind,
-                                pic_context.raster_spatial_node_index,
-                                None,
-                            );
-
-                            let picture_task_id = render_tasks.add(picture_task);
-
-                            let blur_render_task = RenderTask::new_blur(
-                                blur_std_deviation,
-                                picture_task_id,
-                                render_tasks,
-                                RenderTargetKind::Color,
-                                ClearMode::Transparent,
-                            );
-
-                            let render_task_id = render_tasks.add(blur_render_task);
-
-                            surfaces[surface_index.0].tasks.push(render_task_id);
-
-                            render_task_id
-                        }
-                    );
-
-                    PictureSurface::TextureCache(cache_item)
-                }
+                // The clipped field is the part of the picture that is visible
+                // on screen. The unclipped field is the screen-space rect of
+                // the complete picture, if no screen / clip-chain was applied
+                // (this includes the extra space for blur region). To ensure
+                // that we draw a large enough part of the picture to get correct
+                // blur results, inflate that clipped area by the blur range, and
+                // then intersect with the total screen rect, to minimize the
+                // allocation size.
+                let device_rect = clipped
+                    .inflate(blur_range, blur_range)
+                    .intersection(&unclipped.to_i32())
+                    .unwrap();
+
+                let uv_rect_kind = calculate_uv_rect_kind(
+                    &pic_rect,
+                    &transform,
+                    &device_rect,
+                    frame_context.device_pixel_scale,
+                    true,
+                );
+
+                let picture_task = RenderTask::new_picture(
+                    RenderTaskLocation::Dynamic(None, device_rect.size),
+                    unclipped.size,
+                    pic_index,
+                    device_rect.origin,
+                    child_tasks,
+                    uv_rect_kind,
+                    pic_context.raster_spatial_node_index,
+                    None,
+                );
+
+                let picture_task_id = frame_state.render_tasks.add(picture_task);
+
+                let blur_render_task = RenderTask::new_blur(
+                    blur_std_deviation,
+                    picture_task_id,
+                    frame_state.render_tasks,
+                    RenderTargetKind::Color,
+                    ClearMode::Transparent,
+                );
+
+                let render_task_id = frame_state.render_tasks.add(blur_render_task);
+
+                surfaces[surface_index.0].tasks.push(render_task_id);
+
+                PictureSurface::RenderTask(render_task_id)
             }
             PictureCompositeMode::Filter(FilterOp::DropShadow(offset, blur_radius, color)) => {
                 let blur_std_deviation = blur_radius * frame_context.device_pixel_scale.0;
                 let blur_range = (blur_std_deviation * BLUR_SAMPLE_SCALE).ceil() as i32;
 
                 // The clipped field is the part of the picture that is visible
                 // on screen. The unclipped field is the screen-space rect of
                 // the complete picture, if no screen / clip-chain was applied