зеркало из 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,
|
||||
main_scroll_root,
|
||||
LayoutRect::max_rect(),
|
||||
&self.clip_store,
|
||||
Some(tile_cache),
|
||||
));
|
||||
|
||||
|
@ -1214,7 +1213,6 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
let extra_instance = sc.cut_flat_item_sequence(
|
||||
&mut self.prim_store,
|
||||
&mut self.interners,
|
||||
&self.clip_store,
|
||||
);
|
||||
(sc.is_3d(), extra_instance)
|
||||
},
|
||||
|
@ -1365,7 +1363,6 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
),
|
||||
stacking_context.spatial_node_index,
|
||||
max_clip,
|
||||
&self.clip_store,
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
@ -1412,7 +1409,6 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
),
|
||||
stacking_context.spatial_node_index,
|
||||
max_clip,
|
||||
&self.clip_store,
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
@ -1447,7 +1443,6 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
),
|
||||
stacking_context.spatial_node_index,
|
||||
max_clip,
|
||||
&self.clip_store,
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
@ -1490,7 +1485,6 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
),
|
||||
stacking_context.spatial_node_index,
|
||||
max_clip,
|
||||
&self.clip_store,
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
@ -1826,7 +1820,6 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
),
|
||||
pending_shadow.clip_and_scroll.spatial_node_index,
|
||||
max_clip,
|
||||
&self.clip_store,
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
@ -2570,7 +2563,6 @@ impl FlattenedStackingContext {
|
|||
&mut self,
|
||||
prim_store: &mut PrimitiveStore,
|
||||
interners: &mut Interners,
|
||||
clip_store: &ClipStore,
|
||||
) -> Option<PrimitiveInstance> {
|
||||
if !self.is_3d() || self.primitives.is_empty() {
|
||||
return None
|
||||
|
@ -2598,7 +2590,6 @@ impl FlattenedStackingContext {
|
|||
),
|
||||
self.spatial_node_index,
|
||||
LayoutRect::max_rect(),
|
||||
clip_store,
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
|
|
@ -115,7 +115,6 @@ mod segment;
|
|||
mod shade;
|
||||
mod spatial_node;
|
||||
mod storage;
|
||||
mod surface;
|
||||
mod texture_allocator;
|
||||
mod texture_cache;
|
||||
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::{DebugFlags, DeviceVector2D};
|
||||
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 debug_colors;
|
||||
use device::TextureFilter;
|
||||
|
@ -32,7 +32,6 @@ use resource_cache::ResourceCache;
|
|||
use scene::{FilterOpHelpers, SceneProperties};
|
||||
use scene_builder::Interners;
|
||||
use smallvec::SmallVec;
|
||||
use surface::{SurfaceDescriptor};
|
||||
use std::{mem, u16};
|
||||
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||
use texture_cache::{Eviction, TextureCacheHandle};
|
||||
|
@ -1959,9 +1958,6 @@ pub struct PicturePrimitive {
|
|||
/// Local clip rect for this picture.
|
||||
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,
|
||||
|
||||
/// If Some(..) the tile cache that is associated with this picture.
|
||||
|
@ -2051,33 +2047,9 @@ impl PicturePrimitive {
|
|||
prim_list: PrimitiveList,
|
||||
spatial_node_index: SpatialNodeIndex,
|
||||
local_clip_rect: LayoutRect,
|
||||
clip_store: &ClipStore,
|
||||
tile_cache: Option<TileCache>,
|
||||
) -> 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 {
|
||||
surface_desc,
|
||||
prim_list,
|
||||
state: 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 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 {
|
||||
PictureCompositeMode::Filter(FilterOp::Blur(blur_radius)) => {
|
||||
// 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 {
|
||||
composite_mode,
|
||||
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 render_backend::FrameId;
|
||||
use resource_cache::{CacheItem, ResourceCache};
|
||||
use surface::SurfaceCacheKey;
|
||||
use std::{ops, mem, usize, f32, i32, u32};
|
||||
use texture_cache::{TextureCache, TextureCacheHandle, Eviction};
|
||||
use tiling::{RenderPass, RenderTargetIndex};
|
||||
|
@ -1090,8 +1089,6 @@ pub enum RenderTaskCacheKeyKind {
|
|||
Image(ImageCacheKey),
|
||||
#[allow(dead_code)]
|
||||
Glyph(GpuGlyphCacheKey),
|
||||
#[allow(dead_code)]
|
||||
Picture(SurfaceCacheKey),
|
||||
BorderSegment(BorderSegmentCacheKey),
|
||||
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 |
Загрузка…
Ссылка в новой задаче