diff --git a/src/servo/layout/layout_task.rs b/src/servo/layout/layout_task.rs index 34f29212d13..8bd87da10c9 100644 --- a/src/servo/layout/layout_task.rs +++ b/src/servo/layout/layout_task.rs @@ -85,6 +85,100 @@ fn Layout(render_task: RenderTask, impl Layout { + fn start() { + while self.handle_request() { + // loop indefinitely + } + } + + fn handle_request() -> bool { + + match self.from_content.recv() { + BuildMsg(move node, move styles, move doc_url, + move to_content, move window_size, move join_chan) => { + self.handle_build(node, styles, doc_url, to_content, window_size, join_chan); + } + QueryMsg(query, chan) => self.handle_query(query, chan), + ExitMsg => { + debug!("layout: ExitMsg received"); + return false + } + } + + true + } + + fn handle_build(node: Node, styles: ARC, doc_url: Url, + to_content: comm::Chan, window_size: Size2D, + join_chan: pipes::Chan<()>) { + debug!("layout: received layout request for: %s", doc_url.to_str()); + debug!("layout: parsed Node tree"); + debug!("%?", node.dump()); + + // Reset the image cache + self.local_image_cache.next_round(self.make_on_image_available_cb(to_content)); + + let screen_size = Size2D(au::from_px(window_size.width as int), + au::from_px(window_size.height as int)); + + let layout_ctx = LayoutContext { + image_cache: self.local_image_cache, + font_cache: self.font_cache, + doc_url: doc_url, + screen_size: Rect(Point2D(au(0), au(0)), screen_size) + }; + + let layout_root: @FlowContext = do util::time::time("layout: tree construction") { + // TODO: this is dumb. we don't need 3 separate traversals. + node.initialize_style_for_subtree(&layout_ctx, &self.layout_refs); + node.recompute_style_for_subtree(&layout_ctx, &styles); + /* resolve styles (convert relative values) down the node tree */ + apply_style(&layout_ctx, node); + + let builder = LayoutTreeBuilder(); + let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx, + node) { + Ok(root) => root, + Err(*) => fail ~"Root flow should always exist" + }; + + debug!("layout: constructed Flow tree"); + debug!("%?", layout_root.dump()); + + layout_root + }; + + do util::time::time("layout: main layout") { + /* perform layout passes over the flow tree */ + do layout_root.traverse_postorder |f| { f.bubble_widths(&layout_ctx) } + do layout_root.traverse_preorder |f| { f.assign_widths(&layout_ctx) } + do layout_root.traverse_postorder |f| { f.assign_height(&layout_ctx) } + } + + do util::time::time("layout: display list building") { + let dlist = DVec(); + let builder = dl::DisplayListBuilder { + ctx: &layout_ctx, + }; + let render_layer = RenderLayer { + display_list: move dlist, + size: Size2D(au::to_px(screen_size.width) as uint, + au::to_px(screen_size.height) as uint) + }; + + // TODO: set options on the builder before building + // TODO: be smarter about what needs painting + layout_root.build_display_list(&builder, © layout_root.d().position, + &render_layer.display_list); + self.render_task.send(render_task::RenderMsg(move render_layer)); + } // time(layout: display list building) + + // Tell content we're done + join_chan.send(()); + + } + + fn handle_query(query: LayoutQuery, reply_chan: comm::Chan) { match query { @@ -117,92 +211,6 @@ impl Layout { } } - fn start() { - while self.handle_request() { - // loop indefinitely - } - } - - fn handle_request() -> bool { - - match self.from_content.recv() { - QueryMsg(query, chan) => self.handle_query(query, chan), - ExitMsg => { - debug!("layout: ExitMsg received"); - return false - }, - BuildMsg(node, styles, doc_url, to_content, window_size, join_chan) => { - debug!("layout: received layout request for: %s", doc_url.to_str()); - debug!("layout: parsed Node tree"); - debug!("%?", node.dump()); - - // Reset the image cache - self.local_image_cache.next_round(self.make_on_image_available_cb(to_content)); - - let screen_size = Size2D(au::from_px(window_size.width as int), - au::from_px(window_size.height as int)); - - let layout_ctx = LayoutContext { - image_cache: self.local_image_cache, - font_cache: self.font_cache, - doc_url: doc_url, - screen_size: Rect(Point2D(au(0), au(0)), screen_size) - }; - - let layout_root: @FlowContext = do util::time::time("layout: tree construction") { - // TODO: this is dumb. we don't need 3 separate traversals. - node.initialize_style_for_subtree(&layout_ctx, &self.layout_refs); - node.recompute_style_for_subtree(&layout_ctx, &styles); - /* resolve styles (convert relative values) down the node tree */ - apply_style(&layout_ctx, node); - - let builder = LayoutTreeBuilder(); - let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx, - node) { - Ok(root) => root, - Err(*) => fail ~"Root flow should always exist" - }; - - debug!("layout: constructed Flow tree"); - debug!("%?", layout_root.dump()); - - layout_root - }; - - do util::time::time("layout: main layout") { - /* perform layout passes over the flow tree */ - do layout_root.traverse_postorder |f| { f.bubble_widths(&layout_ctx) } - do layout_root.traverse_preorder |f| { f.assign_widths(&layout_ctx) } - do layout_root.traverse_postorder |f| { f.assign_height(&layout_ctx) } - } - - do util::time::time("layout: display list building") { - let dlist = DVec(); - let builder = dl::DisplayListBuilder { - ctx: &layout_ctx, - }; - let render_layer = RenderLayer { - display_list: move dlist, - size: Size2D(au::to_px(screen_size.width) as uint, - au::to_px(screen_size.height) as uint) - }; - - // TODO: set options on the builder before building - // TODO: be smarter about what needs painting - layout_root.build_display_list(&builder, © layout_root.d().position, - &render_layer.display_list); - self.render_task.send(render_task::RenderMsg(move render_layer)); - } // time(layout: display list building) - - // Tell content we're done - join_chan.send(()); - - } // BuildMsg - } // match - - true - } - // When images can't be loaded in time to display they trigger // this callback in some task somewhere. This w fn make_on_image_available_cb(to_content: comm::Chan) -> ~fn(ImageResponseMsg) {