Bug 1592810 - Add support for dynamically disabling picture caching, for pinch zoom cases. r=nical

This patch allows WR to dynamically choose whether picture caching
is enabled per-frame, rather than only during initialization.

This will allow mobile devices to disable picture caching during
pinch zoom events, where tiles will be constantly invalidated.

This can also be controlled via a debug flag, which allows dynamic
toggling of picture caching in both Gecko and Wrench. This is
useful for profiling, to compare direct rasterization to picture
caching performance.

The native compositor interface relies on picture caching. So, if
a native compositor is enabled, picture caching is force enabled.

Differential Revision: https://phabricator.services.mozilla.com/D51211

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Glenn Watson 2019-10-31 08:38:01 +00:00
Родитель cab2ee5f4e
Коммит 5ee706e95f
8 изменённых файлов: 64 добавлений и 19 удалений

Просмотреть файл

@ -140,12 +140,26 @@ pub struct CompositeState {
pub native_surface_updates: Vec<NativeSurfaceOperation>,
/// The kind of compositor for picture cache tiles (e.g. drawn by WR, or OS compositor)
pub compositor_kind: CompositorKind,
/// Picture caching may be disabled dynamically, based on debug flags, pinch zoom etc.
pub picture_caching_is_enabled: bool,
}
impl CompositeState {
/// Construct a new state for compositing picture tiles. This is created
/// during each frame construction and passed to the renderer.
pub fn new(compositor_kind: CompositorKind) -> Self {
pub fn new(
compositor_kind: CompositorKind,
mut picture_caching_is_enabled: bool,
) -> Self {
// The native compositor interface requires picture caching to work, so
// force it here and warn if it was disabled.
if let CompositorKind::Native { .. } = compositor_kind {
if !picture_caching_is_enabled {
warn!("Picture caching cannot be disabled in native compositor config");
}
picture_caching_is_enabled = true;
}
CompositeState {
opaque_tiles: Vec::new(),
alpha_tiles: Vec::new(),
@ -154,6 +168,7 @@ impl CompositeState {
dirty_rects_are_valid: true,
native_surface_updates: Vec::new(),
compositor_kind,
picture_caching_is_enabled,
}
}

Просмотреть файл

@ -56,7 +56,8 @@ pub struct FrameBuilderConfig {
pub dual_source_blending_is_supported: bool,
pub dual_source_blending_is_enabled: bool,
pub chase_primitive: ChasePrimitive,
pub enable_picture_caching: bool,
/// The immutable global picture caching enable from `RendererOptions`
pub global_enable_picture_caching: bool,
/// True if we're running tests (i.e. via wrench).
pub testing: bool,
pub gpu_supports_fast_clears: bool,
@ -314,6 +315,7 @@ impl FrameBuilder {
gpu_cache,
&scene.clip_store,
data_stores,
composite_state,
);
{
@ -495,7 +497,18 @@ impl FrameBuilder {
let output_size = scene.output_rect.size.to_i32();
let screen_world_rect = (scene.output_rect.to_f32() / global_device_pixel_scale).round_out();
let mut composite_state = CompositeState::new(scene.config.compositor_kind);
// Determine if we will draw this frame with picture caching enabled. This depends on:
// (1) If globally enabled when WR was initialized
// (2) If current debug flags allow picture caching
// (3) [In future] Whether we are currently pinch zooming
let picture_caching_is_enabled =
scene.config.global_enable_picture_caching &&
!debug_flags.contains(DebugFlags::DISABLE_PICTURE_CACHING);
let mut composite_state = CompositeState::new(
scene.config.compositor_kind,
picture_caching_is_enabled,
);
let main_render_task_id = self.build_layer_screen_rects_and_cull_layers(
scene,

Просмотреть файл

@ -1949,6 +1949,7 @@ pub struct PictureUpdateState<'a> {
surface_stack: Vec<SurfaceIndex>,
picture_stack: Vec<PictureInfo>,
are_raster_roots_assigned: bool,
composite_state: &'a CompositeState,
}
impl<'a> PictureUpdateState<'a> {
@ -1960,6 +1961,7 @@ impl<'a> PictureUpdateState<'a> {
gpu_cache: &mut GpuCache,
clip_store: &ClipStore,
data_stores: &mut DataStores,
composite_state: &CompositeState,
) {
profile_marker!("UpdatePictures");
@ -1968,6 +1970,7 @@ impl<'a> PictureUpdateState<'a> {
surface_stack: vec![SurfaceIndex(0)],
picture_stack: Vec::new(),
are_raster_roots_assigned: true,
composite_state,
};
state.update(
@ -3656,14 +3659,20 @@ impl PicturePrimitive {
let actual_composite_mode = match self.requested_composite_mode {
Some(PictureCompositeMode::Filter(ref filter)) if filter.is_noop() => None,
Some(PictureCompositeMode::TileCache { .. }) => {
// Disable tile cache if the scroll root has a perspective transform, since
// this breaks many assumptions (it's a very rare edge case anyway, and
// is probably (?) going to be moving / animated in this case).
let spatial_node = &frame_context
.clip_scroll_tree
.spatial_nodes[self.spatial_node_index.0 as usize];
if spatial_node.coordinate_system_id == CoordinateSystemId::root() {
Some(PictureCompositeMode::TileCache { })
// Only allow picture caching composite mode if global picture caching setting
// is enabled this frame.
if state.composite_state.picture_caching_is_enabled {
// Disable tile cache if the scroll root has a perspective transform, since
// this breaks many assumptions (it's a very rare edge case anyway, and
// is probably (?) going to be moving / animated in this case).
let spatial_node = &frame_context
.clip_scroll_tree
.spatial_nodes[self.spatial_node_index.0 as usize];
if spatial_node.coordinate_system_id == CoordinateSystemId::root() {
Some(PictureCompositeMode::TileCache { })
} else {
None
}
} else {
None
}

Просмотреть файл

@ -1763,7 +1763,6 @@ pub struct Renderer {
clear_color: Option<ColorF>,
enable_clear_scissor: bool,
enable_picture_caching: bool,
enable_advanced_blend_barriers: bool,
debug: LazyInitializedDebugRenderer,
@ -2135,7 +2134,7 @@ impl Renderer {
dual_source_blending_is_enabled: true,
dual_source_blending_is_supported: use_dual_source_blending,
chase_primitive: options.chase_primitive,
enable_picture_caching: options.enable_picture_caching,
global_enable_picture_caching: options.enable_picture_caching,
testing: options.testing,
gpu_supports_fast_clears: options.gpu_supports_fast_clears,
gpu_supports_advanced_blend: ext_blend_equation_advanced,
@ -2252,7 +2251,7 @@ impl Renderer {
let texture_cache = TextureCache::new(
max_texture_size,
max_texture_layers,
if config.enable_picture_caching {
if config.global_enable_picture_caching {
picture_tile_sizes
} else {
&[]
@ -2332,7 +2331,6 @@ impl Renderer {
clear_color: options.clear_color,
enable_clear_scissor: options.enable_clear_scissor,
enable_advanced_blend_barriers: !ext_blend_equation_advanced_coherent,
enable_picture_caching: options.enable_picture_caching,
last_time: 0,
gpu_profile,
vaos: RendererVAOs {
@ -4987,7 +4985,10 @@ impl Renderer {
surface_is_y_flipped,
};
if self.enable_picture_caching {
// Picture caching can be enabled / disabled dynamically from frame to
// frame. This is determined by what the frame builder selected, and is
// passed to the renderer via the composite state.
if frame.composite_state.picture_caching_is_enabled {
// If we have a native OS compositor, then make use of that interface
// to specify how to composite each of the picture cache surfaces.
match self.compositor_config {

Просмотреть файл

@ -247,7 +247,7 @@ impl BuiltScene {
dual_source_blending_is_enabled: true,
dual_source_blending_is_supported: false,
chase_primitive: ChasePrimitive::Nothing,
enable_picture_caching: false,
global_enable_picture_caching: false,
testing: false,
gpu_supports_fast_clears: false,
gpu_supports_advanced_blend: false,

Просмотреть файл

@ -488,7 +488,7 @@ impl<'a> SceneBuilder<'a> {
&mut self,
main_prim_list: &mut PrimitiveList,
) {
if !self.config.enable_picture_caching {
if !self.config.global_enable_picture_caching {
return;
}
@ -1693,7 +1693,7 @@ impl<'a> SceneBuilder<'a> {
None
};
if is_pipeline_root && create_tile_cache && self.config.enable_picture_caching {
if is_pipeline_root && create_tile_cache && self.config.global_enable_picture_caching {
// we don't expect any nested tile-cache-enabled stacking contexts
debug_assert!(!self.sc_stack.iter().any(|sc| sc.create_tile_cache));
}

Просмотреть файл

@ -1144,6 +1144,8 @@ bitflags! {
const OBSCURE_IMAGES = 1 << 24;
/// The profiler only displays information that is out of the ordinary.
const SMART_PROFILER = 1 << 26;
/// Dynamically control whether picture caching is enabled.
const DISABLE_PICTURE_CACHING = 1 << 27;
}
}

Просмотреть файл

@ -705,6 +705,11 @@ fn render<'a>(
VirtualKeyCode::Escape => {
return winit::ControlFlow::Break;
}
VirtualKeyCode::A => {
debug_flags.toggle(DebugFlags::DISABLE_PICTURE_CACHING);
wrench.api.send_debug_cmd(DebugCommand::SetFlags(debug_flags));
do_render = true;
}
VirtualKeyCode::P => {
debug_flags.toggle(DebugFlags::PROFILER_DBG);
wrench.api.send_debug_cmd(DebugCommand::SetFlags(debug_flags));