зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
c4d9e1e226
Коммит
2ce421308a
|
@ -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
|
||||
|
|
|
@ -1822,7 +1822,7 @@ impl<T> VertexDataTexture<T> {
|
|||
data.len() * texels_per_item
|
||||
} else {
|
||||
MAX_VERTEX_TEXTURE_WIDTH - (MAX_VERTEX_TEXTURE_WIDTH % texels_per_item)
|
||||
};
|
||||
};
|
||||
|
||||
let rect = DeviceIntRect::new(
|
||||
DeviceIntPoint::zero(),
|
||||
|
@ -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(
|
||||
|
|
Загрузка…
Ссылка в новой задаче