зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1590284 - Construct picture cache slices for scroll roots. r=kvark
With this patch, picture cache slices are constructed each time a new scroll root is established. This reduces rasterization cost on pages that have large fixed position elements, and pages that contain multiple scroll roots. Differential Revision: https://phabricator.services.mozilla.com/D50026 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a05e2f5d41
Коммит
16bde5fcfd
|
@ -18,7 +18,7 @@ use crate::picture::{PictureUpdateState, SurfaceInfo, ROOT_SURFACE_INDEX, Surfac
|
|||
use crate::picture::{RetainedTiles, TileCacheInstance, DirtyRegion, SurfaceRenderTasks, SubpixelMode};
|
||||
use crate::prim_store::{SpaceMapper, PictureIndex, PrimitiveDebugId, PrimitiveScratchBuffer};
|
||||
use crate::prim_store::{DeferredResolve, PrimitiveVisibilityMask};
|
||||
use crate::profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters};
|
||||
use crate::profiler::{FrameProfileCounters, TextureCacheProfileCounters, ResourceProfileCounters};
|
||||
use crate::render_backend::{DataStores, FrameStamp, FrameId};
|
||||
use crate::render_target::{RenderTarget, PictureCacheTarget, TextureCacheRenderTarget};
|
||||
use crate::render_target::{RenderTargetContext, RenderTargetKind};
|
||||
|
@ -443,8 +443,7 @@ impl FrameBuilder {
|
|||
layer: DocumentLayer,
|
||||
device_origin: DeviceIntPoint,
|
||||
pan: WorldPoint,
|
||||
texture_cache_profile: &mut TextureCacheProfileCounters,
|
||||
gpu_cache_profile: &mut GpuCacheProfileCounters,
|
||||
resource_profile: &mut ResourceProfileCounters,
|
||||
scene_properties: &SceneProperties,
|
||||
data_stores: &mut DataStores,
|
||||
scratch: &mut PrimitiveScratchBuffer,
|
||||
|
@ -458,7 +457,7 @@ impl FrameBuilder {
|
|||
profile_counters
|
||||
.total_primitives
|
||||
.set(scene.prim_store.prim_count());
|
||||
|
||||
resource_profile.content_slices.set(scene.content_slice_count);
|
||||
resource_cache.begin_frame(stamp);
|
||||
gpu_cache.begin_frame(stamp);
|
||||
|
||||
|
@ -496,7 +495,7 @@ impl FrameBuilder {
|
|||
&mut surfaces,
|
||||
scratch,
|
||||
debug_flags,
|
||||
texture_cache_profile,
|
||||
&mut resource_profile.texture_cache,
|
||||
&mut composite_state,
|
||||
);
|
||||
|
||||
|
@ -563,11 +562,11 @@ impl FrameBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
let gpu_cache_frame_id = gpu_cache.end_frame(gpu_cache_profile).frame_id();
|
||||
let gpu_cache_frame_id = gpu_cache.end_frame(&mut resource_profile.gpu_cache).frame_id();
|
||||
|
||||
render_tasks.write_task_data();
|
||||
*render_task_counters = render_tasks.counters();
|
||||
resource_cache.end_frame(texture_cache_profile);
|
||||
resource_cache.end_frame(&mut resource_profile.texture_cache);
|
||||
|
||||
Frame {
|
||||
content_origin: scene.output_rect.origin,
|
||||
|
|
|
@ -199,6 +199,10 @@ impl IntProfileCounter {
|
|||
pub fn inc(&mut self) {
|
||||
self.value += 1;
|
||||
}
|
||||
|
||||
pub fn set(&mut self, value: usize) {
|
||||
self.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
impl ProfileCounter for IntProfileCounter {
|
||||
|
@ -679,6 +683,7 @@ pub struct ResourceProfileCounters {
|
|||
pub image_templates: ResourceProfileCounter,
|
||||
pub texture_cache: TextureCacheProfileCounters,
|
||||
pub gpu_cache: GpuCacheProfileCounters,
|
||||
pub content_slices: IntProfileCounter,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -762,6 +767,10 @@ impl BackendProfileCounters {
|
|||
Some(expected::NUM_IMAGE_TEMPLATES),
|
||||
Some(expected::IMAGE_TEMPLATES_MB),
|
||||
),
|
||||
content_slices: IntProfileCounter::new(
|
||||
"Content Slices",
|
||||
None,
|
||||
),
|
||||
texture_cache: TextureCacheProfileCounters::new(),
|
||||
gpu_cache: GpuCacheProfileCounters::new(),
|
||||
},
|
||||
|
@ -1464,6 +1473,7 @@ impl Profiler {
|
|||
|
||||
fn draw_compact_profile(
|
||||
&mut self,
|
||||
backend_profile: &BackendProfileCounters,
|
||||
renderer_profile: &RendererProfileCounters,
|
||||
debug_renderer: &mut DebugRenderer,
|
||||
) {
|
||||
|
@ -1476,6 +1486,7 @@ impl Profiler {
|
|||
&renderer_profile.vertices,
|
||||
&renderer_profile.rendered_picture_cache_tiles,
|
||||
&renderer_profile.texture_data_uploaded,
|
||||
&backend_profile.resources.content_slices,
|
||||
&self.ipc_time,
|
||||
&self.backend_time,
|
||||
&self.renderer_time,
|
||||
|
@ -1507,6 +1518,7 @@ impl Profiler {
|
|||
&renderer_profile.rendered_picture_cache_tiles,
|
||||
&renderer_profile.total_picture_cache_tiles,
|
||||
&renderer_profile.texture_data_uploaded,
|
||||
&backend_profile.resources.content_slices,
|
||||
],
|
||||
None,
|
||||
debug_renderer,
|
||||
|
@ -1760,6 +1772,7 @@ impl Profiler {
|
|||
}
|
||||
ProfileStyle::Compact => {
|
||||
self.draw_compact_profile(
|
||||
backend_profile,
|
||||
renderer_profile,
|
||||
debug_renderer,
|
||||
);
|
||||
|
@ -1769,7 +1782,7 @@ impl Profiler {
|
|||
backend_profile,
|
||||
renderer_profile,
|
||||
debug_renderer,
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -549,8 +549,7 @@ impl Document {
|
|||
self.view.layer,
|
||||
self.view.device_rect.origin,
|
||||
pan,
|
||||
&mut resource_profile.texture_cache,
|
||||
&mut resource_profile.gpu_cache,
|
||||
resource_profile,
|
||||
&self.dynamic_properties,
|
||||
&mut self.data_stores,
|
||||
&mut self.scratch,
|
||||
|
|
|
@ -227,6 +227,7 @@ pub struct BuiltScene {
|
|||
pub config: FrameBuilderConfig,
|
||||
pub clip_scroll_tree: ClipScrollTree,
|
||||
pub hit_testing_scene: Arc<HitTestingScene>,
|
||||
pub content_slice_count: usize,
|
||||
}
|
||||
|
||||
impl BuiltScene {
|
||||
|
@ -240,6 +241,7 @@ impl BuiltScene {
|
|||
clip_store: ClipStore::new(),
|
||||
clip_scroll_tree: ClipScrollTree::new(),
|
||||
hit_testing_scene: Arc::new(HitTestingScene::new(&HitTestingSceneStats::empty())),
|
||||
content_slice_count: 0,
|
||||
config: FrameBuilderConfig {
|
||||
default_font_render_mode: FontRenderMode::Mono,
|
||||
dual_source_blending_is_enabled: true,
|
||||
|
|
|
@ -358,6 +358,9 @@ pub struct SceneBuilder<'a> {
|
|||
/// The current recursion depth of iframes encountered. Used to restrict picture
|
||||
/// caching slices to only the top-level content frame.
|
||||
iframe_depth: usize,
|
||||
|
||||
/// The number of picture cache slices that were created for content.
|
||||
content_slice_count: usize,
|
||||
}
|
||||
|
||||
impl<'a> SceneBuilder<'a> {
|
||||
|
@ -397,6 +400,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
external_scroll_mapper: ScrollOffsetMapper::new(),
|
||||
found_explicit_tile_cache: false,
|
||||
iframe_depth: 0,
|
||||
content_slice_count: 0,
|
||||
};
|
||||
|
||||
let device_pixel_scale = view.accumulated_scale_factor_for_snapping();
|
||||
|
@ -452,6 +456,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
clip_store: builder.clip_store,
|
||||
root_pic_index: builder.root_pic_index,
|
||||
config: builder.config,
|
||||
content_slice_count: builder.content_slice_count,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -578,12 +583,14 @@ impl<'a> SceneBuilder<'a> {
|
|||
clip_instance.clip_chain_id,
|
||||
&mut prim_clips,
|
||||
&self.clip_store,
|
||||
&self.interners,
|
||||
);
|
||||
}
|
||||
add_clips(
|
||||
instance.clip_chain_id,
|
||||
&mut prim_clips,
|
||||
&self.clip_store,
|
||||
&self.interners,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1859,7 +1866,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
// are scrollbars. Once this lands, we can simplify this logic considerably
|
||||
// (and add a separate picture cache slice / OS layer for scroll bars).
|
||||
if parent_sc.pipeline_id != stacking_context.pipeline_id && self.iframe_depth == 1 {
|
||||
stacking_context.init_picture_caching(&self.clip_scroll_tree);
|
||||
self.content_slice_count = stacking_context.init_picture_caching(&self.clip_scroll_tree);
|
||||
|
||||
// Mark that a user supplied tile cache was specified.
|
||||
self.found_explicit_tile_cache = true;
|
||||
|
@ -3521,12 +3528,13 @@ impl FlattenedStackingContext {
|
|||
fn init_picture_caching(
|
||||
&mut self,
|
||||
clip_scroll_tree: &ClipScrollTree,
|
||||
) {
|
||||
) -> usize {
|
||||
struct SliceInfo {
|
||||
cluster_index: usize,
|
||||
scroll_roots: Vec<SpatialNodeIndex>,
|
||||
scroll_root: SpatialNodeIndex,
|
||||
}
|
||||
|
||||
let mut content_slice_count = 0;
|
||||
let mut slices: Vec<SliceInfo> = Vec::new();
|
||||
|
||||
// Step through each cluster, and work out where the slice boundaries should be.
|
||||
|
@ -3537,51 +3545,47 @@ impl FlattenedStackingContext {
|
|||
|
||||
// We want to create a slice in the following conditions:
|
||||
// (1) This cluster is a scrollbar
|
||||
// (2) This cluster begins a 'real' scroll root, where we don't currently have a real scroll root
|
||||
// (2) This cluster begins a scroll root different from the current
|
||||
// (3) No slice exists yet
|
||||
let create_new_slice =
|
||||
cluster.flags.contains(ClusterFlags::SCROLLBAR_CONTAINER) ||
|
||||
slices.last().map(|slice| {
|
||||
scroll_root != ROOT_SPATIAL_NODE_INDEX &&
|
||||
slice.scroll_roots.is_empty()
|
||||
scroll_root != slice.scroll_root
|
||||
}).unwrap_or(true);
|
||||
|
||||
// Create a new slice if required
|
||||
if create_new_slice {
|
||||
slices.push(SliceInfo {
|
||||
cluster_index,
|
||||
scroll_roots: Vec::new(),
|
||||
scroll_root
|
||||
});
|
||||
}
|
||||
|
||||
// If this is a 'real' scroll root, include that in the list of scroll roots
|
||||
// that have been found for this slice.
|
||||
if scroll_root != ROOT_SPATIAL_NODE_INDEX {
|
||||
let slice = slices.last_mut().unwrap();
|
||||
if !slice.scroll_roots.contains(&scroll_root) {
|
||||
slice.scroll_roots.push(scroll_root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Walk the list of slices, setting appropriate flags on the clusters which are
|
||||
// later used during setup_picture_caching.
|
||||
for slice in slices.drain(..) {
|
||||
let cluster = &mut self.prim_list.clusters[slice.cluster_index];
|
||||
// Mark that this cluster creates a picture cache slice
|
||||
cluster.flags.insert(ClusterFlags::CREATE_PICTURE_CACHE_PRE);
|
||||
assert!(!slice.scroll_roots.contains(&ROOT_SPATIAL_NODE_INDEX));
|
||||
// Only select a scroll root for this slice if there's a single 'real' scroll
|
||||
// root. If there are no scroll roots (doesn't scroll) or there are multiple
|
||||
// scroll roots, then cache as a fixed slice. In the case of multiple scroll
|
||||
// roots, this means we'll do some extra rasterization work (but only in dirty
|
||||
// regions) as parts of the slice scroll. However, it does mean that we
|
||||
// reduce number of tiles / GPU memory, and keep subpixel AA. In future, we
|
||||
// might decide to create extra slices in some cases where there are multiple
|
||||
// scroll roots (specifically, non-overlapping sibling scroll roots might be
|
||||
// useful to support).
|
||||
if slice.scroll_roots.len() == 1 {
|
||||
cluster.cache_scroll_root = Some(slice.scroll_roots.first().cloned().unwrap());
|
||||
// If the page would create too many slices (an arbitrary definition where
|
||||
// it's assumed the GPU memory + compositing overhead would be too high)
|
||||
// then just create a single picture cache for the entire content. This at
|
||||
// least means that we can cache small content changes efficiently when
|
||||
// scrolling isn't occurring. Scrolling regions will be handled reasonably
|
||||
// efficiently by the dirty rect tracking (since it's likely that if the
|
||||
// page has so many slices there isn't a single major scroll region).
|
||||
const MAX_CONTENT_SLICES: usize = 8;
|
||||
|
||||
if slices.len() > MAX_CONTENT_SLICES {
|
||||
if let Some(cluster) = self.prim_list.clusters.first_mut() {
|
||||
content_slice_count = 1;
|
||||
cluster.flags.insert(ClusterFlags::CREATE_PICTURE_CACHE_PRE);
|
||||
cluster.cache_scroll_root = None;
|
||||
}
|
||||
} else {
|
||||
// Walk the list of slices, setting appropriate flags on the clusters which are
|
||||
// later used during setup_picture_caching.
|
||||
for slice in slices.drain(..) {
|
||||
content_slice_count += 1;
|
||||
let cluster = &mut self.prim_list.clusters[slice.cluster_index];
|
||||
// Mark that this cluster creates a picture cache slice
|
||||
cluster.flags.insert(ClusterFlags::CREATE_PICTURE_CACHE_PRE);
|
||||
cluster.cache_scroll_root = Some(slice.scroll_root);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3590,6 +3594,8 @@ impl FlattenedStackingContext {
|
|||
if let Some(cluster) = self.prim_list.clusters.last_mut() {
|
||||
cluster.flags.insert(ClusterFlags::CREATE_PICTURE_CACHE_POST);
|
||||
}
|
||||
|
||||
content_slice_count
|
||||
}
|
||||
|
||||
/// Return true if the stacking context isn't needed.
|
||||
|
@ -3933,6 +3939,7 @@ fn add_clips(
|
|||
clip_chain_id: ClipChainId,
|
||||
prim_clips: &mut Vec<ClipDataHandle>,
|
||||
clip_store: &ClipStore,
|
||||
interners: &Interners,
|
||||
) {
|
||||
let mut current_clip_chain_id = clip_chain_id;
|
||||
|
||||
|
@ -3940,7 +3947,10 @@ fn add_clips(
|
|||
let clip_chain_node = &clip_store
|
||||
.clip_chain_nodes[current_clip_chain_id.0 as usize];
|
||||
|
||||
prim_clips.push(clip_chain_node.handle);
|
||||
let clip_kind = interners.clip[clip_chain_node.handle];
|
||||
if let ClipNodeKind::Rectangle = clip_kind {
|
||||
prim_clips.push(clip_chain_node.handle);
|
||||
}
|
||||
|
||||
current_clip_chain_id = clip_chain_node.parent_clip_chain_id;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-001.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-002.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-003.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-004.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-005.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-006.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-007.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-009.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-012.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-013.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-014.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[background-attachment-applies-to-015.xht]
|
||||
expected:
|
||||
if os == "android" and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1900
|
||||
|
|
|
@ -5,3 +5,5 @@
|
|||
if not webrender and (os == "win") and (version == "10.0.17134"): FAIL
|
||||
if (os == "android") and not e10s: FAIL
|
||||
if (os == "android") and e10s: PASS
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=2206
|
||||
|
|
|
@ -2,3 +2,5 @@
|
|||
expected:
|
||||
if (os == "android") and not e10s: FAIL
|
||||
if (os == "android") and e10s: PASS
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=3796
|
||||
|
|
|
@ -3,3 +3,5 @@
|
|||
if os == "android": Bug 1563766
|
||||
expected:
|
||||
if (os == "android") and not e10s: FAIL
|
||||
fuzzy:
|
||||
if webrender and (os == "win"): maxDifference=92;totalPixels=1787
|
||||
|
|
Загрузка…
Ссылка в новой задаче