diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 59845759ca0..0f549d50256 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -18,7 +18,7 @@ use crossbeam_channel::Sender; use embedder_traits::Cursor; use euclid::{Point2D, Rect, Scale, Transform3D, Vector2D}; use fnv::{FnvHashMap, FnvHashSet}; -use gfx_traits::{Epoch, FontData}; +use gfx_traits::{Epoch, FontData, WebRenderEpochToU16}; #[cfg(feature = "gl")] use image::{DynamicImage, ImageFormat}; use ipc_channel::ipc; @@ -283,6 +283,10 @@ struct PipelineDetails { /// The pipeline associated with this PipelineDetails object. pipeline: Option, + /// The epoch of the most recent display list for this pipeline. Note that this display + /// list might not be displayed, as WebRender processes display lists asynchronously. + most_recent_display_list_epoch: Option, + /// Whether animations are running animations_running: bool, @@ -305,6 +309,7 @@ impl PipelineDetails { fn new() -> PipelineDetails { PipelineDetails { pipeline: None, + most_recent_display_list_epoch: None, animations_running: false, animation_callbacks_running: false, visible: true, @@ -696,6 +701,7 @@ impl IOCompositor { let pipeline_id = display_list_info.pipeline_id; let details = self.pipeline_details(PipelineId::from_webrender(pipeline_id)); + details.most_recent_display_list_epoch = Some(display_list_info.epoch); details.hit_test_items = display_list_info.hit_test_info; details.install_new_scroll_tree(display_list_info.scroll_tree); @@ -1134,6 +1140,14 @@ impl IOCompositor { None => return None, }; + // If the epoch in the tag does not match the current epoch of the pipeline, + // then the hit test is against an old version of the display list and we + // should ignore this hit test for now. + match details.most_recent_display_list_epoch { + Some(epoch) if epoch.as_u16() == item.tag.1 => {}, + _ => return None, + } + let info = &details.hit_test_items[item.tag.0 as usize]; Some(CompositorHitTestResult { pipeline_id, diff --git a/components/gfx_traits/lib.rs b/components/gfx_traits/lib.rs index 5b7c53d2848..7cac7ef1fb1 100644 --- a/components/gfx_traits/lib.rs +++ b/components/gfx_traits/lib.rs @@ -31,6 +31,19 @@ impl Into for Epoch { } } +pub trait WebRenderEpochToU16 { + fn as_u16(&self) -> u16; +} + +impl WebRenderEpochToU16 for WebRenderEpoch { + /// The value of this [`Epoch`] as a u16 value. Note that if this Epoch's + /// value is more than u16::MAX, then the return value will be modulo + /// u16::MAX. + fn as_u16(&self) -> u16 { + (self.0 % u16::MAX as u32) as u16 + } +} + /// A unique ID for every stacking context. #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)] pub struct StackingContextId( diff --git a/components/layout/display_list/webrender_helpers.rs b/components/layout/display_list/webrender_helpers.rs index 1e584c0c06f..2a57789f341 100644 --- a/components/layout/display_list/webrender_helpers.rs +++ b/components/layout/display_list/webrender_helpers.rs @@ -7,6 +7,7 @@ // This might be achieved by sharing types between WR and Servo display lists, or // completely converting layout to directly generate WebRender display lists, for example. +use gfx_traits::WebRenderEpochToU16; use log::trace; use msg::constellation_msg::PipelineId; use script_traits::compositor::{CompositorDisplayListInfo, ScrollTreeNodeId, ScrollableNodeInfo}; @@ -190,7 +191,7 @@ impl DisplayItem { clip_id: ClipId::ClipChain(current_clip_chain_id), flags: PrimitiveFlags::default(), }, - (hit_test_index as u64, 0u16), + (hit_test_index as u64, state.compositor_info.epoch.as_u16()), ); }; diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs index 228aa6df62f..e4b88472554 100644 --- a/components/layout_2020/display_list/mod.rs +++ b/components/layout_2020/display_list/mod.rs @@ -9,6 +9,7 @@ use embedder_traits::Cursor; use euclid::{Point2D, SideOffsets2D, Size2D}; use fnv::FnvHashMap; use gfx::text::glyph::GlyphStore; +use gfx_traits::WebRenderEpochToU16; use msg::constellation_msg::BrowsingContextId; use net_traits::image_cache::UsePlaceholder; use script_traits::compositor::{CompositorDisplayListInfo, ScrollTreeNodeId}; @@ -180,7 +181,10 @@ impl<'a> DisplayListBuilder<'a> { Some(cursor(inherited_ui.cursor.keyword, auto_cursor)), self.current_scroll_node_id, ); - Some((hit_test_index as u64, 0u16)) + Some(( + hit_test_index as u64, + self.display_list.compositor_info.epoch.as_u16(), + )) } }