Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async scene building. #2362

Merged
merged 18 commits into from Feb 22, 2018
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -14,7 +14,7 @@ use prim_store::{ClipData, ImageMaskData};
use resource_cache::{ImageRequest, ResourceCache};
use util::{LayerToWorldFastTransform, MaxRect, calculate_screen_bounding_rect};
use util::extract_inner_rect_safe;
use std::rc::Rc;
use std::sync::Arc;

pub type ClipStore = FreeList<ClipSources>;
pub type ClipSourcesHandle = FreeListHandle<ClipSources>;
@@ -353,7 +353,7 @@ pub fn rounded_rectangle_contains_point(point: &LayoutPoint,
true
}

pub type ClipChainNodeRef = Option<Rc<ClipChainNode>>;
pub type ClipChainNodeRef = Option<Arc<ClipChainNode>>;

#[derive(Debug, Clone)]
pub struct ClipChainNode {
@@ -425,7 +425,7 @@ impl ClipChain {
self.combined_inner_screen_rect.intersection(&new_node.screen_inner_rect)
.unwrap_or_else(DeviceIntRect::zero);

self.nodes = Some(Rc::new(new_node));
self.nodes = Some(Arc::new(new_node));
}
}

@@ -434,7 +434,7 @@ pub struct ClipChainNodeIter {
}

impl Iterator for ClipChainNodeIter {
type Item = Rc<ClipChainNode>;
type Item = Arc<ClipChainNode>;

fn next(&mut self) -> ClipChainNodeRef {
let previous = self.current.clone();
@@ -22,9 +22,12 @@ use prim_store::ScrollNodeAndClipChain;
use profiler::{GpuCacheProfileCounters, TextureCacheProfileCounters};
use resource_cache::{FontInstanceMap,ResourceCache, TiledImageMap};
use scene::{Scene, StackingContextHelpers, ScenePipeline, SceneProperties};
use scene_builder::{SceneRequest, BuiltScene};
use std::sync::Arc;
use tiling::{CompositeOps, Frame};
use renderer::PipelineInfo;


#[derive(Copy, Clone, PartialEq, PartialOrd, Debug, Eq, Ord)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
@@ -423,7 +426,8 @@ impl<'a> FlattenContext<'a> {
&mut self.id_to_index_mapper,
);

self.pipeline_epochs.push((iframe_pipeline_id, pipeline.epoch));
let epoch = self.scene.pipeline_epochs[&iframe_pipeline_id];
self.pipeline_epochs.push((iframe_pipeline_id, epoch));

let bounds = item.rect();
let iframe_rect = LayerRect::new(LayerPoint::zero(), bounds.size);
@@ -1008,7 +1012,6 @@ impl<'a> FlattenContext<'a> {
/// Frame context contains the information required to update
/// (e.g. scroll) a renderer frame builder (`FrameBuilder`).
pub struct FrameContext {
window_size: DeviceUintSize,
clip_scroll_tree: ClipScrollTree,
pipeline_epoch_map: FastHashMap<PipelineId, Epoch>,
id: FrameId,
@@ -1018,7 +1021,6 @@ pub struct FrameContext {
impl FrameContext {
pub fn new(config: FrameBuilderConfig) -> Self {
FrameContext {
window_size: DeviceUintSize::zero(),
pipeline_epoch_map: FastHashMap::default(),
clip_scroll_tree: ClipScrollTree::new(),
id: FrameId(0),
@@ -1035,6 +1037,17 @@ impl FrameContext {
self.clip_scroll_tree.drain()
}

pub fn new_async_scene_ready(
&mut self,
clip_scroll_tree: ClipScrollTree,
pipeline_epoch_map: FastHashMap<PipelineId, Epoch>,
) {
let old_scrolling_states = self.reset();
self.clip_scroll_tree = clip_scroll_tree;
self.clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states);
self.pipeline_epoch_map = pipeline_epoch_map;
}

#[cfg(feature = "debugger")]
pub fn get_clip_scroll_tree(&self) -> &ClipScrollTree {
&self.clip_scroll_tree
@@ -1073,6 +1086,8 @@ impl FrameContext {
.discard_frame_state_for_pipeline(pipeline_id);
}

// When changing this, please make the same modification to build_scene,
// which will soon replace this method completely.
pub fn create_frame_builder(
&mut self,
old_builder: FrameBuilder,
@@ -1096,12 +1111,12 @@ impl FrameContext {
if window_size.width == 0 || window_size.height == 0 {
error!("ERROR: Invalid window dimensions! Please call api.set_window_size()");
}
self.window_size = window_size;

let old_scrolling_states = self.reset();

self.pipeline_epoch_map
.insert(root_pipeline_id, root_pipeline.epoch);
let root_epoch = scene.pipeline_epochs[&root_pipeline_id];
self.pipeline_epoch_map.insert(root_pipeline_id, root_epoch);


let background_color = root_pipeline
.background_color
@@ -1113,6 +1128,7 @@ impl FrameContext {
builder: old_builder.recycle(
inner_rect,
background_color,
window_size,
self.frame_builder_config,
),
clip_scroll_tree: &mut self.clip_scroll_tree,
@@ -1179,13 +1195,13 @@ impl FrameContext {
frame_builder: &mut FrameBuilder,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
pipelines: &FastHashMap<PipelineId, ScenePipeline>,
pipelines: &FastHashMap<PipelineId, Arc<ScenePipeline>>,
device_pixel_scale: DevicePixelScale,
layer: DocumentLayer,
pan: WorldPoint,
texture_cache_profile: &mut TextureCacheProfileCounters,
gpu_cache_profile: &mut GpuCacheProfileCounters,
scene_properties: &SceneProperties,
scene_properties: &SceneProperties,
removed_pipelines: Vec<PipelineId>,
) -> (HitTester, RenderedDocument) {
let frame = frame_builder.build(
@@ -1194,7 +1210,6 @@ impl FrameContext {
self.id,
&mut self.clip_scroll_tree,
pipelines,
self.window_size,
device_pixel_scale,
layer,
pan,
@@ -1208,3 +1223,83 @@ impl FrameContext {
(hit_tester, self.make_rendered_document(frame, removed_pipelines))
}
}


pub fn build_scene(
config: &FrameBuilderConfig,
mut request: SceneRequest,
) -> BuiltScene {
let inner_rect = request.view.inner_rect;
let window_size = request.view.window_size;
let device_pixel_scale = request.view.accumulated_scale_factor();

let mut pipeline_epoch_map = FastHashMap::default();
let mut clip_scroll_tree = ClipScrollTree::new();

let frame_builder = {
// Creating the borrow here brings happiness to the borrow checker.
let scene = &mut request.scene;
// We checked that the root pipeline is available on the render backend.
let root_pipeline_id = scene.root_pipeline_id.unwrap();
let root_pipeline = scene.pipelines.get(&root_pipeline_id).unwrap();

let background_color = root_pipeline
.background_color
.and_then(|color| if color.a > 0.0 { Some(color) } else { None });

let root_epoch = scene.pipeline_epochs[&root_pipeline_id];
pipeline_epoch_map.insert(root_pipeline_id, root_epoch);

let mut roller = FlattenContext {
scene,
// TODO, we're not really recycling anything here, clean this up.
builder: FrameBuilder::empty().recycle(
inner_rect,
background_color,
window_size,
*config,
),
clip_scroll_tree: &mut clip_scroll_tree,
font_instances: request.font_instances,
tiled_image_map: request.tiled_image_map,
pipeline_epochs: Vec::new(),
replacements: Vec::new(),
output_pipelines: &request.output_pipelines,
id_to_index_mapper: ClipIdToIndexMapper::new(),
};

roller.builder.push_root(
root_pipeline_id,
&root_pipeline.viewport_size,
&root_pipeline.content_size,
roller.clip_scroll_tree,
&mut roller.id_to_index_mapper,
);

roller.builder.setup_viewport_offset(
inner_rect,
device_pixel_scale,
roller.clip_scroll_tree,
);

roller.flatten_root(
&mut root_pipeline.display_list.iter(),
root_pipeline_id,
&root_pipeline.viewport_size,
);

debug_assert!(roller.builder.picture_stack.is_empty());

pipeline_epoch_map.extend(roller.pipeline_epochs.drain(..));

roller.builder
};

BuiltScene {
scene: request.scene,
frame_builder,
clip_scroll_tree,
pipeline_epoch_map,
removed_pipelines: request.removed_pipelines,
}
}
@@ -32,6 +32,7 @@ use render_task::{ClearMode, RenderTask, RenderTaskId, RenderTaskLocation, Rende
use resource_cache::{ImageRequest, ResourceCache};
use scene::{ScenePipeline, SceneProperties};
use std::{mem, usize, f32};
use std::sync::Arc;
use tiling::{CompositeOps, Frame, RenderPass, RenderTargetKind};
use tiling::{RenderPassKind, RenderTargetContext, ScrollbarPrimitive};
use util::{self, MaxRect, RectHelpers, WorldToLayerFastTransform, recycle_vec};
@@ -81,6 +82,7 @@ pub struct FrameBuilderConfig {
pub struct FrameBuilder {
screen_rect: DeviceUintRect,
background_color: Option<ColorF>,
window_size: DeviceUintSize,
prim_store: PrimitiveStore,
pub clip_store: ClipStore,
hit_testing_runs: Vec<HitTestingRun>,
@@ -110,7 +112,7 @@ pub struct FrameBuilder {
pub struct FrameContext<'a> {
pub device_pixel_scale: DevicePixelScale,
pub scene_properties: &'a SceneProperties,
pub pipelines: &'a FastHashMap<PipelineId, ScenePipeline>,
pub pipelines: &'a FastHashMap<PipelineId, Arc<ScenePipeline>>,
pub screen_rect: DeviceIntRect,
pub clip_scroll_tree: &'a ClipScrollTree,
pub node_data: &'a [ClipScrollNodeData],
@@ -180,6 +182,7 @@ impl FrameBuilder {
prim_store: PrimitiveStore::new(),
clip_store: ClipStore::new(),
screen_rect: DeviceUintRect::zero(),
window_size: DeviceUintSize::zero(),
background_color: None,
config: FrameBuilderConfig {
enable_scrollbars: false,
@@ -195,6 +198,7 @@ impl FrameBuilder {
self,
screen_rect: DeviceUintRect,
background_color: Option<ColorF>,
window_size: DeviceUintSize,
config: FrameBuilderConfig,
) -> Self {
FrameBuilder {
@@ -209,6 +213,7 @@ impl FrameBuilder {
clip_store: self.clip_store.recycle(),
screen_rect,
background_color,
window_size,
config,
}
}
@@ -1678,7 +1683,7 @@ impl FrameBuilder {
fn build_layer_screen_rects_and_cull_layers(
&mut self,
clip_scroll_tree: &ClipScrollTree,
pipelines: &FastHashMap<PipelineId, ScenePipeline>,
pipelines: &FastHashMap<PipelineId, Arc<ScenePipeline>>,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
render_tasks: &mut RenderTaskTree,
@@ -1794,8 +1799,7 @@ impl FrameBuilder {
gpu_cache: &mut GpuCache,
frame_id: FrameId,
clip_scroll_tree: &mut ClipScrollTree,
pipelines: &FastHashMap<PipelineId, ScenePipeline>,
window_size: DeviceUintSize,
pipelines: &FastHashMap<PipelineId, Arc<ScenePipeline>>,
device_pixel_scale: DevicePixelScale,
layer: DocumentLayer,
pan: WorldPoint,
@@ -1805,7 +1809,7 @@ impl FrameBuilder {
) -> Frame {
profile_scope!("build");
debug_assert!(
DeviceUintRect::new(DeviceUintPoint::zero(), window_size)
DeviceUintRect::new(DeviceUintPoint::zero(), self.window_size)
.contains_rect(&self.screen_rect)
);

@@ -1908,7 +1912,7 @@ impl FrameBuilder {
resource_cache.end_frame();

Frame {
window_size,
window_size: self.window_size,
inner_rect: self.screen_rect,
device_pixel_ratio: device_pixel_scale.0,
background_color: self.background_color,
@@ -90,6 +90,7 @@ mod render_task;
mod renderer;
mod resource_cache;
mod scene;
mod scene_builder;
mod segment;
mod spring;
mod texture_allocator;
@@ -24,7 +24,7 @@ use renderer::{MAX_VERTEX_TEXTURE_WIDTH};
use resource_cache::{CacheItem, ImageProperties, ImageRequest, ResourceCache};
use segment::SegmentBuilder;
use std::{mem, usize};
use std::rc::Rc;
use std::sync::Arc;
use util::{MatrixHelpers, WorldToLayerFastTransform, calculate_screen_bounding_rect};
use util::{pack_as_float, recycle_vec};

@@ -1574,7 +1574,7 @@ impl PrimitiveStore {
combined_outer_rect = combined_outer_rect.and_then(|r| r.intersection(&outer));
}

Some(Rc::new(ClipChainNode {
Some(Arc::new(ClipChainNode {
work_item: ClipWorkItem {
scroll_node_data_index: prim_run_context.scroll_node.node_data_index,
clip_sources: metadata.clip_sources.weak(),
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use api::{ApiMsg, DocumentMsg};
use api::{ApiMsg, FrameMsg};
use bincode::{serialize, Infinite};
use byteorder::{LittleEndian, WriteBytesExt};
use std::any::TypeId;
@@ -67,13 +67,14 @@ pub fn should_record_msg(msg: &ApiMsg) -> bool {
ApiMsg::AddDocument { .. } |
ApiMsg::DeleteDocument(..) => true,
ApiMsg::UpdateDocument(_, ref msgs) => {
for msg in msgs {
for msg in &msgs.frame_ops {
match *msg {
DocumentMsg::GetScrollNodeState(..) |
DocumentMsg::HitTest(..) => {}
FrameMsg::GetScrollNodeState(..) |
FrameMsg::HitTest(..) => {}
_ => { return true; }
}
}

false
}
_ => false,
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.