Bug 1549271 - Create render task graph earlier during frame building. r=nical

This moves creation of the render task graph to be slightly
earlier during frame building. Instead of creeating the render
tasks during prepare_prims, they are created during the
take_context call for pictures, before recursing into primitives.

This means that in future we can have a surface that targets
multiple render tasks (e.g. for multiple dirty regions), which
may create a different batch set for each region.

Differential Revision: https://phabricator.services.mozilla.com/D29994

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Glenn Watson 2019-05-07 20:49:56 +00:00
parent d0fdaea75f
commit effaccc4f6
4 changed files with 354 additions and 326 deletions

View File

@ -1043,8 +1043,9 @@ impl AlphaBatchBuilder {
.expect("BUG: 3d primitive was not assigned a surface");
let (uv_rect_address, _) = render_tasks.resolve_surface(
ctx.surfaces[raster_config.surface_index.0]
.surface
.expect("BUG: no surface"),
.render_tasks
.expect("BUG: no surface")
.root,
gpu_cache,
);
@ -1097,7 +1098,10 @@ impl AlphaBatchBuilder {
render_tasks,
).unwrap_or(OPAQUE_TASK_ADDRESS);
let surface = ctx.surfaces[raster_config.surface_index.0].surface;
let surface = ctx
.surfaces[raster_config.surface_index.0]
.render_tasks
.map(|s| s.root);
match raster_config.composite_mode {
PictureCompositeMode::TileCache { .. } => {

View File

@ -15,7 +15,7 @@ use crate::hit_test::{HitTester, HitTestingScene};
use crate::hit_test::HitTestingSceneStats;
use crate::internal_types::{FastHashMap, PlaneSplitter};
use crate::picture::{PictureUpdateState, SurfaceInfo, ROOT_SURFACE_INDEX, SurfaceIndex};
use crate::picture::{RetainedTiles, TileCache, DirtyRegion};
use crate::picture::{RetainedTiles, TileCache, DirtyRegion, SurfaceRenderTasks};
use crate::prim_store::{PrimitiveStore, SpaceMapper, PictureIndex, PrimitiveDebugId, PrimitiveScratchBuffer};
#[cfg(feature = "replay")]
use crate::prim_store::{PrimitiveStoreStats};
@ -29,6 +29,7 @@ use crate::segment::SegmentBuilder;
use std::{f32, mem};
use std::sync::Arc;
use crate::tiling::{Frame, RenderPassKind, RenderTargetContext, RenderTarget};
use crate::util::MaxRect;
#[derive(Clone, Copy, Debug, PartialEq)]
@ -444,7 +445,10 @@ impl FrameBuilder {
.surfaces
.first_mut()
.unwrap()
.surface = Some(root_render_task_id);
.render_tasks = Some(SurfaceRenderTasks {
root: root_render_task_id,
port: root_render_task_id,
});
// Push a default dirty region which culls primitives
// against the screen world rect, in absence of any
@ -460,6 +464,7 @@ impl FrameBuilder {
.pictures[self.root_pic_index.0]
.take_context(
self.root_pic_index,
WorldRect::max_rect(),
root_spatial_node_index,
root_spatial_node_index,
ROOT_SURFACE_INDEX,
@ -492,17 +497,6 @@ impl FrameBuilder {
frame_state.pop_dirty_region();
let child_tasks = frame_state
.surfaces[ROOT_SURFACE_INDEX.0]
.take_render_tasks();
for child_task_id in child_tasks {
frame_state.render_tasks.add_dependency(
root_render_task_id,
child_task_id,
);
}
Some(root_render_task_id)
}

View File

@ -1780,6 +1780,17 @@ pub struct SurfaceIndex(pub usize);
pub const ROOT_SURFACE_INDEX: SurfaceIndex = SurfaceIndex(0);
#[derive(Debug, Copy, Clone)]
pub struct SurfaceRenderTasks {
/// The root of the render task chain for this surface. This
/// is attached to parent tasks, and also the surface that
/// gets added during batching.
pub root: RenderTaskId,
/// The port of the render task change for this surface. This
/// is where child tasks for this surface get attached to.
pub port: RenderTaskId,
}
/// Information about an offscreen surface. For now,
/// it contains information about the size and coordinate
/// system of the surface. In the future, it will contain
@ -1799,9 +1810,7 @@ pub struct SurfaceInfo {
pub raster_spatial_node_index: SpatialNodeIndex,
pub surface_spatial_node_index: SpatialNodeIndex,
/// This is set when the render task is created.
pub surface: Option<RenderTaskId>,
/// A list of render tasks that are dependencies of this surface.
pub tasks: Vec<RenderTaskId>,
pub render_tasks: Option<SurfaceRenderTasks>,
/// How much the local surface rect should be inflated (for blur radii).
pub inflation_factor: f32,
/// The device pixel ratio specific to this surface.
@ -1839,21 +1848,14 @@ impl SurfaceInfo {
SurfaceInfo {
rect: PictureRect::zero(),
map_local_to_surface,
surface: None,
render_tasks: None,
raster_spatial_node_index,
surface_spatial_node_index,
tasks: Vec::new(),
inflation_factor,
device_pixel_scale,
allow_subpixel_aa,
}
}
/// Take the set of child render tasks for this surface. This is
/// used when constructing the render task tree.
pub fn take_render_tasks(&mut self) -> Vec<RenderTaskId> {
mem::replace(&mut self.tasks, Vec::new())
}
}
#[derive(Debug)]
@ -2152,7 +2154,7 @@ pub struct PicturePrimitive {
pub prim_list: PrimitiveList,
#[cfg_attr(feature = "capture", serde(skip))]
pub state: Option<(PictureState, PictureContext)>,
pub state: Option<PictureState>,
/// The pipeline that the primitives on this picture belong to.
pub pipeline_id: PipelineId,
@ -2350,9 +2352,10 @@ impl PicturePrimitive {
pub fn take_context(
&mut self,
pic_index: PictureIndex,
clipped_prim_bounding_rect: WorldRect,
surface_spatial_node_index: SpatialNodeIndex,
raster_spatial_node_index: SpatialNodeIndex,
surface_index: SurfaceIndex,
parent_surface_index: SurfaceIndex,
frame_state: &mut FrameBuildingState,
frame_context: &FrameBuildingContext,
) -> Option<(PictureContext, PictureState, PrimitiveList)> {
@ -2378,7 +2381,7 @@ impl PicturePrimitive {
(
raster_spatial_node_index,
surface_spatial_node_index,
surface_index,
parent_surface_index,
0.0,
)
}
@ -2418,6 +2421,304 @@ impl PicturePrimitive {
}
};
let (is_composite, is_passthrough) = match self.raster_config {
Some(ref rc @ RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) => {
// For a picture surface, just push any child tasks and tile
// blits up to the parent surface.
let port = frame_state
.surfaces[parent_surface_index.0]
.render_tasks
.expect("bug: no render tasks set for parent!")
.port;
frame_state
.surfaces[rc.surface_index.0]
.render_tasks = Some(SurfaceRenderTasks {
root: RenderTaskId::INVALID,
port,
});
(false, false)
},
Some(ref raster_config) => {
let pic_rect = PictureRect::from_untyped(&self.snapped_local_rect.to_untyped());
let device_pixel_scale = frame_state
.surfaces[raster_config.surface_index.0]
.device_pixel_scale;
let (clipped, unclipped) = match get_raster_rects(
pic_rect,
&map_pic_to_raster,
&map_raster_to_world,
clipped_prim_bounding_rect,
device_pixel_scale,
) {
Some(info) => info,
None => {
return None
}
};
let transform = map_pic_to_raster.get_transform();
let (root, port) = match raster_config.composite_mode {
PictureCompositeMode::TileCache { .. } => {
unreachable!();
}
PictureCompositeMode::Filter(FilterOp::Blur(blur_radius)) => {
let blur_std_deviation = blur_radius * device_pixel_scale.0;
let scale_factors = scale_factors(&transform);
let blur_std_deviation = DeviceSize::new(
blur_std_deviation * scale_factors.0,
blur_std_deviation * scale_factors.1
);
let inflation_factor = frame_state.surfaces[raster_config.surface_index.0].inflation_factor;
let inflation_factor = (inflation_factor * device_pixel_scale.0).ceil() as i32;
// The clipped field is the part of the picture that is visible
// on screen. The unclipped field is the screen-space rect of
// the complete picture, if no screen / clip-chain was applied
// (this includes the extra space for blur region). To ensure
// that we draw a large enough part of the picture to get correct
// blur results, inflate that clipped area by the blur range, and
// then intersect with the total screen rect, to minimize the
// allocation size.
let mut device_rect = clipped
.inflate(inflation_factor, inflation_factor)
.intersection(&unclipped.to_i32())
.unwrap();
// Adjust the size to avoid introducing sampling errors during the down-scaling passes.
// what would be even better is to rasterize the picture at the down-scaled size
// directly.
device_rect.size = RenderTask::adjusted_blur_source_size(
device_rect.size,
blur_std_deviation,
);
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&device_rect,
device_pixel_scale,
true,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, device_rect.size),
unclipped.size,
pic_index,
device_rect.origin,
Vec::new(),
uv_rect_kind,
raster_spatial_node_index,
device_pixel_scale,
);
let picture_task_id = frame_state.render_tasks.add(picture_task);
let blur_render_task = RenderTask::new_blur(
blur_std_deviation,
picture_task_id,
frame_state.render_tasks,
RenderTargetKind::Color,
ClearMode::Transparent,
);
let render_task_id = frame_state.render_tasks.add(blur_render_task);
(render_task_id, picture_task_id)
}
PictureCompositeMode::Filter(FilterOp::DropShadow(_, blur_radius, _)) => {
let blur_std_deviation = blur_radius * device_pixel_scale.0;
let blur_range = (blur_std_deviation * BLUR_SAMPLE_SCALE).ceil() as i32;
let rounded_std_dev = blur_std_deviation.round();
let rounded_std_dev = DeviceSize::new(rounded_std_dev, rounded_std_dev);
// The clipped field is the part of the picture that is visible
// on screen. The unclipped field is the screen-space rect of
// the complete picture, if no screen / clip-chain was applied
// (this includes the extra space for blur region). To ensure
// that we draw a large enough part of the picture to get correct
// blur results, inflate that clipped area by the blur range, and
// then intersect with the total screen rect, to minimize the
// allocation size.
let mut device_rect = clipped.inflate(blur_range, blur_range)
.intersection(&unclipped.to_i32())
.unwrap();
device_rect.size = RenderTask::adjusted_blur_source_size(
device_rect.size,
rounded_std_dev,
);
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&device_rect,
device_pixel_scale,
true,
);
let mut picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, device_rect.size),
unclipped.size,
pic_index,
device_rect.origin,
Vec::new(),
uv_rect_kind,
raster_spatial_node_index,
device_pixel_scale,
);
picture_task.mark_for_saving();
let picture_task_id = frame_state.render_tasks.add(picture_task);
let blur_render_task = RenderTask::new_blur(
rounded_std_dev,
picture_task_id,
frame_state.render_tasks,
RenderTargetKind::Color,
ClearMode::Transparent,
);
self.secondary_render_task_id = Some(picture_task_id);
let render_task_id = frame_state.render_tasks.add(blur_render_task);
(render_task_id, picture_task_id)
}
PictureCompositeMode::MixBlend(..) if !frame_context.fb_config.gpu_supports_advanced_blend => {
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&clipped,
device_pixel_scale,
true,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, clipped.size),
unclipped.size,
pic_index,
clipped.origin,
Vec::new(),
uv_rect_kind,
raster_spatial_node_index,
device_pixel_scale,
);
let readback_task_id = frame_state.render_tasks.add(
RenderTask::new_readback(clipped)
);
frame_state.render_tasks.add_dependency(
frame_state.surfaces[parent_surface_index.0].render_tasks.unwrap().port,
readback_task_id,
);
self.secondary_render_task_id = Some(readback_task_id);
let render_task_id = frame_state.render_tasks.add(picture_task);
(render_task_id, render_task_id)
}
PictureCompositeMode::Filter(..) => {
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&clipped,
device_pixel_scale,
true,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, clipped.size),
unclipped.size,
pic_index,
clipped.origin,
Vec::new(),
uv_rect_kind,
raster_spatial_node_index,
device_pixel_scale,
);
let render_task_id = frame_state.render_tasks.add(picture_task);
(render_task_id, render_task_id)
}
PictureCompositeMode::ComponentTransferFilter(..) => {
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&clipped,
device_pixel_scale,
true,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, clipped.size),
unclipped.size,
pic_index,
clipped.origin,
Vec::new(),
uv_rect_kind,
raster_spatial_node_index,
device_pixel_scale,
);
let render_task_id = frame_state.render_tasks.add(picture_task);
(render_task_id, render_task_id)
}
PictureCompositeMode::MixBlend(..) |
PictureCompositeMode::Blit(_) => {
// The SplitComposite shader used for 3d contexts doesn't snap
// to pixels, so we shouldn't snap our uv coordinates either.
let supports_snapping = match self.context_3d {
Picture3DContext::In{ .. } => false,
_ => true,
};
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&clipped,
device_pixel_scale,
supports_snapping,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, clipped.size),
unclipped.size,
pic_index,
clipped.origin,
Vec::new(),
uv_rect_kind,
raster_spatial_node_index,
device_pixel_scale,
);
let render_task_id = frame_state.render_tasks.add(picture_task);
(render_task_id, render_task_id)
}
};
frame_state.surfaces[raster_config.surface_index.0].render_tasks = Some(SurfaceRenderTasks {
root,
port,
});
frame_state.render_tasks.add_dependency(
frame_state.surfaces[parent_surface_index.0].render_tasks.unwrap().port,
root,
);
(true, false)
}
None => {
(false, true)
}
};
let state = PictureState {
//TODO: check for MAX_CACHE_SIZE here?
map_local_to_pic,
@ -2427,18 +2728,6 @@ impl PicturePrimitive {
plane_splitter,
};
let (is_composite, is_passthrough) = match self.raster_config {
Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) => {
(false, false)
},
Some(_) => {
(true, false)
}
None => {
(false, true)
}
};
let mut dirty_region_count = 0;
// If this is a picture cache, push the dirty region to ensure any
@ -2488,10 +2777,10 @@ impl PicturePrimitive {
}
self.prim_list = prim_list;
self.state = Some((state, context));
self.state = Some(state);
}
pub fn take_state_and_context(&mut self) -> (PictureState, PictureContext) {
pub fn take_state(&mut self) -> PictureState {
self.state.take().expect("bug: no state present!")
}
@ -2876,14 +3165,11 @@ impl PicturePrimitive {
pub fn prepare_for_render(
&mut self,
pic_index: PictureIndex,
clipped_prim_bounding_rect: WorldRect,
surface_index: SurfaceIndex,
frame_context: &FrameBuildingContext,
frame_state: &mut FrameBuildingState,
data_stores: &mut DataStores,
) -> bool {
let (mut pic_state_for_children, pic_context) = self.take_state_and_context();
let mut pic_state_for_children = self.take_state();
if let Some(ref mut splitter) = pic_state_for_children.plane_splitter {
self.resolve_split_planes(splitter, frame_state);
@ -2896,36 +3182,6 @@ impl PicturePrimitive {
}
};
let (raster_spatial_node_index, child_tasks, device_pixel_scale) = {
let surface_info = &mut frame_state.surfaces[raster_config.surface_index.0];
(
surface_info.raster_spatial_node_index,
surface_info.take_render_tasks(),
surface_info.device_pixel_scale,
)
};
let (map_raster_to_world, map_pic_to_raster) = create_raster_mappers(
self.spatial_node_index,
raster_spatial_node_index,
frame_context.screen_world_rect,
frame_context.clip_scroll_tree,
);
let pic_rect = PictureRect::from_untyped(&self.snapped_local_rect.to_untyped());
let (clipped, unclipped) = match get_raster_rects(
pic_rect,
&map_pic_to_raster,
&map_raster_to_world,
clipped_prim_bounding_rect,
device_pixel_scale,
) {
Some(info) => info,
None => return false,
};
let transform = map_pic_to_raster.get_transform();
// TODO(gw): Almost all of the Picture types below use extra_gpu_cache_data
// to store the same type of data. The exception is the filter
// with a ColorMatrix, which stores the color matrix here. It's
@ -2933,136 +3189,10 @@ impl PicturePrimitive {
// Perhaps store the color matrix after the common data, even though
// it's not used by that shader.
let surface = match raster_config.composite_mode {
PictureCompositeMode::TileCache { .. } => {
// For a picture surface, just push any child tasks and tile
// blits up to the parent surface.
let surface = &mut frame_state.surfaces[surface_index.0];
surface.tasks.extend(child_tasks);
return true;
}
PictureCompositeMode::Filter(FilterOp::Blur(blur_radius)) => {
let blur_std_deviation = blur_radius * device_pixel_scale.0;
let scale_factors = scale_factors(&transform);
let blur_std_deviation = DeviceSize::new(
blur_std_deviation * scale_factors.0,
blur_std_deviation * scale_factors.1
);
let inflation_factor = frame_state.surfaces[raster_config.surface_index.0].inflation_factor;
let inflation_factor = (inflation_factor * device_pixel_scale.0).ceil() as i32;
// The clipped field is the part of the picture that is visible
// on screen. The unclipped field is the screen-space rect of
// the complete picture, if no screen / clip-chain was applied
// (this includes the extra space for blur region). To ensure
// that we draw a large enough part of the picture to get correct
// blur results, inflate that clipped area by the blur range, and
// then intersect with the total screen rect, to minimize the
// allocation size.
let mut device_rect = clipped
.inflate(inflation_factor, inflation_factor)
.intersection(&unclipped.to_i32())
.unwrap();
// Adjust the size to avoid introducing sampling errors during the down-scaling passes.
// what would be even better is to rasterize the picture at the down-scaled size
// directly.
device_rect.size = RenderTask::adjusted_blur_source_size(
device_rect.size,
blur_std_deviation,
);
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&device_rect,
device_pixel_scale,
true,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, device_rect.size),
unclipped.size,
pic_index,
device_rect.origin,
child_tasks,
uv_rect_kind,
pic_context.raster_spatial_node_index,
device_pixel_scale,
);
let picture_task_id = frame_state.render_tasks.add(picture_task);
let blur_render_task = RenderTask::new_blur(
blur_std_deviation,
picture_task_id,
frame_state.render_tasks,
RenderTargetKind::Color,
ClearMode::Transparent,
);
let render_task_id = frame_state.render_tasks.add(blur_render_task);
frame_state.surfaces[surface_index.0].tasks.push(render_task_id);
render_task_id
}
PictureCompositeMode::Filter(FilterOp::DropShadow(offset, blur_radius, color)) => {
let blur_std_deviation = blur_radius * device_pixel_scale.0;
let blur_range = (blur_std_deviation * BLUR_SAMPLE_SCALE).ceil() as i32;
let rounded_std_dev = blur_std_deviation.round();
let rounded_std_dev = DeviceSize::new(rounded_std_dev, rounded_std_dev);
// The clipped field is the part of the picture that is visible
// on screen. The unclipped field is the screen-space rect of
// the complete picture, if no screen / clip-chain was applied
// (this includes the extra space for blur region). To ensure
// that we draw a large enough part of the picture to get correct
// blur results, inflate that clipped area by the blur range, and
// then intersect with the total screen rect, to minimize the
// allocation size.
let mut device_rect = clipped.inflate(blur_range, blur_range)
.intersection(&unclipped.to_i32())
.unwrap();
device_rect.size = RenderTask::adjusted_blur_source_size(
device_rect.size,
rounded_std_dev,
);
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&device_rect,
device_pixel_scale,
true,
);
let mut picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, device_rect.size),
unclipped.size,
pic_index,
device_rect.origin,
child_tasks,
uv_rect_kind,
pic_context.raster_spatial_node_index,
device_pixel_scale,
);
picture_task.mark_for_saving();
let picture_task_id = frame_state.render_tasks.add(picture_task);
let blur_render_task = RenderTask::new_blur(
rounded_std_dev,
picture_task_id,
frame_state.render_tasks,
RenderTargetKind::Color,
ClearMode::Transparent,
);
self.secondary_render_task_id = Some(picture_task_id);
let render_task_id = frame_state.render_tasks.add(blur_render_task);
frame_state.surfaces[surface_index.0].tasks.push(render_task_id);
match raster_config.composite_mode {
PictureCompositeMode::TileCache { .. } => {}
PictureCompositeMode::Filter(FilterOp::Blur(..)) => {}
PictureCompositeMode::Filter(FilterOp::DropShadow(offset, _, color)) => {
if let Some(mut request) = frame_state.gpu_cache.request(&mut self.extra_gpu_data_handle) {
// TODO(gw): This is very hacky code below! It stores an extra
// brush primitive below for the special case of a
@ -3090,40 +3220,8 @@ impl PicturePrimitive {
request.push(shadow_rect);
request.push([0.0, 0.0, 0.0, 0.0]);
}
render_task_id
}
PictureCompositeMode::MixBlend(..) if !frame_context.fb_config.gpu_supports_advanced_blend => {
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&clipped,
device_pixel_scale,
true,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, clipped.size),
unclipped.size,
pic_index,
clipped.origin,
child_tasks,
uv_rect_kind,
pic_context.raster_spatial_node_index,
device_pixel_scale,
);
let readback_task_id = frame_state.render_tasks.add(
RenderTask::new_readback(clipped)
);
self.secondary_render_task_id = Some(readback_task_id);
frame_state.surfaces[surface_index.0].tasks.push(readback_task_id);
let render_task_id = frame_state.render_tasks.add(picture_task);
frame_state.surfaces[surface_index.0].tasks.push(render_task_id);
render_task_id
}
PictureCompositeMode::MixBlend(..) if !frame_context.fb_config.gpu_supports_advanced_blend => {}
PictureCompositeMode::Filter(ref filter) => {
if let FilterOp::ColorMatrix(m) = *filter {
if let Some(mut request) = frame_state.gpu_cache.request(&mut self.extra_gpu_data_handle) {
@ -3132,92 +3230,14 @@ impl PicturePrimitive {
}
}
}
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&clipped,
device_pixel_scale,
true,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, clipped.size),
unclipped.size,
pic_index,
clipped.origin,
child_tasks,
uv_rect_kind,
pic_context.raster_spatial_node_index,
device_pixel_scale,
);
let render_task_id = frame_state.render_tasks.add(picture_task);
frame_state.surfaces[surface_index.0].tasks.push(render_task_id);
render_task_id
}
PictureCompositeMode::ComponentTransferFilter(handle) => {
let filter_data = &mut data_stores.filter_data[handle];
filter_data.update(frame_state);
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&clipped,
device_pixel_scale,
true,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, clipped.size),
unclipped.size,
pic_index,
clipped.origin,
child_tasks,
uv_rect_kind,
pic_context.raster_spatial_node_index,
device_pixel_scale,
);
let render_task_id = frame_state.render_tasks.add(picture_task);
frame_state.surfaces[surface_index.0].tasks.push(render_task_id);
render_task_id
}
PictureCompositeMode::MixBlend(..) |
PictureCompositeMode::Blit(_) => {
// The SplitComposite shader used for 3d contexts doesn't snap
// to pixels, so we shouldn't snap our uv coordinates either.
let supports_snapping = match self.context_3d {
Picture3DContext::In{ .. } => false,
_ => true,
};
let uv_rect_kind = calculate_uv_rect_kind(
&pic_rect,
&transform,
&clipped,
device_pixel_scale,
supports_snapping,
);
let picture_task = RenderTask::new_picture(
RenderTaskLocation::Dynamic(None, clipped.size),
unclipped.size,
pic_index,
clipped.origin,
child_tasks,
uv_rect_kind,
pic_context.raster_spatial_node_index,
device_pixel_scale,
);
let render_task_id = frame_state.render_tasks.add(picture_task);
frame_state.surfaces[surface_index.0].tasks.push(render_task_id);
render_task_id
}
};
frame_state.surfaces[raster_config.surface_index.0].surface = Some(surface);
PictureCompositeMode::Blit(_) => {}
}
true
}

View File

@ -988,7 +988,10 @@ impl BrushSegment {
);
let clip_task_id = frame_state.render_tasks.add(clip_task);
frame_state.surfaces[surface_index.0].tasks.push(clip_task_id);
frame_state.render_tasks.add_dependency(
frame_state.surfaces[surface_index.0].render_tasks.unwrap().port,
clip_task_id,
);
ClipMaskKind::Mask(clip_task_id)
}
None => {
@ -2470,8 +2473,13 @@ impl PrimitiveStore {
PrimitiveInstanceKind::Picture { pic_index ,.. } => {
let pic = &mut self.pictures[pic_index.0];
let clipped_prim_bounding_rect = scratch
.prim_info[prim_instance.visibility_info.0 as usize]
.clipped_world_rect;
match pic.take_context(
pic_index,
clipped_prim_bounding_rect,
pic_context.surface_spatial_node_index,
pic_context.raster_spatial_node_index,
pic_context.surface_index,
@ -2484,6 +2492,8 @@ impl PrimitiveStore {
println!("\tculled for carrying an invisible composite filter");
}
prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
return false;
}
}
@ -3071,9 +3081,6 @@ impl PrimitiveStore {
let pic = &mut self.pictures[pic_index.0];
let prim_info = &scratch.prim_info[prim_instance.visibility_info.0 as usize];
if pic.prepare_for_render(
*pic_index,
prim_info.clipped_world_rect,
pic_context.surface_index,
frame_context,
frame_state,
data_stores,
@ -3747,7 +3754,10 @@ impl PrimitiveInstance {
let clip_task_index = ClipTaskIndex(scratch.clip_mask_instances.len() as _);
scratch.clip_mask_instances.push(ClipMaskKind::Mask(clip_task_id));
prim_info.clip_task_index = clip_task_index;
frame_state.surfaces[pic_context.surface_index.0].tasks.push(clip_task_id);
frame_state.render_tasks.add_dependency(
frame_state.surfaces[pic_context.surface_index.0].render_tasks.unwrap().port,
clip_task_id,
);
}
}
}