mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
layout: Make the compositor rather than layout determine the position of
each iframe. The old code that attempted to do this during layout wasn't able to work for multiple reasons: it couldn't know where the iframe was going to be on the page (because of nested iframes), and at the time it was building the display list for a fragment it couldn't know where that fragment was going to be in page coordinates. This patch rewrites that code so that both the sizes and positions of iframes are determined by the compositor. Layout layerizes all iframes and marks the iframe layers with the appropriate pipeline and subpage IDs so that the compositor can place them correctly. This approach is similar in spirit to Gecko's `RefLayer` infrastructure. The logic that determines when it is time to take the screenshot for reftests has been significantly revamped to deal with this change in delegation of responsibility. Additionally, this code removes the infrastructure that sends layout data back to the layout task to be destroyed, since it is now all thread-safe and can be destroyed on the script task. The failing tests now fail because of a pre-existing bug related to intrinsic heights and borders on inline replaced elements. They happened to pass before because we never rendered the iframes at all, which meant they never had a chance to draw the red border the tests expect to not render! Closes #7377.
This commit is contained in:
parent
ed0d70e234
commit
c72d0c2ed0
20 changed files with 602 additions and 389 deletions
|
@ -2126,10 +2126,11 @@ impl Flow for BlockFlow {
|
|||
}
|
||||
|
||||
fn compute_overflow(&self) -> Rect<Au> {
|
||||
self.fragment.compute_overflow(&self.base.early_absolute_position_info
|
||||
.relative_containing_block_size,
|
||||
self.base.early_absolute_position_info
|
||||
.relative_containing_block_mode)
|
||||
let flow_size = self.base.position.size.to_physical(self.base.writing_mode);
|
||||
self.fragment.compute_overflow(&flow_size,
|
||||
&self.base
|
||||
.early_absolute_position_info
|
||||
.relative_containing_block_size)
|
||||
}
|
||||
|
||||
fn iterate_through_fragment_border_boxes(&self,
|
||||
|
|
|
@ -285,15 +285,6 @@ impl<'a> FlowConstructor<'a> {
|
|||
fn set_flow_construction_result(&self,
|
||||
node: &ThreadSafeLayoutNode,
|
||||
result: ConstructionResult) {
|
||||
if let ConstructionResult::None = result {
|
||||
let mut layout_data_ref = node.mutate_layout_data();
|
||||
let layout_data = layout_data_ref.as_mut().expect("no layout data");
|
||||
layout_data.remove_compositor_layers(self.layout_context
|
||||
.shared
|
||||
.constellation_chan
|
||||
.clone());
|
||||
}
|
||||
|
||||
node.set_flow_construction_result(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
* 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 construct::{ConstructionItem, ConstructionResult};
|
||||
use construct::ConstructionResult;
|
||||
use incremental::RestyleDamage;
|
||||
use msg::constellation_msg::ConstellationChan;
|
||||
use parallel::DomParallelInfo;
|
||||
use script::dom::node::SharedLayoutData;
|
||||
use std::sync::Arc;
|
||||
|
@ -64,30 +63,6 @@ pub struct LayoutDataWrapper {
|
|||
pub data: Box<PrivateLayoutData>,
|
||||
}
|
||||
|
||||
impl LayoutDataWrapper {
|
||||
pub fn remove_compositor_layers(&self, constellation_chan: ConstellationChan) {
|
||||
match self.data.flow_construction_result {
|
||||
ConstructionResult::None => {}
|
||||
ConstructionResult::Flow(ref flow_ref, _) => {
|
||||
flow_ref.remove_compositor_layers(constellation_chan);
|
||||
}
|
||||
ConstructionResult::ConstructionItem(ref construction_item) => {
|
||||
match *construction_item {
|
||||
ConstructionItem::InlineFragments(ref inline_fragments) => {
|
||||
for fragment in &inline_fragments.fragments.fragments {
|
||||
fragment.remove_compositor_layers(constellation_chan.clone());
|
||||
}
|
||||
}
|
||||
ConstructionItem::Whitespace(..) => {}
|
||||
ConstructionItem::TableColumnFragment(ref fragment) => {
|
||||
fragment.remove_compositor_layers(constellation_chan.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code, unsafe_code)]
|
||||
fn static_assertion(x: Option<LayoutDataWrapper>) {
|
||||
unsafe {
|
||||
|
|
|
@ -14,13 +14,12 @@ use azure::azure_hl::Color;
|
|||
use block::BlockFlow;
|
||||
use canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||
use context::LayoutContext;
|
||||
use euclid::Matrix4;
|
||||
use euclid::{Point2D, Point3D, Rect, SideOffsets2D, Size2D};
|
||||
use euclid::{Matrix4, Point2D, Point3D, Rect, SideOffsets2D, Size2D};
|
||||
use flex::FlexFlow;
|
||||
use flow::{self, BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
|
||||
use flow_ref;
|
||||
use fragment::{CoordinateSystem, Fragment, HAS_LAYER, IframeFragmentInfo, ImageFragmentInfo};
|
||||
use fragment::{ScannedTextFragmentInfo, SpecificFragmentInfo};
|
||||
use fragment::{CoordinateSystem, Fragment, HAS_LAYER, ImageFragmentInfo, ScannedTextFragmentInfo};
|
||||
use fragment::{SpecificFragmentInfo};
|
||||
use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayItem};
|
||||
use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion};
|
||||
use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayList};
|
||||
|
@ -35,9 +34,7 @@ use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
|
|||
use ipc_channel::ipc::{self, IpcSharedMemory};
|
||||
use list_item::ListItemFlow;
|
||||
use model::{self, MaybeAuto, ToGfxMatrix};
|
||||
use msg::compositor_msg::{LayerId, ScrollPolicy};
|
||||
use msg::constellation_msg::ConstellationChan;
|
||||
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||
use msg::compositor_msg::{LayerId, ScrollPolicy, SubpageLayerInfo};
|
||||
use net_traits::image::base::{Image, PixelFormat};
|
||||
use net_traits::image_cache_task::UsePlaceholder;
|
||||
use std::default::Default;
|
||||
|
@ -70,7 +67,7 @@ const INSERTION_POINT_LOGICAL_WIDTH: Au = Au(1 * AU_PER_PX);
|
|||
/// Whether a stacking context needs a layer or not.
|
||||
pub enum StackingContextLayerNecessity {
|
||||
Always(LayerId, ScrollPolicy),
|
||||
IfCanvas(LayerId),
|
||||
IfCanvasOrIframe(LayerId),
|
||||
}
|
||||
|
||||
/// The results of display list building for a single flow.
|
||||
|
@ -206,13 +203,6 @@ pub trait FragmentDisplayListBuilding {
|
|||
clip: &ClippingRegion,
|
||||
stacking_relative_display_port: &Rect<Au>);
|
||||
|
||||
/// Sends the size and position of this iframe fragment to the constellation. This is out of
|
||||
/// line to guide inlining.
|
||||
fn finalize_position_and_size_of_iframe(&self,
|
||||
iframe_fragment: &IframeFragmentInfo,
|
||||
offset: Point2D<Au>,
|
||||
layout_context: &LayoutContext);
|
||||
|
||||
/// Returns the appropriate clipping region for descendants of this fragment.
|
||||
fn clipping_region_for_children(&self,
|
||||
current_clip: &ClippingRegion,
|
||||
|
@ -270,7 +260,6 @@ pub trait FragmentDisplayListBuilding {
|
|||
needs_layer: StackingContextLayerNecessity,
|
||||
mode: StackingContextCreationMode)
|
||||
-> Arc<StackingContext>;
|
||||
|
||||
}
|
||||
|
||||
fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> BorderRadii<Au> {
|
||||
|
@ -1060,28 +1049,6 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
&stacking_relative_border_box,
|
||||
&clip)
|
||||
}
|
||||
|
||||
// If this is an iframe, then send its position and size up to the constellation.
|
||||
//
|
||||
// FIXME(pcwalton): Doing this during display list construction seems potentially
|
||||
// problematic if iframes are outside the area we're computing the display list for, since
|
||||
// they won't be able to reflow at all until the user scrolls to them. Perhaps we should
|
||||
// separate this into two parts: first we should send the size only to the constellation
|
||||
// once that's computed during assign-block-sizes, and second we should should send the
|
||||
// origin to the constellation here during display list construction. This should work
|
||||
// because layout for the iframe only needs to know size, and origin is only relevant if
|
||||
// the iframe is actually going to be displayed.
|
||||
if let SpecificFragmentInfo::Iframe(ref iframe_fragment) = self.specific {
|
||||
let stacking_relative_border_box_in_parent_coordinate_system =
|
||||
self.stacking_relative_border_box(stacking_relative_flow_origin,
|
||||
relative_containing_block_size,
|
||||
relative_containing_block_mode,
|
||||
CoordinateSystem::Parent);
|
||||
self.finalize_position_and_size_of_iframe(
|
||||
&**iframe_fragment,
|
||||
stacking_relative_border_box_in_parent_coordinate_system.origin,
|
||||
layout_context)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_fragment_type_specific_display_items(&mut self,
|
||||
|
@ -1317,15 +1284,18 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
filters.push(Filter::Opacity(effects.opacity))
|
||||
}
|
||||
|
||||
// Ensure every canvas has a layer
|
||||
// Ensure every canvas or iframe has a layer.
|
||||
let (scroll_policy, layer_id) = match needs_layer {
|
||||
StackingContextLayerNecessity::Always(layer_id, scroll_policy) =>
|
||||
(scroll_policy, Some(layer_id)),
|
||||
StackingContextLayerNecessity::IfCanvas(layer_id) => {
|
||||
if let SpecificFragmentInfo::Canvas(_) = self.specific {
|
||||
(ScrollPolicy::Scrollable, Some(layer_id))
|
||||
} else {
|
||||
(ScrollPolicy::Scrollable, None)
|
||||
StackingContextLayerNecessity::Always(layer_id, scroll_policy) => {
|
||||
(scroll_policy, Some(layer_id))
|
||||
}
|
||||
StackingContextLayerNecessity::IfCanvasOrIframe(layer_id) => {
|
||||
// FIXME(pcwalton): So so bogus :(
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Iframe(_) => {
|
||||
(ScrollPolicy::Scrollable, Some(layer_id))
|
||||
}
|
||||
_ => (ScrollPolicy::Scrollable, None),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1341,6 +1311,18 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
let subpage_layer_info = match self.specific {
|
||||
SpecificFragmentInfo::Iframe(ref iframe_fragment_info) => {
|
||||
let border_padding = self.border_padding.to_physical(self.style().writing_mode);
|
||||
Some(SubpageLayerInfo {
|
||||
pipeline_id: iframe_fragment_info.pipeline_id,
|
||||
subpage_id: iframe_fragment_info.subpage_id,
|
||||
origin: Point2D::new(border_padding.left, border_padding.top),
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let scrolls_overflow_area = mode == StackingContextCreationMode::OuterScrollWrapper;
|
||||
let transform_style = self.style().get_used_transform_style();
|
||||
let establishes_3d_context = scrolls_overflow_area ||
|
||||
|
@ -1357,28 +1339,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
establishes_3d_context,
|
||||
scrolls_overflow_area,
|
||||
scroll_policy,
|
||||
layer_id))
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn finalize_position_and_size_of_iframe(&self,
|
||||
iframe_fragment: &IframeFragmentInfo,
|
||||
offset: Point2D<Au>,
|
||||
layout_context: &LayoutContext) {
|
||||
let border_padding = (self.border_padding).to_physical(self.style.writing_mode);
|
||||
let content_size = self.content_box().size.to_physical(self.style.writing_mode);
|
||||
let iframe_rect = Rect::new(Point2D::new((offset.x + border_padding.left).to_f32_px(),
|
||||
(offset.y + border_padding.top).to_f32_px()),
|
||||
Size2D::new(content_size.width.to_f32_px(),
|
||||
content_size.height.to_f32_px()));
|
||||
|
||||
debug!("finalizing position and size of iframe for {:?},{:?}",
|
||||
iframe_fragment.pipeline_id,
|
||||
iframe_fragment.subpage_id);
|
||||
let ConstellationChan(ref chan) = layout_context.shared.constellation_chan;
|
||||
chan.send(ConstellationMsg::FrameRect(iframe_fragment.pipeline_id,
|
||||
iframe_fragment.subpage_id,
|
||||
iframe_rect)).unwrap();
|
||||
layer_id,
|
||||
subpage_layer_info))
|
||||
}
|
||||
|
||||
fn clipping_region_for_children(&self,
|
||||
|
@ -1643,7 +1605,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayerNecessity::IfCanvas(self.layer_id()),
|
||||
StackingContextLayerNecessity::IfCanvasOrIframe(self.layer_id()),
|
||||
StackingContextCreationMode::Normal))
|
||||
} else {
|
||||
match self.fragment.style.get_box().position {
|
||||
|
@ -1720,7 +1682,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayerNecessity::IfCanvas(self.layer_id()),
|
||||
StackingContextLayerNecessity::IfCanvasOrIframe(self.layer_id()),
|
||||
StackingContextCreationMode::Normal));
|
||||
}
|
||||
return
|
||||
|
@ -1785,7 +1747,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayerNecessity::IfCanvas(self.layer_id()),
|
||||
StackingContextLayerNecessity::IfCanvasOrIframe(self.layer_id()),
|
||||
StackingContextCreationMode::Normal))
|
||||
} else {
|
||||
DisplayListBuildingResult::Normal(display_list)
|
||||
|
@ -1871,13 +1833,17 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
|
||||
// FIXME(Savago): fix Fragment::establishes_stacking_context() for absolute positioned item
|
||||
// and remove the check for filter presence. Further details on #5812.
|
||||
has_stacking_context = has_stacking_context && {
|
||||
if let SpecificFragmentInfo::Canvas(_) = self.fragments.fragments[0].specific {
|
||||
true
|
||||
} else {
|
||||
!self.fragments.fragments[0].style().get_effects().filter.is_empty()
|
||||
//
|
||||
// FIXME(#7424, pcwalton): This is terribly bogus! What is even going on here?
|
||||
if has_stacking_context {
|
||||
match self.fragments.fragments[0].specific {
|
||||
SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Iframe(_) => {}
|
||||
_ => {
|
||||
has_stacking_context =
|
||||
!self.fragments.fragments[0].style().get_effects().filter.is_empty()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
self.base.display_list_building_result = if has_stacking_context {
|
||||
DisplayListBuildingResult::StackingContext(
|
||||
|
@ -1885,7 +1851,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayerNecessity::IfCanvas(self.layer_id()),
|
||||
StackingContextLayerNecessity::Always(self.layer_id(),
|
||||
ScrollPolicy::Scrollable),
|
||||
StackingContextCreationMode::Normal))
|
||||
} else {
|
||||
DisplayListBuildingResult::Normal(display_list)
|
||||
|
|
|
@ -22,7 +22,7 @@ use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT};
|
|||
use ipc_channel::ipc::IpcSender;
|
||||
use layout_debug;
|
||||
use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified};
|
||||
use msg::constellation_msg::{ConstellationChan, Msg, PipelineId, SubpageId};
|
||||
use msg::constellation_msg::{PipelineId, SubpageId};
|
||||
use net_traits::image::base::Image;
|
||||
use net_traits::image_cache_task::UsePlaceholder;
|
||||
use rustc_serialize::{Encodable, Encoder};
|
||||
|
@ -2102,6 +2102,16 @@ impl Fragment {
|
|||
stacking_relative_border_box.size.height - border_padding.vertical()))
|
||||
}
|
||||
|
||||
/// Returns true if this fragment unconditionally layerizes.
|
||||
pub fn needs_layer(&self) -> bool {
|
||||
// Canvas and iframes always layerize, as an special case
|
||||
// FIXME(pcwalton): Don't unconditionally form stacking contexts for each canvas.
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Iframe(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this fragment establishes a new stacking context and false otherwise.
|
||||
pub fn establishes_stacking_context(&self) -> bool {
|
||||
if self.flags.contains(HAS_LAYER) {
|
||||
|
@ -2126,9 +2136,7 @@ impl Fragment {
|
|||
transform_style::T::auto => {}
|
||||
}
|
||||
|
||||
// Canvas always layerizes, as an special case
|
||||
// FIXME(pcwalton): Don't unconditionally form stacking contexts for each canvas.
|
||||
if let SpecificFragmentInfo::Canvas(_) = self.specific {
|
||||
if self.needs_layer() {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -2161,12 +2169,10 @@ impl Fragment {
|
|||
|
||||
/// Computes the overflow rect of this fragment relative to the start of the flow.
|
||||
pub fn compute_overflow(&self,
|
||||
relative_containing_block_size: &LogicalSize<Au>,
|
||||
relative_containing_block_mode: WritingMode)
|
||||
flow_size: &Size2D<Au>,
|
||||
relative_containing_block_size: &LogicalSize<Au>)
|
||||
-> Rect<Au> {
|
||||
let container_size =
|
||||
relative_containing_block_size.to_physical(relative_containing_block_mode);
|
||||
let mut border_box = self.border_box.to_physical(self.style.writing_mode, container_size);
|
||||
let mut border_box = self.border_box.to_physical(self.style.writing_mode, *flow_size);
|
||||
|
||||
// Relative position can cause us to draw outside our border box.
|
||||
//
|
||||
|
@ -2209,23 +2215,6 @@ impl Fragment {
|
|||
overflow
|
||||
}
|
||||
|
||||
/// Remove any compositor layers associated with this fragment - it is being
|
||||
/// removed from the tree or had its display property set to none.
|
||||
/// TODO(gw): This just hides the compositor layer for now. In the future
|
||||
/// it probably makes sense to provide a hint to the compositor whether
|
||||
/// the layers should be destroyed to free memory.
|
||||
pub fn remove_compositor_layers(&self, constellation_chan: ConstellationChan) {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::Iframe(ref iframe_info) => {
|
||||
let ConstellationChan(ref chan) = constellation_chan;
|
||||
chan.send(Msg::FrameRect(iframe_info.pipeline_id,
|
||||
iframe_info.subpage_id,
|
||||
Rect::zero())).unwrap();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn requires_line_break_afterward_if_wrapping_on_newlines(&self) -> bool {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::ScannedText(ref scanned_text) => {
|
||||
|
|
|
@ -9,7 +9,7 @@ use context::LayoutContext;
|
|||
use display_list_builder::{FragmentDisplayListBuilding, InlineFlowDisplayListBuilding};
|
||||
use euclid::{Point2D, Rect, Size2D};
|
||||
use floats::{FloatKind, Floats, PlacementInfo};
|
||||
use flow::{EarlyAbsolutePositionInfo, MutableFlowUtils, OpaqueFlow};
|
||||
use flow::{EarlyAbsolutePositionInfo, LAYERS_NEEDED_FOR_DESCENDANTS, MutableFlowUtils, OpaqueFlow};
|
||||
use flow::{self, BaseFlow, Flow, FlowClass, ForceNonfloatedFlag, IS_ABSOLUTELY_POSITIONED};
|
||||
use flow_ref;
|
||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
|
||||
|
@ -1465,6 +1465,7 @@ impl Flow for InlineFlow {
|
|||
|
||||
// Now, go through each line and lay out the fragments inside.
|
||||
let mut line_distance_from_flow_block_start = Au(0);
|
||||
let mut layers_needed_for_descendants = false;
|
||||
let line_count = self.lines.len();
|
||||
for line_index in 0..line_count {
|
||||
let line = &mut self.lines[line_index];
|
||||
|
@ -1493,6 +1494,10 @@ impl Flow for InlineFlow {
|
|||
for fragment_index in line.range.each_index() {
|
||||
let fragment = &mut self.fragments.fragments[fragment_index.to_usize()];
|
||||
|
||||
if fragment.needs_layer() && !fragment.is_positioned() {
|
||||
layers_needed_for_descendants = true
|
||||
}
|
||||
|
||||
let InlineMetrics {
|
||||
mut block_size_above_baseline,
|
||||
mut depth_below_baseline,
|
||||
|
@ -1589,6 +1594,10 @@ impl Flow for InlineFlow {
|
|||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context, thread_id);
|
||||
}
|
||||
|
||||
// Mark ourselves for layerization if that will be necessary to paint in the proper
|
||||
// order (CSS 2.1, Appendix E).
|
||||
self.base.flags.set(LAYERS_NEEDED_FOR_DESCENDANTS, layers_needed_for_descendants);
|
||||
|
||||
if self.contains_positioned_fragments() {
|
||||
// Assign block-sizes for all flows in this absolute flow tree.
|
||||
// This is preorder because the block-size of an absolute flow may depend on
|
||||
|
@ -1773,10 +1782,12 @@ impl Flow for InlineFlow {
|
|||
|
||||
fn compute_overflow(&self) -> Rect<Au> {
|
||||
let mut overflow = ZERO_RECT;
|
||||
let flow_size = self.base.position.size.to_physical(self.base.writing_mode);
|
||||
let relative_containing_block_size =
|
||||
&self.base.early_absolute_position_info.relative_containing_block_size;
|
||||
for fragment in &self.fragments.fragments {
|
||||
overflow = overflow.union(&fragment.compute_overflow(
|
||||
&self.base.early_absolute_position_info.relative_containing_block_size,
|
||||
self.base.early_absolute_position_info.relative_containing_block_mode));
|
||||
overflow = overflow.union(&fragment.compute_overflow(&flow_size,
|
||||
&relative_containing_block_size))
|
||||
}
|
||||
overflow
|
||||
}
|
||||
|
|
|
@ -637,7 +637,7 @@ impl LayoutTask {
|
|||
unsafe {
|
||||
self.handle_reap_layout_data(dead_layout_data)
|
||||
}
|
||||
},
|
||||
}
|
||||
Msg::CollectReports(reports_chan) => {
|
||||
self.collect_reports(reports_chan, possibly_locked_rw_data);
|
||||
},
|
||||
|
@ -724,8 +724,7 @@ impl LayoutTask {
|
|||
info.layout_shutdown_chan);
|
||||
}
|
||||
|
||||
/// Enters a quiescent state in which no new messages except for
|
||||
/// `layout_interface::Msg::ReapLayoutData` will be processed until an `ExitNow` is
|
||||
/// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is
|
||||
/// received. A pong is immediately sent on the given response channel.
|
||||
fn prepare_to_exit<'a>(&'a self,
|
||||
response_chan: Sender<()>,
|
||||
|
@ -1099,6 +1098,7 @@ impl LayoutTask {
|
|||
flow::mut_base(flow_ref::deref_mut(layout_root))
|
||||
.display_list_building_result
|
||||
.add_to(&mut *display_list);
|
||||
|
||||
let origin = Rect::new(Point2D::new(Au(0), Au(0)), root_size);
|
||||
let layer_id = layout_root.layer_id();
|
||||
let stacking_context = Arc::new(StackingContext::new(display_list,
|
||||
|
@ -1112,11 +1112,8 @@ impl LayoutTask {
|
|||
true,
|
||||
false,
|
||||
ScrollPolicy::Scrollable,
|
||||
Some(layer_id)));
|
||||
let paint_layer = PaintLayer::new(layer_id,
|
||||
root_background_color,
|
||||
stacking_context.clone());
|
||||
|
||||
Some(layer_id),
|
||||
None));
|
||||
if opts::get().dump_display_list {
|
||||
stacking_context.print("DisplayList".to_owned());
|
||||
}
|
||||
|
@ -1124,7 +1121,12 @@ impl LayoutTask {
|
|||
println!("{}", serde_json::to_string_pretty(&stacking_context).unwrap());
|
||||
}
|
||||
|
||||
rw_data.stacking_context = Some(stacking_context);
|
||||
rw_data.stacking_context = Some(stacking_context.clone());
|
||||
|
||||
let paint_layer = PaintLayer::new(layout_root.layer_id(),
|
||||
root_background_color,
|
||||
stacking_context,
|
||||
ScrollPolicy::Scrollable);
|
||||
|
||||
debug!("Layout done!");
|
||||
|
||||
|
@ -1489,8 +1491,7 @@ impl LayoutTask {
|
|||
/// Handles a message to destroy layout data. Layout data must be destroyed on *this* task
|
||||
/// because the struct type is transmuted to a different type on the script side.
|
||||
unsafe fn handle_reap_layout_data(&self, layout_data: LayoutData) {
|
||||
let layout_data_wrapper: LayoutDataWrapper = transmute(layout_data);
|
||||
layout_data_wrapper.remove_compositor_layers(self.constellation_chan.clone());
|
||||
let _: LayoutDataWrapper = transmute(layout_data);
|
||||
}
|
||||
|
||||
/// Returns profiling information which is passed to the time profiler.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue