Bug 1650984 - add invalidate_tile to WR Compositor interface. r=gw

This restructures the WR Compositor interface a bit to support compositing
earlier in the frame. An invalidate_tile hook is added that gets called
first to signal that some picture cache tiles will be modified later in the
frame. The renderer then calls add_surface earlier before the picture cache
tiles are updated, so that any tiles that aren't invalid can proceed to
composite early before that. Finally, bind/unbind get called after so that
it can work potentially work in parallel with any tiles that are already
compositing early.

Differential Revision: https://phabricator.services.mozilla.com/D82473
This commit is contained in:
Lee Salzman 2020-07-14 20:49:01 +00:00
Родитель c4d9e1e226
Коммит 2ce421308a
2 изменённых файлов: 51 добавлений и 3 удалений

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

@ -880,6 +880,15 @@ pub trait Compositor {
id: NativeTileId,
);
/// Mark a tile as invalid before any surfaces are queued for
/// composition and before it is updated with bind. This is useful
/// for early composition, allowing for dependency tracking of which
/// surfaces can be composited early while others are still updating.
fn invalidate_tile(
&mut self,
_id: NativeTileId,
) {}
/// Bind this surface such that WR can issue OpenGL commands
/// that will target the surface. Returns an (x, y) offset
/// where WR should draw into the surface. This can be set

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

@ -5937,6 +5937,44 @@ impl Renderer {
self.bind_frame_data(frame);
// If we have a native OS compositor, then make use of that interface to
// specify how to composite each of the picture cache surfaces. First, we
// need to find each tile that may be bound and updated later in the frame
// and invalidate it so that the native render compositor knows that these
// tiles can't be composited early. Next, after all such tiles have been
// invalidated, then we queue surfaces for native composition by the render
// compositor before we actually update the tiles. This allows the render
// compositor to start early composition while the tiles are updating.
if let CompositorKind::Native { .. } = self.current_compositor_kind {
assert!(frame.composite_state.picture_caching_is_enabled);
let compositor = self.compositor_config.compositor().unwrap();
// Invalidate any native surface tiles that might be updated by passes.
if !frame.has_been_rendered {
for tile in frame.composite_state.opaque_tiles.iter().chain(frame.composite_state.alpha_tiles.iter()) {
if !tile.dirty_rect.is_empty() {
if let CompositeTileSurface::Texture { surface: ResolvedSurfaceTexture::Native { id, .. } } =
tile.surface {
compositor.invalidate_tile(id);
}
}
}
}
// Ensure any external surfaces that might be used during early composition
// are invalidated first so that the native compositor can properly schedule
// composition to happen only when the external surface is updated.
// See update_external_native_surfaces for more details.
for surface in &frame.composite_state.external_surfaces {
if let Some((native_surface_id, _)) = surface.update_params {
compositor.invalidate_tile(NativeTileId { surface_id: native_surface_id, x: 0, y: 0 });
}
}
// Finally queue native surfaces for early composition, if applicable. By now,
// we have already invalidated any tiles that such surfaces may depend upon, so
// the native render compositor can keep track of when to actually schedule
// composition as surfaces are updated.
frame.composite_state.composite_native(&mut **compositor);
}
for (_pass_index, pass) in frame.passes.iter_mut().enumerate() {
#[cfg(not(target_os = "android"))]
let _gm = self.gpu_profile.start_marker(&format!("pass {}", _pass_index));
@ -5998,12 +6036,13 @@ impl Renderer {
// to specify how to composite each of the picture cache surfaces.
match self.current_compositor_kind {
CompositorKind::Native { .. } => {
// We have already queued surfaces for early native composition by this point.
// All that is left is to finally update any external native surfaces that were
// invalidated so that composition can complete.
self.update_external_native_surfaces(
&frame.composite_state.external_surfaces,
results,
);
let compositor = self.compositor_config.compositor().unwrap();
frame.composite_state.composite_native(&mut **compositor);
}
CompositorKind::Draw { max_partial_present_rects, draw_previous_partial_present_regions, .. } => {
self.composite_simple(