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 1 commit
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

Handle the pipeline epoch map properly.

  • Loading branch information
nical committed Feb 21, 2018
commit 4bd50525168a9dc78c345823f5d3f7d15303d059
@@ -24,7 +24,7 @@ use resource_cache::{FontInstanceMap,ResourceCache, TiledImageMap};
use scene::{Scene, StackingContextHelpers, ScenePipeline, SceneProperties};
use tiling::{CompositeOps, Frame};
use renderer::PipelineInfo;
use render_backend::SceneRequest;
use render_backend::{SceneRequest, BuiltScene};

use std::sync::Arc;

This comment has been minimized.

@mrobinson

mrobinson Feb 20, 2018

Member

This should probably go with the rest of the use statements.


@@ -1037,10 +1037,15 @@ impl FrameContext {
self.clip_scroll_tree.drain()
}

pub fn set_clip_scroll_tree(&mut self, tree: ClipScrollTree) {
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 = tree;
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")]
@@ -1165,36 +1170,32 @@ impl FrameContext {
frame_builder
}

// WIP: this will likely not end up in FrameContext but for now I am mostly mimicking
// the current code.
pub fn create_async(
// WIP: There is no reason for this to be in FrameContext other than making it easier
// to keep in sync with changes with the create_frame_builder method above.
// This will soon replace the method above and move somewhere else.
pub fn create_frame_builder_async(
config: &FrameBuilderConfig,
request: SceneRequest,
clip_scroll_tree: &mut ClipScrollTree,
) -> Option<FrameBuilder> {
) -> BuiltScene {
let scene = &request.scene;
let inner_rect = request.view.inner_rect;
let window_size = request.view.window_size;
let device_pixel_scale = request.view.accumulated_scale_factor();

let root_pipeline_id = match scene.root_pipeline_id {
Some(root_pipeline_id) => root_pipeline_id,
None => return None,
};

let root_pipeline = match scene.pipelines.get(&root_pipeline_id) {
Some(root_pipeline) => root_pipeline,
None => return None,
};

if window_size.width == 0 || window_size.height == 0 {
error!("ERROR: Invalid window dimensions! Please call api.set_window_size()");
}
// We checked that the root pipeline is available on therender 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 mut pipeline_epoch_map = FastHashMap::default();
let mut clip_scroll_tree = ClipScrollTree::new();

let root_epoch = *scene.pipeline_epochs.get(&root_pipeline_id).unwrap();
pipeline_epoch_map.insert(root_pipeline_id, root_epoch);

let frame_builder = {
let mut roller = FlattenContext {
scene,
@@ -1205,7 +1206,7 @@ impl FrameContext {
window_size,
*config,
),
clip_scroll_tree,
clip_scroll_tree: &mut clip_scroll_tree,
font_instances: request.font_instances,
tiled_image_map: request.tiled_image_map,
pipeline_epochs: Vec::new(),
@@ -1236,15 +1237,18 @@ impl FrameContext {

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

// WIP: move this to the render backend thread I think
//self.pipeline_epoch_map.extend(roller.pipeline_epochs.drain(..));
pipeline_epoch_map.extend(roller.pipeline_epochs.drain(..));

roller.builder
};

// WIP
//clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states);

Some(frame_builder)
BuiltScene {
frame_builder,
clip_scroll_tree,
pipeline_epoch_map,
document_id: request.document_id,
render: request.render,
}
}

pub fn update_epoch(&mut self, pipeline_id: PipelineId, epoch: Epoch) {
@@ -4,7 +4,7 @@

use api::{ApiMsg, BuiltDisplayList, ClearCache, DebugCommand};
#[cfg(feature = "debugger")]
use api::{BuiltDisplayListIter, SpecificDisplayItem};
use api::{BuiltDisplayListIter, SpecificDisplayItem, Epoch};
use api::{DeviceIntPoint, DevicePixelScale, DeviceUintPoint, DeviceUintRect, DeviceUintSize};
use api::{DocumentId, DocumentLayer, DocumentMsg, HitTestResult, IdNamespace, PipelineId};
use api::RenderNotifier;
@@ -161,6 +161,24 @@ impl Document {
scene_tx: &Sender<SceneBuilderMsg>,
ops: &DocumentOps,
) {
// Do as much of the error handling as possible here before dispatching to
// the scene builder thread.
match self.scene.root_pipeline_id {
Some(id) => {
if !self.scene.pipelines.contains_key(&id) {
return;
}
}
None => {
return;
}
}

if self.view.window_size.width == 0 || self.view.window_size.height == 0 {
error!("ERROR: Invalid window dimensions! Please call api.set_window_size()");
return;
}

scene_tx.send(SceneBuilderMsg::BuildScene(
SceneRequest {
scene: self.scene.clone(),
@@ -551,7 +569,10 @@ impl RenderBackend {
while let Ok(msg) = self.scene_rx.try_recv() {
if let Some(doc) = self.documents.get_mut(&msg.document_id) {
doc.frame_builder = Some(msg.frame_builder);
doc.frame_ctx.set_clip_scroll_tree(msg.clip_scroll_tree);
doc.frame_ctx.new_async_scene_ready(
msg.clip_scroll_tree,
msg.pipeline_epoch_map,
);
} else {
// The document was removed while we were building it, skip it.
continue;
@@ -1132,6 +1153,7 @@ pub struct SceneRequest {
pub struct BuiltScene {
pub frame_builder: FrameBuilder,
pub clip_scroll_tree: ClipScrollTree,
pub pipeline_epoch_map: FastHashMap<PipelineId, Epoch>,
pub document_id: DocumentId,
pub render: bool,
}
@@ -1177,35 +1199,23 @@ impl SceneBuilder {
pub fn process_message(&mut self, msg: SceneBuilderMsg) -> bool {
match msg {
SceneBuilderMsg::BuildScene(request) => {
let document_id = request.document_id;
let render = request.render;
let result = self.build_scene(request);

let (frame_builder, clip_scroll_tree) = self.build_scene(request);
self.tx.send(result).unwrap();

self.tx.send(BuiltScene {
frame_builder,
clip_scroll_tree,
document_id,
render,
}).unwrap();
let _ = self.api_tx.send(ApiMsg::WakeUp);
}
SceneBuilderMsg::Stop => { return false; }
}
return true;
}

pub fn build_scene(&mut self, request: SceneRequest) -> (FrameBuilder, ClipScrollTree) {
let mut clip_scroll_tree = ClipScrollTree::new();
let frame_builder = FrameContext::create_async(
&self.config,
request,
&mut clip_scroll_tree,
).unwrap();
pub fn build_scene(&mut self, request: SceneRequest) -> BuiltScene {
let built_scene = FrameContext::create_frame_builder_async(&self.config, request);

// Here will go other things that could be offloaded from the render backend
// like some of the rasterization that we know we'd have to do in the next frame.

(frame_builder, clip_scroll_tree)
built_scene
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.