mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
When display lists update quickly, a hit test result might be returned for a previous display list / list of hit test items. When that happens, ignore the hit test result. This fixes a crash, but there might be situations where we can do something better, such as wait for display list processing to finish before performing the hit test. A future change might do this for events like mouse clicks and touch events that should never be thrown away. Ultimately, the best thing is likely moving hit testing back to layout or script so a valid hit test can always be performed against the current DOM. Fixes #29796.
130 lines
4.2 KiB
Rust
130 lines
4.2 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
#![crate_name = "gfx_traits"]
|
|
#![crate_type = "rlib"]
|
|
#![deny(unsafe_code)]
|
|
|
|
pub mod print_tree;
|
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
|
|
use malloc_size_of_derive::MallocSizeOf;
|
|
use range::{int_range_index, RangeIndex};
|
|
use serde::{Deserialize, Serialize};
|
|
use webrender_api::{Epoch as WebRenderEpoch, FontInstanceKey, FontKey, NativeFontHandle};
|
|
|
|
/// A newtype struct for denoting the age of messages; prevents race conditions.
|
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
|
pub struct Epoch(pub u32);
|
|
|
|
impl Epoch {
|
|
pub fn next(&mut self) {
|
|
self.0 += 1;
|
|
}
|
|
}
|
|
|
|
impl Into<WebRenderEpoch> for Epoch {
|
|
fn into(self) -> WebRenderEpoch {
|
|
WebRenderEpoch(self.0)
|
|
}
|
|
}
|
|
|
|
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(
|
|
/// The identifier for this StackingContext, derived from the Flow's memory address
|
|
/// and fragment type. As a space optimization, these are combined into a single word.
|
|
pub u64,
|
|
);
|
|
|
|
impl StackingContextId {
|
|
/// Returns the stacking context ID for the outer document/layout root.
|
|
#[inline]
|
|
pub fn root() -> StackingContextId {
|
|
StackingContextId(0)
|
|
}
|
|
|
|
pub fn next(&self) -> StackingContextId {
|
|
let StackingContextId(id) = *self;
|
|
StackingContextId(id + 1)
|
|
}
|
|
}
|
|
|
|
int_range_index! {
|
|
#[derive(Deserialize, MallocSizeOf, Serialize)]
|
|
/// An index that refers to a byte offset in a text run. This could
|
|
/// the middle of a glyph.
|
|
struct ByteIndex(isize)
|
|
}
|
|
|
|
/// The type of fragment that a scroll root is created for.
|
|
///
|
|
/// This can only ever grow to maximum 4 entries. That's because we cram the value of this enum
|
|
/// into the lower 2 bits of the `ScrollRootId`, which otherwise contains a 32-bit-aligned
|
|
/// heap address.
|
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
|
pub enum FragmentType {
|
|
/// A StackingContext for the fragment body itself.
|
|
FragmentBody,
|
|
/// A StackingContext created to contain ::before pseudo-element content.
|
|
BeforePseudoContent,
|
|
/// A StackingContext created to contain ::after pseudo-element content.
|
|
AfterPseudoContent,
|
|
}
|
|
|
|
/// The next ID that will be used for a special scroll root id.
|
|
///
|
|
/// A special scroll root is a scroll root that is created for generated content.
|
|
static NEXT_SPECIAL_SCROLL_ROOT_ID: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
/// If none of the bits outside this mask are set, the scroll root is a special scroll root.
|
|
/// Note that we assume that the top 16 bits of the address space are unused on the platform.
|
|
const SPECIAL_SCROLL_ROOT_ID_MASK: usize = 0xffff;
|
|
|
|
/// Returns a new scroll root ID for a scroll root.
|
|
fn next_special_id() -> usize {
|
|
// We shift this left by 2 to make room for the fragment type ID.
|
|
((NEXT_SPECIAL_SCROLL_ROOT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) &
|
|
SPECIAL_SCROLL_ROOT_ID_MASK
|
|
}
|
|
|
|
pub fn combine_id_with_fragment_type(id: usize, fragment_type: FragmentType) -> usize {
|
|
debug_assert_eq!(id & (fragment_type as usize), 0);
|
|
if fragment_type == FragmentType::FragmentBody {
|
|
id
|
|
} else {
|
|
next_special_id() | (fragment_type as usize)
|
|
}
|
|
}
|
|
|
|
pub fn node_id_from_scroll_id(id: usize) -> Option<usize> {
|
|
if (id & !SPECIAL_SCROLL_ROOT_ID_MASK) != 0 {
|
|
return Some((id & !3) as usize);
|
|
}
|
|
None
|
|
}
|
|
|
|
pub enum FontData {
|
|
Raw(Vec<u8>),
|
|
Native(NativeFontHandle),
|
|
}
|
|
|
|
pub trait WebrenderApi {
|
|
fn add_font_instance(&self, font_key: FontKey, size: f32) -> FontInstanceKey;
|
|
fn add_font(&self, data: FontData) -> FontKey;
|
|
}
|