diff options
author | Martin Robinson <mrobinson@igalia.com> | 2014-09-12 11:37:41 -0700 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2014-09-16 08:57:08 -0700 |
commit | ea14fca1dcd93a6eb9b47b8586aade8ff2b69204 (patch) | |
tree | 13943da224b52cffd6e400b6ee1762c34e8e0ffb | |
parent | 13ae369dec3f02b5f992f1c6c276cde646ef39e9 (diff) | |
download | servo-ea14fca1dcd93a6eb9b47b8586aade8ff2b69204.tar.gz servo-ea14fca1dcd93a6eb9b47b8586aade8ff2b69204.zip |
Store content offset in unscaled pixels
Content offset is now stored in unscaled pixels, so that it can be
applied to tile positions during compositor rendering without unscaling
it. This means that when using it in calculations of layer size (stored
in device pixels), we need to scale it. Scene scale is now stored as a
scale rather than a transformation.
Fixes #3269.
Fixes #3042.
-rw-r--r-- | Cargo.lock | 10 | ||||
-rw-r--r-- | components/compositing/compositor.rs | 81 | ||||
-rw-r--r-- | components/compositing/compositor_data.rs | 7 | ||||
-rw-r--r-- | components/compositing/events.rs | 77 | ||||
-rw-r--r-- | ports/cef/Cargo.lock | 12 |
5 files changed, 88 insertions, 99 deletions
diff --git a/Cargo.lock b/Cargo.lock index b79a663c2f8..adffdff6db5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,7 +32,7 @@ dependencies = [ "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#fb15dd309750c8ec664b2c9f245cfcb06731872e)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)", "glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#dd1a111c827994886d2cdebf91a1838603256390)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)", "opengles 0.1.0 (git+https://github.com/servo/rust-opengles#13cccda11011716fd75526a74dfd03122110f95a)", "skia-sys 0.0.20130412 (git+https://github.com/servo/skia#6d696712962fd0d41120b7a414a48417da8e6a92)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib#79904fb42ff8a0e888f70fae336fbf6c11f1e6c8)", @@ -63,7 +63,7 @@ dependencies = [ "gfx 0.0.1", "glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#dd1a111c827994886d2cdebf91a1838603256390)", "glut 0.0.1 (git+https://github.com/servo/rust-glut#d351eed425464c58671c6ec33445ee896fd42ff1)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)", "layout_traits 0.0.1", "msg 0.0.1", "net 0.0.1", @@ -163,7 +163,7 @@ dependencies = [ "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#fb15dd309750c8ec664b2c9f245cfcb06731872e)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)", "harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz#a502be3df659cd13bac0e62638f4dac3dfb2f52d)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)", "macros 0.0.1", "msg 0.0.1", "net 0.0.1", @@ -242,7 +242,7 @@ dependencies = [ [[package]] name = "layers" version = "0.1.0" -source = "git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f" +source = "git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#9aeaee0bceb3241d6efca07cc6b82747339ffbff)", "egl 0.1.0 (git+https://github.com/servo/rust-egl#48b85e30d557ab2ee536730a73dd86a8160d618b)", @@ -301,7 +301,7 @@ dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#9aeaee0bceb3241d6efca07cc6b82747339ffbff)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)", "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface#05f102273e16e9432245f813e5fe6280087e2b44)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)", "url 0.1.0 (git+https://github.com/servo/rust-url#678bb4d52638b1cfdab78ef8e521566c9240fb1a)", "util 0.0.1", ] diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index ea8bf447257..f17954245d5 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -22,7 +22,6 @@ use windowing::PinchZoomWindowEvent; use azure::azure_hl::SourceSurfaceMethods; use azure::azure_hl; use std::cmp; -use geom::matrix::identity; use geom::point::{Point2D, TypedPoint2D}; use geom::rect::Rect; use geom::size::TypedSize2D; @@ -159,7 +158,7 @@ impl IOCompositor { context: rendergl::RenderContext::new(CompositorTask::create_graphics_context(), show_debug_borders), root_pipeline: None, - scene: Scene::new(window_size.as_f32().to_untyped(), identity()), + scene: Scene::new(window_size.as_f32().to_untyped()), window_size: window_size, hidpi_factor: hidpi_factor, composite_ready: false, @@ -543,26 +542,41 @@ impl IOCompositor { })); } + + pub fn move_layer(&self, + pipeline_id: PipelineId, + layer_id: LayerId, + origin: TypedPoint2D<DevicePixel, f32>) + -> bool { + match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) { + Some(ref layer) => { + if layer.extra_data.borrow().wants_scroll_events == WantsScrollEvents { + events::clamp_scroll_offset_and_scroll_layer(layer.clone(), + TypedPoint2D(0f32, 0f32) - origin, + self.window_size.as_f32(), + self.device_pixels_per_page_px()); + } + true + } + None => false, + } + } + fn scroll_layer_to_fragment_point_if_necessary(&mut self, pipeline_id: PipelineId, layer_id: LayerId) { let device_pixels_per_page_px = self.device_pixels_per_page_px(); - let window_size = self.window_size.as_f32(); - let needs_recomposite = match self.scene.root { - Some(ref mut root_layer) => { - self.fragment_point.take().map_or(false, |fragment_point| { - let fragment_point = fragment_point * device_pixels_per_page_px.get(); - events::move(root_layer.clone(), - pipeline_id, - layer_id, - Point2D::from_untyped(&fragment_point), - window_size) - }) + match self.fragment_point.take() { + Some(point) => { + let point = point * device_pixels_per_page_px.get(); + if !self.move_layer(pipeline_id, layer_id, Point2D::from_untyped(&point)) { + fail!("Compositor: Tried to scroll to fragment with unknown layer."); + } + + self.recomposite = true; } - None => fail!("Compositor: Tried to scroll to fragment without root layer."), + None => {} }; - - self.recomposite_if(needs_recomposite); } fn set_layer_origin(&mut self, @@ -610,30 +624,13 @@ impl IOCompositor { pipeline_id: PipelineId, layer_id: LayerId, point: Point2D<f32>) { - let device_pixels_per_page_px = self.device_pixels_per_page_px(); let device_point = point * device_pixels_per_page_px.get(); - let window_size = self.window_size.as_f32(); - - let (ask, move): (bool, bool) = match self.scene.root { - Some(ref layer) if layer.extra_data.borrow().pipeline.id == pipeline_id => { - (true, - events::move(layer.clone(), - pipeline_id, - layer_id, - Point2D::from_untyped(&device_point), - window_size)) - } - Some(_) | None => { - self.fragment_point = Some(point); - - (false, false) - } - }; - - if ask { - self.recomposite_if(move); + if self.move_layer(pipeline_id, layer_id, Point2D::from_untyped(&device_point)) { + self.recomposite = true; self.send_buffer_requests_for_all_layers(); + } else { + self.fragment_point = Some(point); } } @@ -750,12 +747,14 @@ impl IOCompositor { cursor: TypedPoint2D<DevicePixel, i32>) { let mut scroll = false; let window_size = self.window_size.as_f32(); + let scene_scale = self.device_pixels_per_page_px(); match self.scene.root { Some(ref mut layer) => { scroll = events::handle_scroll_event(layer.clone(), delta, cursor.as_f32(), - window_size) || scroll; + window_size, + scene_scale) || scroll; } None => { } } @@ -779,7 +778,7 @@ impl IOCompositor { fn update_zoom_transform(&mut self) { let scale = self.device_pixels_per_page_px(); - self.scene.transform = identity().scale(scale.get(), scale.get(), 1f32); + self.scene.scale = scale.get(); } fn on_zoom_window_event(&mut self, magnification: f32) { @@ -806,12 +805,14 @@ impl IOCompositor { let delta = page_delta * self.device_pixels_per_page_px(); let cursor = TypedPoint2D(-1f32, -1f32); // Make sure this hits the base layer. + let scene_scale = self.device_pixels_per_page_px(); match self.scene.root { Some(ref mut layer) => { events::handle_scroll_event(layer.clone(), delta, cursor, - window_size); + window_size, + scene_scale); } None => { } } diff --git a/components/compositing/compositor_data.rs b/components/compositing/compositor_data.rs index fdfeac7656e..dfd58f5d2b6 100644 --- a/components/compositing/compositor_data.rs +++ b/components/compositing/compositor_data.rs @@ -8,6 +8,7 @@ use pipeline::CompositionPipeline; use azure::azure_hl::Color; use geom::point::TypedPoint2D; +use geom::scale_factor::ScaleFactor; use geom::size::{Size2D, TypedSize2D}; use geom::rect::Rect; use gfx::render_task::UnusedBufferMsg; @@ -74,11 +75,13 @@ impl CompositorData { layer.contents_changed(); // Call scroll for bounds checking if the page shrunk. Use (-1, -1) as the - // cursor position to make sure the scroll isn't propagated downwards. + // cursor position to make sure the scroll isn't propagated downwards. The + // scale doesn't matter here since 0, 0 is 0, 0 no matter the scene scale. events::handle_scroll_event(layer.clone(), TypedPoint2D(0f32, 0f32), TypedPoint2D(-1f32, -1f32), - size); + size, + ScaleFactor(1.0) /* scene_scale */); } pub fn find_layer_with_pipeline_and_layer_id(layer: Rc<Layer<CompositorData>>, diff --git a/components/compositing/events.rs b/components/compositing/events.rs index 25779a417af..c4e86cae26a 100644 --- a/components/compositing/events.rs +++ b/components/compositing/events.rs @@ -7,15 +7,14 @@ use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEve use windowing::MouseWindowMouseUpEvent; use geom::length::Length; -use geom::point::TypedPoint2D; +use geom::point::{Point2D, TypedPoint2D}; use geom::scale_factor::ScaleFactor; use geom::size::TypedSize2D; use layers::geometry::DevicePixel; use layers::layers::Layer; use script_traits::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent, SendEventMsg}; use script_traits::{ScriptControlChan}; -use servo_msg::compositor_msg::{FixedPosition, LayerId}; -use servo_msg::constellation_msg::PipelineId; +use servo_msg::compositor_msg::FixedPosition; use servo_util::geometry::PagePx; use std::rc::Rc; @@ -47,7 +46,8 @@ impl Clampable for f32 { pub fn handle_scroll_event(layer: Rc<Layer<CompositorData>>, delta: TypedPoint2D<DevicePixel, f32>, cursor: TypedPoint2D<DevicePixel, f32>, - window_size: TypedSize2D<DevicePixel, f32>) + window_size: TypedSize2D<DevicePixel, f32>, + scale: ScaleFactor<PagePx, DevicePixel, f32>) -> bool { // If this layer doesn't want scroll events, neither it nor its children can handle scroll // events. @@ -56,53 +56,60 @@ pub fn handle_scroll_event(layer: Rc<Layer<CompositorData>>, } // Allow children to scroll. - let content_offset = layer.content_offset.borrow().clone(); - let cursor = cursor - content_offset; + let content_offset_in_page_pixels : TypedPoint2D<PagePx, f32> = + Point2D::from_untyped(&*layer.content_offset.borrow()); + let content_offset : TypedPoint2D<DevicePixel, f32> = content_offset_in_page_pixels * scale; + let new_cursor = cursor - content_offset; for child in layer.children().iter() { let child_bounds = child.bounds.borrow(); - if child_bounds.contains(&cursor) && + if child_bounds.contains(&new_cursor) && handle_scroll_event(child.clone(), delta, - cursor - child_bounds.origin, - child_bounds.size) { + new_cursor - child_bounds.origin, + child_bounds.size, + scale) { return true } } - clamp_scroll_offset_and_scroll_layer(layer, content_offset + delta, window_size) + clamp_scroll_offset_and_scroll_layer(layer, content_offset + delta, window_size, scale) } pub fn clamp_scroll_offset_and_scroll_layer(layer: Rc<Layer<CompositorData>>, - mut new_offset: TypedPoint2D<DevicePixel, f32>, - window_size: TypedSize2D<DevicePixel, f32>) + new_offset: TypedPoint2D<DevicePixel, f32>, + window_size: TypedSize2D<DevicePixel, f32>, + scale: ScaleFactor<PagePx, DevicePixel, f32>) -> bool { let layer_size = layer.bounds.borrow().size; let min_x = (window_size.width - layer_size.width).get().min(0.0); - new_offset.x = Length(new_offset.x.get().clamp(&min_x, &0.0)); - let min_y = (window_size.height - layer_size.height).get().min(0.0); - new_offset.y = Length(new_offset.y.get().clamp(&min_y, &0.0)); + let new_offset : TypedPoint2D<DevicePixel, f32> = + Point2D(Length(new_offset.x.get().clamp(&min_x, &0.0)), + Length(new_offset.y.get().clamp(&min_y, &0.0))); - if *layer.content_offset.borrow() == new_offset { + let new_offset_in_page_px = new_offset / scale; + let untyped_new_offset = new_offset_in_page_px.to_untyped(); + if *layer.content_offset.borrow() == untyped_new_offset { return false } // FIXME: This allows the base layer to record the current content offset without // updating its transform. This should be replaced with something less strange. - *layer.content_offset.borrow_mut() = new_offset; - scroll_layer_and_all_child_layers(layer.clone(), new_offset) + *layer.content_offset.borrow_mut() = untyped_new_offset; + scroll_layer_and_all_child_layers(layer.clone(), new_offset_in_page_px) } fn scroll_layer_and_all_child_layers(layer: Rc<Layer<CompositorData>>, - new_offset: TypedPoint2D<DevicePixel, f32>) + new_offset: TypedPoint2D<PagePx, f32>) -> bool { let mut result = false; // Only scroll this layer if it's not fixed-positioned. if layer.extra_data.borrow().scroll_policy != FixedPosition { - *layer.transform.borrow_mut() = identity().translate(new_offset.x.get(), - new_offset.y.get(), + let new_offset = new_offset.to_untyped(); + *layer.transform.borrow_mut() = identity().translate(new_offset.x, + new_offset.y, 0.0); *layer.content_offset.borrow_mut() = new_offset; result = true @@ -122,7 +129,9 @@ pub fn send_mouse_event(layer: Rc<Layer<CompositorData>>, event: MouseWindowEvent, cursor: TypedPoint2D<DevicePixel, f32>, device_pixels_per_page_px: ScaleFactor<PagePx, DevicePixel, f32>) { - let cursor = cursor - *layer.content_offset.borrow(); + let content_offset = *layer.content_offset.borrow() * device_pixels_per_page_px.get(); + let content_offset : TypedPoint2D<DevicePixel, f32> = Point2D::from_untyped(&content_offset); + let cursor = cursor - content_offset; for child in layer.children().iter() { let child_bounds = child.bounds.borrow(); if child_bounds.contains(&cursor) { @@ -152,27 +161,3 @@ pub fn send_mouse_move_event(layer: Rc<Layer<CompositorData>>, let _ = chan.send_opt(SendEventMsg(layer.extra_data.borrow().pipeline.id.clone(), message)); } -pub fn move(layer: Rc<Layer<CompositorData>>, - pipeline_id: PipelineId, - layer_id: LayerId, - origin: TypedPoint2D<DevicePixel, f32>, - window_size: TypedSize2D<DevicePixel, f32>) - -> bool { - // Search children for the right layer to move. - if layer.extra_data.borrow().pipeline.id != pipeline_id || - layer.extra_data.borrow().id != layer_id { - return layer.children().iter().any(|kid| { - move(kid.clone(), - pipeline_id, - layer_id, - origin, - window_size) - }); - } - - if layer.extra_data.borrow().wants_scroll_events != WantsScrollEvents { - return false - } - - clamp_scroll_offset_and_scroll_layer(layer, TypedPoint2D(0f32, 0f32) - origin, window_size) -} diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index dad6d3e58d2..6d447735290 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ "glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#a646f0badaccaebd61d0f8aaec5646da0a7c2a14)", "glut 0.0.1 (git+https://github.com/servo/rust-glut#d351eed425464c58671c6ec33445ee896fd42ff1)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs#c9bd679428e8e83e585702a949d593bda8ac04d6)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)", "macros 0.0.1", "msg 0.0.1", "net 0.0.1", @@ -45,7 +45,7 @@ dependencies = [ "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#fb15dd309750c8ec664b2c9f245cfcb06731872e)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)", "glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#a646f0badaccaebd61d0f8aaec5646da0a7c2a14)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)", "opengles 0.1.0 (git+https://github.com/servo/rust-opengles#13cccda11011716fd75526a74dfd03122110f95a)", "skia-sys 0.0.20130412 (git+https://github.com/servo/skia#6d696712962fd0d41120b7a414a48417da8e6a92)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib#79904fb42ff8a0e888f70fae336fbf6c11f1e6c8)", @@ -76,7 +76,7 @@ dependencies = [ "gfx 0.0.1", "glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo#a646f0badaccaebd61d0f8aaec5646da0a7c2a14)", "glut 0.0.1 (git+https://github.com/servo/rust-glut#d351eed425464c58671c6ec33445ee896fd42ff1)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)", "layout_traits 0.0.1", "msg 0.0.1", "net 0.0.1", @@ -176,7 +176,7 @@ dependencies = [ "freetype 0.1.0 (git+https://github.com/servo/rust-freetype#fb15dd309750c8ec664b2c9f245cfcb06731872e)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)", "harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz#a502be3df659cd13bac0e62638f4dac3dfb2f52d)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)", "macros 0.0.1", "msg 0.0.1", "net 0.0.1", @@ -255,7 +255,7 @@ dependencies = [ [[package]] name = "layers" version = "0.1.0" -source = "git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f" +source = "git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#9aeaee0bceb3241d6efca07cc6b82747339ffbff)", "egl 0.1.0 (git+https://github.com/servo/rust-egl#48b85e30d557ab2ee536730a73dd86a8160d618b)", @@ -314,7 +314,7 @@ dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation#9aeaee0bceb3241d6efca07cc6b82747339ffbff)", "geom 0.1.0 (git+https://github.com/servo/rust-geom#2982b770db6e5e3270305e0fd6b8068f6f80a489)", "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface#05f102273e16e9432245f813e5fe6280087e2b44)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers#c04029907be1f2242d48235d3b03608b905bbd9f)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers#e29c5cd670a0b42e8ac50e7099c265c481640dd5)", "url 0.1.0 (git+https://github.com/servo/rust-url#678bb4d52638b1cfdab78ef8e521566c9240fb1a)", "util 0.0.1", ] |