зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1522555 - Remove a lot of dead WebRender code. r=kvark
We can always pull this back from history should we need it, but given how broken the texture caching of pictures was (see the recent text shadow story) I suspect we won't. Differential Revision: https://phabricator.services.mozilla.com/D17524
This commit is contained in:
Родитель
ff201af524
Коммит
89d4f21d5f
|
@ -390,7 +390,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
prim_list,
|
prim_list,
|
||||||
main_scroll_root,
|
main_scroll_root,
|
||||||
LayoutRect::max_rect(),
|
LayoutRect::max_rect(),
|
||||||
&self.clip_store,
|
|
||||||
Some(tile_cache),
|
Some(tile_cache),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -1214,7 +1213,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
let extra_instance = sc.cut_flat_item_sequence(
|
let extra_instance = sc.cut_flat_item_sequence(
|
||||||
&mut self.prim_store,
|
&mut self.prim_store,
|
||||||
&mut self.interners,
|
&mut self.interners,
|
||||||
&self.clip_store,
|
|
||||||
);
|
);
|
||||||
(sc.is_3d(), extra_instance)
|
(sc.is_3d(), extra_instance)
|
||||||
},
|
},
|
||||||
|
@ -1365,7 +1363,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
),
|
),
|
||||||
stacking_context.spatial_node_index,
|
stacking_context.spatial_node_index,
|
||||||
max_clip,
|
max_clip,
|
||||||
&self.clip_store,
|
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
@ -1412,7 +1409,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
),
|
),
|
||||||
stacking_context.spatial_node_index,
|
stacking_context.spatial_node_index,
|
||||||
max_clip,
|
max_clip,
|
||||||
&self.clip_store,
|
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
@ -1447,7 +1443,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
),
|
),
|
||||||
stacking_context.spatial_node_index,
|
stacking_context.spatial_node_index,
|
||||||
max_clip,
|
max_clip,
|
||||||
&self.clip_store,
|
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
@ -1490,7 +1485,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
),
|
),
|
||||||
stacking_context.spatial_node_index,
|
stacking_context.spatial_node_index,
|
||||||
max_clip,
|
max_clip,
|
||||||
&self.clip_store,
|
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
@ -1826,7 +1820,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
),
|
),
|
||||||
pending_shadow.clip_and_scroll.spatial_node_index,
|
pending_shadow.clip_and_scroll.spatial_node_index,
|
||||||
max_clip,
|
max_clip,
|
||||||
&self.clip_store,
|
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
@ -2570,7 +2563,6 @@ impl FlattenedStackingContext {
|
||||||
&mut self,
|
&mut self,
|
||||||
prim_store: &mut PrimitiveStore,
|
prim_store: &mut PrimitiveStore,
|
||||||
interners: &mut Interners,
|
interners: &mut Interners,
|
||||||
clip_store: &ClipStore,
|
|
||||||
) -> Option<PrimitiveInstance> {
|
) -> Option<PrimitiveInstance> {
|
||||||
if !self.is_3d() || self.primitives.is_empty() {
|
if !self.is_3d() || self.primitives.is_empty() {
|
||||||
return None
|
return None
|
||||||
|
@ -2598,7 +2590,6 @@ impl FlattenedStackingContext {
|
||||||
),
|
),
|
||||||
self.spatial_node_index,
|
self.spatial_node_index,
|
||||||
LayoutRect::max_rect(),
|
LayoutRect::max_rect(),
|
||||||
clip_store,
|
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|
|
@ -115,7 +115,6 @@ mod segment;
|
||||||
mod shade;
|
mod shade;
|
||||||
mod spatial_node;
|
mod spatial_node;
|
||||||
mod storage;
|
mod storage;
|
||||||
mod surface;
|
|
||||||
mod texture_allocator;
|
mod texture_allocator;
|
||||||
mod texture_cache;
|
mod texture_cache;
|
||||||
mod tiling;
|
mod tiling;
|
||||||
|
|
|
@ -8,7 +8,7 @@ use api::{DevicePixelScale, RasterRect, RasterSpace, ColorF, ImageKey, DirtyRect
|
||||||
use api::{PicturePixel, RasterPixel, WorldPixel, WorldRect, ImageFormat, ImageDescriptor, WorldVector2D, LayoutPoint};
|
use api::{PicturePixel, RasterPixel, WorldPixel, WorldRect, ImageFormat, ImageDescriptor, WorldVector2D, LayoutPoint};
|
||||||
use api::{DebugFlags, DeviceVector2D};
|
use api::{DebugFlags, DeviceVector2D};
|
||||||
use box_shadow::{BLUR_SAMPLE_SCALE};
|
use box_shadow::{BLUR_SAMPLE_SCALE};
|
||||||
use clip::{ClipStore, ClipChainId, ClipChainNode, ClipItem};
|
use clip::{ClipChainId, ClipChainNode, ClipItem};
|
||||||
use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex, CoordinateSystemId};
|
use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex, CoordinateSystemId};
|
||||||
use debug_colors;
|
use debug_colors;
|
||||||
use device::TextureFilter;
|
use device::TextureFilter;
|
||||||
|
@ -32,7 +32,6 @@ use resource_cache::ResourceCache;
|
||||||
use scene::{FilterOpHelpers, SceneProperties};
|
use scene::{FilterOpHelpers, SceneProperties};
|
||||||
use scene_builder::Interners;
|
use scene_builder::Interners;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use surface::{SurfaceDescriptor};
|
|
||||||
use std::{mem, u16};
|
use std::{mem, u16};
|
||||||
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||||
use texture_cache::{Eviction, TextureCacheHandle};
|
use texture_cache::{Eviction, TextureCacheHandle};
|
||||||
|
@ -1959,9 +1958,6 @@ pub struct PicturePrimitive {
|
||||||
/// Local clip rect for this picture.
|
/// Local clip rect for this picture.
|
||||||
pub local_clip_rect: LayoutRect,
|
pub local_clip_rect: LayoutRect,
|
||||||
|
|
||||||
/// A descriptor for this surface that can be used as a cache key.
|
|
||||||
surface_desc: Option<SurfaceDescriptor>,
|
|
||||||
|
|
||||||
pub gpu_location: GpuCacheHandle,
|
pub gpu_location: GpuCacheHandle,
|
||||||
|
|
||||||
/// If Some(..) the tile cache that is associated with this picture.
|
/// If Some(..) the tile cache that is associated with this picture.
|
||||||
|
@ -2051,33 +2047,9 @@ impl PicturePrimitive {
|
||||||
prim_list: PrimitiveList,
|
prim_list: PrimitiveList,
|
||||||
spatial_node_index: SpatialNodeIndex,
|
spatial_node_index: SpatialNodeIndex,
|
||||||
local_clip_rect: LayoutRect,
|
local_clip_rect: LayoutRect,
|
||||||
clip_store: &ClipStore,
|
|
||||||
tile_cache: Option<TileCache>,
|
tile_cache: Option<TileCache>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// For now, only create a cache descriptor for blur filters (which
|
|
||||||
// includes text shadows). We can incrementally expand this to
|
|
||||||
// handle more composite modes.
|
|
||||||
let create_cache_descriptor = match requested_composite_mode {
|
|
||||||
Some(PictureCompositeMode::Filter(FilterOp::Blur(blur_radius))) => {
|
|
||||||
blur_radius > 0.0
|
|
||||||
}
|
|
||||||
Some(_) | None => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let surface_desc = if create_cache_descriptor {
|
|
||||||
SurfaceDescriptor::new(
|
|
||||||
&prim_list.prim_instances,
|
|
||||||
spatial_node_index,
|
|
||||||
clip_store,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
PicturePrimitive {
|
PicturePrimitive {
|
||||||
surface_desc,
|
|
||||||
prim_list,
|
prim_list,
|
||||||
state: None,
|
state: None,
|
||||||
secondary_render_task_id: None,
|
secondary_render_task_id: None,
|
||||||
|
@ -2391,12 +2363,6 @@ impl PicturePrimitive {
|
||||||
let parent_raster_spatial_node_index = state.current_surface().raster_spatial_node_index;
|
let parent_raster_spatial_node_index = state.current_surface().raster_spatial_node_index;
|
||||||
let surface_spatial_node_index = self.spatial_node_index;
|
let surface_spatial_node_index = self.spatial_node_index;
|
||||||
|
|
||||||
// TODO(gw): For now, we always raster in screen space. Soon,
|
|
||||||
// we will be able to respect the requested raster
|
|
||||||
// space, and/or override the requested raster root
|
|
||||||
// if it makes sense to.
|
|
||||||
let raster_space = RasterSpace::Screen;
|
|
||||||
|
|
||||||
let inflation_factor = match composite_mode {
|
let inflation_factor = match composite_mode {
|
||||||
PictureCompositeMode::Filter(FilterOp::Blur(blur_radius)) => {
|
PictureCompositeMode::Filter(FilterOp::Blur(blur_radius)) => {
|
||||||
// The amount of extra space needed for primitives inside
|
// The amount of extra space needed for primitives inside
|
||||||
|
@ -2444,17 +2410,6 @@ impl PicturePrimitive {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// If we have a cache key / descriptor for this surface,
|
|
||||||
// update any transforms it cares about.
|
|
||||||
if let Some(ref mut surface_desc) = self.surface_desc {
|
|
||||||
surface_desc.update(
|
|
||||||
surface_spatial_node_index,
|
|
||||||
surface.raster_spatial_node_index,
|
|
||||||
frame_context.clip_scroll_tree,
|
|
||||||
raster_space,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.raster_config = Some(RasterConfig {
|
self.raster_config = Some(RasterConfig {
|
||||||
composite_mode,
|
composite_mode,
|
||||||
establishes_raster_root: surface_spatial_node_index == surface.raster_spatial_node_index,
|
establishes_raster_root: surface_spatial_node_index == surface.raster_spatial_node_index,
|
||||||
|
|
|
@ -28,7 +28,6 @@ use prim_store::line_dec::LineDecorationCacheKey;
|
||||||
use print_tree::{PrintTreePrinter};
|
use print_tree::{PrintTreePrinter};
|
||||||
use render_backend::FrameId;
|
use render_backend::FrameId;
|
||||||
use resource_cache::{CacheItem, ResourceCache};
|
use resource_cache::{CacheItem, ResourceCache};
|
||||||
use surface::SurfaceCacheKey;
|
|
||||||
use std::{ops, mem, usize, f32, i32, u32};
|
use std::{ops, mem, usize, f32, i32, u32};
|
||||||
use texture_cache::{TextureCache, TextureCacheHandle, Eviction};
|
use texture_cache::{TextureCache, TextureCacheHandle, Eviction};
|
||||||
use tiling::{RenderPass, RenderTargetIndex};
|
use tiling::{RenderPass, RenderTargetIndex};
|
||||||
|
@ -1090,8 +1089,6 @@ pub enum RenderTaskCacheKeyKind {
|
||||||
Image(ImageCacheKey),
|
Image(ImageCacheKey),
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
Glyph(GpuGlyphCacheKey),
|
Glyph(GpuGlyphCacheKey),
|
||||||
#[allow(dead_code)]
|
|
||||||
Picture(SurfaceCacheKey),
|
|
||||||
BorderSegment(BorderSegmentCacheKey),
|
BorderSegment(BorderSegmentCacheKey),
|
||||||
LineDecoration(LineDecorationCacheKey),
|
LineDecoration(LineDecorationCacheKey),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,326 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
use api::{LayoutPixel, PicturePixel, RasterSpace};
|
|
||||||
use clip::{ClipChainId, ClipStore};
|
|
||||||
use clip_scroll_tree::{ClipScrollTree, SpatialNodeIndex};
|
|
||||||
use euclid::TypedTransform3D;
|
|
||||||
use intern::ItemUid;
|
|
||||||
use internal_types::FastHashSet;
|
|
||||||
use prim_store::{CoordinateSpaceMapping, PrimitiveInstance, PrimitiveInstanceKind};
|
|
||||||
use std::hash;
|
|
||||||
use util::ScaleOffset;
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Notes for future implementation work on surface caching:
|
|
||||||
|
|
||||||
State that can affect the contents of a cached surface:
|
|
||||||
|
|
||||||
Primitives
|
|
||||||
These are handled by the PrimitiveUid value. The structure interning
|
|
||||||
code during scene building guarantees that each PrimitiveUid will
|
|
||||||
represent a unique identifier for the content of this primitive.
|
|
||||||
Clip chains
|
|
||||||
Similarly, the ClipUid value uniquely identifies the contents of
|
|
||||||
a clip node.
|
|
||||||
Transforms
|
|
||||||
Each picture contains a list of transforms that affect the content
|
|
||||||
of the picture itself. The value of the surface transform relative
|
|
||||||
to the raster root transform is only relevant if the picture is
|
|
||||||
being rasterized in screen-space.
|
|
||||||
External images
|
|
||||||
An external image (e.g. video) can change the contents of a picture
|
|
||||||
without a scene build occurring. We don't need to handle this yet,
|
|
||||||
but once images support interning and caching, we'll need to include
|
|
||||||
a list of external image dependencies in the cache key.
|
|
||||||
Property animation
|
|
||||||
Transform animations are handled by the transforms case above. We don't
|
|
||||||
need to handle opacity animations yet, since the interning and picture
|
|
||||||
caching doesn't support images and / or solid rects. Once those
|
|
||||||
primitives are ported, we'll need a list of property animation keys
|
|
||||||
that a surface depends on.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Matches the definition of SK_ScalarNearlyZero in Skia.
|
|
||||||
// TODO(gw): Some testing to see what's reasonable for this value
|
|
||||||
// to avoid invalidating the cache for minor changes.
|
|
||||||
const QUANTIZE_SCALE: f32 = 4096.0;
|
|
||||||
|
|
||||||
fn quantize(value: f32) -> f32 {
|
|
||||||
(value * QUANTIZE_SCALE).round() / QUANTIZE_SCALE
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A quantized, hashable version of util::ScaleOffset that
|
|
||||||
/// can be used as a cache key.
|
|
||||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
|
||||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub struct ScaleOffsetKey {
|
|
||||||
pub scale_x: f32,
|
|
||||||
pub scale_y: f32,
|
|
||||||
pub offset_x: f32,
|
|
||||||
pub offset_y: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ScaleOffsetKey {
|
|
||||||
fn new(scale_offset: &ScaleOffset) -> Self {
|
|
||||||
// TODO(gw): Since these are quantized, it might make sense in the future to
|
|
||||||
// convert these to ints to remove the need for custom hash impl.
|
|
||||||
ScaleOffsetKey {
|
|
||||||
scale_x: quantize(scale_offset.scale.x),
|
|
||||||
scale_y: quantize(scale_offset.scale.y),
|
|
||||||
offset_x: quantize(scale_offset.offset.x),
|
|
||||||
offset_y: quantize(scale_offset.offset.y),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for ScaleOffsetKey {}
|
|
||||||
|
|
||||||
impl hash::Hash for ScaleOffsetKey {
|
|
||||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
|
||||||
self.scale_x.to_bits().hash(state);
|
|
||||||
self.scale_y.to_bits().hash(state);
|
|
||||||
self.offset_x.to_bits().hash(state);
|
|
||||||
self.offset_y.to_bits().hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A quantized, hashable version of PictureTransform that
|
|
||||||
/// can be used as a cache key.
|
|
||||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
|
||||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub struct MatrixKey {
|
|
||||||
values: [f32; 16],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MatrixKey {
|
|
||||||
fn new<Src, Dst>(transform: &TypedTransform3D<f32, Src, Dst>) -> Self {
|
|
||||||
let mut values = transform.to_row_major_array();
|
|
||||||
|
|
||||||
// TODO(gw): Since these are quantized, it might make sense in the future to
|
|
||||||
// convert these to ints to remove the need for custom hash impl.
|
|
||||||
for value in &mut values {
|
|
||||||
*value = quantize(*value);
|
|
||||||
}
|
|
||||||
|
|
||||||
MatrixKey {
|
|
||||||
values,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for MatrixKey {}
|
|
||||||
|
|
||||||
impl hash::Hash for MatrixKey {
|
|
||||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
|
||||||
for value in &self.values {
|
|
||||||
value.to_bits().hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A quantized, hashable version of CoordinateSpaceMapping that
|
|
||||||
/// can be used as a cache key.
|
|
||||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
|
||||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
|
||||||
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
|
|
||||||
pub enum TransformKey {
|
|
||||||
Local,
|
|
||||||
ScaleOffset(ScaleOffsetKey),
|
|
||||||
Transform(MatrixKey),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransformKey {
|
|
||||||
pub fn local() -> Self {
|
|
||||||
TransformKey::Local
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, T> From<CoordinateSpaceMapping<F, T>> for TransformKey {
|
|
||||||
/// Construct a transform cache key from a coordinate space mapping.
|
|
||||||
fn from(mapping: CoordinateSpaceMapping<F, T>) -> TransformKey {
|
|
||||||
match mapping {
|
|
||||||
CoordinateSpaceMapping::Local => {
|
|
||||||
TransformKey::Local
|
|
||||||
}
|
|
||||||
CoordinateSpaceMapping::ScaleOffset(ref scale_offset) => {
|
|
||||||
TransformKey::ScaleOffset(ScaleOffsetKey::new(scale_offset))
|
|
||||||
}
|
|
||||||
CoordinateSpaceMapping::Transform(ref transform) => {
|
|
||||||
TransformKey::Transform(MatrixKey::new(transform))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This key uniquely identifies the contents of a cached
|
|
||||||
/// picture surface.
|
|
||||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
|
||||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
|
||||||
pub struct SurfaceCacheKey {
|
|
||||||
/// The list of primitives that are part of this surface.
|
|
||||||
/// The uid uniquely identifies the content of the primitive.
|
|
||||||
pub primitive_ids: Vec<ItemUid>,
|
|
||||||
/// The list of clips that affect the primitives on this surface.
|
|
||||||
/// The uid uniquely identifies the content of the clip.
|
|
||||||
pub clip_ids: Vec<ItemUid>,
|
|
||||||
/// A list of transforms that can affect the contents of primitives
|
|
||||||
/// and/or clips on this picture surface.
|
|
||||||
pub transforms: Vec<TransformKey>,
|
|
||||||
/// Information about the transform of the picture surface itself. If we are
|
|
||||||
/// drawing in screen-space, then the value of this affects the contents
|
|
||||||
/// of the cached surface. If we're drawing in local space, then the transform
|
|
||||||
/// of the surface in its parent is not relevant to the contents.
|
|
||||||
pub raster_transform: TransformKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A descriptor for the contents of a picture surface.
|
|
||||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
|
||||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
|
||||||
pub struct SurfaceDescriptor {
|
|
||||||
/// The cache key identifies the contents or primitives, clips and the current
|
|
||||||
/// state of relevant transforms.
|
|
||||||
pub cache_key: SurfaceCacheKey,
|
|
||||||
|
|
||||||
/// The spatial nodes array is used to update the cache key each frame, without
|
|
||||||
/// relying on the value of a spatial node index (these may change, if other parts of the
|
|
||||||
/// display list result in a different clip-scroll tree).
|
|
||||||
pub spatial_nodes: Vec<SpatialNodeIndex>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SurfaceDescriptor {
|
|
||||||
/// Construct a new surface descriptor for this list of primitives.
|
|
||||||
/// This method is fallible - it will return None if this picture
|
|
||||||
/// contains primitives that can't currently be cached safely.
|
|
||||||
pub fn new(
|
|
||||||
prim_instances: &[PrimitiveInstance],
|
|
||||||
pic_spatial_node_index: SpatialNodeIndex,
|
|
||||||
clip_store: &ClipStore,
|
|
||||||
) -> Option<Self> {
|
|
||||||
let mut relevant_spatial_nodes = FastHashSet::default();
|
|
||||||
let mut primitive_ids = Vec::new();
|
|
||||||
let mut clip_ids = Vec::new();
|
|
||||||
|
|
||||||
for prim_instance in prim_instances {
|
|
||||||
// If the prim has the same spatial node as the surface,
|
|
||||||
// then the content can't move relative to it, so we don't
|
|
||||||
// care if the transform changes.
|
|
||||||
if pic_spatial_node_index != prim_instance.spatial_node_index {
|
|
||||||
relevant_spatial_nodes.insert(prim_instance.spatial_node_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect clip node transforms that we care about.
|
|
||||||
let mut clip_chain_id = prim_instance.clip_chain_id;
|
|
||||||
while clip_chain_id != ClipChainId::NONE {
|
|
||||||
let clip_chain_node = &clip_store.clip_chain_nodes[clip_chain_id.0 as usize];
|
|
||||||
|
|
||||||
// TODO(gw): This needs to be a bit more careful once we create
|
|
||||||
// descriptors for pictures that might be pass-through.
|
|
||||||
|
|
||||||
// Ignore clip chain nodes that will be handled by the clip node collector.
|
|
||||||
if clip_chain_node.spatial_node_index > pic_spatial_node_index {
|
|
||||||
relevant_spatial_nodes.insert(prim_instance.spatial_node_index);
|
|
||||||
|
|
||||||
clip_ids.push(clip_chain_node.handle.uid());
|
|
||||||
}
|
|
||||||
|
|
||||||
clip_chain_id = clip_chain_node.parent_clip_chain_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For now, we only handle interned primitives. If we encounter
|
|
||||||
// a legacy primitive or picture, then fail to create a cache
|
|
||||||
// descriptor.
|
|
||||||
if let PrimitiveInstanceKind::Picture { .. } = prim_instance.kind {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record the unique identifier for the content represented
|
|
||||||
// by this primitive.
|
|
||||||
primitive_ids.push(prim_instance.uid());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a list of spatial nodes that are relevant for the contents
|
|
||||||
// of this picture. Sort them to ensure that for a given clip-scroll
|
|
||||||
// tree, we end up with the same transform ordering.
|
|
||||||
let mut spatial_nodes: Vec<SpatialNodeIndex> = relevant_spatial_nodes
|
|
||||||
.into_iter()
|
|
||||||
.collect();
|
|
||||||
spatial_nodes.sort();
|
|
||||||
|
|
||||||
// Create the array of transform values that gets built each
|
|
||||||
// frame during update.
|
|
||||||
let transforms = vec![TransformKey::local(); spatial_nodes.len()];
|
|
||||||
|
|
||||||
let cache_key = SurfaceCacheKey {
|
|
||||||
primitive_ids,
|
|
||||||
clip_ids,
|
|
||||||
transforms,
|
|
||||||
raster_transform: TransformKey::local(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(SurfaceDescriptor {
|
|
||||||
cache_key,
|
|
||||||
spatial_nodes,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Update the transforms for this cache key, by extracting the current
|
|
||||||
/// values from the clip-scroll tree state.
|
|
||||||
pub fn update(
|
|
||||||
&mut self,
|
|
||||||
surface_spatial_node_index: SpatialNodeIndex,
|
|
||||||
raster_spatial_node_index: SpatialNodeIndex,
|
|
||||||
clip_scroll_tree: &ClipScrollTree,
|
|
||||||
raster_space: RasterSpace,
|
|
||||||
) {
|
|
||||||
// Update the state of the transform for compositing this picture.
|
|
||||||
self.cache_key.raster_transform = match raster_space {
|
|
||||||
RasterSpace::Screen => {
|
|
||||||
// In general cases, if we're rasterizing a picture in screen space, then the
|
|
||||||
// value of the surface spatial node will affect the contents of the picture
|
|
||||||
// itself. However, if the surface and raster spatial nodes are in the same
|
|
||||||
// coordinate system (which is the common case!) then we are effectively drawing
|
|
||||||
// in a local space anyway, so don't care about that transform for the purposes
|
|
||||||
// of validating the surface cache contents.
|
|
||||||
let raster_spatial_node = &clip_scroll_tree.spatial_nodes[raster_spatial_node_index.0 as usize];
|
|
||||||
let surface_spatial_node = &clip_scroll_tree.spatial_nodes[surface_spatial_node_index.0 as usize];
|
|
||||||
|
|
||||||
let mut key = CoordinateSpaceMapping::<LayoutPixel, PicturePixel>::new(
|
|
||||||
raster_spatial_node_index,
|
|
||||||
surface_spatial_node_index,
|
|
||||||
clip_scroll_tree,
|
|
||||||
).expect("bug: unable to get coord mapping").into();
|
|
||||||
|
|
||||||
if let TransformKey::ScaleOffset(ref mut key) = key {
|
|
||||||
if raster_spatial_node.coordinate_system_id == surface_spatial_node.coordinate_system_id {
|
|
||||||
key.offset_x = 0.0;
|
|
||||||
key.offset_y = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
key
|
|
||||||
}
|
|
||||||
RasterSpace::Local(..) => {
|
|
||||||
TransformKey::local()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update the state of any relevant transforms for this picture.
|
|
||||||
for (spatial_node_index, transform) in self.spatial_nodes
|
|
||||||
.iter()
|
|
||||||
.zip(self.cache_key.transforms.iter_mut())
|
|
||||||
{
|
|
||||||
*transform = CoordinateSpaceMapping::<LayoutPixel, PicturePixel>::new(
|
|
||||||
raster_spatial_node_index,
|
|
||||||
*spatial_node_index,
|
|
||||||
clip_scroll_tree,
|
|
||||||
).expect("bug: unable to get coord mapping").into();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Двоичные данные
gfx/wr/wrench/reftests/border/border-suite-2.png
Двоичные данные
gfx/wr/wrench/reftests/border/border-suite-2.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 48 KiB После Ширина: | Высота: | Размер: 48 KiB |
Загрузка…
Ссылка в новой задаче