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

Extra display list data #482

Closed
wants to merge 11 commits into from
Prev

Fix merge fallout.

  • Loading branch information
pcwalton committed May 25, 2013
commit 3bcb1cfa623c8ccf050f602b4a1b539a4f4b1a87
@@ -127,15 +127,15 @@ impl<E> DisplayItem<E> {
new_run,
&text.range,
baseline_origin,
text.color)
text.color);

// Draw the underline if applicable.
if new_run.underline {
// TODO: Use the font metrics to properly position the underline bar.
let width = text.base.bounds.size.width;
let underline_bounds = Rect(Point2D(baseline_origin.x, baseline_origin.y),
Size2D(width, font.metrics.underline_size));
render_context.draw_solid_color(&underline_bounds, color)
render_context.draw_solid_color(&underline_bounds, text.color)
}
}

@@ -46,12 +46,14 @@ pub struct FontContext {
pub impl<'self> FontContext {
fn new(backend: BackendType,
needs_font_list: bool,
prof_chan: ProfilerChan)
profiler_chan: ProfilerChan)
-> FontContext {
let handle = FontContextHandle::new();
let font_list = if needs_font_list {
Some(FontList::new(&handle, prof_chan.clone())) }
else { None };
Some(FontList::new(&handle, profiler_chan.clone()))
} else {
None
};

// TODO: Allow users to specify these.
let mut generic_fonts = HashMap::with_capacity(5);
@@ -34,7 +34,10 @@ pub struct RenderTask {
}

impl RenderTask {
pub fn new<C:Compositor + Owned>(compositor: C, opts: Opts) -> RenderTask {
pub fn new<C:Compositor + Owned>(compositor: C,
opts: Opts,
profiler_chan: ProfilerChan)
-> RenderTask {
let compositor_cell = Cell(compositor);
let opts_cell = Cell(opts);
let (port, chan) = comm::stream();
@@ -47,15 +50,20 @@ impl RenderTask {
let opts = opts_cell.with_ref(|o| copy *o);
let n_threads = opts.n_render_threads;
let new_opts_cell = Cell(opts);
let profiler_chan = profiler_chan.clone();
let profiler_chan_copy = profiler_chan.clone();

let thread_pool = do TaskPool::new(n_threads, Some(SingleThreaded)) {
let opts_cell = Cell(new_opts_cell.with_ref(|o| copy *o));
let profiler_chan = Cell(profiler_chan.clone());
let f: ~fn(uint) -> ThreadRenderContext = |thread_index| {
let opts = opts_cell.with_ref(|opts| copy *opts);

ThreadRenderContext {
thread_index: thread_index,
font_ctx: @mut FontContext::new(opts.render_backend, false),
font_ctx: @mut FontContext::new(opts.render_backend,
false,
profiler_chan.take()),
opts: opts,
}
};
@@ -67,7 +75,8 @@ impl RenderTask {
port: port.take(),
compositor: compositor,
thread_pool: thread_pool,
opts: opts_cell.take()
opts: opts_cell.take(),
profiler_chan: profiler_chan_copy,
};

renderer.start();
@@ -91,7 +100,9 @@ priv struct Renderer<C> {
compositor: C,
thread_pool: TaskPool<ThreadRenderContext>,
opts: Opts,
prof_chan: ProfilerChan,

/// Channel to the profiler.
profiler_chan: ProfilerChan,
}

impl<C: Compositor + Owned> Renderer<C> {
@@ -112,8 +123,11 @@ impl<C: Compositor + Owned> Renderer<C> {
fn render(&mut self, render_layer: RenderLayer) {
debug!("renderer: rendering");
do time("rendering") {
let layer_buffer_set = do render_layers(&render_layer, &self.opts)
|render_layer_ref, layer_buffer, buffer_chan| {
let layer_buffer_set = do render_layers(&render_layer,
&self.opts,
self.profiler_chan.clone()) |render_layer_ref,
layer_buffer,
buffer_chan| {
let layer_buffer_cell = Cell(layer_buffer);
do self.thread_pool.execute |thread_render_context| {
do layer_buffer_cell.with_ref |layer_buffer| {
@@ -190,7 +190,7 @@ fn run_main_loop(port: Port<Msg>,
};

do window.set_composite_callback {
do profile(time::CompositingCategory, prof_chan.clone()) {
do profile(time::CompositingCategory, profiler_chan.clone()) {
debug!("compositor: compositing");
// Adjust the layer dimensions as necessary to correspond to the size of the window.
scene.size = window.size();
@@ -18,11 +18,9 @@ use script::script_task;
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
use servo_net::resource_task::ResourceTask;
use servo_net::resource_task;
use std::net::url::Url;

use servo_util::time::{ProfilerChan, ProfilerPort, ProfilerTask};
use servo_util::time;
use servo_util::time::ProfilerChan;
use servo_util::time::ProfilerPort;
use std::net::url::Url;

pub type EngineTask = Chan<Msg>;

@@ -65,15 +63,14 @@ impl Engine {
let layout_task = layout_task::create_layout_task(render_task.clone(),
image_cache_task.clone(),
opts,
profiler_task.chan.clone());
profiler_chan.clone());

let script_task = ScriptTask::new(script_port.take(),
script_chan.take(),
layout_task.clone(),
resource_task.clone(),
image_cache_task.clone());


Engine {
request_port: request,
compositor: compositor.clone(),
@@ -82,7 +79,7 @@ impl Engine {
image_cache_task: image_cache_task.clone(),
layout_task: layout_task,
script_task: script_task,
profiler_task: profiler_task,
profiler_task: ProfilerTask::new(profiler_port.take(), profiler_chan.clone()),
}.run()
}
}
@@ -23,7 +23,7 @@ pub struct BlockFlowData {
common: FlowData,

/// The associated render box.
box: Option<@RenderBox>,
box: Option<RenderBox>,

/// Whether this block flow is the root flow.
is_root: bool
@@ -137,11 +137,11 @@ pub enum RenderBoxType {

/// Represents the outcome of attempting to split a render box.
pub enum SplitBoxResult {
CannotSplit(@RenderBox),
CannotSplit(RenderBox),
// in general, when splitting the left or right side can
// be zero length, due to leading/trailing trimmable whitespace
SplitDidFit(Option<@RenderBox>, Option<@RenderBox>),
SplitDidNotFit(Option<@RenderBox>, Option<@RenderBox>)
SplitDidFit(Option<RenderBox>, Option<RenderBox>),
SplitDidNotFit(Option<RenderBox>, Option<RenderBox>)
}

/// Data common to all render boxes.
@@ -271,10 +271,10 @@ pub impl RenderBox {

/// Attempts to split this box so that its width is no more than `max_width`. Fails if this box
/// is an unscanned text box.
fn split_to_width(@self, _: &LayoutContext, max_width: Au, starts_line: bool)
fn split_to_width(&self, _: &LayoutContext, max_width: Au, starts_line: bool)
-> SplitBoxResult {
match *self {
GenericRenderBoxClass(*) | ImageRenderBoxClass(*) => CannotSplit(self),
GenericRenderBoxClass(*) | ImageRenderBoxClass(*) => CannotSplit(*self),
UnscannedTextRenderBoxClass(*) => {
fail!(~"WAT: shouldn't be an unscanned text box here.")
}
@@ -351,7 +351,7 @@ pub impl RenderBox {
let new_text_box = @mut text::adapt_textbox_with_range(text_box.base,
text_box.text_data.run,
left_range);
Some(@TextRenderBoxClass(new_text_box))
Some(TextRenderBoxClass(new_text_box))
} else {
None
};
@@ -360,7 +360,7 @@ pub impl RenderBox {
let new_text_box = @mut text::adapt_textbox_with_range(text_box.base,
text_box.text_data.run,
*range);
Some(@TextRenderBoxClass(new_text_box))
Some(TextRenderBoxClass(new_text_box))
};

if pieces_processed_count == 1 || left_box.is_none() {
@@ -549,7 +549,7 @@ pub impl RenderBox {
/// representing the box's stacking context. When asked to construct its constituent display
/// items, each box puts its display items into the correct stack layer according to CSS 2.1
/// Appendix E. Finally, the builder flattens the list.
fn build_display_list<E: ExtraDisplayListData>(@self,
fn build_display_list<E: ExtraDisplayListData>(&self,
_: &DisplayListBuilder,
dirty: &Rect<Au>,
offset: &Point2D<Au>,
@@ -581,7 +581,7 @@ pub impl RenderBox {
let text_display_item = ~TextDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
extra: ExtraDisplayListData::new(self),
extra: ExtraDisplayListData::new(*self),
},
// FIXME(pcwalton): Allocation? Why?!
text_run: ~text_box.text_data.run.serialize(),
@@ -602,7 +602,7 @@ pub impl RenderBox {
let border_display_item = ~BorderDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
extra: ExtraDisplayListData::new(self),
extra: ExtraDisplayListData::new(*self),
},
width: Au::from_px(1),
color: rgb(0, 0, 200).to_gfx_color(),
@@ -622,7 +622,7 @@ pub impl RenderBox {
let border_display_item = ~BorderDisplayItem {
base: BaseDisplayItem {
bounds: baseline,
extra: ExtraDisplayListData::new(self),
extra: ExtraDisplayListData::new(*self),
},
width: Au::from_px(1),
color: rgb(0, 200, 0).to_gfx_color(),
@@ -646,7 +646,7 @@ pub impl RenderBox {
let image_display_item = ~ImageDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
extra: ExtraDisplayListData::new(self),
extra: ExtraDisplayListData::new(*self),
},
image: image.clone(),
};
@@ -671,9 +671,9 @@ pub impl RenderBox {

/// Adds the display items necessary to paint the background of this render box to the display
/// list if necessary.
fn paint_background_if_applicable<E: ExtraDisplayListData>(@self,
list: &Cell<DisplayList<E>>,
absolute_bounds: &Rect<Au>) {
fn paint_background_if_applicable<E: ExtraDisplayListData>(&self,
list: &Cell<DisplayList<E>>,
absolute_bounds: &Rect<Au>) {
// FIXME: This causes a lot of background colors to be displayed when they are clearly not
// needed. We could use display list optimization to clean this up, but it still seems
// inefficient. What we really want is something like "nearest ancestor element that
@@ -686,7 +686,7 @@ pub impl RenderBox {
let solid_color_display_item = ~SolidColorDisplayItem {
base: BaseDisplayItem {
bounds: *absolute_bounds,
extra: ExtraDisplayListData::new(self),
extra: ExtraDisplayListData::new(*self),
},
color: background_color.to_gfx_color(),
};
@@ -698,7 +698,7 @@ pub impl RenderBox {

/// Adds the display items necessary to paint the borders of this render box to the display
/// list if necessary.
fn paint_borders_if_applicable<E: ExtraDisplayListData>(@self,
fn paint_borders_if_applicable<E: ExtraDisplayListData>(&self,
list: &Cell<DisplayList<E>>,
abs_bounds: &Rect<Au>) {
if !self.is_element() {
@@ -740,7 +740,7 @@ pub impl RenderBox {
let border_display_item = ~BorderDisplayItem {
base: BaseDisplayItem {
bounds: bounds,
extra: ExtraDisplayListData::new(self),
extra: ExtraDisplayListData::new(*self),
},
width: border_width,
color: color,
@@ -814,7 +814,7 @@ pub impl RenderBox {
fn text_decoration(&self) -> CSSTextDecoration {
/// Computes the propagated value of text-decoration, as specified in CSS 2.1 § 16.3.1
/// TODO: make sure this works with anonymous box generation.
fn get_propagated_text_decoration(element: AbstractNode) -> CSSTextDecoration {
fn get_propagated_text_decoration(element: AbstractNode<LayoutView>) -> CSSTextDecoration {
//Skip over non-element nodes in the DOM
if(!element.is_element()){
return match element.parent_node() {
@@ -104,7 +104,7 @@ impl BoxGenerator {
_: &LayoutContext,
_: AbstractNode<LayoutView>,
_: InlineSpacerSide)
-> Option<@RenderBox> {
-> Option<RenderBox> {
None
}

@@ -129,20 +129,20 @@ impl BoxGenerator {

// if a leaf, make a box.
if node.is_leaf() {
let new_box = @builder.make_box(ctx, box_type, node, self.flow);
let new_box = builder.make_box(ctx, box_type, node, self.flow);
inline.boxes.push(new_box);
} else if self.inline_spacers_needed_for_node(node) {
// else, maybe make a spacer for "left" margin, border, padding
for self.make_inline_spacer_for_node_side(ctx, node, LogicalBefore).each
|spacer: &@RenderBox| {
|spacer: &RenderBox| {
inline.boxes.push(*spacer);
}
}
// TODO: cases for inline-block, etc.
},
BlockFlow(block) => {
debug!("BoxGenerator[f%d]: point b", block.common.id);
let new_box = @builder.make_box(ctx, box_type, node, self.flow);
let new_box = builder.make_box(ctx, box_type, node, self.flow);

debug!("BoxGenerator[f%d]: attaching box[b%d] to block flow (node: %s)",
block.common.id,
@@ -21,17 +21,17 @@ use newcss;
use servo_util::tree::TreeNodeRef;

pub trait ExtraDisplayListData {
fn new(box: @RenderBox) -> Self;
fn new(box: RenderBox) -> Self;
}

impl ExtraDisplayListData for () {
fn new(box: @RenderBox) -> () {
fn new(_: RenderBox) -> () {
()
}
}

impl ExtraDisplayListData for @RenderBox {
fn new(box: @RenderBox) -> @RenderBox {
impl ExtraDisplayListData for RenderBox {
fn new(box: RenderBox) -> RenderBox {
box
}
}
@@ -61,19 +61,19 @@ pub trait FlowDisplayListBuilderMethods {

impl FlowDisplayListBuilderMethods for FlowContext {
fn build_display_list<E: ExtraDisplayListData>(&self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
list: &Cell<DisplayList<E>>) {
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
list: &Cell<DisplayList<E>>) {
let zero = gfx::geometry::zero_point();
self.build_display_list_recurse(builder, dirty, &zero, list);
}

fn build_display_list_for_child<E: ExtraDisplayListData>(&self,
builder: &DisplayListBuilder,
child_flow: FlowContext,
dirty: &Rect<Au>,
offset: &Point2D<Au>,
list: &Cell<DisplayList<E>>) {
builder: &DisplayListBuilder,
child_flow: FlowContext,
dirty: &Rect<Au>,
offset: &Point2D<Au>,
list: &Cell<DisplayList<E>>) {
// Adjust the dirty rect to child flow context coordinates.
do child_flow.with_base |child_node| {
let abs_flow_bounds = child_node.position.translate(offset);
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.