зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1510082 - Update webrender to commit e2e52b1145ad959191c0612edd41b0b189cf6b59 (WR PR #3346). r=kats
https://github.com/servo/webrender/pull/3346 Differential Revision: https://phabricator.services.mozilla.com/D13026 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1669ae2beb
Коммит
0d52f7e529
|
@ -1 +1 @@
|
|||
f450af9277e2474e2a2a2c1358689ca9486e2a09
|
||||
e2e52b1145ad959191c0612edd41b0b189cf6b59
|
||||
|
|
|
@ -17,7 +17,7 @@ use internal_types::{FastHashMap, SavedTargetIndex, TextureSource};
|
|||
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureSurface};
|
||||
use prim_store::{BrushKind, BrushPrimitive, DeferredResolve, PrimitiveTemplateKind};
|
||||
use prim_store::{EdgeAaSegmentMask, ImageSource, PrimitiveInstanceKind, PrimitiveStore};
|
||||
use prim_store::{VisibleGradientTile, PrimitiveInstance, PrimitiveOpacity};
|
||||
use prim_store::{VisibleGradientTile, PrimitiveInstance, PrimitiveOpacity, SegmentInstanceIndex};
|
||||
use prim_store::{BrushSegment, ClipMaskKind, ClipTaskIndex, PrimitiveDetails};
|
||||
use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskTree};
|
||||
use renderer::{BlendMode, ImageBufferKind, ShaderColorMode};
|
||||
|
@ -905,6 +905,7 @@ impl AlphaBatchBuilder {
|
|||
PrimitiveInstanceKind::LegacyPrimitive { .. } |
|
||||
PrimitiveInstanceKind::NormalBorder { .. } |
|
||||
PrimitiveInstanceKind::ImageBorder { .. } |
|
||||
PrimitiveInstanceKind::Rectangle { .. } |
|
||||
PrimitiveInstanceKind::Clear => {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -1617,6 +1618,71 @@ impl AlphaBatchBuilder {
|
|||
ctx,
|
||||
);
|
||||
}
|
||||
(
|
||||
PrimitiveInstanceKind::Rectangle { segment_instance_index, opacity_binding_index, .. },
|
||||
PrimitiveTemplateKind::Rectangle { .. }
|
||||
) => {
|
||||
let specified_blend_mode = BlendMode::PremultipliedAlpha;
|
||||
let opacity_binding = ctx.prim_store.get_opacity_binding(*opacity_binding_index);
|
||||
|
||||
let opacity = PrimitiveOpacity::from_alpha(opacity_binding);
|
||||
let opacity = opacity.combine(prim_data.opacity);
|
||||
|
||||
let non_segmented_blend_mode = if !opacity.is_opaque ||
|
||||
prim_instance.clip_task_index != ClipTaskIndex::INVALID ||
|
||||
transform_kind == TransformedRectKind::Complex
|
||||
{
|
||||
specified_blend_mode
|
||||
} else {
|
||||
BlendMode::None
|
||||
};
|
||||
|
||||
let batch_params = BrushBatchParameters::shared(
|
||||
BrushBatchKind::Solid,
|
||||
BatchTextures::no_texture(),
|
||||
[get_shader_opacity(opacity_binding), 0, 0],
|
||||
0,
|
||||
);
|
||||
|
||||
let (prim_cache_address, segments) = if *segment_instance_index == SegmentInstanceIndex::UNUSED {
|
||||
(gpu_cache.get_address(&prim_data.gpu_cache_handle), None)
|
||||
} else {
|
||||
let segment_instance = &ctx.scratch.segment_instances[*segment_instance_index];
|
||||
let segments = Some(&ctx.scratch.segments[segment_instance.segments_range]);
|
||||
(gpu_cache.get_address(&segment_instance.gpu_cache_handle), segments)
|
||||
};
|
||||
|
||||
let prim_header = PrimitiveHeader {
|
||||
local_rect: prim_data.prim_rect,
|
||||
local_clip_rect: prim_instance.combined_local_clip_rect,
|
||||
task_address,
|
||||
specific_prim_address: prim_cache_address,
|
||||
clip_task_address,
|
||||
transform_id,
|
||||
};
|
||||
|
||||
let prim_header_index = prim_headers.push(
|
||||
&prim_header,
|
||||
z_id,
|
||||
batch_params.prim_user_data,
|
||||
);
|
||||
|
||||
self.add_segmented_prim_to_batch(
|
||||
segments,
|
||||
opacity,
|
||||
&batch_params,
|
||||
specified_blend_mode,
|
||||
non_segmented_blend_mode,
|
||||
prim_header_index,
|
||||
clip_task_address,
|
||||
bounding_rect,
|
||||
transform_kind,
|
||||
render_tasks,
|
||||
z_id,
|
||||
prim_instance.clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -1794,7 +1860,7 @@ impl AlphaBatchBuilder {
|
|||
textures: segment_data.textures,
|
||||
};
|
||||
let instance = PrimitiveInstanceData::from(BrushInstance {
|
||||
segment_index: 0,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
|
@ -1999,15 +2065,6 @@ impl BrushPrimitive {
|
|||
))
|
||||
}
|
||||
}
|
||||
BrushKind::Solid { opacity_binding_index, .. } => {
|
||||
let opacity_binding = prim_store.get_opacity_binding(opacity_binding_index);
|
||||
Some(BrushBatchParameters::shared(
|
||||
BrushBatchKind::Solid,
|
||||
BatchTextures::no_texture(),
|
||||
[get_shader_opacity(opacity_binding), 0, 0],
|
||||
0,
|
||||
))
|
||||
}
|
||||
BrushKind::RadialGradient { ref stops_handle, .. } => {
|
||||
Some(BrushBatchParameters::shared(
|
||||
BrushBatchKind::RadialGradient,
|
||||
|
@ -2106,7 +2163,6 @@ impl PrimitiveInstance {
|
|||
AlphaType::Alpha => BlendMode::Alpha,
|
||||
}
|
||||
}
|
||||
BrushKind::Solid { .. } |
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::RadialGradient { .. } |
|
||||
BrushKind::LinearGradient { .. } => {
|
||||
|
|
|
@ -8,7 +8,7 @@ use clip::ClipItemKey;
|
|||
use display_list_flattener::DisplayListFlattener;
|
||||
use gpu_cache::GpuCacheHandle;
|
||||
use gpu_types::BoxShadowStretchMode;
|
||||
use prim_store::{BrushKind, BrushPrimitive, PrimitiveContainer};
|
||||
use prim_store::PrimitiveContainer;
|
||||
use prim_store::ScrollNodeAndClipChain;
|
||||
use render_task::RenderTaskCacheEntryHandle;
|
||||
use util::RectHelpers;
|
||||
|
@ -149,7 +149,9 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
clip_and_scroll,
|
||||
&LayoutPrimitiveInfo::with_clip_rect(final_prim_rect, prim_info.clip_rect),
|
||||
clips,
|
||||
PrimitiveContainer::Brush(BrushPrimitive::new(BrushKind::new_solid(*color), None)),
|
||||
PrimitiveContainer::Rectangle {
|
||||
color: *color,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// Normal path for box-shadows with a valid blur radius.
|
||||
|
@ -170,7 +172,9 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
|
||||
// Draw the box-shadow as a solid rect, using a box-shadow
|
||||
// clip mask item.
|
||||
let prim = BrushPrimitive::new(BrushKind::new_solid(*color), None);
|
||||
let prim = PrimitiveContainer::Rectangle {
|
||||
color: *color,
|
||||
};
|
||||
|
||||
// Create the box-shadow clip item.
|
||||
let shadow_clip_source = ClipItemKey::box_shadow(
|
||||
|
@ -221,7 +225,7 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
clip_and_scroll,
|
||||
&prim_info,
|
||||
extra_clips,
|
||||
PrimitiveContainer::Brush(prim),
|
||||
prim,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -840,7 +840,9 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
// style PrimitiveDetails structure from the
|
||||
// source primitive container.
|
||||
let mut info = info.clone();
|
||||
let (prim_key_kind, prim_details) = container.build(&mut info);
|
||||
let (prim_key_kind, prim_details) = container.build(
|
||||
&mut info,
|
||||
);
|
||||
|
||||
let prim_key = PrimitiveKey::new(
|
||||
info.is_backface_visible,
|
||||
|
@ -1679,16 +1681,13 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
return;
|
||||
}
|
||||
|
||||
let prim = BrushPrimitive::new(
|
||||
BrushKind::new_solid(color),
|
||||
None,
|
||||
);
|
||||
|
||||
self.add_primitive(
|
||||
clip_and_scroll,
|
||||
info,
|
||||
Vec::new(),
|
||||
PrimitiveContainer::Brush(prim),
|
||||
PrimitiveContainer::Rectangle {
|
||||
color,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,6 @@ pub struct FrameBuildingState<'a> {
|
|||
pub transforms: &'a mut TransformPalette,
|
||||
pub segment_builder: SegmentBuilder,
|
||||
pub surfaces: &'a mut Vec<SurfaceInfo>,
|
||||
pub scratch: &'a mut PrimitiveScratchBuffer,
|
||||
}
|
||||
|
||||
/// Immutable context of a picture when processing children.
|
||||
|
@ -255,7 +254,6 @@ impl FrameBuilder {
|
|||
transforms: transform_palette,
|
||||
segment_builder: SegmentBuilder::new(),
|
||||
surfaces: pic_update_state.surfaces,
|
||||
scratch,
|
||||
};
|
||||
|
||||
let (pic_context, mut pic_state, mut prim_list) = self
|
||||
|
@ -279,6 +277,7 @@ impl FrameBuilder {
|
|||
&frame_context,
|
||||
&mut frame_state,
|
||||
resources,
|
||||
scratch,
|
||||
);
|
||||
|
||||
let pic = &mut self.prim_store.pictures[self.root_pic_index.0];
|
||||
|
|
|
@ -414,14 +414,6 @@ impl TileCache {
|
|||
// TODO(gw): In future, we might be able to completely remove
|
||||
// opacity collapsing support. It's of limited use
|
||||
// once we have full picture caching.
|
||||
BrushKind::Solid { opacity_binding_index, .. } => {
|
||||
let opacity_binding = &opacity_binding_store[opacity_binding_index];
|
||||
for binding in &opacity_binding.bindings {
|
||||
if let PropertyBinding::Binding(key, default) = binding {
|
||||
opacity_bindings.push((key.id, *default));
|
||||
}
|
||||
}
|
||||
}
|
||||
BrushKind::Image { opacity_binding_index, ref request, .. } => {
|
||||
let opacity_binding = &opacity_binding_store[opacity_binding_index];
|
||||
for binding in &opacity_binding.bindings {
|
||||
|
@ -442,6 +434,14 @@ impl TileCache {
|
|||
}
|
||||
}
|
||||
}
|
||||
PrimitiveInstanceKind::Rectangle { opacity_binding_index, .. } => {
|
||||
let opacity_binding = &opacity_binding_store[opacity_binding_index];
|
||||
for binding in &opacity_binding.bindings {
|
||||
if let PropertyBinding::Binding(key, default) = binding {
|
||||
opacity_bindings.push((key.id, *default));
|
||||
}
|
||||
}
|
||||
}
|
||||
PrimitiveInstanceKind::TextRun { .. } |
|
||||
PrimitiveInstanceKind::LineDecoration { .. } |
|
||||
PrimitiveInstanceKind::Clear |
|
||||
|
|
|
@ -12,7 +12,7 @@ use api::{PicturePixel, RasterPixel, ColorDepth, LineStyle, LineOrientation, Lay
|
|||
use app_units::Au;
|
||||
use border::{get_max_scale_for_border, build_border_instances, create_border_segments};
|
||||
use border::{create_nine_patch_segments, BorderSegmentCacheKey, NormalBorderAu};
|
||||
use clip::ClipStore;
|
||||
use clip::{ClipStore};
|
||||
use clip_scroll_tree::{ClipScrollTree, SpatialNodeIndex};
|
||||
use clip::{ClipDataStore, ClipNodeFlags, ClipChainId, ClipChainInstance, ClipItem, ClipNodeCollector};
|
||||
use euclid::{SideOffsets2D, TypedTransform3D, TypedRect, TypedScale};
|
||||
|
@ -33,6 +33,7 @@ use render_task::{RenderTaskCacheKeyKind, RenderTaskId, RenderTaskCacheEntryHand
|
|||
use renderer::{MAX_VERTEX_TEXTURE_WIDTH};
|
||||
use resource_cache::{ImageProperties, ImageRequest, ResourceCache};
|
||||
use scene::SceneProperties;
|
||||
use segment::SegmentBuilder;
|
||||
use std::{cmp, fmt, mem, ops, u32, usize};
|
||||
#[cfg(debug_assertions)]
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
@ -100,6 +101,12 @@ impl PrimitiveOpacity {
|
|||
is_opaque: alpha >= 1.0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn combine(&self, other: PrimitiveOpacity) -> PrimitiveOpacity {
|
||||
PrimitiveOpacity{
|
||||
is_opaque: self.is_opaque && other.is_opaque
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
@ -377,6 +384,9 @@ pub enum PrimitiveKeyKind {
|
|||
repeat_vertical: RepeatMode,
|
||||
outset: SideOffsets2D<Au>,
|
||||
},
|
||||
Rectangle {
|
||||
color: ColorU,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
|
@ -439,6 +449,12 @@ impl PrimitiveKey {
|
|||
PrimitiveInstanceKind::ImageBorder {
|
||||
}
|
||||
}
|
||||
PrimitiveKeyKind::Rectangle { .. } => {
|
||||
PrimitiveInstanceKind::Rectangle {
|
||||
opacity_binding_index: OpacityBindingIndex::INVALID,
|
||||
segment_instance_index: SegmentInstanceIndex::INVALID,
|
||||
}
|
||||
}
|
||||
PrimitiveKeyKind::Unused => {
|
||||
// Should never be hit as this method should not be
|
||||
// called for old style primitives.
|
||||
|
@ -478,6 +494,9 @@ pub enum PrimitiveTemplateKind {
|
|||
request: ImageRequest,
|
||||
brush_segments: Vec<BrushSegment>,
|
||||
},
|
||||
Rectangle {
|
||||
color: ColorF,
|
||||
},
|
||||
Clear,
|
||||
Unused,
|
||||
}
|
||||
|
@ -486,7 +505,10 @@ pub enum PrimitiveTemplateKind {
|
|||
/// is invoked when a primitive key is created and the interner
|
||||
/// doesn't currently contain a primitive with this key.
|
||||
impl PrimitiveKeyKind {
|
||||
fn into_template(self, rect: &LayoutRect) -> PrimitiveTemplateKind {
|
||||
fn into_template(
|
||||
self,
|
||||
rect: &LayoutRect,
|
||||
) -> PrimitiveTemplateKind {
|
||||
match self {
|
||||
PrimitiveKeyKind::Unused => PrimitiveTemplateKind::Unused,
|
||||
PrimitiveKeyKind::TextRun { glyphs, font, offset, .. } => {
|
||||
|
@ -562,6 +584,11 @@ impl PrimitiveKeyKind {
|
|||
brush_segments,
|
||||
}
|
||||
}
|
||||
PrimitiveKeyKind::Rectangle { color, .. } => {
|
||||
PrimitiveTemplateKind::Rectangle {
|
||||
color: color.into(),
|
||||
}
|
||||
}
|
||||
PrimitiveKeyKind::LineDecoration { cache_key, color } => {
|
||||
PrimitiveTemplateKind::LineDecoration {
|
||||
cache_key,
|
||||
|
@ -627,6 +654,13 @@ impl PrimitiveTemplate {
|
|||
|
||||
PrimitiveOpacity::translucent()
|
||||
}
|
||||
PrimitiveTemplateKind::Rectangle { ref color, .. } => {
|
||||
if let Some(mut request) = frame_state.gpu_cache.request(&mut self.gpu_cache_handle) {
|
||||
request.push(color.premultiplied());
|
||||
}
|
||||
|
||||
PrimitiveOpacity::from_alpha(color.a)
|
||||
}
|
||||
PrimitiveTemplateKind::NormalBorder { ref template, .. } => {
|
||||
if let Some(mut request) = frame_state.gpu_cache.request(&mut self.gpu_cache_handle) {
|
||||
// Border primitives currently used for
|
||||
|
@ -856,10 +890,6 @@ pub struct BorderSegmentInfo {
|
|||
}
|
||||
|
||||
pub enum BrushKind {
|
||||
Solid {
|
||||
color: ColorF,
|
||||
opacity_binding_index: OpacityBindingIndex,
|
||||
},
|
||||
Image {
|
||||
request: ImageRequest,
|
||||
alpha_type: AlphaType,
|
||||
|
@ -915,21 +945,12 @@ impl BrushKind {
|
|||
.is_none()
|
||||
}
|
||||
|
||||
BrushKind::Solid { .. } |
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::RadialGradient { .. } |
|
||||
BrushKind::LinearGradient { .. } => true,
|
||||
}
|
||||
}
|
||||
|
||||
// Construct a brush that is a solid color rectangle.
|
||||
pub fn new_solid(color: ColorF) -> BrushKind {
|
||||
BrushKind::Solid {
|
||||
color,
|
||||
opacity_binding_index: OpacityBindingIndex::INVALID,
|
||||
}
|
||||
}
|
||||
|
||||
// Construct a brush that is an image wisth `stretch_size` dimensions and
|
||||
// `color`.
|
||||
pub fn new_image(
|
||||
|
@ -1117,10 +1138,6 @@ impl BrushPrimitive {
|
|||
0.0,
|
||||
]);
|
||||
}
|
||||
// Solid rects also support opacity collapsing.
|
||||
BrushKind::Solid { ref color, .. } => {
|
||||
request.push(color.premultiplied());
|
||||
}
|
||||
BrushKind::LinearGradient { stretch_size, start_point, end_point, extend_mode, .. } => {
|
||||
request.push([
|
||||
start_point.x,
|
||||
|
@ -1725,6 +1742,9 @@ pub enum PrimitiveContainer {
|
|||
repeat_vertical: RepeatMode,
|
||||
outset: SideOffsets2D<f32>,
|
||||
},
|
||||
Rectangle {
|
||||
color: ColorF,
|
||||
},
|
||||
}
|
||||
|
||||
impl PrimitiveContainer {
|
||||
|
@ -1742,9 +1762,6 @@ impl PrimitiveContainer {
|
|||
}
|
||||
PrimitiveContainer::Brush(ref brush) => {
|
||||
match brush.kind {
|
||||
BrushKind::Solid { ref color, .. } => {
|
||||
color.a > 0.0
|
||||
}
|
||||
BrushKind::Image { .. } |
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::RadialGradient { .. } |
|
||||
|
@ -1758,6 +1775,7 @@ impl PrimitiveContainer {
|
|||
PrimitiveContainer::Clear => {
|
||||
true
|
||||
}
|
||||
PrimitiveContainer::Rectangle { ref color, .. } |
|
||||
PrimitiveContainer::LineDecoration { ref color, .. } => {
|
||||
color.a > 0.0
|
||||
}
|
||||
|
@ -1784,6 +1802,13 @@ impl PrimitiveContainer {
|
|||
PrimitiveContainer::Clear => {
|
||||
(PrimitiveKeyKind::Clear, None)
|
||||
}
|
||||
PrimitiveContainer::Rectangle { color, .. } => {
|
||||
let key = PrimitiveKeyKind::Rectangle {
|
||||
color: color.into(),
|
||||
};
|
||||
|
||||
(key, None)
|
||||
}
|
||||
PrimitiveContainer::ImageBorder {
|
||||
request,
|
||||
widths,
|
||||
|
@ -1920,6 +1945,11 @@ impl PrimitiveContainer {
|
|||
wavy_line_thickness,
|
||||
}
|
||||
}
|
||||
PrimitiveContainer::Rectangle { .. } => {
|
||||
PrimitiveContainer::Rectangle {
|
||||
color: shadow.color,
|
||||
}
|
||||
}
|
||||
PrimitiveContainer::NormalBorder { border, widths, .. } => {
|
||||
let border = border.with_color(shadow.color);
|
||||
PrimitiveContainer::NormalBorder {
|
||||
|
@ -1929,12 +1959,6 @@ impl PrimitiveContainer {
|
|||
}
|
||||
PrimitiveContainer::Brush(ref brush) => {
|
||||
match brush.kind {
|
||||
BrushKind::Solid { .. } => {
|
||||
PrimitiveContainer::Brush(BrushPrimitive::new(
|
||||
BrushKind::new_solid(shadow.color),
|
||||
None,
|
||||
))
|
||||
}
|
||||
BrushKind::Image { request, stretch_size, .. } => {
|
||||
PrimitiveContainer::Brush(BrushPrimitive::new(
|
||||
BrushKind::new_image(request.clone(),
|
||||
|
@ -2008,6 +2032,10 @@ pub enum PrimitiveInstanceKind {
|
|||
},
|
||||
ImageBorder {
|
||||
},
|
||||
Rectangle {
|
||||
opacity_binding_index: OpacityBindingIndex,
|
||||
segment_instance_index: SegmentInstanceIndex,
|
||||
},
|
||||
/// Clear out a rect, used for special effects.
|
||||
Clear,
|
||||
}
|
||||
|
@ -2091,12 +2119,22 @@ impl PrimitiveInstance {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SegmentedInstance {
|
||||
pub gpu_cache_handle: GpuCacheHandle,
|
||||
pub segments_range: SegmentsRange,
|
||||
}
|
||||
|
||||
pub type GlyphKeyStorage = storage::Storage<GlyphKey>;
|
||||
pub type TextRunIndex = storage::Index<TextRunPrimitive>;
|
||||
pub type TextRunStorage = storage::Storage<TextRunPrimitive>;
|
||||
pub type OpacityBindingIndex = storage::Index<OpacityBinding>;
|
||||
pub type OpacityBindingStorage = storage::Storage<OpacityBinding>;
|
||||
pub type BorderHandleStorage = storage::Storage<RenderTaskCacheEntryHandle>;
|
||||
pub type SegmentStorage = storage::Storage<BrushSegment>;
|
||||
pub type SegmentsRange = storage::Range<BrushSegment>;
|
||||
pub type SegmentInstanceStorage = storage::Storage<SegmentedInstance>;
|
||||
pub type SegmentInstanceIndex = storage::Index<SegmentedInstance>;
|
||||
|
||||
/// Contains various vecs of data that is used only during frame building,
|
||||
/// where we want to recycle the memory each new display list, to avoid constantly
|
||||
|
@ -2114,6 +2152,14 @@ pub struct PrimitiveScratchBuffer {
|
|||
/// List of render task handles for border segment instances
|
||||
/// that have been added this frame.
|
||||
pub border_cache_handles: BorderHandleStorage,
|
||||
|
||||
/// A list of brush segments that have been built for this scene.
|
||||
pub segments: SegmentStorage,
|
||||
|
||||
/// A list of segment ranges and GPU cache handles for prim instances
|
||||
/// that have opted into segment building. In future, this should be
|
||||
/// removed in favor of segment building during primitive interning.
|
||||
pub segment_instances: SegmentInstanceStorage,
|
||||
}
|
||||
|
||||
impl PrimitiveScratchBuffer {
|
||||
|
@ -2122,6 +2168,8 @@ impl PrimitiveScratchBuffer {
|
|||
clip_mask_instances: Vec::new(),
|
||||
glyph_keys: GlyphKeyStorage::new(0),
|
||||
border_cache_handles: BorderHandleStorage::new(0),
|
||||
segments: SegmentStorage::new(0),
|
||||
segment_instances: SegmentInstanceStorage::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2129,6 +2177,8 @@ impl PrimitiveScratchBuffer {
|
|||
recycle_vec(&mut self.clip_mask_instances);
|
||||
self.glyph_keys.recycle();
|
||||
self.border_cache_handles.recycle();
|
||||
self.segments.recycle();
|
||||
self.segment_instances.recycle();
|
||||
}
|
||||
|
||||
pub fn begin_frame(&mut self) {
|
||||
|
@ -2282,7 +2332,7 @@ impl PrimitiveStore {
|
|||
fn get_opacity_collapse_prim(
|
||||
&self,
|
||||
pic_index: PictureIndex,
|
||||
) -> Option<PrimitiveIndex> {
|
||||
) -> Option<PictureIndex> {
|
||||
let pic = &self.pictures[pic_index.0];
|
||||
|
||||
// We can only collapse opacity if there is a single primitive, otherwise
|
||||
|
@ -2298,6 +2348,9 @@ impl PrimitiveStore {
|
|||
// handled by this optimization. In the future, we can easily extend
|
||||
// this to other primitives, such as text runs and gradients.
|
||||
match prim_instance.kind {
|
||||
PrimitiveInstanceKind::Rectangle { .. } => {
|
||||
return Some(pic_index);
|
||||
}
|
||||
PrimitiveInstanceKind::Clear |
|
||||
PrimitiveInstanceKind::TextRun { .. } |
|
||||
PrimitiveInstanceKind::NormalBorder { .. } |
|
||||
|
@ -2324,9 +2377,8 @@ impl PrimitiveStore {
|
|||
match brush.kind {
|
||||
// If we find a single rect or image, we can use that
|
||||
// as the primitive to collapse the opacity into.
|
||||
BrushKind::Solid { .. } |
|
||||
BrushKind::Image { .. } => {
|
||||
return Some(prim_index)
|
||||
return Some(pic_index)
|
||||
}
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::LinearGradient { .. } |
|
||||
|
@ -2361,28 +2413,43 @@ impl PrimitiveStore {
|
|||
// See if this picture contains a single primitive that supports
|
||||
// opacity collapse.
|
||||
match self.get_opacity_collapse_prim(pic_index) {
|
||||
Some(prim_index) => {
|
||||
let prim = &mut self.primitives[prim_index.0];
|
||||
match prim.details {
|
||||
PrimitiveDetails::Brush(ref mut brush) => {
|
||||
// By this point, we know we should only have found a primitive
|
||||
// that supports opacity collapse.
|
||||
match brush.kind {
|
||||
BrushKind::Solid { ref mut opacity_binding_index, .. } |
|
||||
BrushKind::Image { ref mut opacity_binding_index, .. } => {
|
||||
if *opacity_binding_index == OpacityBindingIndex::INVALID {
|
||||
*opacity_binding_index = self.opacity_bindings.push(OpacityBinding::new());
|
||||
Some(pic_index) => {
|
||||
let pic = &mut self.pictures[pic_index.0];
|
||||
let prim_instance = &mut pic.prim_list.prim_instances[0];
|
||||
match prim_instance.kind {
|
||||
PrimitiveInstanceKind::Rectangle { ref mut opacity_binding_index, .. } => {
|
||||
if *opacity_binding_index == OpacityBindingIndex::INVALID {
|
||||
*opacity_binding_index = self.opacity_bindings.push(OpacityBinding::new());
|
||||
}
|
||||
let opacity_binding = &mut self.opacity_bindings[*opacity_binding_index];
|
||||
opacity_binding.push(binding);
|
||||
}
|
||||
PrimitiveInstanceKind::LegacyPrimitive { prim_index } => {
|
||||
let prim = &mut self.primitives[prim_index.0];
|
||||
match prim.details {
|
||||
PrimitiveDetails::Brush(ref mut brush) => {
|
||||
// By this point, we know we should only have found a primitive
|
||||
// that supports opacity collapse.
|
||||
match brush.kind {
|
||||
BrushKind::Image { ref mut opacity_binding_index, .. } => {
|
||||
if *opacity_binding_index == OpacityBindingIndex::INVALID {
|
||||
*opacity_binding_index = self.opacity_bindings.push(OpacityBinding::new());
|
||||
}
|
||||
let opacity_binding = &mut self.opacity_bindings[*opacity_binding_index];
|
||||
opacity_binding.push(binding);
|
||||
}
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::LinearGradient { .. } |
|
||||
BrushKind::RadialGradient { .. } => {
|
||||
unreachable!("bug: invalid prim type for opacity collapse");
|
||||
}
|
||||
}
|
||||
let opacity_binding = &mut self.opacity_bindings[*opacity_binding_index];
|
||||
opacity_binding.push(binding);
|
||||
}
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::LinearGradient { .. } |
|
||||
BrushKind::RadialGradient { .. } => {
|
||||
unreachable!("bug: invalid prim type for opacity collapse");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
|
@ -2413,6 +2480,7 @@ impl PrimitiveStore {
|
|||
display_list: &BuiltDisplayList,
|
||||
plane_split_anchor: usize,
|
||||
resources: &mut FrameResources,
|
||||
scratch: &mut PrimitiveScratchBuffer,
|
||||
) -> bool {
|
||||
// If we have dependencies, we need to prepare them first, in order
|
||||
// to know the actual rect of this primitive.
|
||||
|
@ -2444,6 +2512,7 @@ impl PrimitiveStore {
|
|||
}
|
||||
}
|
||||
PrimitiveInstanceKind::TextRun { .. } |
|
||||
PrimitiveInstanceKind::Rectangle { .. } |
|
||||
PrimitiveInstanceKind::LineDecoration { .. } |
|
||||
PrimitiveInstanceKind::LegacyPrimitive { .. } |
|
||||
PrimitiveInstanceKind::NormalBorder { .. } |
|
||||
|
@ -2466,6 +2535,7 @@ impl PrimitiveStore {
|
|||
frame_context,
|
||||
frame_state,
|
||||
resources,
|
||||
scratch,
|
||||
);
|
||||
|
||||
if !pic_state_for_children.is_cacheable {
|
||||
|
@ -2498,6 +2568,7 @@ impl PrimitiveStore {
|
|||
PrimitiveInstanceKind::Clear |
|
||||
PrimitiveInstanceKind::NormalBorder { .. } |
|
||||
PrimitiveInstanceKind::ImageBorder { .. } |
|
||||
PrimitiveInstanceKind::Rectangle { .. } |
|
||||
PrimitiveInstanceKind::LineDecoration { .. } => {
|
||||
let prim_data = &resources
|
||||
.prim_data_store[prim_instance.prim_data_handle];
|
||||
|
@ -2633,6 +2704,7 @@ impl PrimitiveStore {
|
|||
&clip_node_collector,
|
||||
&mut self.primitives,
|
||||
resources,
|
||||
scratch,
|
||||
);
|
||||
|
||||
if prim_instance.is_chased() {
|
||||
|
@ -2688,6 +2760,7 @@ impl PrimitiveStore {
|
|||
}
|
||||
PrimitiveInstanceKind::TextRun { .. } |
|
||||
PrimitiveInstanceKind::Clear |
|
||||
PrimitiveInstanceKind::Rectangle { .. } |
|
||||
PrimitiveInstanceKind::NormalBorder { .. } |
|
||||
PrimitiveInstanceKind::ImageBorder { .. } |
|
||||
PrimitiveInstanceKind::LineDecoration { .. } => {
|
||||
|
@ -2698,6 +2771,7 @@ impl PrimitiveStore {
|
|||
frame_context,
|
||||
frame_state,
|
||||
resources,
|
||||
scratch,
|
||||
);
|
||||
}
|
||||
PrimitiveInstanceKind::LegacyPrimitive { prim_index } => {
|
||||
|
@ -2728,6 +2802,7 @@ impl PrimitiveStore {
|
|||
frame_context: &FrameBuildingContext,
|
||||
frame_state: &mut FrameBuildingState,
|
||||
resources: &mut FrameResources,
|
||||
scratch: &mut PrimitiveScratchBuffer,
|
||||
) {
|
||||
let display_list = &frame_context
|
||||
.pipelines
|
||||
|
@ -2808,6 +2883,7 @@ impl PrimitiveStore {
|
|||
display_list,
|
||||
plane_split_anchor,
|
||||
resources,
|
||||
scratch,
|
||||
) {
|
||||
frame_state.profile_counters.visible_primitives.inc();
|
||||
}
|
||||
|
@ -2825,6 +2901,7 @@ impl PrimitiveStore {
|
|||
frame_context: &FrameBuildingContext,
|
||||
frame_state: &mut FrameBuildingState,
|
||||
resources: &mut FrameResources,
|
||||
scratch: &mut PrimitiveScratchBuffer,
|
||||
) {
|
||||
let prim_data = &mut resources
|
||||
.prim_data_store[prim_instance.prim_data_handle];
|
||||
|
@ -2907,7 +2984,7 @@ impl PrimitiveStore {
|
|||
frame_state.gpu_cache,
|
||||
frame_state.render_tasks,
|
||||
frame_state.special_render_passes,
|
||||
frame_state.scratch,
|
||||
scratch,
|
||||
);
|
||||
}
|
||||
(
|
||||
|
@ -2969,8 +3046,7 @@ impl PrimitiveStore {
|
|||
));
|
||||
}
|
||||
|
||||
*cache_handles = frame_state
|
||||
.scratch
|
||||
*cache_handles = scratch
|
||||
.border_cache_handles
|
||||
.extend(handles);
|
||||
}
|
||||
|
@ -2979,6 +3055,33 @@ impl PrimitiveStore {
|
|||
PrimitiveTemplateKind::ImageBorder { .. }
|
||||
) => {
|
||||
}
|
||||
(
|
||||
PrimitiveInstanceKind::Rectangle { segment_instance_index, opacity_binding_index, .. },
|
||||
PrimitiveTemplateKind::Rectangle { ref color, .. }
|
||||
) => {
|
||||
if *segment_instance_index != SegmentInstanceIndex::UNUSED {
|
||||
let segment_instance = &mut scratch.segment_instances[*segment_instance_index];
|
||||
|
||||
if let Some(mut request) = frame_state.gpu_cache.request(&mut segment_instance.gpu_cache_handle) {
|
||||
let segments = &scratch.segments[segment_instance.segments_range];
|
||||
|
||||
request.push(color.premultiplied());
|
||||
|
||||
for segment in segments {
|
||||
request.write_segment(
|
||||
segment.local_rect,
|
||||
[0.0; 4],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_opacity_binding(
|
||||
&mut self.opacity_bindings,
|
||||
*opacity_binding_index,
|
||||
frame_context.scene_properties,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -3103,29 +3206,14 @@ impl<'a> GpuDataRequest<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl BrushPrimitive {
|
||||
fn write_brush_segment_description(
|
||||
&mut self,
|
||||
prim_local_rect: LayoutRect,
|
||||
prim_local_clip_rect: LayoutRect,
|
||||
clip_chain: &ClipChainInstance,
|
||||
frame_state: &mut FrameBuildingState,
|
||||
segment_builder: &mut SegmentBuilder,
|
||||
clip_store: &ClipStore,
|
||||
resources: &FrameResources,
|
||||
) {
|
||||
match self.segment_desc {
|
||||
Some(..) => {
|
||||
// If we already have a segment descriptor, skip segment build.
|
||||
return;
|
||||
}
|
||||
None => {
|
||||
// If no segment descriptor built yet, see if it is a brush
|
||||
// type that wants to be segmented.
|
||||
if !self.kind.supports_segments(frame_state.resource_cache) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
) -> bool {
|
||||
// If the brush is small, we generally want to skip building segments
|
||||
// and just draw it as a single primitive with clip mask. However,
|
||||
// if the clips are purely rectangles that have no per-fragment
|
||||
|
@ -3138,7 +3226,6 @@ impl BrushPrimitive {
|
|||
// the clip sources here.
|
||||
let mut rect_clips_only = true;
|
||||
|
||||
let segment_builder = &mut frame_state.segment_builder;
|
||||
segment_builder.initialize(
|
||||
prim_local_rect,
|
||||
None,
|
||||
|
@ -3148,8 +3235,7 @@ impl BrushPrimitive {
|
|||
// Segment the primitive on all the local-space clip sources that we can.
|
||||
let mut local_clip_count = 0;
|
||||
for i in 0 .. clip_chain.clips_range.count {
|
||||
let clip_instance = frame_state
|
||||
.clip_store
|
||||
let clip_instance = clip_store
|
||||
.get_instance_from_range(&clip_chain.clips_range, i);
|
||||
let clip_node = &resources.clip_data_store[clip_instance.handle];
|
||||
|
||||
|
@ -3241,35 +3327,11 @@ impl BrushPrimitive {
|
|||
}
|
||||
}
|
||||
|
||||
match self.segment_desc {
|
||||
Some(..) => panic!("bug: should not already have descriptor"),
|
||||
None => {
|
||||
// TODO(gw): We can probably make the allocation
|
||||
// patterns of this and the segment
|
||||
// builder significantly better, by
|
||||
// retaining it across primitives.
|
||||
let mut segments = BrushSegmentVec::new();
|
||||
|
||||
segment_builder.build(|segment| {
|
||||
segments.push(
|
||||
BrushSegment::new(
|
||||
segment.rect,
|
||||
segment.has_mask,
|
||||
segment.edge_flags,
|
||||
[0.0; 4],
|
||||
BrushFlags::empty(),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
self.segment_desc = Some(BrushSegmentDescriptor {
|
||||
segments,
|
||||
});
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl PrimitiveInstance {
|
||||
fn build_segments_if_needed(
|
||||
|
@ -3280,20 +3342,100 @@ impl PrimitiveInstance {
|
|||
frame_state: &mut FrameBuildingState,
|
||||
primitives: &mut [Primitive],
|
||||
resources: &FrameResources,
|
||||
scratch: &mut PrimitiveScratchBuffer,
|
||||
) {
|
||||
if let PrimitiveInstanceKind::LegacyPrimitive { prim_index } = self.kind {
|
||||
let prim = &mut primitives[prim_index.0];
|
||||
match prim.details {
|
||||
PrimitiveDetails::Brush(ref mut brush) => {
|
||||
brush.write_brush_segment_description(
|
||||
match self.kind {
|
||||
PrimitiveInstanceKind::Rectangle { ref mut segment_instance_index, .. } => {
|
||||
if *segment_instance_index == SegmentInstanceIndex::INVALID {
|
||||
let mut segments: SmallVec<[BrushSegment; 8]> = SmallVec::new();
|
||||
|
||||
if write_brush_segment_description(
|
||||
prim_local_rect,
|
||||
prim_local_clip_rect,
|
||||
prim_clip_chain,
|
||||
frame_state,
|
||||
&mut frame_state.segment_builder,
|
||||
frame_state.clip_store,
|
||||
resources,
|
||||
);
|
||||
) {
|
||||
frame_state.segment_builder.build(|segment| {
|
||||
segments.push(
|
||||
BrushSegment::new(
|
||||
segment.rect,
|
||||
segment.has_mask,
|
||||
segment.edge_flags,
|
||||
[0.0; 4],
|
||||
BrushFlags::empty(),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if segments.is_empty() {
|
||||
*segment_instance_index = SegmentInstanceIndex::UNUSED;
|
||||
} else {
|
||||
let segments_range = scratch
|
||||
.segments
|
||||
.extend(segments);
|
||||
|
||||
let instance = SegmentedInstance {
|
||||
segments_range,
|
||||
gpu_cache_handle: GpuCacheHandle::new(),
|
||||
};
|
||||
|
||||
*segment_instance_index = scratch
|
||||
.segment_instances
|
||||
.push(instance);
|
||||
};
|
||||
}
|
||||
}
|
||||
PrimitiveInstanceKind::LegacyPrimitive { prim_index } => {
|
||||
let prim = &mut primitives[prim_index.0];
|
||||
match prim.details {
|
||||
PrimitiveDetails::Brush(ref mut brush) => {
|
||||
match brush.segment_desc {
|
||||
Some(..) => {
|
||||
// If we already have a segment descriptor, skip segment build.
|
||||
return;
|
||||
}
|
||||
None => {
|
||||
// If no segment descriptor built yet, see if it is a brush
|
||||
// type that wants to be segmented.
|
||||
if brush.kind.supports_segments(frame_state.resource_cache) {
|
||||
let mut segments = BrushSegmentVec::new();
|
||||
|
||||
if write_brush_segment_description(
|
||||
prim_local_rect,
|
||||
prim_local_clip_rect,
|
||||
prim_clip_chain,
|
||||
&mut frame_state.segment_builder,
|
||||
frame_state.clip_store,
|
||||
resources,
|
||||
) {
|
||||
frame_state.segment_builder.build(|segment| {
|
||||
segments.push(
|
||||
BrushSegment::new(
|
||||
segment.rect,
|
||||
segment.has_mask,
|
||||
segment.edge_flags,
|
||||
[0.0; 4],
|
||||
BrushFlags::empty(),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if !segments.is_empty() {
|
||||
brush.segment_desc = Some(BrushSegmentDescriptor {
|
||||
segments,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3311,6 +3453,7 @@ impl PrimitiveInstance {
|
|||
clip_node_collector: &Option<ClipNodeCollector>,
|
||||
primitives: &[Primitive],
|
||||
resources: &mut FrameResources,
|
||||
scratch: &mut PrimitiveScratchBuffer,
|
||||
) -> bool {
|
||||
let segments = match self.kind {
|
||||
PrimitiveInstanceKind::Picture { .. } |
|
||||
|
@ -3319,6 +3462,17 @@ impl PrimitiveInstance {
|
|||
PrimitiveInstanceKind::LineDecoration { .. } => {
|
||||
return false;
|
||||
}
|
||||
PrimitiveInstanceKind::Rectangle { segment_instance_index, .. } => {
|
||||
debug_assert!(segment_instance_index != SegmentInstanceIndex::INVALID);
|
||||
|
||||
if segment_instance_index == SegmentInstanceIndex::UNUSED {
|
||||
return false;
|
||||
}
|
||||
|
||||
let segment_instance = &scratch.segment_instances[segment_instance_index];
|
||||
|
||||
&mut scratch.segments[segment_instance.segments_range]
|
||||
}
|
||||
PrimitiveInstanceKind::ImageBorder { .. } => {
|
||||
let prim_data = &resources.prim_data_store[self.prim_data_handle];
|
||||
|
||||
|
@ -3326,7 +3480,7 @@ impl PrimitiveInstance {
|
|||
// can change this to be a tuple match on (instance, template)
|
||||
match prim_data.kind {
|
||||
PrimitiveTemplateKind::ImageBorder { ref brush_segments, .. } => {
|
||||
brush_segments
|
||||
brush_segments.as_slice()
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
|
@ -3373,7 +3527,7 @@ impl PrimitiveInstance {
|
|||
// Set where in the clip mask instances array the clip mask info
|
||||
// can be found for this primitive. Each segment will push the
|
||||
// clip mask information for itself in update_clip_task below.
|
||||
self.clip_task_index = ClipTaskIndex(frame_state.scratch.clip_mask_instances.len() as _);
|
||||
self.clip_task_index = ClipTaskIndex(scratch.clip_mask_instances.len() as _);
|
||||
|
||||
// If we only built 1 segment, there is no point in re-running
|
||||
// the clip chain builder. Instead, just use the clip chain
|
||||
|
@ -3390,7 +3544,7 @@ impl PrimitiveInstance {
|
|||
frame_state,
|
||||
&mut resources.clip_data_store,
|
||||
);
|
||||
frame_state.scratch.clip_mask_instances.push(clip_mask_kind);
|
||||
scratch.clip_mask_instances.push(clip_mask_kind);
|
||||
} else {
|
||||
for segment in segments {
|
||||
// Build a clip chain for the smaller segment rect. This will
|
||||
|
@ -3424,7 +3578,7 @@ impl PrimitiveInstance {
|
|||
frame_state,
|
||||
&mut resources.clip_data_store,
|
||||
);
|
||||
frame_state.scratch.clip_mask_instances.push(clip_mask_kind);
|
||||
scratch.clip_mask_instances.push(clip_mask_kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3802,14 +3956,6 @@ impl PrimitiveInstance {
|
|||
PrimitiveOpacity::translucent()
|
||||
}
|
||||
}
|
||||
BrushKind::Solid { ref color, opacity_binding_index, .. } => {
|
||||
let current_opacity = update_opacity_binding(
|
||||
opacity_bindings,
|
||||
opacity_binding_index,
|
||||
frame_context.scene_properties,
|
||||
);
|
||||
PrimitiveOpacity::from_alpha(current_opacity * color.a)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -3845,6 +3991,7 @@ impl PrimitiveInstance {
|
|||
clip_node_collector: &Option<ClipNodeCollector>,
|
||||
primitives: &mut [Primitive],
|
||||
resources: &mut FrameResources,
|
||||
scratch: &mut PrimitiveScratchBuffer,
|
||||
) {
|
||||
if self.is_chased() {
|
||||
println!("\tupdating clip task with pic rect {:?}", clip_chain.pic_clip_rect);
|
||||
|
@ -3860,6 +4007,7 @@ impl PrimitiveInstance {
|
|||
frame_state,
|
||||
primitives,
|
||||
resources,
|
||||
scratch,
|
||||
);
|
||||
|
||||
// First try to render this primitive's mask using optimized brush rendering.
|
||||
|
@ -3876,6 +4024,7 @@ impl PrimitiveInstance {
|
|||
clip_node_collector,
|
||||
primitives,
|
||||
resources,
|
||||
scratch,
|
||||
) {
|
||||
if self.is_chased() {
|
||||
println!("\tsegment tasks have been created for clipping");
|
||||
|
@ -3908,8 +4057,8 @@ impl PrimitiveInstance {
|
|||
clip_task_id, device_rect);
|
||||
}
|
||||
// Set the global clip mask instance for this primitive.
|
||||
let clip_task_index = ClipTaskIndex(frame_state.scratch.clip_mask_instances.len() as _);
|
||||
frame_state.scratch.clip_mask_instances.push(ClipMaskKind::Mask(clip_task_id));
|
||||
let clip_task_index = ClipTaskIndex(scratch.clip_mask_instances.len() as _);
|
||||
scratch.clip_mask_instances.push(ClipMaskKind::Mask(clip_task_id));
|
||||
self.clip_task_index = clip_task_index;
|
||||
frame_state.surfaces[pic_context.surface_index.0].tasks.push(clip_task_id);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ impl<T> Index<T> {
|
|||
}
|
||||
|
||||
pub const INVALID: Index<T> = Index(u32::MAX, PhantomData);
|
||||
pub const UNUSED: Index<T> = Index(u32::MAX-1, PhantomData);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -243,6 +243,7 @@ impl SurfaceDescriptor {
|
|||
PrimitiveInstanceKind::LineDecoration { .. } |
|
||||
PrimitiveInstanceKind::TextRun { .. } |
|
||||
PrimitiveInstanceKind::NormalBorder { .. } |
|
||||
PrimitiveInstanceKind::Rectangle { .. } |
|
||||
PrimitiveInstanceKind::ImageBorder { .. } |
|
||||
PrimitiveInstanceKind::Clear => {}
|
||||
}
|
||||
|
|
Двоичные данные
gfx/wr/wrench/reftests/boxshadow/inset-alpha.png
Двоичные данные
gfx/wr/wrench/reftests/boxshadow/inset-alpha.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 1.6 KiB После Ширина: | Высота: | Размер: 1.6 KiB |
Загрузка…
Ссылка в новой задаче