fune/servo/components/gfx_traits/lib.rs
Martin Robinson 5b6df44ee7 servo: Merge #19933 - Update WebRender (from mrobinson:update-wr); r=emilio
This allows servo to use the ExternalScrollId API from WebRender fixing
some issues related to duplicate scroll root ids.

Fixes #17176.
Fixes #19287.
Fixes #19648.

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #17176, #19287, and #19648.

<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 8f24005e17aa0b5e274e6efbe0e44f208eb71e42

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 3283c6cf9a36acfd46b65058459ad98871674458
2018-02-06 09:12:58 -05:00

109 lines
3.6 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 http://mozilla.org/MPL/2.0/. */
#![crate_name = "gfx_traits"]
#![crate_type = "rlib"]
#![deny(unsafe_code)]
extern crate malloc_size_of;
#[macro_use] extern crate malloc_size_of_derive;
#[macro_use] extern crate range;
#[macro_use] extern crate serde;
pub mod print_tree;
use range::RangeIndex;
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
/// 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;
}
}
/// 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, Serialize)]
#[doc = "An index that refers to a byte offset in a text run. This could \
point to the middle of a glyph."]
#[derive(MallocSizeOf)]
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 = ATOMIC_USIZE_INIT;
/// 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 trait DisplayList {
/// Returns true if this display list contains meaningful content.
fn is_contentful(&self) -> bool;
}