Bug 1642629 - Recycle a couple of vectors in PictureUpdateState. r=gw

Differential Revision: https://phabricator.services.mozilla.com/D79857
This commit is contained in:
Nicolas Silva 2020-06-22 08:49:35 +00:00
Родитель ebb2b1e263
Коммит 64e4930c6f
3 изменённых файлов: 47 добавлений и 5 удалений

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

@ -15,7 +15,7 @@ use crate::gpu_types::TransformData;
use crate::internal_types::{FastHashMap, PlaneSplitter, SavedTargetIndex};
use crate::picture::{PictureUpdateState, SurfaceInfo, ROOT_SURFACE_INDEX, SurfaceIndex, RecordedDirtyRegion};
use crate::picture::{RetainedTiles, TileCacheInstance, DirtyRegion, SurfaceRenderTasks, SubpixelMode};
use crate::picture::{BackdropKind, TileCacheLogger};
use crate::picture::{BackdropKind, TileCacheLogger, PictureUpdateStateBuffers};
use crate::prim_store::{SpaceMapper, PictureIndex, PrimitiveDebugId, PrimitiveScratchBuffer};
use crate::prim_store::{DeferredResolve, PrimitiveVisibilityMask};
use crate::profiler::{FrameProfileCounters, TextureCacheProfileCounters, ResourceProfileCounters};
@ -121,10 +121,13 @@ pub struct FrameBuilder {
/// that can optionally be consumed by this frame builder.
pending_retained_tiles: RetainedTiles,
pub globals: FrameGlobalResources,
// A vector that is cleared and re-built each frame. We keep it
// here to avoid reallocations.
// A few data structures that are cleared and re-built each frame.
// We keep them here to avoid reallocations.
#[cfg_attr(any(feature = "capture", feature = "replay"), serde(skip))]
surfaces: Vec<SurfaceInfo>,
#[cfg_attr(any(feature = "capture", feature = "replay"), serde(skip))]
picture_update_buffers: PictureUpdateStateBuffers,
}
pub struct FrameVisibilityContext<'a> {
@ -242,6 +245,7 @@ impl FrameBuilder {
pending_retained_tiles: RetainedTiles::new(),
globals: FrameGlobalResources::empty(),
surfaces: Vec::new(),
picture_update_buffers: PictureUpdateStateBuffers::default(),
}
}
@ -262,6 +266,7 @@ impl FrameBuilder {
pub fn memory_pressure(&mut self) {
self.surfaces = Vec::new();
self.picture_update_buffers.memory_pressure();
}
/// Compute the contribution (bounding rectangles, and resources) of layers and their
@ -350,6 +355,7 @@ impl FrameBuilder {
// which surfaces have valid cached surfaces that don't need to
// be rendered this frame.
PictureUpdateState::update_all(
&mut self.picture_update_buffers,
&mut self.surfaces,
scene.root_pic_index,
&mut scene.prim_store.pictures,

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

@ -3817,6 +3817,27 @@ impl TileCacheInstance {
}
}
pub struct PictureUpdateStateBuffers {
surface_stack: Vec<SurfaceIndex>,
picture_stack: Vec<PictureInfo>,
}
impl Default for PictureUpdateStateBuffers {
fn default() -> Self {
PictureUpdateStateBuffers {
surface_stack: Vec::new(),
picture_stack: Vec::new(),
}
}
}
impl PictureUpdateStateBuffers {
pub fn memory_pressure(&mut self) {
self.surface_stack = Vec::new();
self.picture_stack = Vec::new();
}
}
/// Maintains a stack of picture and surface information, that
/// is used during the initial picture traversal.
pub struct PictureUpdateState<'a> {
@ -3829,6 +3850,7 @@ pub struct PictureUpdateState<'a> {
impl<'a> PictureUpdateState<'a> {
pub fn update_all(
buffers: &mut PictureUpdateStateBuffers,
surfaces: &'a mut Vec<SurfaceInfo>,
pic_index: PictureIndex,
picture_primitives: &mut [PicturePrimitive],
@ -3843,12 +3865,14 @@ impl<'a> PictureUpdateState<'a> {
let mut state = PictureUpdateState {
surfaces,
surface_stack: vec![SurfaceIndex(0)],
picture_stack: Vec::new(),
surface_stack: buffers.surface_stack.take().cleared(),
picture_stack: buffers.picture_stack.take().cleared(),
are_raster_roots_assigned: true,
composite_state,
};
state.surface_stack.push(SurfaceIndex(0));
state.update(
pic_index,
picture_primitives,
@ -3865,6 +3889,9 @@ impl<'a> PictureUpdateState<'a> {
ROOT_SPATIAL_NODE_INDEX,
);
}
buffers.surface_stack = state.surface_stack.take();
buffers.picture_stack = state.picture_stack.take();
}
/// Return the current surface

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

@ -66,6 +66,9 @@ pub trait VecHelper<T> {
/// Equivalent to `mem::replace(&mut vec, Vec::new())`
fn take(&mut self) -> Self;
/// Call clear and return self (useful for chaining with calls that move the vector).
fn cleared(self) -> Self;
/// Functionally equivalent to `mem::replace(&mut vec, Vec::new())` but tries
/// to keep the allocation in the caller if it is empty or replace it with a
/// pre-allocated vector.
@ -99,6 +102,12 @@ impl<T> VecHelper<T> for Vec<T> {
replace(self, Vec::new())
}
fn cleared(mut self) -> Self {
self.clear();
self
}
fn take_and_preallocate(&mut self) -> Self {
let len = self.len();
if len == 0 {