зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1583460 - Refactor picture caching setup to simplify creating multiple slices. r=nical
Differential Revision: https://phabricator.services.mozilla.com/D46907 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
5a2c81ed47
Коммит
b0ffdb3a87
|
@ -2244,6 +2244,10 @@ bitflags! {
|
|||
const IS_VISIBLE = 4;
|
||||
/// Is a backdrop-filter cluster that requires special handling during post_update.
|
||||
const IS_BACKDROP_FILTER = 8;
|
||||
/// Force creation of a picture caching slice before this cluster.
|
||||
const CREATE_PICTURE_CACHE_PRE = 16;
|
||||
/// Force creation of a picture caching slice after this cluster.
|
||||
const CREATE_PICTURE_CACHE_POST = 32;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2299,7 +2303,6 @@ impl PrimitiveCluster {
|
|||
&mut self,
|
||||
prim_instance: PrimitiveInstance,
|
||||
prim_size: LayoutSize,
|
||||
insert_position: PrimitiveListPosition,
|
||||
) {
|
||||
let prim_rect = LayoutRect::new(
|
||||
prim_instance.prim_origin,
|
||||
|
@ -2310,15 +2313,7 @@ impl PrimitiveCluster {
|
|||
.unwrap_or_else(LayoutRect::zero);
|
||||
|
||||
self.bounding_rect = self.bounding_rect.union(&culling_rect);
|
||||
|
||||
match insert_position {
|
||||
PrimitiveListPosition::Begin => {
|
||||
self.prim_instances.insert(0, prim_instance);
|
||||
}
|
||||
PrimitiveListPosition::End => {
|
||||
self.prim_instances.push(prim_instance);
|
||||
}
|
||||
}
|
||||
self.prim_instances.push(prim_instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2373,24 +2368,17 @@ impl PrimitiveList {
|
|||
// Insert the primitive into the first or last cluster as required
|
||||
match insert_position {
|
||||
PrimitiveListPosition::Begin => {
|
||||
if let Some(cluster) = self.clusters.first_mut() {
|
||||
if cluster.is_compatible(spatial_node_index, flags) {
|
||||
cluster.push(prim_instance, prim_size, insert_position);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let mut cluster = PrimitiveCluster::new(
|
||||
spatial_node_index,
|
||||
flags,
|
||||
);
|
||||
cluster.push(prim_instance, prim_size, insert_position);
|
||||
cluster.push(prim_instance, prim_size);
|
||||
self.clusters.insert(0, cluster);
|
||||
}
|
||||
PrimitiveListPosition::End => {
|
||||
if let Some(cluster) = self.clusters.last_mut() {
|
||||
if cluster.is_compatible(spatial_node_index, flags) {
|
||||
cluster.push(prim_instance, prim_size, insert_position);
|
||||
cluster.push(prim_instance, prim_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2399,7 +2387,7 @@ impl PrimitiveList {
|
|||
spatial_node_index,
|
||||
flags,
|
||||
);
|
||||
cluster.push(prim_instance, prim_size, insert_position);
|
||||
cluster.push(prim_instance, prim_size);
|
||||
self.clusters.push(cluster);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -683,72 +683,15 @@ impl<'a> SceneBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
let prim_list = remaining_prims;
|
||||
|
||||
// Now, create a picture with tile caching enabled that will hold all
|
||||
// of the primitives selected as belonging to the main scroll root.
|
||||
let pic_key = PictureKey::new(
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
LayoutSize::zero(),
|
||||
Picture {
|
||||
composite_mode_key: PictureCompositeKey::Identity,
|
||||
},
|
||||
);
|
||||
|
||||
let pic_data_handle = self.interners
|
||||
.picture
|
||||
.intern(&pic_key, || {
|
||||
PrimitiveSceneData {
|
||||
prim_size: LayoutSize::zero(),
|
||||
flags: PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Build a clip-chain for the tile cache, that contains any of the shared clips
|
||||
// we will apply when drawing the tiles. In all cases provided by Gecko, these
|
||||
// are rectangle clips with a scale/offset transform only, and get handled as
|
||||
// a simple local clip rect in the vertex shader. However, this should in theory
|
||||
// also work with any complex clips, such as rounded rects and image masks, by
|
||||
// producing a clip mask that is applied to the picture cache tiles.
|
||||
let mut parent_clip_chain_id = ClipChainId::NONE;
|
||||
for clip_handle in &shared_clips {
|
||||
parent_clip_chain_id = self.clip_store.add_clip_chain_node(
|
||||
*clip_handle,
|
||||
parent_clip_chain_id,
|
||||
);
|
||||
}
|
||||
|
||||
let tile_cache = Box::new(TileCacheInstance::new(
|
||||
let instance = create_tile_cache(
|
||||
0,
|
||||
main_scroll_root,
|
||||
remaining_prims,
|
||||
self.config.background_color,
|
||||
shared_clips,
|
||||
parent_clip_chain_id,
|
||||
));
|
||||
|
||||
let pic_index = self.prim_store.pictures.alloc().init(PicturePrimitive::new_image(
|
||||
Some(PictureCompositeMode::TileCache { }),
|
||||
Picture3DContext::Out,
|
||||
None,
|
||||
true,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
RasterSpace::Screen,
|
||||
prim_list,
|
||||
main_scroll_root,
|
||||
Some(tile_cache),
|
||||
PictureOptions::default(),
|
||||
));
|
||||
|
||||
let instance = PrimitiveInstance::new(
|
||||
LayoutPoint::zero(),
|
||||
LayoutRect::max_rect(),
|
||||
PrimitiveInstanceKind::Picture {
|
||||
data_handle: pic_data_handle,
|
||||
pic_index: PictureIndex(pic_index),
|
||||
segment_instance_index: SegmentInstanceIndex::INVALID,
|
||||
},
|
||||
parent_clip_chain_id,
|
||||
&mut self.interners,
|
||||
&mut self.prim_store,
|
||||
&mut self.clip_store,
|
||||
);
|
||||
|
||||
// This contains the tile caching picture, with preceding and
|
||||
|
@ -2013,71 +1956,22 @@ impl<'a> SceneBuilder<'a> {
|
|||
!self.found_explicit_tile_cache &&
|
||||
self.config.enable_picture_caching {
|
||||
|
||||
let scroll_root = ROOT_SPATIAL_NODE_INDEX;
|
||||
|
||||
// Now, create a picture with tile caching enabled that will hold all
|
||||
// of the primitives selected as belonging to the main scroll root.
|
||||
let pic_key = PictureKey::new(
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
LayoutSize::zero(),
|
||||
Picture {
|
||||
composite_mode_key: PictureCompositeKey::Identity,
|
||||
},
|
||||
);
|
||||
|
||||
let pic_data_handle = self.interners
|
||||
.picture
|
||||
.intern(&pic_key, || {
|
||||
PrimitiveSceneData {
|
||||
prim_size: LayoutSize::zero(),
|
||||
flags: PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// TODO(gw): For now, we don't bother trying to share any clips if we create an
|
||||
// implicit picture cache. This cache always caches with a fixed position
|
||||
// root scroll node, so it won't save any invalidations. It might save
|
||||
// some per-item clipping work though. We should handle this by unifying
|
||||
// the implicit cache creation code here to work as part of the normal
|
||||
// setup_picture_caching method.
|
||||
let tile_cache = TileCacheInstance::new(
|
||||
let instance = create_tile_cache(
|
||||
0,
|
||||
ROOT_SPATIAL_NODE_INDEX,
|
||||
stacking_context.prim_list,
|
||||
self.config.background_color,
|
||||
Vec::new(),
|
||||
ClipChainId::NONE,
|
||||
);
|
||||
|
||||
let pic_index = self.prim_store.pictures.alloc().init(PicturePrimitive::new_image(
|
||||
Some(PictureCompositeMode::TileCache {}),
|
||||
Picture3DContext::Out,
|
||||
None,
|
||||
true,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
RasterSpace::Screen,
|
||||
stacking_context.prim_list,
|
||||
scroll_root,
|
||||
Some(Box::new(tile_cache)),
|
||||
PictureOptions::default(),
|
||||
));
|
||||
|
||||
let instance = PrimitiveInstance::new(
|
||||
LayoutPoint::zero(),
|
||||
LayoutRect::max_rect(),
|
||||
PrimitiveInstanceKind::Picture {
|
||||
data_handle: pic_data_handle,
|
||||
pic_index: PictureIndex(pic_index),
|
||||
segment_instance_index: SegmentInstanceIndex::INVALID,
|
||||
},
|
||||
ClipChainId::NONE,
|
||||
&mut self.interners,
|
||||
&mut self.prim_store,
|
||||
&mut self.clip_store,
|
||||
);
|
||||
|
||||
let mut prim_list = PrimitiveList::empty();
|
||||
prim_list.add_prim(
|
||||
instance,
|
||||
LayoutSize::zero(),
|
||||
scroll_root,
|
||||
ROOT_SPATIAL_NODE_INDEX,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
);
|
||||
stacking_context.prim_list = prim_list;
|
||||
|
@ -3941,3 +3835,82 @@ fn process_repeat_size(
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Given a PrimitiveList and scroll root, construct a tile cache primitive instance
|
||||
/// that wraps the primitive list.
|
||||
fn create_tile_cache(
|
||||
slice: usize,
|
||||
scroll_root: SpatialNodeIndex,
|
||||
prim_list: PrimitiveList,
|
||||
background_color: Option<ColorF>,
|
||||
shared_clips: Vec<ClipDataHandle>,
|
||||
interners: &mut Interners,
|
||||
prim_store: &mut PrimitiveStore,
|
||||
clip_store: &mut ClipStore,
|
||||
) -> PrimitiveInstance {
|
||||
// Now, create a picture with tile caching enabled that will hold all
|
||||
// of the primitives selected as belonging to the main scroll root.
|
||||
let pic_key = PictureKey::new(
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
LayoutSize::zero(),
|
||||
Picture {
|
||||
composite_mode_key: PictureCompositeKey::Identity,
|
||||
},
|
||||
);
|
||||
|
||||
let pic_data_handle = interners
|
||||
.picture
|
||||
.intern(&pic_key, || {
|
||||
PrimitiveSceneData {
|
||||
prim_size: LayoutSize::zero(),
|
||||
flags: PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Build a clip-chain for the tile cache, that contains any of the shared clips
|
||||
// we will apply when drawing the tiles. In all cases provided by Gecko, these
|
||||
// are rectangle clips with a scale/offset transform only, and get handled as
|
||||
// a simple local clip rect in the vertex shader. However, this should in theory
|
||||
// also work with any complex clips, such as rounded rects and image masks, by
|
||||
// producing a clip mask that is applied to the picture cache tiles.
|
||||
let mut parent_clip_chain_id = ClipChainId::NONE;
|
||||
for clip_handle in &shared_clips {
|
||||
parent_clip_chain_id = clip_store.add_clip_chain_node(
|
||||
*clip_handle,
|
||||
parent_clip_chain_id,
|
||||
);
|
||||
}
|
||||
|
||||
let tile_cache = Box::new(TileCacheInstance::new(
|
||||
slice,
|
||||
scroll_root,
|
||||
background_color,
|
||||
shared_clips,
|
||||
parent_clip_chain_id,
|
||||
));
|
||||
|
||||
let pic_index = prim_store.pictures.alloc().init(PicturePrimitive::new_image(
|
||||
Some(PictureCompositeMode::TileCache { }),
|
||||
Picture3DContext::Out,
|
||||
None,
|
||||
true,
|
||||
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||
RasterSpace::Screen,
|
||||
prim_list,
|
||||
scroll_root,
|
||||
Some(tile_cache),
|
||||
PictureOptions::default(),
|
||||
));
|
||||
|
||||
PrimitiveInstance::new(
|
||||
LayoutPoint::zero(),
|
||||
LayoutRect::max_rect(),
|
||||
PrimitiveInstanceKind::Picture {
|
||||
data_handle: pic_data_handle,
|
||||
pic_index: PictureIndex(pic_index),
|
||||
segment_instance_index: SegmentInstanceIndex::INVALID,
|
||||
},
|
||||
parent_clip_chain_id,
|
||||
)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче