зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1552984 - Refactor parts of the WR batching and flattening code, to support future picture caching improvements. r=kvark
This patch contains two isolated changes related to upcoming picture caching improvements. Specifically: * Determine the blit reason for stacking contexts with clips earlier, during scene building. This simplifies the code and allows better detection of redundant stacking contexts. * Centralize the code for pushing batch instances into a small number of places. This will simplify the switch to adding a single primitive to multiple batch lists, in the case of dirty regions with different batchers. Differential Revision: https://phabricator.services.mozilla.com/D31898 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
2e337923ae
Коммит
0f8cee5dd5
|
@ -467,6 +467,7 @@ pub struct AlphaBatchBuilder {
|
|||
screen_size: DeviceIntSize,
|
||||
break_advanced_blend_batches: bool,
|
||||
render_task_id: RenderTaskId,
|
||||
render_task_address: RenderTaskAddress,
|
||||
}
|
||||
|
||||
impl AlphaBatchBuilder {
|
||||
|
@ -474,6 +475,7 @@ impl AlphaBatchBuilder {
|
|||
screen_size: DeviceIntSize,
|
||||
break_advanced_blend_batches: bool,
|
||||
render_task_id: RenderTaskId,
|
||||
render_task_address: RenderTaskAddress,
|
||||
) -> Self {
|
||||
let batch_lists = vec![
|
||||
BatchList::new(
|
||||
|
@ -489,6 +491,7 @@ impl AlphaBatchBuilder {
|
|||
screen_size,
|
||||
break_advanced_blend_batches,
|
||||
render_task_id,
|
||||
render_task_address,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,26 +549,97 @@ impl AlphaBatchBuilder {
|
|||
/// Supports (recursively) adding a list of primitives and pictures to an alpha batch
|
||||
/// builder. In future, it will support multiple dirty regions / slices, allowing the
|
||||
/// contents of a picture to be spliced into multiple batch builders.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct BatchBuilder {
|
||||
/// A temporary buffer that is used during glyph fetching, stored here
|
||||
/// to reduce memory allocations.
|
||||
glyph_fetch_buffer: Vec<GlyphFetchResult>,
|
||||
|
||||
/// The batchers that primitives will be added to as the
|
||||
/// picture tree is traversed.
|
||||
batcher: AlphaBatchBuilder,
|
||||
}
|
||||
|
||||
impl BatchBuilder {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(
|
||||
batcher: AlphaBatchBuilder,
|
||||
) -> Self {
|
||||
BatchBuilder {
|
||||
glyph_fetch_buffer: Vec::new(),
|
||||
batcher,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finalize(self) -> AlphaBatchBuilder {
|
||||
self.batcher
|
||||
}
|
||||
|
||||
fn add_brush_instance_to_batches(
|
||||
&mut self,
|
||||
batch_key: BatchKey,
|
||||
bounding_rect: &PictureRect,
|
||||
z_id: ZBufferId,
|
||||
segment_index: i32,
|
||||
edge_flags: EdgeAaSegmentMask,
|
||||
clip_task_address: RenderTaskAddress,
|
||||
brush_flags: BrushFlags,
|
||||
prim_header_index: PrimitiveHeaderIndex,
|
||||
user_data: i32,
|
||||
) {
|
||||
// TODO(gw): In future, this will be a loop adding the primitive
|
||||
// to multiple batch list(s), depending on the primitive
|
||||
// visibility mask.
|
||||
|
||||
let render_task_address = self.batcher.render_task_address;
|
||||
|
||||
let instance = BrushInstance {
|
||||
segment_index,
|
||||
edge_flags,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
brush_flags,
|
||||
prim_header_index,
|
||||
user_data,
|
||||
};
|
||||
|
||||
self.batcher.current_batch_list().push_single_instance(
|
||||
batch_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
);
|
||||
}
|
||||
|
||||
fn add_split_composite_instance_to_batches(
|
||||
&mut self,
|
||||
batch_key: BatchKey,
|
||||
bounding_rect: &PictureRect,
|
||||
z_id: ZBufferId,
|
||||
prim_header_index: PrimitiveHeaderIndex,
|
||||
polygons_address: GpuCacheAddress,
|
||||
) {
|
||||
// TODO(gw): In future, this will be a loop adding the primitive
|
||||
// to multiple batch list(s), depending on the primitive
|
||||
// visibility mask.
|
||||
|
||||
let render_task_address = self.batcher.render_task_address;
|
||||
|
||||
self.batcher.current_batch_list().push_single_instance(
|
||||
batch_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(SplitCompositeInstance {
|
||||
prim_header_index,
|
||||
render_task_address,
|
||||
polygons_address,
|
||||
z: z_id,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/// Add a picture to a given batch builder.
|
||||
pub fn add_pic_to_batch(
|
||||
&mut self,
|
||||
pic: &PicturePrimitive,
|
||||
batcher: &mut AlphaBatchBuilder,
|
||||
ctx: &RenderTargetContext,
|
||||
gpu_cache: &mut GpuCache,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
|
@ -579,7 +653,6 @@ impl BatchBuilder {
|
|||
for prim_instance in &pic.prim_list.prim_instances {
|
||||
self.add_prim_to_batch(
|
||||
prim_instance,
|
||||
batcher,
|
||||
ctx,
|
||||
gpu_cache,
|
||||
render_tasks,
|
||||
|
@ -599,7 +672,6 @@ impl BatchBuilder {
|
|||
fn add_prim_to_batch(
|
||||
&mut self,
|
||||
prim_instance: &PrimitiveInstance,
|
||||
batcher: &mut AlphaBatchBuilder,
|
||||
ctx: &RenderTargetContext,
|
||||
gpu_cache: &mut GpuCache,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
|
@ -641,7 +713,6 @@ impl BatchBuilder {
|
|||
);
|
||||
|
||||
let snap_offsets = prim_info.snap_offsets;
|
||||
let render_task_address = render_tasks.get_task_address(batcher.render_task_id);
|
||||
|
||||
if is_chased {
|
||||
println!("\tbatch {:?} with bound {:?}", prim_rect, bounding_rect);
|
||||
|
@ -681,21 +752,16 @@ impl BatchBuilder {
|
|||
render_tasks,
|
||||
).unwrap_or(OPAQUE_TASK_ADDRESS);
|
||||
|
||||
let instance = PrimitiveInstanceData::from(BrushInstance {
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
user_data: 0,
|
||||
});
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
batch_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
0,
|
||||
);
|
||||
}
|
||||
PrimitiveInstanceKind::NormalBorder { data_handle, ref cache_handles, .. } => {
|
||||
|
@ -758,7 +824,6 @@ impl BatchBuilder {
|
|||
|
||||
let border_data = &prim_data.kind;
|
||||
self.add_segmented_prim_to_batch(
|
||||
batcher,
|
||||
Some(border_data.brush_segments.as_slice()),
|
||||
common_data.opacity,
|
||||
&batch_params,
|
||||
|
@ -769,7 +834,6 @@ impl BatchBuilder {
|
|||
transform_kind,
|
||||
render_tasks,
|
||||
z_id,
|
||||
render_task_address,
|
||||
prim_info.clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -781,7 +845,6 @@ impl BatchBuilder {
|
|||
// The GPU cache data is stored in the template and reused across
|
||||
// frames and display lists.
|
||||
let prim_data = &ctx.data_stores.text_run[data_handle];
|
||||
let alpha_batch_list = &mut batcher.batch_lists.last_mut().unwrap().alpha_batch_list;
|
||||
let prim_cache_address = gpu_cache.get_address(&prim_data.gpu_cache_handle);
|
||||
|
||||
let prim_header = PrimitiveHeader {
|
||||
|
@ -798,6 +861,28 @@ impl BatchBuilder {
|
|||
).unwrap_or(OPAQUE_TASK_ADDRESS);
|
||||
|
||||
let glyph_keys = &ctx.scratch.glyph_keys[run.glyph_keys_range];
|
||||
let rasterization_space = match run.raster_space {
|
||||
RasterSpace::Screen => RasterizationSpace::Screen,
|
||||
RasterSpace::Local(..) => RasterizationSpace::Local,
|
||||
};
|
||||
let raster_scale = run.raster_space.local_scale().unwrap_or(1.0).max(0.001);
|
||||
let prim_header_index = prim_headers.push(
|
||||
&prim_header,
|
||||
z_id,
|
||||
[
|
||||
(run.reference_frame_relative_offset.x * 256.0) as i32,
|
||||
(run.reference_frame_relative_offset.y * 256.0) as i32,
|
||||
(raster_scale * 65535.0).round() as i32,
|
||||
clip_task_address.0 as i32,
|
||||
],
|
||||
);
|
||||
let base_instance = GlyphInstance::new(
|
||||
prim_header_index,
|
||||
);
|
||||
let alpha_batch_list = &mut self.batcher.batch_lists.last_mut().unwrap().alpha_batch_list;
|
||||
let render_task_address = render_tasks.get_task_address(
|
||||
self.batcher.render_task_id,
|
||||
);
|
||||
|
||||
ctx.resource_cache.fetch_glyphs(
|
||||
run.used_font.clone(),
|
||||
|
@ -865,31 +950,13 @@ impl BatchBuilder {
|
|||
}
|
||||
};
|
||||
|
||||
let raster_scale = run.raster_space.local_scale().unwrap_or(1.0).max(0.001);
|
||||
let prim_header_index = prim_headers.push(
|
||||
&prim_header,
|
||||
z_id,
|
||||
[
|
||||
(run.reference_frame_relative_offset.x * 256.0) as i32,
|
||||
(run.reference_frame_relative_offset.y * 256.0) as i32,
|
||||
(raster_scale * 65535.0).round() as i32,
|
||||
clip_task_address.0 as i32,
|
||||
],
|
||||
);
|
||||
let key = BatchKey::new(kind, blend_mode, textures);
|
||||
let base_instance = GlyphInstance::new(
|
||||
prim_header_index,
|
||||
);
|
||||
let batch = alpha_batch_list.set_params_and_get_batch(
|
||||
key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
);
|
||||
|
||||
let rasterization_space = match run.raster_space {
|
||||
RasterSpace::Screen => RasterizationSpace::Screen,
|
||||
RasterSpace::Local(..) => RasterizationSpace::Local,
|
||||
};
|
||||
for glyph in glyphs {
|
||||
batch.push(base_instance.build(
|
||||
glyph.index_in_text_run | ((render_task_address.0 as i32) << 16),
|
||||
|
@ -976,21 +1043,16 @@ impl BatchBuilder {
|
|||
render_tasks,
|
||||
).unwrap_or(OPAQUE_TASK_ADDRESS);
|
||||
|
||||
let instance = PrimitiveInstanceData::from(BrushInstance {
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
user_data: segment_user_data,
|
||||
});
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
batch_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
segment_user_data,
|
||||
);
|
||||
}
|
||||
PrimitiveInstanceKind::Picture { pic_index, segment_instance_index, .. } => {
|
||||
|
@ -1074,18 +1136,12 @@ impl BatchBuilder {
|
|||
BatchTextures::no_texture(),
|
||||
);
|
||||
|
||||
let instance = SplitCompositeInstance::new(
|
||||
prim_header_index,
|
||||
child.gpu_address,
|
||||
render_task_address,
|
||||
z_id,
|
||||
);
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_split_composite_instance_to_batches(
|
||||
key,
|
||||
&prim_info.clip_chain.pic_clip_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
prim_header_index,
|
||||
child.gpu_address,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1126,7 +1182,6 @@ impl BatchBuilder {
|
|||
if !tile_cache.is_enabled {
|
||||
self.add_pic_to_batch(
|
||||
picture,
|
||||
batcher,
|
||||
ctx,
|
||||
gpu_cache,
|
||||
render_tasks,
|
||||
|
@ -1199,27 +1254,17 @@ impl BatchBuilder {
|
|||
.get_address(&cache_item.uv_rect_handle)
|
||||
.as_int();
|
||||
|
||||
let instance = BrushInstance {
|
||||
prim_header_index,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::empty(),
|
||||
brush_flags,
|
||||
user_data: uv_rect_address,
|
||||
};
|
||||
|
||||
// Instead of retrieving the batch once and adding each tile instance,
|
||||
// use this API to get an appropriate batch for each tile, since
|
||||
// the batch textures may be different. The batch list internally
|
||||
// caches the current batch if the key hasn't changed.
|
||||
let batch = batcher.current_batch_list().set_params_and_get_batch(
|
||||
self.add_brush_instance_to_batches(
|
||||
key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
clip_task_address,
|
||||
brush_flags,
|
||||
prim_header_index,
|
||||
uv_rect_address,
|
||||
);
|
||||
|
||||
batch.push(PrimitiveInstanceData::from(instance));
|
||||
}
|
||||
|
||||
// If there is a dirty rect for the tile cache, recurse into the
|
||||
|
@ -1227,7 +1272,7 @@ impl BatchBuilder {
|
|||
if !tile_cache.dirty_region.is_empty() {
|
||||
let mut tile_blits = Vec::new();
|
||||
|
||||
let (target_rect, _) = render_tasks[batcher.render_task_id]
|
||||
let (target_rect, _) = render_tasks[self.batcher.render_task_id]
|
||||
.get_target_rect();
|
||||
|
||||
for blit in &tile_cache.pending_blits {
|
||||
|
@ -1253,14 +1298,13 @@ impl BatchBuilder {
|
|||
})
|
||||
.collect();
|
||||
|
||||
batcher.push_new_batch_list(
|
||||
self.batcher.push_new_batch_list(
|
||||
batch_regions,
|
||||
tile_blits,
|
||||
);
|
||||
|
||||
self.add_pic_to_batch(
|
||||
picture,
|
||||
batcher,
|
||||
ctx,
|
||||
gpu_cache,
|
||||
render_tasks,
|
||||
|
@ -1271,7 +1315,7 @@ impl BatchBuilder {
|
|||
z_generator,
|
||||
);
|
||||
|
||||
batcher.push_new_batch_list(
|
||||
self.batcher.push_new_batch_list(
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
);
|
||||
|
@ -1301,21 +1345,16 @@ impl BatchBuilder {
|
|||
0,
|
||||
]);
|
||||
|
||||
let instance = BrushInstance {
|
||||
prim_header_index,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::empty(),
|
||||
brush_flags,
|
||||
render_task_address,
|
||||
clip_task_address,
|
||||
user_data: uv_rect_address.as_int(),
|
||||
};
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
clip_task_address,
|
||||
brush_flags,
|
||||
prim_header_index,
|
||||
uv_rect_address.as_int(),
|
||||
);
|
||||
}
|
||||
Filter::DropShadows(shadows) => {
|
||||
|
@ -1376,21 +1415,16 @@ impl BatchBuilder {
|
|||
0,
|
||||
]);
|
||||
|
||||
let shadow_instance = BrushInstance {
|
||||
prim_header_index: shadow_prim_header_index,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::empty(),
|
||||
brush_flags,
|
||||
user_data: shadow_uv_rect_address,
|
||||
};
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
shadow_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(shadow_instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
clip_task_address,
|
||||
brush_flags,
|
||||
shadow_prim_header_index,
|
||||
shadow_uv_rect_address,
|
||||
);
|
||||
}
|
||||
let z_id_content = z_generator.next();
|
||||
|
@ -1402,21 +1436,16 @@ impl BatchBuilder {
|
|||
0,
|
||||
]);
|
||||
|
||||
let content_instance = BrushInstance {
|
||||
prim_header_index: content_prim_header_index,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::empty(),
|
||||
brush_flags,
|
||||
user_data: content_uv_rect_address,
|
||||
};
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
content_key,
|
||||
bounding_rect,
|
||||
z_id_content,
|
||||
PrimitiveInstanceData::from(content_instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
clip_task_address,
|
||||
brush_flags,
|
||||
content_prim_header_index,
|
||||
content_uv_rect_address,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
|
@ -1482,21 +1511,16 @@ impl BatchBuilder {
|
|||
0,
|
||||
]);
|
||||
|
||||
let instance = BrushInstance {
|
||||
prim_header_index,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::empty(),
|
||||
brush_flags,
|
||||
user_data: 0,
|
||||
};
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
clip_task_address,
|
||||
brush_flags,
|
||||
prim_header_index,
|
||||
0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1532,21 +1556,16 @@ impl BatchBuilder {
|
|||
0,
|
||||
]);
|
||||
|
||||
let instance = BrushInstance {
|
||||
prim_header_index,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::empty(),
|
||||
brush_flags,
|
||||
user_data: 0,
|
||||
};
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
clip_task_address,
|
||||
brush_flags,
|
||||
prim_header_index,
|
||||
0,
|
||||
);
|
||||
}
|
||||
PictureCompositeMode::MixBlend(mode) if ctx.use_advanced_blending => {
|
||||
|
@ -1568,21 +1587,16 @@ impl BatchBuilder {
|
|||
0,
|
||||
]);
|
||||
|
||||
let instance = BrushInstance {
|
||||
prim_header_index,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::empty(),
|
||||
brush_flags,
|
||||
user_data: uv_rect_address.as_int(),
|
||||
};
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
clip_task_address,
|
||||
brush_flags,
|
||||
prim_header_index,
|
||||
uv_rect_address.as_int(),
|
||||
);
|
||||
}
|
||||
PictureCompositeMode::MixBlend(mode) => {
|
||||
|
@ -1592,7 +1606,7 @@ impl BatchBuilder {
|
|||
let key = BatchKey::new(
|
||||
BatchKind::Brush(
|
||||
BrushBatchKind::MixBlend {
|
||||
task_id: batcher.render_task_id,
|
||||
task_id: self.batcher.render_task_id,
|
||||
source_id: cache_task_id,
|
||||
backdrop_id,
|
||||
},
|
||||
|
@ -1609,21 +1623,16 @@ impl BatchBuilder {
|
|||
0,
|
||||
]);
|
||||
|
||||
let instance = BrushInstance {
|
||||
prim_header_index,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::empty(),
|
||||
brush_flags,
|
||||
user_data: 0,
|
||||
};
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
clip_task_address,
|
||||
brush_flags,
|
||||
prim_header_index,
|
||||
0,
|
||||
);
|
||||
}
|
||||
PictureCompositeMode::Blit(_) => {
|
||||
|
@ -1679,7 +1688,6 @@ impl BatchBuilder {
|
|||
let specified_blend_mode = BlendMode::PremultipliedAlpha;
|
||||
|
||||
self.add_segmented_prim_to_batch(
|
||||
batcher,
|
||||
segments,
|
||||
opacity,
|
||||
&batch_params,
|
||||
|
@ -1690,7 +1698,6 @@ impl BatchBuilder {
|
|||
transform_kind,
|
||||
render_tasks,
|
||||
z_id,
|
||||
render_task_address,
|
||||
prim_info.clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -1702,7 +1709,6 @@ impl BatchBuilder {
|
|||
// no composition operation), recurse and add to the current batch list.
|
||||
self.add_pic_to_batch(
|
||||
picture,
|
||||
batcher,
|
||||
ctx,
|
||||
gpu_cache,
|
||||
render_tasks,
|
||||
|
@ -1769,7 +1775,6 @@ impl BatchBuilder {
|
|||
);
|
||||
|
||||
self.add_segmented_prim_to_batch(
|
||||
batcher,
|
||||
Some(border_data.brush_segments.as_slice()),
|
||||
common_data.opacity,
|
||||
&batch_params,
|
||||
|
@ -1780,7 +1785,6 @@ impl BatchBuilder {
|
|||
transform_kind,
|
||||
render_tasks,
|
||||
z_id,
|
||||
render_task_address,
|
||||
prim_info.clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -1832,7 +1836,6 @@ impl BatchBuilder {
|
|||
);
|
||||
|
||||
self.add_segmented_prim_to_batch(
|
||||
batcher,
|
||||
segments,
|
||||
opacity,
|
||||
&batch_params,
|
||||
|
@ -1843,7 +1846,6 @@ impl BatchBuilder {
|
|||
transform_kind,
|
||||
render_tasks,
|
||||
z_id,
|
||||
render_task_address,
|
||||
prim_info.clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -1941,7 +1943,6 @@ impl BatchBuilder {
|
|||
);
|
||||
|
||||
self.add_segmented_prim_to_batch(
|
||||
batcher,
|
||||
segments,
|
||||
prim_common_data.opacity,
|
||||
&batch_params,
|
||||
|
@ -1952,7 +1953,6 @@ impl BatchBuilder {
|
|||
transform_kind,
|
||||
render_tasks,
|
||||
z_id,
|
||||
render_task_address,
|
||||
prim_info.clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -2047,7 +2047,6 @@ impl BatchBuilder {
|
|||
);
|
||||
|
||||
self.add_segmented_prim_to_batch(
|
||||
batcher,
|
||||
segments,
|
||||
opacity,
|
||||
&batch_params,
|
||||
|
@ -2058,7 +2057,6 @@ impl BatchBuilder {
|
|||
transform_kind,
|
||||
render_tasks,
|
||||
z_id,
|
||||
render_task_address,
|
||||
prim_info.clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -2102,25 +2100,21 @@ impl BatchBuilder {
|
|||
deferred_resolves,
|
||||
request.with_tile(tile.tile_offset),
|
||||
) {
|
||||
let base_instance = BrushInstance {
|
||||
prim_header_index,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
segment_index: i as i32,
|
||||
edge_flags: tile.edge_flags,
|
||||
brush_flags: BrushFlags::SEGMENT_RELATIVE | BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
user_data: uv_rect_address.as_int(),
|
||||
};
|
||||
let batch_key = BatchKey {
|
||||
blend_mode: specified_blend_mode,
|
||||
kind: BatchKind::Brush(batch_kind),
|
||||
textures,
|
||||
};
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
batch_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
base_instance.into(),
|
||||
i as i32,
|
||||
tile.edge_flags,
|
||||
clip_task_address,
|
||||
BrushFlags::SEGMENT_RELATIVE | BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
uv_rect_address.as_int(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2187,21 +2181,16 @@ impl BatchBuilder {
|
|||
render_tasks,
|
||||
).unwrap_or(OPAQUE_TASK_ADDRESS);
|
||||
|
||||
let instance = PrimitiveInstanceData::from(BrushInstance {
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
user_data: segment_user_data,
|
||||
});
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
batch_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
segment_user_data,
|
||||
);
|
||||
} else if gradient.visible_tiles_range.is_empty() {
|
||||
let batch_params = BrushBatchParameters::shared(
|
||||
|
@ -2231,7 +2220,6 @@ impl BatchBuilder {
|
|||
};
|
||||
|
||||
self.add_segmented_prim_to_batch(
|
||||
batcher,
|
||||
segments,
|
||||
prim_data.opacity,
|
||||
&batch_params,
|
||||
|
@ -2242,7 +2230,6 @@ impl BatchBuilder {
|
|||
transform_kind,
|
||||
render_tasks,
|
||||
z_id,
|
||||
render_task_address,
|
||||
prim_info.clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -2254,16 +2241,14 @@ impl BatchBuilder {
|
|||
render_tasks,
|
||||
).unwrap_or(OPAQUE_TASK_ADDRESS);
|
||||
|
||||
add_gradient_tiles(
|
||||
self.add_gradient_tiles(
|
||||
visible_tiles,
|
||||
&prim_data.stops_handle,
|
||||
BrushBatchKind::LinearGradient,
|
||||
specified_blend_mode,
|
||||
bounding_rect,
|
||||
render_task_address,
|
||||
clip_task_address,
|
||||
gpu_cache,
|
||||
batcher.current_batch_list(),
|
||||
&prim_header,
|
||||
prim_headers,
|
||||
z_id,
|
||||
|
@ -2319,7 +2304,6 @@ impl BatchBuilder {
|
|||
};
|
||||
|
||||
self.add_segmented_prim_to_batch(
|
||||
batcher,
|
||||
segments,
|
||||
prim_data.opacity,
|
||||
&batch_params,
|
||||
|
@ -2330,7 +2314,6 @@ impl BatchBuilder {
|
|||
transform_kind,
|
||||
render_tasks,
|
||||
z_id,
|
||||
render_task_address,
|
||||
prim_info.clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -2342,16 +2325,14 @@ impl BatchBuilder {
|
|||
render_tasks,
|
||||
).unwrap_or(OPAQUE_TASK_ADDRESS);
|
||||
|
||||
add_gradient_tiles(
|
||||
self.add_gradient_tiles(
|
||||
visible_tiles,
|
||||
&prim_data.stops_handle,
|
||||
BrushBatchKind::RadialGradient,
|
||||
specified_blend_mode,
|
||||
bounding_rect,
|
||||
render_task_address,
|
||||
clip_task_address,
|
||||
gpu_cache,
|
||||
batcher.current_batch_list(),
|
||||
&prim_header,
|
||||
prim_headers,
|
||||
z_id,
|
||||
|
@ -2364,7 +2345,6 @@ impl BatchBuilder {
|
|||
/// Add a single segment instance to a batch.
|
||||
fn add_segment_to_batch(
|
||||
&mut self,
|
||||
batcher: &mut AlphaBatchBuilder,
|
||||
segment: &BrushSegment,
|
||||
segment_data: &SegmentInstanceData,
|
||||
segment_index: i32,
|
||||
|
@ -2376,7 +2356,6 @@ impl BatchBuilder {
|
|||
render_tasks: &RenderTaskGraph,
|
||||
z_id: ZBufferId,
|
||||
prim_opacity: PrimitiveOpacity,
|
||||
render_task_address: RenderTaskAddress,
|
||||
clip_task_index: ClipTaskIndex,
|
||||
ctx: &RenderTargetContext,
|
||||
) {
|
||||
|
@ -2399,34 +2378,28 @@ impl BatchBuilder {
|
|||
clip_task_address != OPAQUE_TASK_ADDRESS ||
|
||||
(!is_inner && transform_kind == TransformedRectKind::Complex);
|
||||
|
||||
let instance = PrimitiveInstanceData::from(BrushInstance {
|
||||
segment_index,
|
||||
edge_flags: segment.edge_flags,
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION | segment.brush_flags,
|
||||
prim_header_index,
|
||||
user_data: segment_data.user_data,
|
||||
});
|
||||
|
||||
let batch_key = BatchKey {
|
||||
blend_mode: if needs_blending { alpha_blend_mode } else { BlendMode::None },
|
||||
kind: BatchKind::Brush(batch_kind),
|
||||
textures: segment_data.textures,
|
||||
};
|
||||
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
batch_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
instance,
|
||||
segment_index,
|
||||
segment.edge_flags,
|
||||
clip_task_address,
|
||||
BrushFlags::PERSPECTIVE_INTERPOLATION | segment.brush_flags,
|
||||
prim_header_index,
|
||||
segment_data.user_data,
|
||||
);
|
||||
}
|
||||
|
||||
/// Add any segment(s) from a brush to batches.
|
||||
fn add_segmented_prim_to_batch(
|
||||
&mut self,
|
||||
batcher: &mut AlphaBatchBuilder,
|
||||
brush_segments: Option<&[BrushSegment]>,
|
||||
prim_opacity: PrimitiveOpacity,
|
||||
params: &BrushBatchParameters,
|
||||
|
@ -2437,7 +2410,6 @@ impl BatchBuilder {
|
|||
transform_kind: TransformedRectKind,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
z_id: ZBufferId,
|
||||
render_task_address: RenderTaskAddress,
|
||||
clip_task_index: ClipTaskIndex,
|
||||
ctx: &RenderTargetContext,
|
||||
) {
|
||||
|
@ -2452,7 +2424,6 @@ impl BatchBuilder {
|
|||
.enumerate()
|
||||
{
|
||||
self.add_segment_to_batch(
|
||||
batcher,
|
||||
segment,
|
||||
segment_data,
|
||||
segment_index as i32,
|
||||
|
@ -2464,7 +2435,6 @@ impl BatchBuilder {
|
|||
render_tasks,
|
||||
z_id,
|
||||
prim_opacity,
|
||||
render_task_address,
|
||||
clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -2478,7 +2448,6 @@ impl BatchBuilder {
|
|||
.enumerate()
|
||||
{
|
||||
self.add_segment_to_batch(
|
||||
batcher,
|
||||
segment,
|
||||
segment_data,
|
||||
segment_index as i32,
|
||||
|
@ -2490,7 +2459,6 @@ impl BatchBuilder {
|
|||
render_tasks,
|
||||
z_id,
|
||||
prim_opacity,
|
||||
render_task_address,
|
||||
clip_task_index,
|
||||
ctx,
|
||||
);
|
||||
|
@ -2508,20 +2476,16 @@ impl BatchBuilder {
|
|||
clip_task_index,
|
||||
render_tasks,
|
||||
).unwrap_or(OPAQUE_TASK_ADDRESS);
|
||||
let instance = PrimitiveInstanceData::from(BrushInstance {
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
user_data: segment_data.user_data,
|
||||
});
|
||||
batcher.current_batch_list().push_single_instance(
|
||||
self.add_brush_instance_to_batches(
|
||||
batch_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
segment_data.user_data,
|
||||
);
|
||||
}
|
||||
(None, SegmentDataKind::Instanced(..)) => {
|
||||
|
@ -2531,62 +2495,57 @@ impl BatchBuilder {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_gradient_tiles(
|
||||
visible_tiles: &[VisibleGradientTile],
|
||||
stops_handle: &GpuCacheHandle,
|
||||
kind: BrushBatchKind,
|
||||
blend_mode: BlendMode,
|
||||
bounding_rect: &PictureRect,
|
||||
render_task_address: RenderTaskAddress,
|
||||
clip_task_address: RenderTaskAddress,
|
||||
gpu_cache: &GpuCache,
|
||||
batch_list: &mut BatchList,
|
||||
base_prim_header: &PrimitiveHeader,
|
||||
prim_headers: &mut PrimitiveHeaders,
|
||||
z_id: ZBufferId,
|
||||
) {
|
||||
let batch = batch_list.set_params_and_get_batch(
|
||||
BatchKey {
|
||||
fn add_gradient_tiles(
|
||||
&mut self,
|
||||
visible_tiles: &[VisibleGradientTile],
|
||||
stops_handle: &GpuCacheHandle,
|
||||
kind: BrushBatchKind,
|
||||
blend_mode: BlendMode,
|
||||
bounding_rect: &PictureRect,
|
||||
clip_task_address: RenderTaskAddress,
|
||||
gpu_cache: &GpuCache,
|
||||
base_prim_header: &PrimitiveHeader,
|
||||
prim_headers: &mut PrimitiveHeaders,
|
||||
z_id: ZBufferId,
|
||||
) {
|
||||
let key = BatchKey {
|
||||
blend_mode: blend_mode,
|
||||
kind: BatchKind::Brush(kind),
|
||||
textures: BatchTextures::no_texture(),
|
||||
},
|
||||
bounding_rect,
|
||||
z_id,
|
||||
);
|
||||
|
||||
let user_data = [stops_handle.as_int(gpu_cache), 0, 0, 0];
|
||||
|
||||
for tile in visible_tiles {
|
||||
// Adjust the snap offsets for the tile.
|
||||
let snap_offsets = recompute_snap_offsets(
|
||||
tile.local_rect,
|
||||
base_prim_header.local_rect,
|
||||
base_prim_header.snap_offsets,
|
||||
);
|
||||
|
||||
let prim_header = PrimitiveHeader {
|
||||
specific_prim_address: gpu_cache.get_address(&tile.handle),
|
||||
local_rect: tile.local_rect,
|
||||
local_clip_rect: tile.local_clip_rect,
|
||||
snap_offsets,
|
||||
..*base_prim_header
|
||||
};
|
||||
let prim_header_index = prim_headers.push(&prim_header, z_id, user_data);
|
||||
|
||||
batch.push(PrimitiveInstanceData::from(
|
||||
BrushInstance {
|
||||
prim_header_index,
|
||||
let user_data = [stops_handle.as_int(gpu_cache), 0, 0, 0];
|
||||
|
||||
for tile in visible_tiles {
|
||||
// Adjust the snap offsets for the tile.
|
||||
let snap_offsets = recompute_snap_offsets(
|
||||
tile.local_rect,
|
||||
base_prim_header.local_rect,
|
||||
base_prim_header.snap_offsets,
|
||||
);
|
||||
|
||||
let prim_header = PrimitiveHeader {
|
||||
specific_prim_address: gpu_cache.get_address(&tile.handle),
|
||||
local_rect: tile.local_rect,
|
||||
local_clip_rect: tile.local_clip_rect,
|
||||
snap_offsets,
|
||||
..*base_prim_header
|
||||
};
|
||||
let prim_header_index = prim_headers.push(&prim_header, z_id, user_data);
|
||||
|
||||
self.add_brush_instance_to_batches(
|
||||
key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
render_task_address,
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::all(),
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
user_data: 0,
|
||||
}
|
||||
));
|
||||
BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
0,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -209,6 +209,7 @@ pub struct ClipChainNode {
|
|||
pub local_pos: LayoutPoint,
|
||||
pub spatial_node_index: SpatialNodeIndex,
|
||||
pub parent_clip_chain_id: ClipChainId,
|
||||
pub has_complex_clip: bool,
|
||||
}
|
||||
|
||||
// When a clip node is found to be valid for a
|
||||
|
@ -563,6 +564,7 @@ impl ClipStore {
|
|||
local_pos: LayoutPoint,
|
||||
spatial_node_index: SpatialNodeIndex,
|
||||
parent_clip_chain_id: ClipChainId,
|
||||
has_complex_clip: bool,
|
||||
) -> ClipChainId {
|
||||
let id = ClipChainId(self.clip_chain_nodes.len() as u32);
|
||||
self.clip_chain_nodes.push(ClipChainNode {
|
||||
|
@ -570,6 +572,7 @@ impl ClipStore {
|
|||
spatial_node_index,
|
||||
local_pos,
|
||||
parent_clip_chain_id,
|
||||
has_complex_clip,
|
||||
});
|
||||
id
|
||||
}
|
||||
|
@ -867,6 +870,17 @@ impl ClipItemKey {
|
|||
clip_mode,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn has_complex_clip(&self) -> bool {
|
||||
match *self {
|
||||
ClipItemKey::Rectangle(_, ClipMode::Clip) => false,
|
||||
|
||||
ClipItemKey::Rectangle(_, ClipMode::ClipOut) |
|
||||
ClipItemKey::RoundedRectangle(..) |
|
||||
ClipItemKey::ImageMask(..) |
|
||||
ClipItemKey::BoxShadow(..) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl intern::InternDebug for ClipItemKey {}
|
||||
|
|
|
@ -1220,14 +1220,19 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
|
||||
for _ in 0 .. item_clip_node.count {
|
||||
// Get the id of the clip sources entry for that clip chain node.
|
||||
let (handle, spatial_node_index, local_pos) = {
|
||||
let (handle, spatial_node_index, local_pos, has_complex_clip) = {
|
||||
let clip_chain = self
|
||||
.clip_store
|
||||
.get_clip_chain(clip_node_clip_chain_id);
|
||||
|
||||
clip_node_clip_chain_id = clip_chain.parent_clip_chain_id;
|
||||
|
||||
(clip_chain.handle, clip_chain.spatial_node_index, clip_chain.local_pos)
|
||||
(
|
||||
clip_chain.handle,
|
||||
clip_chain.spatial_node_index,
|
||||
clip_chain.local_pos,
|
||||
clip_chain.has_complex_clip,
|
||||
)
|
||||
};
|
||||
|
||||
// Add a new clip chain node, which references the same clip sources, and
|
||||
|
@ -1239,6 +1244,7 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
local_pos,
|
||||
spatial_node_index,
|
||||
clip_chain_id,
|
||||
has_complex_clip,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1308,6 +1314,7 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
for (local_pos, item) in clip_items {
|
||||
// Intern this clip item, and store the handle
|
||||
// in the clip chain node.
|
||||
let has_complex_clip = item.has_complex_clip();
|
||||
let handle = self.interners
|
||||
.clip
|
||||
.intern(&item, || ());
|
||||
|
@ -1317,6 +1324,7 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
local_pos,
|
||||
spatial_node_index,
|
||||
clip_chain_id,
|
||||
has_complex_clip,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1585,15 +1593,27 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
Picture3DContext::Out
|
||||
};
|
||||
|
||||
// Force an intermediate surface if the stacking context
|
||||
// has a clip node. In the future, we may decide during
|
||||
// Force an intermediate surface if the stacking context has a
|
||||
// complex clip node. In the future, we may decide during
|
||||
// prepare step to skip the intermediate surface if the
|
||||
// clip node doesn't affect the stacking context rect.
|
||||
let blit_reason = if clip_chain_id == ClipChainId::NONE {
|
||||
BlitReason::empty()
|
||||
} else {
|
||||
BlitReason::CLIP
|
||||
};
|
||||
let mut blit_reason = BlitReason::empty();
|
||||
let mut current_clip_chain_id = clip_chain_id;
|
||||
|
||||
// Walk each clip in this chain, to see whether any of the clips
|
||||
// require that we draw this to an intermediate surface.
|
||||
while current_clip_chain_id != ClipChainId::NONE {
|
||||
let clip_chain_node = &self
|
||||
.clip_store
|
||||
.clip_chain_nodes[current_clip_chain_id.0 as usize];
|
||||
|
||||
if clip_chain_node.has_complex_clip {
|
||||
blit_reason = BlitReason::CLIP;
|
||||
break;
|
||||
}
|
||||
|
||||
current_clip_chain_id = clip_chain_node.parent_clip_chain_id;
|
||||
}
|
||||
|
||||
// Push the SC onto the stack, so we know how to handle things in
|
||||
// pop_stacking_context.
|
||||
|
@ -2021,6 +2041,7 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
clip_region.main.origin,
|
||||
spatial_node,
|
||||
parent_clip_chain_index,
|
||||
false,
|
||||
);
|
||||
clip_count += 1;
|
||||
|
||||
|
@ -2037,6 +2058,7 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
image_mask.rect.origin,
|
||||
spatial_node,
|
||||
parent_clip_chain_index,
|
||||
true,
|
||||
);
|
||||
clip_count += 1;
|
||||
}
|
||||
|
@ -2054,6 +2076,7 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
region.rect.origin,
|
||||
spatial_node,
|
||||
parent_clip_chain_index,
|
||||
true,
|
||||
);
|
||||
clip_count += 1;
|
||||
}
|
||||
|
|
|
@ -321,22 +321,6 @@ pub struct SplitCompositeInstance {
|
|||
pub render_task_address: RenderTaskAddress,
|
||||
}
|
||||
|
||||
impl SplitCompositeInstance {
|
||||
pub fn new(
|
||||
prim_header_index: PrimitiveHeaderIndex,
|
||||
polygons_address: GpuCacheAddress,
|
||||
render_task_address: RenderTaskAddress,
|
||||
z: ZBufferId,
|
||||
) -> Self {
|
||||
SplitCompositeInstance {
|
||||
prim_header_index,
|
||||
polygons_address,
|
||||
z,
|
||||
render_task_address,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SplitCompositeInstance> for PrimitiveInstanceData {
|
||||
fn from(instance: SplitCompositeInstance) -> Self {
|
||||
PrimitiveInstanceData {
|
||||
|
|
|
@ -1645,7 +1645,6 @@ impl<'a> PictureUpdateState<'a> {
|
|||
|
||||
state.update(
|
||||
pic_index,
|
||||
ClipChainId::NONE,
|
||||
picture_primitives,
|
||||
frame_context,
|
||||
gpu_cache,
|
||||
|
@ -1709,7 +1708,6 @@ impl<'a> PictureUpdateState<'a> {
|
|||
fn update(
|
||||
&mut self,
|
||||
pic_index: PictureIndex,
|
||||
clip_chain_id: ClipChainId,
|
||||
picture_primitives: &mut [PicturePrimitive],
|
||||
frame_context: &FrameBuildingContext,
|
||||
gpu_cache: &mut GpuCache,
|
||||
|
@ -1717,16 +1715,12 @@ impl<'a> PictureUpdateState<'a> {
|
|||
clip_data_store: &ClipDataStore,
|
||||
) {
|
||||
if let Some(prim_list) = picture_primitives[pic_index.0].pre_update(
|
||||
clip_chain_id,
|
||||
self,
|
||||
frame_context,
|
||||
clip_store,
|
||||
clip_data_store,
|
||||
) {
|
||||
for (child_pic_index, clip_chain_id) in &prim_list.pictures {
|
||||
for child_pic_index in &prim_list.pictures {
|
||||
self.update(
|
||||
*child_pic_index,
|
||||
*clip_chain_id,
|
||||
picture_primitives,
|
||||
frame_context,
|
||||
gpu_cache,
|
||||
|
@ -1768,7 +1762,7 @@ impl<'a> PictureUpdateState<'a> {
|
|||
None => fallback_raster_spatial_node,
|
||||
};
|
||||
|
||||
for (child_pic_index, _) in &picture.prim_list.pictures {
|
||||
for child_pic_index in &picture.prim_list.pictures {
|
||||
self.assign_raster_roots(*child_pic_index, picture_primitives, new_fallback);
|
||||
}
|
||||
}
|
||||
|
@ -1995,7 +1989,7 @@ impl ClusterIndex {
|
|||
|
||||
/// A list of pictures, stored by the PrimitiveList to enable a
|
||||
/// fast traversal of just the pictures.
|
||||
pub type PictureList = SmallVec<[(PictureIndex, ClipChainId); 4]>;
|
||||
pub type PictureList = SmallVec<[PictureIndex; 4]>;
|
||||
|
||||
/// A list of primitive instances that are added to a picture
|
||||
/// This ensures we can keep a list of primitives that
|
||||
|
@ -2044,7 +2038,7 @@ impl PrimitiveList {
|
|||
// remove this match and embed this info directly in the primitive instance.
|
||||
let is_pic = match prim_instance.kind {
|
||||
PrimitiveInstanceKind::Picture { pic_index, .. } => {
|
||||
pictures.push((pic_index, prim_instance.clip_chain_id));
|
||||
pictures.push(pic_index);
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
|
@ -2238,7 +2232,7 @@ impl PicturePrimitive {
|
|||
pt.add_item(format!("raster_config: {:?}", self.raster_config));
|
||||
pt.add_item(format!("requested_composite_mode: {:?}", self.requested_composite_mode));
|
||||
|
||||
for (index, _) in &self.prim_list.pictures {
|
||||
for index in &self.prim_list.pictures {
|
||||
pictures[index.0].print(pictures, *index, pt);
|
||||
}
|
||||
|
||||
|
@ -2905,11 +2899,8 @@ impl PicturePrimitive {
|
|||
/// surface / raster config now though.
|
||||
fn pre_update(
|
||||
&mut self,
|
||||
clip_chain_id: ClipChainId,
|
||||
state: &mut PictureUpdateState,
|
||||
frame_context: &FrameBuildingContext,
|
||||
clip_store: &ClipStore,
|
||||
clip_data_store: &ClipDataStore,
|
||||
) -> Option<PrimitiveList> {
|
||||
// Reset raster config in case we early out below.
|
||||
self.raster_config = None;
|
||||
|
@ -2941,52 +2932,6 @@ impl PicturePrimitive {
|
|||
// See if this picture actually needs a surface for compositing.
|
||||
let actual_composite_mode = match self.requested_composite_mode {
|
||||
Some(PictureCompositeMode::Filter(ref filter)) if filter.is_noop() => None,
|
||||
Some(PictureCompositeMode::Blit(reason)) if reason == BlitReason::CLIP => {
|
||||
// If the only reason a picture has requested a surface is due to the clip
|
||||
// chain node, we might choose to skip drawing a surface, and instead apply
|
||||
// the clips to each individual primitive. The logic below works out which
|
||||
// option to choose.
|
||||
|
||||
// Assume that we will apply clips to individual items
|
||||
let mut apply_clip_to_picture = false;
|
||||
let mut current_clip_chain_id = clip_chain_id;
|
||||
|
||||
// Walk each clip in this chain, to see whether to allocate a surface and clip
|
||||
// that, or whether to apply clips to each primitive.
|
||||
while current_clip_chain_id != ClipChainId::NONE {
|
||||
let clip_chain_node = &clip_store.clip_chain_nodes[current_clip_chain_id.0 as usize];
|
||||
let clip_node = &clip_data_store[clip_chain_node.handle];
|
||||
|
||||
match clip_node.item {
|
||||
ClipItem::Rectangle(_, ClipMode::Clip) => {
|
||||
// Normal rectangle clips can be handled as per-item clips.
|
||||
// TODO(gw): In future, we might want to consider selecting
|
||||
// a surface in some situations here (e.g. if the
|
||||
// stacking context is in a different coord system
|
||||
// from the clip, and there are enough primitives
|
||||
// in the stacking context to justify a surface).
|
||||
}
|
||||
ClipItem::Rectangle(_, ClipMode::ClipOut) |
|
||||
ClipItem::RoundedRectangle(..) |
|
||||
ClipItem::Image { .. } |
|
||||
ClipItem::BoxShadow(..) => {
|
||||
// Any of these clip types will require a surface.
|
||||
apply_clip_to_picture = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current_clip_chain_id = clip_chain_node.parent_clip_chain_id;
|
||||
}
|
||||
|
||||
// If we decided not to use a surfce for clipping, then skip and draw straight
|
||||
// into the parent surface.
|
||||
if apply_clip_to_picture {
|
||||
Some(PictureCompositeMode::Blit(reason))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
ref mode => mode.clone(),
|
||||
};
|
||||
|
||||
|
|
|
@ -374,10 +374,6 @@ pub struct ColorRenderTarget {
|
|||
// we can set a scissor rect and only clear to the
|
||||
// used portion of the target as an optimization.
|
||||
pub used_rect: DeviceIntRect,
|
||||
// This is used to build batches for this render target. In future,
|
||||
// this will be used to support splitting a single picture primitive
|
||||
// list into multiple batch sets.
|
||||
batch_builder: BatchBuilder,
|
||||
}
|
||||
|
||||
impl RenderTarget for ColorRenderTarget {
|
||||
|
@ -396,7 +392,6 @@ impl RenderTarget for ColorRenderTarget {
|
|||
alpha_tasks: Vec::new(),
|
||||
screen_size,
|
||||
used_rect: DeviceIntRect::zero(),
|
||||
batch_builder: BatchBuilder::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,15 +431,24 @@ impl RenderTarget for ColorRenderTarget {
|
|||
Some(target_rect)
|
||||
};
|
||||
|
||||
let mut alpha_batch_builder = AlphaBatchBuilder::new(
|
||||
// TODO(gw): The type names of AlphaBatchBuilder and BatchBuilder
|
||||
// are still confusing. Once more of the picture caching
|
||||
// improvement code lands, the AlphaBatchBuilder and
|
||||
// AlphaBatchList types will be collapsed into one, which
|
||||
// should simplify coming up with better type names.
|
||||
let alpha_batch_builder = AlphaBatchBuilder::new(
|
||||
self.screen_size,
|
||||
ctx.break_advanced_blend_batches,
|
||||
*task_id,
|
||||
render_tasks.get_task_address(*task_id),
|
||||
);
|
||||
|
||||
self.batch_builder.add_pic_to_batch(
|
||||
let mut batch_builder = BatchBuilder::new(
|
||||
alpha_batch_builder,
|
||||
);
|
||||
|
||||
batch_builder.add_pic_to_batch(
|
||||
pic,
|
||||
&mut alpha_batch_builder,
|
||||
ctx,
|
||||
gpu_cache,
|
||||
render_tasks,
|
||||
|
@ -455,6 +459,8 @@ impl RenderTarget for ColorRenderTarget {
|
|||
z_generator,
|
||||
);
|
||||
|
||||
let alpha_batch_builder = batch_builder.finalize();
|
||||
|
||||
alpha_batch_builder.build(
|
||||
&mut self.alpha_batch_containers,
|
||||
&mut merged_batches,
|
||||
|
|
|
@ -1878,7 +1878,7 @@ fails-if(webrender) == 1059498-3.html 1059498-1-ref.html # WebRender: see bug 14
|
|||
== 1069716-1.html 1069716-1-ref.html
|
||||
== 1078262-1.html about:blank
|
||||
test-pref(layout.testing.overlay-scrollbars.always-visible,false) == 1081072-1.html 1081072-1-ref.html
|
||||
fuzzy-if(webrender,64-64,407-409) == 1081185-1.html 1081185-1-ref.html
|
||||
fuzzy-if(webrender,64-64,407-486) == 1081185-1.html 1081185-1-ref.html
|
||||
== 1097437-1.html 1097437-1-ref.html
|
||||
== 1103258-1.html 1103258-1-ref.html # assertion crash test with layers culling test
|
||||
== 1105137-1.html 1105137-1-ref.html
|
||||
|
|
|
@ -47,8 +47,8 @@ fuzzy-if(d2d,0-1,0-24606) fuzzy-if(skiaContent,0-1,0-17000) == border-collapse-o
|
|||
fuzzy-if(d2d,0-1,0-11000) fuzzy-if(skiaContent,0-1,0-11000) == border-collapse-opacity-table-row.html border-collapse-opacity-table-row-ref.html
|
||||
fuzzy-if(d2d||skiaContent,0-1,0-60000) == border-collapse-opacity-table.html border-collapse-opacity-table-ref.html
|
||||
fuzzy-if(d2d,0-1,0-2478) fuzzy-if(skiaContent,0-1,0-2500) == border-separate-opacity-table-cell.html border-separate-opacity-table-cell-ref.html
|
||||
fuzzy-if(d2d,0-1,0-38000) == border-separate-opacity-table-column-group.html border-separate-opacity-table-column-group-ref.html
|
||||
fuzzy-if(d2d,0-1,0-13000) == border-separate-opacity-table-column.html border-separate-opacity-table-column-ref.html
|
||||
fuzzy-if(d2d,0-1,0-38000) fuzzy-if(webrender,0-1,0-4078) == border-separate-opacity-table-column-group.html border-separate-opacity-table-column-group-ref.html
|
||||
fuzzy-if(d2d,0-1,0-13000) fuzzy-if(webrender,0-1,0-1329) == border-separate-opacity-table-column.html border-separate-opacity-table-column-ref.html
|
||||
fuzzy-if(d2d,0-1,0-37170) fuzzy-if(skiaContent,0-1,0-38000) == border-separate-opacity-table-row-group.html border-separate-opacity-table-row-group-ref.html
|
||||
fuzzy-if(d2d,0-1,0-12390) fuzzy-if(skiaContent,0-1,0-13000) == border-separate-opacity-table-row.html border-separate-opacity-table-row-ref.html
|
||||
fuzzy-if(d2d||skiaContent,0-1,0-95000) == border-separate-opacity-table.html border-separate-opacity-table-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче