Skip to content

Commit a6737e4

Browse files
committed
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 only the size of an iframe is determined during layout, and the position is determined by the compositor. Layout layerizes iframes and marks the iframe layers with the appropriate subpage ID so that the compositor can place them correctly. Closes #7377.
1 parent 6431e8d commit a6737e4

16 files changed

+270
-137
lines changed

components/compositing/compositor.rs

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use msg::constellation_msg::AnimationState;
3535
use msg::constellation_msg::Msg as ConstellationMsg;
3636
use msg::constellation_msg::{ConstellationChan, NavigationDirection};
3737
use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
38-
use msg::constellation_msg::{PipelineId, WindowSizeData};
38+
use msg::constellation_msg::{PipelineId, SubpageId, WindowSizeData};
3939
use png;
4040
use profile_traits::mem::{self, Reporter, ReporterRequest, ReportKind};
4141
use profile_traits::time::{self, ProfilerCategory, profile};
@@ -394,9 +394,14 @@ impl<Window: WindowMethods> IOCompositor<Window> {
394394
chan.send(Some(self.native_display.clone())).unwrap();
395395
}
396396

397-
(Msg::SetLayerRect(pipeline_id, layer_id, rect),
397+
(Msg::SetLayerSize(pipeline_id, layer_id, size),
398398
ShutdownState::NotShuttingDown) => {
399-
self.set_layer_rect(pipeline_id, layer_id, &rect);
399+
self.set_layer_size(pipeline_id, layer_id, &size);
400+
}
401+
402+
(Msg::SetLayerPosition(pipeline_id, layer_id, position),
403+
ShutdownState::NotShuttingDown) => {
404+
self.set_layer_position(pipeline_id, layer_id, &position);
400405
}
401406

402407
(Msg::AssignPaintedBuffers(pipeline_id, epoch, replies, frame_tree_id),
@@ -618,9 +623,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
618623
self.composite_if_necessary(CompositingReason::NewFrameTree);
619624
}
620625

621-
fn create_root_layer_for_pipeline_and_rect(&mut self,
626+
fn create_root_layer_for_pipeline_and_size(&mut self,
622627
pipeline: &CompositionPipeline,
623-
frame_rect: Option<TypedRect<PagePx, f32>>)
628+
frame_size: Option<TypedSize2D<PagePx, f32>>)
624629
-> Rc<Layer<CompositorData>> {
625630
let layer_properties = LayerProperties {
626631
id: LayerId::null(),
@@ -630,6 +635,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
630635
scroll_policy: ScrollPolicy::Scrollable,
631636
transform: Matrix4::identity(),
632637
perspective: Matrix4::identity(),
638+
subpage_layer_info: None,
633639
establishes_3d_context: true,
634640
scrolls_overflow_area: false,
635641
};
@@ -644,22 +650,22 @@ impl<Window: WindowMethods> IOCompositor<Window> {
644650
// All root layers mask to bounds.
645651
*root_layer.masks_to_bounds.borrow_mut() = true;
646652

647-
if let Some(ref frame_rect) = frame_rect {
648-
let frame_rect = frame_rect.to_untyped();
649-
*root_layer.bounds.borrow_mut() = Rect::from_untyped(&frame_rect);
653+
if let Some(ref frame_size) = frame_size {
654+
let frame_size = frame_size.to_untyped();
655+
root_layer.bounds.borrow_mut().size = Size2D::from_untyped(&frame_size);
650656
}
651657

652658
return root_layer;
653659
}
654660

655661
fn create_frame_tree_root_layers(&mut self,
656662
frame_tree: &SendableFrameTree,
657-
frame_rect: Option<TypedRect<PagePx, f32>>)
663+
frame_size: Option<TypedSize2D<PagePx, f32>>)
658664
-> Rc<Layer<CompositorData>> {
659-
let root_layer = self.create_root_layer_for_pipeline_and_rect(&frame_tree.pipeline,
660-
frame_rect);
665+
let root_layer = self.create_root_layer_for_pipeline_and_size(&frame_tree.pipeline,
666+
frame_size);
661667
for kid in &frame_tree.children {
662-
root_layer.add_child(self.create_frame_tree_root_layers(kid, kid.rect));
668+
root_layer.add_child(self.create_frame_tree_root_layers(kid, kid.size));
663669
}
664670
return root_layer;
665671
}
@@ -695,7 +701,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
695701
self.pipeline_details.remove(&pipeline_id);
696702
}
697703

698-
fn update_layer_if_exists(&mut self, pipeline_id: PipelineId, properties: LayerProperties) -> bool {
704+
fn update_layer_if_exists(&mut self, pipeline_id: PipelineId, properties: LayerProperties)
705+
-> bool {
699706
match self.find_layer_with_pipeline_and_layer_id(pipeline_id, properties.id) {
700707
Some(existing_layer) => {
701708
existing_layer.update_layer(properties);
@@ -741,7 +748,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
741748
layer_properties.id);
742749
}
743750

744-
fn create_or_update_descendant_layer(&mut self, pipeline_id: PipelineId, layer_properties: LayerProperties) {
751+
fn create_or_update_descendant_layer(&mut self,
752+
pipeline_id: PipelineId,
753+
layer_properties: LayerProperties) {
745754
debug_assert!(layer_properties.parent_id.is_some());
746755

747756
if !self.update_layer_if_exists(pipeline_id, layer_properties) {
@@ -751,7 +760,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
751760
layer_properties.id);
752761
}
753762

754-
fn create_descendant_layer(&self, pipeline_id: PipelineId, layer_properties: LayerProperties) {
763+
fn create_descendant_layer(&mut self,
764+
pipeline_id: PipelineId,
765+
layer_properties: LayerProperties) {
755766
let parent_id = layer_properties.parent_id.unwrap();
756767

757768
if let Some(parent_layer) = self.find_layer_with_pipeline_and_layer_id(pipeline_id,
@@ -773,6 +784,15 @@ impl<Window: WindowMethods> IOCompositor<Window> {
773784

774785
parent_layer.add_child(new_layer);
775786
}
787+
788+
if let Some(ref subpage_layer_info) = layer_properties.subpage_layer_info {
789+
let layer_origin = Point2D::new(subpage_layer_info.origin.x.to_f32_px(),
790+
subpage_layer_info.origin.y.to_f32_px());
791+
self.send_subpage_position_request_to_constellation(pipeline_id,
792+
subpage_layer_info.subpage_id,
793+
&(layer_properties.rect.origin +
794+
layer_origin));
795+
}
776796
}
777797

778798
fn send_window_size(&self) {
@@ -828,21 +848,49 @@ impl<Window: WindowMethods> IOCompositor<Window> {
828848
self.composition_request = CompositionRequest::CompositeOnScrollTimeout(timestamp);
829849
}
830850

831-
fn set_layer_rect(&mut self,
851+
fn set_layer_size(&mut self,
832852
pipeline_id: PipelineId,
833853
layer_id: LayerId,
834-
new_rect: &Rect<f32>) {
854+
new_size: &Size2D<f32>) {
835855
match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) {
836856
Some(ref layer) => {
837-
*layer.bounds.borrow_mut() = Rect::from_untyped(new_rect)
857+
layer.bounds.borrow_mut().size = Size2D::from_untyped(new_size)
858+
}
859+
None => {
860+
panic!("Compositor received SetLayerSize for nonexistent layer: {:?}", pipeline_id)
838861
}
839-
None => panic!("Compositor received SetLayerRect for nonexistent \
840-
layer: {:?}", pipeline_id),
841862
};
842863

843864
self.send_buffer_requests_for_all_layers();
844865
}
845866

867+
fn send_subpage_position_request_to_constellation(&mut self,
868+
pipeline_id: PipelineId,
869+
subpage_id: SubpageId,
870+
new_position: &Point2D<f32>) {
871+
self.constellation_chan
872+
.0
873+
.send(ConstellationMsg::SetSubpagePosition(pipeline_id, subpage_id, *new_position))
874+
.unwrap();
875+
}
876+
877+
fn set_layer_position(&mut self,
878+
pipeline_id: PipelineId,
879+
layer_id: LayerId,
880+
new_position: &Point2D<f32>) {
881+
match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) {
882+
Some(ref layer) => {
883+
layer.bounds.borrow_mut().origin = Point2D::from_untyped(new_position)
884+
}
885+
None => {
886+
panic!("Compositor received trying to set layer position of nonexistent layer: \
887+
{:?}/{:?}",
888+
pipeline_id,
889+
layer_id)
890+
}
891+
}
892+
}
893+
846894
fn assign_painted_buffers(&mut self,
847895
pipeline_id: PipelineId,
848896
layer_id: LayerId,

components/compositing/compositor_task.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use headless;
1212
use windowing::{WindowEvent, WindowMethods};
1313

1414
use euclid::point::Point2D;
15-
use euclid::rect::Rect;
15+
use euclid::size::Size2D;
1616
use ipc_channel::ipc::{IpcReceiver, IpcSender};
1717
use layers::layers::{BufferRequest, LayerBufferSet};
1818
use layers::platform::surface::{NativeDisplay, NativeSurface};
@@ -156,8 +156,10 @@ pub enum Msg {
156156
/// Tells the compositor to create or update the layers for a pipeline if necessary
157157
/// (i.e. if no layer with that ID exists).
158158
InitializeLayersForPipeline(PipelineId, Epoch, Vec<LayerProperties>),
159-
/// Alerts the compositor that the specified layer's rect has changed.
160-
SetLayerRect(PipelineId, LayerId, Rect<f32>),
159+
/// Alerts the compositor that the specified layer's size has changed.
160+
SetLayerSize(PipelineId, LayerId, Size2D<f32>),
161+
/// Alerts the compositor that the specified layer's position has changed.
162+
SetLayerPosition(PipelineId, LayerId, Point2D<f32>),
161163
/// Scroll a page in a window
162164
ScrollFragmentPoint(PipelineId, LayerId, Point2D<f32>),
163165
/// Requests that the compositor assign the painted buffers to the given layers.
@@ -210,7 +212,8 @@ impl Debug for Msg {
210212
Msg::ShutdownComplete(..) => write!(f, "ShutdownComplete"),
211213
Msg::GetNativeDisplay(..) => write!(f, "GetNativeDisplay"),
212214
Msg::InitializeLayersForPipeline(..) => write!(f, "InitializeLayersForPipeline"),
213-
Msg::SetLayerRect(..) => write!(f, "SetLayerRect"),
215+
Msg::SetLayerSize(..) => write!(f, "SetLayerSize"),
216+
Msg::SetLayerPosition(..) => write!(f, "SetLayerPosition"),
214217
Msg::ScrollFragmentPoint(..) => write!(f, "ScrollFragmentPoint"),
215218
Msg::AssignPaintedBuffers(..) => write!(f, "AssignPaintedBuffers"),
216219
Msg::ChangeRunningAnimationsState(..) => write!(f, "ChangeRunningAnimationsState"),

0 commit comments

Comments
 (0)