dependencies: Upgrade to WebRender 0.64 (#31486)

This brings the version of WebRender used in Servo up-to-date with Gecko
upstream. The big change here is that HiDPI is no longer handled via
WebRender. Instead this happens via a scale applied to the root layer in
the compositor. In addition to this change, various changes are made to
Servo to adapt to the new WebRender API.

Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
Martin Robinson 2024-03-14 18:40:54 +01:00 committed by GitHub
parent 4597aeae5f
commit ad37a54f59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
102 changed files with 704 additions and 600 deletions

183
Cargo.lock generated
View file

@ -176,7 +176,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac57f2b058a76363e357c056e4f74f1945bf734d37b8b3ef49066c4787dde0fc"
dependencies = [
"clipboard-win",
"core-graphics",
"core-graphics 0.22.3",
"image",
"log",
"objc",
@ -311,12 +311,6 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "binary-space-partition"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
[[package]]
name = "bincode"
version = "1.3.3"
@ -737,7 +731,7 @@ dependencies = [
"block",
"cocoa-foundation",
"core-foundation",
"core-graphics",
"core-graphics 0.22.3",
"foreign-types 0.3.2",
"libc",
"objc",
@ -924,12 +918,6 @@ dependencies = [
"url",
]
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "cookie"
version = "0.12.0"
@ -978,6 +966,19 @@ dependencies = [
"libc",
]
[[package]]
name = "core-graphics"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"core-graphics-types",
"foreign-types 0.5.0",
"libc",
]
[[package]]
name = "core-graphics-types"
version = "0.1.3"
@ -996,11 +997,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25"
dependencies = [
"core-foundation",
"core-graphics",
"core-graphics 0.22.3",
"foreign-types 0.3.2",
"libc",
]
[[package]]
name = "core-text"
version = "20.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5"
dependencies = [
"core-foundation",
"core-graphics 0.23.1",
"foreign-types 0.5.0",
"libc",
]
[[package]]
name = "cpufeatures"
version = "0.2.12"
@ -1101,16 +1114,6 @@ dependencies = [
"syn 2.0.52",
]
[[package]]
name = "cstr"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8aa998c33a6d3271e3678950a22134cd7dd27cef86dee1b611b5b14207d1d90b"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "d3d12"
version = "0.7.0"
@ -1208,7 +1211,7 @@ dependencies = [
[[package]]
name = "derive_common"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"darling",
"proc-macro2",
@ -1223,10 +1226,8 @@ version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
"syn 1.0.109",
]
@ -1680,8 +1681,8 @@ dependencies = [
"bitflags 1.3.2",
"byteorder",
"core-foundation",
"core-graphics",
"core-text",
"core-graphics 0.22.3",
"core-text 19.2.0",
"dirs-next",
"dwrote",
"float-ord",
@ -1951,8 +1952,8 @@ dependencies = [
"bitflags 2.4.2",
"byteorder",
"core-foundation",
"core-graphics",
"core-text",
"core-graphics 0.22.3",
"core-text 19.2.0",
"dwrote",
"euclid",
"fnv",
@ -2565,8 +2566,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf8c27ca13930dc4ffe474880040fe9e0f03c2121600dc9c95423624cab3e467"
dependencies = [
"cc",
"core-graphics",
"core-text",
"core-graphics 0.22.3",
"core-text 19.2.0",
"foreign-types 0.3.2",
"freetype",
"pkg-config",
@ -3463,7 +3464,7 @@ dependencies = [
[[package]]
name = "malloc_size_of"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"accountable-refcell",
"app_units",
@ -4229,8 +4230,8 @@ dependencies = [
[[package]]
name = "peek-poke"
version = "0.2.0"
source = "git+https://github.com/servo/webrender?rev=f91b68a61#f91b68a616377da0f3f8858f3cead3e47da4acdd"
version = "0.3.0"
source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391"
dependencies = [
"euclid",
"peek-poke-derive",
@ -4238,13 +4239,13 @@ dependencies = [
[[package]]
name = "peek-poke-derive"
version = "0.2.1"
source = "git+https://github.com/servo/webrender?rev=f91b68a61#f91b68a616377da0f3f8858f3cead3e47da4acdd"
version = "0.3.0"
source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"synstructure 0.12.6",
"syn 2.0.52",
"synstructure 0.13.1",
"unicode-xid",
]
@ -4404,14 +4405,13 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "plane-split"
version = "0.17.1"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3f7075ec146b897b6e0faca47adeb7ed3d4f6eaa8145bf19db17311081b3f63"
checksum = "8c1f7d82649829ecdef8e258790b0587acf0a8403f0ce963473d8e918acc1643"
dependencies = [
"binary-space-partition",
"euclid",
"log",
"num-traits",
"smallvec",
]
[[package]]
@ -5075,7 +5075,7 @@ dependencies = [
[[package]]
name = "selectors"
version = "0.24.0"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"bitflags 1.3.2",
"cssparser",
@ -5363,7 +5363,7 @@ dependencies = [
[[package]]
name = "servo_arc"
version = "0.2.0"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"nodrop",
"serde",
@ -5373,7 +5373,7 @@ dependencies = [
[[package]]
name = "servo_atoms"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"string_cache",
"string_cache_codegen",
@ -5579,7 +5579,7 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]]
name = "size_of_test"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"static_assertions",
]
@ -5705,7 +5705,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "static_prefs"
version = "0.1.0"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
[[package]]
name = "str-buf"
@ -5748,7 +5748,7 @@ dependencies = [
[[package]]
name = "style"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"app_units",
"arrayvec",
@ -5806,7 +5806,7 @@ dependencies = [
[[package]]
name = "style_config"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"lazy_static",
]
@ -5814,7 +5814,7 @@ dependencies = [
[[package]]
name = "style_derive"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"darling",
"derive_common",
@ -5845,7 +5845,7 @@ dependencies = [
[[package]]
name = "style_traits"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"app_units",
"bitflags 1.3.2",
@ -5876,7 +5876,7 @@ dependencies = [
"cgl",
"cocoa",
"core-foundation",
"core-graphics",
"core-graphics 0.22.3",
"euclid",
"fnv",
"gl_generator",
@ -6188,7 +6188,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "to_shmem"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"cssparser",
"servo_arc",
@ -6201,7 +6201,7 @@ dependencies = [
[[package]]
name = "to_shmem_derive"
version = "0.0.1"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#6614be88ec2b773e397767eb0d0554dd1145e81e"
source = "git+https://github.com/servo/stylo.git?branch=2023-07-23#7dd884031d6b97d801d50f8fcdff69bbeb292ae0"
dependencies = [
"darling",
"derive_common",
@ -6330,6 +6330,12 @@ dependencies = [
"winnow",
]
[[package]]
name = "topological-sort"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa7c7f42dea4b1b99439786f5633aeb9c14c1b53f75e282803c2ec2ad545873c"
[[package]]
name = "tower-service"
version = "0.3.2"
@ -6866,31 +6872,24 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "webrender"
version = "0.61.0"
source = "git+https://github.com/servo/webrender?rev=f91b68a61#f91b68a616377da0f3f8858f3cead3e47da4acdd"
version = "0.64.0"
source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391"
dependencies = [
"bincode",
"bitflags 1.3.2",
"bitflags 2.4.2",
"build-parallel",
"byteorder",
"core-foundation",
"core-graphics",
"core-text",
"cstr",
"derive_more",
"dwrote",
"etagere",
"euclid",
"freetype",
"fxhash",
"gleam",
"glslopt",
"lazy_static",
"libc",
"log",
"malloc_size_of_derive",
"num-traits",
"objc",
"peek-poke",
"plane-split",
"rayon",
"ron",
@ -6898,24 +6897,23 @@ dependencies = [
"smallvec",
"svg_fmt",
"time 0.1.45",
"topological-sort",
"tracy-rs",
"webrender_api",
"webrender_build",
"wr_glyph_rasterizer",
"wr_malloc_size_of",
]
[[package]]
name = "webrender_api"
version = "0.61.0"
source = "git+https://github.com/servo/webrender?rev=f91b68a61#f91b68a616377da0f3f8858f3cead3e47da4acdd"
version = "0.64.0"
source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391"
dependencies = [
"app_units",
"bitflags 1.3.2",
"bitflags 2.4.2",
"byteorder",
"core-foundation",
"core-graphics",
"crossbeam-channel",
"derive_more",
"euclid",
"malloc_size_of_derive",
"peek-poke",
@ -6928,10 +6926,10 @@ dependencies = [
[[package]]
name = "webrender_build"
version = "0.0.1"
source = "git+https://github.com/servo/webrender?rev=f91b68a61#f91b68a616377da0f3f8858f3cead3e47da4acdd"
version = "0.0.2"
source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391"
dependencies = [
"bitflags 1.3.2",
"bitflags 2.4.2",
"lazy_static",
]
@ -7332,7 +7330,7 @@ dependencies = [
"bitflags 1.3.2",
"cfg_aliases",
"core-foundation",
"core-graphics",
"core-graphics 0.22.3",
"dispatch",
"instant",
"libc",
@ -7384,10 +7382,35 @@ dependencies = [
"winapi",
]
[[package]]
name = "wr_glyph_rasterizer"
version = "0.1.0"
source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391"
dependencies = [
"core-foundation",
"core-graphics 0.23.1",
"core-text 20.1.0",
"dwrote",
"euclid",
"freetype",
"fxhash",
"lazy_static",
"libc",
"log",
"malloc_size_of_derive",
"objc",
"rayon",
"serde",
"smallvec",
"tracy-rs",
"webrender_api",
"wr_malloc_size_of",
]
[[package]]
name = "wr_malloc_size_of"
version = "0.0.1"
source = "git+https://github.com/servo/webrender?rev=f91b68a61#f91b68a616377da0f3f8858f3cead3e47da4acdd"
version = "0.0.2"
source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391"
dependencies = [
"app_units",
"euclid",

View file

@ -123,8 +123,8 @@ uuid = { version = "1.7.0", features = ["v4"] }
webdriver = "0.49.0"
webpki = "0.22"
webpki-roots = "0.25"
webrender = { git = "https://github.com/servo/webrender", rev = "f91b68a61", features = ["capture"] }
webrender_api = { git = "https://github.com/servo/webrender", rev = "f91b68a61" }
webrender = { git = "https://github.com/servo/webrender", branch = "0.64", features = ["capture"] }
webrender_api = { git = "https://github.com/servo/webrender", branch = "0.64" }
webrender_traits = { path = "components/shared/webrender" }
wgpu-core = "0.18"
wgpu-types = "0.18"

View file

@ -48,10 +48,10 @@ use webrender_api::units::{
LayoutVector2D, WorldPoint,
};
use webrender_api::{
self, BuiltDisplayList, ClipId, DirtyRect, DocumentId, Epoch as WebRenderEpoch,
self, BuiltDisplayList, DirtyRect, DisplayListPayload, DocumentId, Epoch as WebRenderEpoch,
ExternalScrollId, HitTestFlags, PipelineId as WebRenderPipelineId, PropertyBinding,
ReferenceFrameKind, ScrollClamping, ScrollLocation, SpaceAndClipInfo, SpatialId,
TransformStyle, ZoomFactor,
ReferenceFrameKind, RenderReasons, SampledScrollOffset, ScrollLocation, SpaceAndClipInfo,
SpatialId, SpatialTreeItemKey, TransformStyle,
};
use crate::gl::RenderTargetInfo;
@ -109,13 +109,6 @@ impl FrameTreeId {
}
}
/// One pixel in layer coordinate space.
///
/// This unit corresponds to a "pixel" in layer coordinate space, which after scaling and
/// transformation becomes a device pixel.
#[derive(Clone, Copy, Debug)]
enum LayerPixel {}
struct RootPipeline {
top_level_browsing_context_id: TopLevelBrowsingContextId,
id: Option<PipelineId>,
@ -137,9 +130,6 @@ pub struct IOCompositor<Window: WindowMethods + ?Sized> {
/// Tracks details about each active pipeline that the compositor knows about.
pipeline_details: HashMap<PipelineId, PipelineDetails>,
/// The scene scale, to allow for zooming and high-resolution painting.
scale: Scale<f32, LayerPixel, DevicePixel>,
/// "Mobile-style" zoom that does not reflow the page.
viewport_zoom: PinchZoomFactor,
@ -395,7 +385,6 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
id: None,
},
pipeline_details: HashMap::new(),
scale: Scale::new(1.0),
composition_request: CompositionRequest::NoCompositingNecessary,
touch_handler: TouchHandler::new(),
pending_scroll_zoom_events: Vec::new(),
@ -439,7 +428,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
convert_mouse_to_touch: bool,
top_level_browsing_context_id: TopLevelBrowsingContextId,
) -> Self {
let mut compositor = IOCompositor::new(
let compositor = IOCompositor::new(
window,
state,
composite_target,
@ -450,10 +439,6 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
// Make sure the GL state is OK
compositor.assert_gl_framebuffer_complete();
// Set the size of the root layer.
compositor.update_zoom_transform();
compositor
}
@ -570,8 +555,8 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
self.touch_handler.on_event_processed(result);
},
(CompositorMsg::CreatePng(rect, reply), ShutdownState::NotShuttingDown) => {
let res = self.composite_specific_target(CompositeTarget::SharedMemory, rect);
(CompositorMsg::CreatePng(page_rect, reply), ShutdownState::NotShuttingDown) => {
let res = self.composite_specific_target(CompositeTarget::SharedMemory, page_rect);
if let Err(ref e) = res {
info!("Error retrieving PNG: {:?}", e);
}
@ -613,11 +598,9 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
ShutdownState::NotShuttingDown,
) => {
if recomposite_needed {
if let Some(result) = self.hit_test_at_device_point(self.cursor_pos) {
if let Some(result) = self.hit_test_at_point(self.cursor_pos) {
self.update_cursor(result);
}
self.composition_request =
CompositionRequest::CompositeNow(CompositingReason::NewWebRenderFrame);
}
if recomposite_needed || self.animation_callbacks_active() {
@ -644,7 +627,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
CompositorMsg::WebDriverMouseButtonEvent(mouse_event_type, mouse_button, x, y),
ShutdownState::NotShuttingDown,
) => {
let dppx = self.device_pixels_per_page_px();
let dppx = self.device_pixels_per_page_pixel();
let point = dppx.transform_point(Point2D::new(x, y));
self.on_mouse_window_event_class(match mouse_event_type {
MouseEventType::Click => MouseWindowEvent::Click(mouse_button, point),
@ -654,7 +637,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
},
(CompositorMsg::WebDriverMouseMoveEvent(x, y), ShutdownState::NotShuttingDown) => {
let dppx = self.device_pixels_per_page_px();
let dppx = self.device_pixels_per_page_pixel();
let point = dppx.transform_point(Point2D::new(x, y));
self.on_mouse_window_move_event_class(DevicePoint::new(point.x, point.y));
},
@ -705,25 +688,46 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
script_traits::ScriptToCompositorMsg::SendInitialTransaction(pipeline),
) => {
let mut txn = Transaction::new();
txn.set_display_list(
WebRenderEpoch(0),
None,
Default::default(),
(pipeline, Default::default()),
false,
);
self.generate_frame(&mut txn);
txn.set_display_list(WebRenderEpoch(0), (pipeline, Default::default()));
self.generate_frame(&mut txn, RenderReasons::SCENE);
self.webrender_api
.send_transaction(self.webrender_document, txn);
},
ForwardedToCompositorMsg::Layout(
script_traits::ScriptToCompositorMsg::SendScrollNode(point, scroll_id),
script_traits::ScriptToCompositorMsg::SendScrollNode(
pipeline_id,
point,
external_scroll_id,
),
) => {
let pipeline_id = PipelineId::from_webrender(pipeline_id);
let pipeline_details = match self.pipeline_details.get_mut(&pipeline_id) {
Some(details) => details,
None => return,
};
let offset = LayoutVector2D::new(point.x, point.y);
if !pipeline_details
.scroll_tree
.set_scroll_offsets_for_node_with_external_scroll_id(
external_scroll_id,
-offset,
)
{
warn!("Could not scroll not with id: {external_scroll_id:?}");
return;
}
let mut txn = Transaction::new();
txn.scroll_node_with_id(point, scroll_id, ScrollClamping::NoClamping);
self.generate_frame(&mut txn);
txn.set_scroll_offsets(
external_scroll_id,
vec![SampledScrollOffset {
offset,
generation: 0,
}],
);
self.generate_frame(&mut txn, RenderReasons::APZ);
self.webrender_api
.send_transaction(self.webrender_document, txn);
},
@ -735,10 +739,39 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
display_list_receiver,
},
) => {
let display_list_data = match display_list_receiver.recv() {
// This must match the order from the sender, currently in `shared/script/lib.rs`.
let items_data = match display_list_receiver.recv() {
Ok(display_list_data) => display_list_data,
_ => return warn!("Could not recieve WebRender display list."),
Err(error) => {
return warn!(
"Could not receive WebRender display list items data: {error}"
)
},
};
let cache_data = match display_list_receiver.recv() {
Ok(display_list_data) => display_list_data,
Err(error) => {
return warn!(
"Could not receive WebRender display list cache data: {error}"
)
},
};
let spatial_tree = match display_list_receiver.recv() {
Ok(display_list_data) => display_list_data,
Err(error) => {
return warn!(
"Could not receive WebRender display list spatial tree: {error}."
)
},
};
let built_display_list = BuiltDisplayList::from_data(
DisplayListPayload {
items_data,
cache_data,
spatial_tree,
},
display_list_descriptor,
);
let pipeline_id = display_list_info.pipeline_id;
let details = self.pipeline_details(PipelineId::from_webrender(pipeline_id));
@ -746,20 +779,25 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
details.hit_test_items = display_list_info.hit_test_info;
details.install_new_scroll_tree(display_list_info.scroll_tree);
let mut txn = Transaction::new();
txn.set_display_list(
display_list_info.epoch,
None,
display_list_info.viewport_size,
(
pipeline_id,
BuiltDisplayList::from_data(display_list_data, display_list_descriptor),
),
true,
let mut transaction = Transaction::new();
transaction
.set_display_list(display_list_info.epoch, (pipeline_id, built_display_list));
for node in details.scroll_tree.nodes.iter() {
if let (Some(offset), Some(external_id)) = (node.offset(), node.external_id()) {
let offset = LayoutVector2D::new(-offset.x, -offset.y);
transaction.set_scroll_offsets(
external_id,
vec![SampledScrollOffset {
offset,
generation: 0,
}],
);
self.generate_frame(&mut txn);
}
}
self.generate_frame(&mut transaction, RenderReasons::SCENE);
self.webrender_api
.send_transaction(self.webrender_document, txn);
.send_transaction(self.webrender_document, transaction);
},
ForwardedToCompositorMsg::Layout(script_traits::ScriptToCompositorMsg::HitTest(
@ -880,9 +918,9 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}
/// Queue a new frame in the transaction and increase the pending frames count.
fn generate_frame(&mut self, transaction: &mut Transaction) {
fn generate_frame(&mut self, transaction: &mut Transaction, reason: RenderReasons) {
self.pending_frames += 1;
transaction.generate_frame(0);
transaction.generate_frame(0, reason);
}
/// Sets or unsets the animations-running flag for the given pipeline, and schedules a
@ -944,18 +982,12 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
/// the root pipeline is the root content pipeline. If there is pinch zoom, the root
/// content pipeline is wrapped in a display list that applies a pinch zoom
/// transformation to it.
fn set_root_content_pipeline_handling_pinch_zoom(&self, transaction: &mut Transaction) {
fn set_root_content_pipeline_handling_device_scaling(&self, transaction: &mut Transaction) {
let root_content_pipeline = match self.root_content_pipeline.id {
Some(id) => id.to_webrender(),
None => return,
};
let zoom_factor = self.pinch_zoom_level();
if zoom_factor == 1.0 {
transaction.set_root_pipeline(root_content_pipeline);
return;
}
// Every display list needs a pipeline, but we'd like to choose one that is unlikely
// to conflict with our content pipelines, which start at (1, 1). (0, 0) is WebRender's
// dummy pipeline, so we choose (0, 1).
@ -963,11 +995,13 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
transaction.set_root_pipeline(root_pipeline);
let mut builder = webrender_api::DisplayListBuilder::new(root_pipeline);
builder.begin();
let viewport_size = LayoutSize::new(
self.embedder_coordinates.get_viewport().width() as f32,
self.embedder_coordinates.get_viewport().height() as f32,
);
let viewport_rect = LayoutRect::new(LayoutPoint::zero(), viewport_size);
let zoom_factor = self.device_pixels_per_page_pixel().0;
let zoom_reference_frame = builder.push_reference_frame(
LayoutPoint::zero(),
SpatialId::root_reference_frame(root_pipeline),
@ -976,31 +1010,37 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
ReferenceFrameKind::Transform {
is_2d_scale_translation: true,
should_snap: true,
paired_with_perspective: false,
},
SpatialTreeItemKey::new(0, 0),
);
let scaled_viewport_rect = LayoutRect::from_origin_and_size(
LayoutPoint::zero(),
LayoutSize::new(
viewport_size.width / zoom_factor,
viewport_size.height / zoom_factor,
),
);
let root_clip_id = builder.define_clip_rect(zoom_reference_frame, scaled_viewport_rect);
let clip_chain_id = builder.define_clip_chain(None, [root_clip_id]);
builder.push_iframe(
viewport_rect,
viewport_rect,
scaled_viewport_rect,
scaled_viewport_rect,
&SpaceAndClipInfo {
spatial_id: zoom_reference_frame,
clip_id: ClipId::root(root_pipeline),
clip_chain_id,
},
root_content_pipeline,
true,
);
let built_display_list = builder.finalize();
let built_display_list = builder.end();
// NB: We are always passing 0 as the epoch here, but this doesn't seem to
// be an issue. WebRender will still update the scene and generate a new
// frame even though the epoch hasn't changed.
transaction.set_display_list(
WebRenderEpoch(0),
None,
viewport_rect.size,
built_display_list,
false,
);
transaction.set_display_list(WebRenderEpoch(0), built_display_list);
}
fn set_frame_tree(&mut self, frame_tree: &SendableFrameTree) {
@ -1015,8 +1055,8 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
};
let mut txn = Transaction::new();
self.set_root_content_pipeline_handling_pinch_zoom(&mut txn);
self.generate_frame(&mut txn);
self.set_root_content_pipeline_handling_device_scaling(&mut txn);
self.generate_frame(&mut txn, RenderReasons::SCENE);
self.webrender_api
.send_transaction(self.webrender_document, txn);
@ -1065,45 +1105,14 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
self.pipeline_details.remove(&pipeline_id);
}
fn send_window_size(&mut self, size_type: WindowSizeType) {
let dppx = self.page_zoom * self.embedder_coordinates.hidpi_factor;
let mut transaction = Transaction::new();
transaction.set_document_view(
self.embedder_coordinates.get_viewport(),
self.embedder_coordinates.hidpi_factor.get(),
);
self.webrender_api
.send_transaction(self.webrender_document, transaction);
let initial_viewport = self.embedder_coordinates.viewport.size.to_f32() / dppx;
let data = WindowSizeData {
device_pixel_ratio: dppx,
initial_viewport,
};
let top_level_browsing_context_id =
self.root_content_pipeline.top_level_browsing_context_id;
let msg = ConstellationMsg::WindowSize(top_level_browsing_context_id, data, size_type);
if let Err(e) = self.constellation_chan.send(msg) {
warn!("Sending window resize to constellation failed ({:?}).", e);
}
}
pub fn on_resize_window_event(&mut self) -> bool {
trace!("Compositor resize requested");
if self.shutdown_state != ShutdownState::NotShuttingDown {
return false;
}
let old_coords = self.embedder_coordinates;
self.embedder_coordinates = self.window.get_coordinates();
// A size change could also mean a resolution change.
if self.embedder_coordinates.hidpi_factor != old_coords.hidpi_factor {
self.update_zoom_transform();
}
// If the framebuffer size has changed, invalidate the current framebuffer object, and mark
// the last framebuffer object as needing to be invalidated at the end of the next frame.
if self.embedder_coordinates.framebuffer != old_coords.framebuffer {
@ -1111,11 +1120,21 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
self.invalidate_prev_offscreen_framebuffer = true;
}
if self.embedder_coordinates.viewport == old_coords.viewport {
if self.embedder_coordinates.viewport != old_coords.viewport {
let mut transaction = Transaction::new();
transaction.set_document_view(self.embedder_coordinates.get_viewport());
self.webrender_api
.send_transaction(self.webrender_document, transaction);
}
// A size change could also mean a resolution change.
if self.embedder_coordinates.hidpi_factor == old_coords.hidpi_factor &&
self.embedder_coordinates.viewport == old_coords.viewport
{
return false;
}
self.send_window_size(WindowSizeType::Resize);
self.update_after_zoom_or_hidpi_change();
self.composite_if_necessary(CompositingReason::Resize);
true
}
@ -1140,7 +1159,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
MouseWindowEvent::MouseUp(_, p) => p,
};
let result = match self.hit_test_at_device_point(point) {
let result = match self.hit_test_at_point(point) {
Some(result) => result,
None => return,
};
@ -1166,14 +1185,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}
}
fn hit_test_at_device_point(&self, point: DevicePoint) -> Option<CompositorHitTestResult> {
let dppx = self.page_zoom * self.hidpi_factor();
let scaled_point = (point / dppx).to_untyped();
let world_point = WorldPoint::from_untyped(scaled_point);
self.hit_test_at_point(world_point)
}
fn hit_test_at_point(&self, point: WorldPoint) -> Option<CompositorHitTestResult> {
fn hit_test_at_point(&self, point: DevicePoint) -> Option<CompositorHitTestResult> {
return self
.hit_test_at_point_with_flags_and_pipeline(point, HitTestFlags::empty(), None)
.first()
@ -1182,7 +1194,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
fn hit_test_at_point_with_flags_and_pipeline(
&self,
point: WorldPoint,
point: DevicePoint,
flags: HitTestFlags,
pipeline_id: Option<WebRenderPipelineId>,
) -> Vec<CompositorHitTestResult> {
@ -1193,9 +1205,11 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
if self.pipeline(root_pipeline_id).is_none() {
return vec![];
}
// DevicePoint and WorldPoint are the same for us.
let world_point = WorldPoint::from_untyped(point.to_untyped());
let results =
self.webrender_api
.hit_test(self.webrender_document, pipeline_id, point, flags);
.hit_test(self.webrender_document, pipeline_id, world_point, flags);
results
.items
@ -1238,7 +1252,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}
fn dispatch_mouse_window_move_event_class(&mut self, cursor: DevicePoint) {
let result = match self.hit_test_at_device_point(cursor) {
let result = match self.hit_test_at_point(cursor) {
Some(result) => result,
None => return,
};
@ -1257,7 +1271,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
identifier: TouchId,
point: DevicePoint,
) {
if let Some(result) = self.hit_test_at_device_point(point) {
if let Some(result) = self.hit_test_at_point(point) {
let event = TouchEvent(
event_type,
identifier,
@ -1272,7 +1286,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}
pub fn send_wheel_event(&mut self, delta: WheelDelta, point: DevicePoint) {
if let Some(result) = self.hit_test_at_device_point(point) {
if let Some(result) = self.hit_test_at_point(point) {
let event = WheelEvent(delta, result.point_in_viewport, Some(result.node));
let msg = ConstellationMsg::ForwardEvent(result.pipeline_id, event);
if let Err(e) = self.constellation_chan.send(msg) {
@ -1433,11 +1447,10 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}
let zoom_changed =
self.set_pinch_zoom_level(self.pinch_zoom_level() * combined_magnification);
self.set_pinch_zoom_level(self.pinch_zoom_level().get() * combined_magnification);
let scroll_result = combined_scroll_event.and_then(|combined_event| {
let cursor = (combined_event.cursor.to_f32() / self.scale).to_untyped();
self.scroll_node_at_world_point(
WorldPoint::from_untyped(cursor),
self.scroll_node_at_device_point(
combined_event.cursor.to_f32(),
combined_event.scroll_location,
)
});
@ -1447,33 +1460,41 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
let mut transaction = Transaction::new();
if zoom_changed {
self.set_root_content_pipeline_handling_pinch_zoom(&mut transaction);
self.set_root_content_pipeline_handling_device_scaling(&mut transaction);
}
if let Some((pipeline_id, external_id, offset)) = scroll_result {
let scroll_origin = LayoutPoint::new(-offset.x, -offset.y);
transaction.scroll_node_with_id(scroll_origin, external_id, ScrollClamping::NoClamping);
let offset = LayoutVector2D::new(-offset.x, -offset.y);
transaction.set_scroll_offsets(
external_id,
vec![SampledScrollOffset {
offset,
generation: 0,
}],
);
self.send_scroll_positions_to_layout_for_pipeline(&pipeline_id);
}
self.generate_frame(&mut transaction);
self.generate_frame(&mut transaction, RenderReasons::APZ);
self.webrender_api
.send_transaction(self.webrender_document, transaction);
}
/// Perform a hit test at the given [`WorldPoint`] and apply the [`ScrollLocation`]
/// Perform a hit test at the given [`DevicePoint`] and apply the [`ScrollLocation`]
/// scrolling to the applicable scroll node under that point. If a scroll was
/// performed, returns the [`PipelineId`] of the node scrolled, the id, and the final
/// scroll delta.
fn scroll_node_at_world_point(
fn scroll_node_at_device_point(
&mut self,
cursor: WorldPoint,
cursor: DevicePoint,
scroll_location: ScrollLocation,
) -> Option<(PipelineId, ExternalScrollId, LayoutVector2D)> {
let scroll_location = match scroll_location {
ScrollLocation::Delta(delta) => {
let scaled_delta =
(Vector2D::from_untyped(delta.to_untyped()) / self.scale).to_untyped();
let device_pixels_per_page = self.device_pixels_per_page_pixel();
let scaled_delta = (Vector2D::from_untyped(delta.to_untyped()) /
device_pixels_per_page)
.to_untyped();
let calculated_delta = LayoutVector2D::from_untyped(scaled_delta);
ScrollLocation::Delta(calculated_delta)
},
@ -1558,20 +1579,19 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
self.embedder_coordinates.hidpi_factor
}
fn device_pixels_per_page_px(&self) -> Scale<f32, CSSPixel, DevicePixel> {
self.page_zoom * self.hidpi_factor()
fn device_pixels_per_page_pixel(&self) -> Scale<f32, CSSPixel, DevicePixel> {
self.device_pixels_per_page_pixel_not_including_page_zoom() * self.pinch_zoom_level()
}
fn update_zoom_transform(&mut self) {
let scale = self.device_pixels_per_page_px();
self.scale = Scale::new(scale.get());
fn device_pixels_per_page_pixel_not_including_page_zoom(
&self,
) -> Scale<f32, CSSPixel, DevicePixel> {
self.page_zoom * self.hidpi_factor()
}
pub fn on_zoom_reset_window_event(&mut self) {
self.page_zoom = Scale::new(1.0);
self.update_zoom_transform();
self.send_window_size(WindowSizeType::Resize);
self.update_page_zoom_for_webrender();
self.update_after_zoom_or_hidpi_change();
}
pub fn on_zoom_window_event(&mut self, magnification: f32) {
@ -1580,18 +1600,37 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
.max(MIN_ZOOM)
.min(MAX_ZOOM),
);
self.update_zoom_transform();
self.send_window_size(WindowSizeType::Resize);
self.update_page_zoom_for_webrender();
self.update_after_zoom_or_hidpi_change();
}
fn update_page_zoom_for_webrender(&mut self) {
let page_zoom = ZoomFactor::new(self.page_zoom.get());
fn update_after_zoom_or_hidpi_change(&mut self) {
// The device pixel ratio used by the style system should include the scale from page pixels
// to device pixels, but not including any pinch zoom.
let device_pixel_ratio = self.device_pixels_per_page_pixel_not_including_page_zoom();
let initial_viewport =
self.embedder_coordinates.viewport.size().to_f32() / device_pixel_ratio;
let data = WindowSizeData {
device_pixel_ratio,
initial_viewport,
};
let mut txn = webrender::Transaction::new();
txn.set_page_zoom(page_zoom);
let top_level_browsing_context_id =
self.root_content_pipeline.top_level_browsing_context_id;
let msg = ConstellationMsg::WindowSize(
top_level_browsing_context_id,
data,
WindowSizeType::Resize,
);
if let Err(e) = self.constellation_chan.send(msg) {
warn!("Sending window resize to constellation failed ({:?}).", e);
}
// Update the root transform in WebRender to reflect the new zoom.
let mut transaction = webrender::Transaction::new();
self.set_root_content_pipeline_handling_device_scaling(&mut transaction);
self.webrender_api
.send_transaction(self.webrender_document, txn);
.send_transaction(self.webrender_document, transaction);
}
/// Simulate a pinch zoom
@ -1722,7 +1761,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
fn composite_specific_target(
&mut self,
target: CompositeTarget,
rect: Option<Rect<f32, CSSPixel>>,
page_rect: Option<Rect<f32, CSSPixel>>,
) -> Result<Option<Image>, UnableToComposite> {
if self.waiting_on_present {
debug!("tried to composite while waiting on present");
@ -1843,8 +1882,8 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}
}
let (x, y, width, height) = if let Some(rect) = rect {
let rect = self.device_pixels_per_page_px().transform_rect(&rect);
let (x, y, width, height) = if let Some(rect) = page_rect {
let rect = self.device_pixels_per_page_pixel().transform_rect(&rect);
let x = rect.origin.x as i32;
// We need to convert to the bottom-left origin coordinate
@ -1974,10 +2013,10 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
// Set the viewport background based on prefs.
let viewport = self.embedder_coordinates.get_flipped_viewport();
gl.scissor(
viewport.origin.x,
viewport.origin.y,
viewport.size.width,
viewport.size.height,
viewport.min.x,
viewport.min.y,
viewport.size().width,
viewport.size().height,
);
let color = servo_config::pref!(shell.background_color.rgba);
@ -2086,8 +2125,8 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
}
}
pub fn pinch_zoom_level(&self) -> f32 {
self.viewport_zoom.get()
pub fn pinch_zoom_level(&self) -> Scale<f32, DevicePixel, DevicePixel> {
Scale::new(self.viewport_zoom.get())
}
fn set_pinch_zoom_level(&mut self, mut zoom: f32) -> bool {
@ -2117,7 +2156,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
self.webrender.set_debug_flags(flags);
let mut txn = Transaction::new();
self.generate_frame(&mut txn);
self.generate_frame(&mut txn, RenderReasons::TESTING);
self.webrender_api
.send_transaction(self.webrender_document, txn);
}

View file

@ -219,7 +219,7 @@ impl EmbedderCoordinates {
pub fn get_flipped_viewport(&self) -> DeviceIntRect {
let fb_height = self.framebuffer.height;
let mut view = self.viewport;
view.origin.y = fb_height - view.origin.y - view.size.height;
view.min.y = fb_height - view.min.y - view.size().height;
DeviceIntRect::from_untyped(&view.to_untyped())
}
}

View file

@ -51,7 +51,7 @@ impl MaxRect for Rect<Au> {
impl MaxRect for LayoutRect {
#[inline]
fn max_rect() -> LayoutRect {
LayoutRect::new(
LayoutRect::from_origin_and_size(
LayoutPoint::new(f32::MIN / 2.0, f32::MIN / 2.0),
LayoutSize::new(f32::MAX, f32::MAX),
)

View file

@ -125,8 +125,14 @@ impl FontTemplateData {
/// Returns the native font that underlies this font template, if applicable.
pub fn native_font(&self) -> Option<NativeFontHandle> {
self.ctfont(0.0)
.map(|ctfont| NativeFontHandle(ctfont.copy_to_CGFont()))
let local_identifier = match &self.identifier {
FontIdentifier::Local(local_identifier) => local_identifier,
FontIdentifier::Web(_) => return None,
};
Some(NativeFontHandle {
name: local_identifier.postscript_name.to_string(),
path: local_identifier.path.to_string(),
})
}
}

View file

@ -29,6 +29,7 @@ use log::{debug, warn};
use msg::constellation_msg::{BrowsingContextId, PipelineId};
use net_traits::image_cache::UsePlaceholder;
use range::Range;
use script_traits::compositor::ScrollSensitivity;
use servo_config::opts;
use servo_geometry::{self, MaxRect};
use style::color::AbsoluteColor;
@ -51,7 +52,7 @@ use webrender_api::units::{LayoutRect, LayoutTransform, LayoutVector2D};
use webrender_api::{
self, BorderDetails, BorderRadius, BorderSide, BoxShadowClipMode, ColorF, ColorU,
ExternalScrollId, FilterOp, GlyphInstance, ImageRendering, LineStyle, NinePatchBorder,
NinePatchBorderSource, NormalBorder, PropertyBinding, ScrollSensitivity, StickyOffsetBounds,
NinePatchBorderSource, NormalBorder, PropertyBinding, StickyOffsetBounds,
};
use crate::block::BlockFlow;
@ -384,6 +385,7 @@ impl<'a> DisplayListBuildState<'a> {
&self,
clip_rect: Rect<Au>,
node: OpaqueNode,
unique_id: u64,
cursor: Option<Cursor>,
section: DisplayListSection,
) -> BaseDisplayItem {
@ -397,6 +399,7 @@ impl<'a> DisplayListBuildState<'a> {
self.create_base_display_item_with_clipping_and_scrolling(
clip_rect,
node,
unique_id,
cursor,
section,
clipping_and_scrolling,
@ -407,12 +410,17 @@ impl<'a> DisplayListBuildState<'a> {
&self,
clip_rect: Rect<Au>,
node: OpaqueNode,
unique_id: u64,
cursor: Option<Cursor>,
section: DisplayListSection,
clipping_and_scrolling: ClippingAndScrolling,
) -> BaseDisplayItem {
BaseDisplayItem::new(
DisplayItemMetadata { node, cursor },
DisplayItemMetadata {
node,
unique_id,
cursor,
},
clip_rect.to_layout(),
section,
self.current_stacking_context_id,
@ -702,6 +710,7 @@ impl Fragment {
let base = state.create_base_display_item(
bounds,
self.node,
self.unique_id(),
get_cursor(style, Cursor::Default),
display_list_section,
);
@ -842,6 +851,7 @@ impl Fragment {
let base = state.create_base_display_item(
placement.clip_rect,
self.node,
self.unique_id(),
get_cursor(style, Cursor::Default),
display_list_section,
);
@ -964,6 +974,7 @@ impl Fragment {
let base = state.create_base_display_item(
placement.clip_rect,
self.node,
self.unique_id(),
get_cursor(style, Cursor::Default),
display_list_section,
);
@ -1040,6 +1051,7 @@ impl Fragment {
let base = state.create_base_display_item(
clip,
self.node,
self.unique_id(),
get_cursor(style, Cursor::Default),
display_list_section,
);
@ -1126,6 +1138,7 @@ impl Fragment {
let base = state.create_base_display_item(
clip,
self.node,
self.unique_id(),
get_cursor(style, Cursor::Default),
display_list_section,
);
@ -1221,7 +1234,7 @@ impl Fragment {
)?;
width = image.width;
height = image.height;
NinePatchBorderSource::Image(image.key?)
NinePatchBorderSource::Image(image.key?, ImageRendering::Auto)
},
Image::PaintWorklet(ref paint_worklet) => {
let image = self.get_webrender_image_for_paint_worklet(
@ -1232,7 +1245,7 @@ impl Fragment {
)?;
width = image.width;
height = image.height;
NinePatchBorderSource::Image(image.key?)
NinePatchBorderSource::Image(image.key?, ImageRendering::Auto)
},
Image::Gradient(ref gradient) => match **gradient {
Gradient::Linear {
@ -1288,7 +1301,6 @@ impl Fragment {
fill: border_image_fill,
repeat_horizontal: border_image_repeat.0.to_layout(),
repeat_vertical: border_image_repeat.1.to_layout(),
outset: SideOffsets2D::zero(),
});
state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
base,
@ -1340,6 +1352,7 @@ impl Fragment {
let base = state.create_base_display_item(
clip,
self.node,
self.unique_id(),
get_cursor(style, Cursor::Default),
DisplayListSection::Outlines,
);
@ -1372,6 +1385,7 @@ impl Fragment {
let base = state.create_base_display_item(
clip,
self.node,
self.unique_id(),
get_cursor(style, Cursor::Default),
DisplayListSection::Content,
);
@ -1402,12 +1416,13 @@ impl Fragment {
let base = state.create_base_display_item(
clip,
self.node,
self.unique_id(),
get_cursor(style, Cursor::Default),
DisplayListSection::Content,
);
// TODO(gw): Use a better estimate for wavy line thickness.
let area = baseline.to_layout();
let wavy_line_thickness = (0.33 * area.size.height).ceil();
let wavy_line_thickness = (0.33 * area.size().height).ceil();
state.add_display_item(DisplayItem::Line(CommonDisplayItem::new(
base,
webrender_api::LineDisplayItem {
@ -1432,6 +1447,7 @@ impl Fragment {
let base = state.create_base_display_item(
clip,
self.node,
self.unique_id(),
get_cursor(&self.style, Cursor::Default),
DisplayListSection::Content,
);
@ -1475,6 +1491,7 @@ impl Fragment {
let base = state.create_base_display_item(
stacking_relative_border_box,
self.node,
self.unique_id(),
get_cursor(&self.style, Cursor::Default),
display_list_section,
);
@ -1522,6 +1539,7 @@ impl Fragment {
let base = state.create_base_display_item(
insertion_point_bounds,
self.node,
self.unique_id(),
get_cursor(&self.style, cursor),
display_list_section,
);
@ -1709,6 +1727,7 @@ impl Fragment {
let base = state.create_base_display_item_with_clipping_and_scrolling(
content_size,
self.node,
self.unique_id(),
// FIXME(emilio): Why does this ignore pointer-events?
get_cursor(&self.style, Cursor::Default).or(Some(Cursor::Default)),
display_list_section,
@ -1773,6 +1792,7 @@ impl Fragment {
state.create_base_display_item(
stacking_relative_border_box,
self.node,
self.unique_id(),
get_cursor(&self.style, Cursor::Default),
DisplayListSection::Content,
)
@ -1859,7 +1879,7 @@ impl Fragment {
// looks bogus.
state.iframe_sizes.insert(
browsing_context_id,
euclid::Size2D::new(bounds.size.width, bounds.size.height),
euclid::Size2D::new(bounds.size().width, bounds.size().height),
);
let pipeline_id = match fragment_info.pipeline_id {
@ -2067,6 +2087,7 @@ impl Fragment {
let base = state.create_base_display_item(
clip,
self.node,
self.unique_id(),
get_cursor(&self.style, cursor),
DisplayListSection::Content,
);
@ -2230,13 +2251,14 @@ impl Fragment {
let base = state.create_base_display_item(
clip,
self.node,
self.unique_id(),
get_cursor(&self.style, Cursor::Default),
DisplayListSection::Content,
);
// TODO(gw): Use a better estimate for wavy line thickness.
let area = stacking_relative_box.to_layout();
let wavy_line_thickness = (0.33 * area.size.height).ceil();
let wavy_line_thickness = (0.33 * area.size().height).ceil();
state.add_display_item(DisplayItem::Line(CommonDisplayItem::new(
base,
webrender_api::LineDisplayItem {
@ -2945,8 +2967,15 @@ impl BaseFlow {
let mut color = THREAD_TINT_COLORS[thread_id as usize % THREAD_TINT_COLORS.len()];
color.a = 1.0;
let base =
state.create_base_display_item(self.clip, node, None, DisplayListSection::Content);
let base = state.create_base_display_item(
self.clip,
node,
// This item will never become a spatial tree node, so it's fine
// to pass 0 here.
0,
None,
DisplayListSection::Content,
);
let bounds = stacking_context_relative_bounds.inflate(Au::from_px(2), Au::from_px(2));
state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
base,
@ -3123,6 +3152,6 @@ trait ToF32Px {
impl ToF32Px for Rect<Au> {
type Output = LayoutRect;
fn to_f32_px(&self) -> LayoutRect {
LayoutRect::from_untyped(&servo_geometry::au_rect_to_f32_rect(*self))
LayoutRect::from_untyped(&servo_geometry::au_rect_to_f32_rect(*self).to_box2d())
}
}

View file

@ -139,7 +139,7 @@ impl ToLayout for Point2D<Au> {
impl ToLayout for Rect<Au> {
type Type = wr::units::LayoutRect;
fn to_layout(&self) -> Self::Type {
wr::units::LayoutRect::new(self.origin.to_layout(), self.size.to_layout())
wr::units::LayoutRect::from_origin_and_size(self.origin.to_layout(), self.size.to_layout())
}
}

View file

@ -24,7 +24,7 @@ use gfx_traits::print_tree::PrintTree;
use gfx_traits::{self, StackingContextId};
use msg::constellation_msg::PipelineId;
use net_traits::image::base::Image;
use script_traits::compositor::ScrollTreeNodeId;
use script_traits::compositor::{ScrollSensitivity, ScrollTreeNodeId};
use serde::Serialize;
use servo_geometry::MaxRect;
use style::computed_values::_servo_top_layer::T as InTopLayer;
@ -32,9 +32,9 @@ pub use style::dom::OpaqueNode;
use webrender_api as wr;
use webrender_api::units::{LayoutPixel, LayoutRect, LayoutTransform};
use webrender_api::{
BorderRadius, ClipChainId, ClipId, ClipMode, CommonItemProperties, ComplexClipRegion,
ExternalScrollId, FilterOp, GlyphInstance, GradientStop, ImageKey, MixBlendMode,
PrimitiveFlags, ScrollSensitivity, Shadow, SpatialId, StickyOffsetBounds, TransformStyle,
BorderRadius, ClipChainId, ClipMode, CommonItemProperties, ComplexClipRegion, ExternalScrollId,
FilterOp, GlyphInstance, GradientStop, ImageKey, MixBlendMode, PrimitiveFlags, Shadow,
SpatialId, StickyOffsetBounds, TransformStyle,
};
/// The factor that we multiply the blur radius by in order to inflate the boundaries of display
@ -479,6 +479,7 @@ impl BaseDisplayItem {
BaseDisplayItem {
metadata: DisplayItemMetadata {
node: OpaqueNode(0),
unique_id: 0,
cursor: None,
},
// Create a rectangle of maximal size.
@ -495,7 +496,7 @@ impl BaseDisplayItem {
pub fn empty_common_item_properties() -> CommonItemProperties {
CommonItemProperties {
clip_rect: LayoutRect::max_rect(),
clip_id: ClipId::root(wr::PipelineId::dummy()),
clip_chain_id: ClipChainId::INVALID,
spatial_id: SpatialId::root_scroll_node(wr::PipelineId::dummy()),
flags: PrimitiveFlags::empty(),
}
@ -553,6 +554,8 @@ impl fmt::Debug for ClippingRegion {
pub struct DisplayItemMetadata {
/// The DOM node from which this display item originated.
pub node: OpaqueNode,
/// The unique fragment id of the fragment of this item.
pub unique_id: u64,
/// The value of the `cursor` property when the mouse hovers over this display item. If `None`,
/// this display item is ineligible for pointer events (`pointer-events: none`).
pub cursor: Option<Cursor>,

View file

@ -10,12 +10,14 @@
use gfx_traits::WebRenderEpochToU16;
use log::trace;
use msg::constellation_msg::PipelineId;
use script_traits::compositor::{CompositorDisplayListInfo, ScrollTreeNodeId, ScrollableNodeInfo};
use script_traits::compositor::{
CompositorDisplayListInfo, ScrollSensitivity, ScrollTreeNodeId, ScrollableNodeInfo,
};
use webrender_api::units::{LayoutPoint, LayoutSize, LayoutVector2D};
use webrender_api::{
self, ClipChainId, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem,
DisplayListBuilder, Epoch, PrimitiveFlags, PropertyBinding, PushStackingContextDisplayItem,
RasterSpace, ReferenceFrameKind, SpaceAndClipInfo, SpatialId, StackingContext,
DisplayListBuilder, Epoch, HasScrollLinkedEffect, PrimitiveFlags, PropertyBinding, RasterSpace,
ReferenceFrameKind, SpaceAndClipInfo, SpatialId, SpatialTreeItemKey,
};
use crate::display_list::items::{
@ -32,7 +34,6 @@ impl<'a> ClipScrollState<'a> {
fn new(
clip_scroll_nodes: &'a mut Vec<ClipScrollNode>,
compositor_info: CompositorDisplayListInfo,
builder: &mut DisplayListBuilder,
) -> Self {
let mut state = ClipScrollState {
clip_scroll_nodes,
@ -48,9 +49,7 @@ impl<'a> ClipScrollState<'a> {
Some(state.compositor_info.root_reference_frame_id);
state.clip_scroll_nodes[1].scroll_node_id = Some(state.compositor_info.root_scroll_node_id);
let root_clip_chain =
builder.define_clip_chain(None, [ClipId::root(state.compositor_info.pipeline_id)]);
let root_clip_chain = ClipChainId::INVALID;
state.add_clip_node_mapping(0, root_clip_chain);
state.add_clip_node_mapping(1, root_clip_chain);
@ -100,6 +99,25 @@ impl<'a> ClipScrollState<'a> {
self.clip_scroll_nodes[index].scroll_node_id =
self.clip_scroll_nodes[parent_index].scroll_node_id
}
pub fn define_clip_chain<I>(
&self,
builder: &mut DisplayListBuilder,
parent: ClipChainId,
clips: I,
) -> ClipChainId
where
I: IntoIterator<Item = ClipId>,
I::IntoIter: ExactSizeIterator + Clone,
{
// We use INVALID to mean "no clipping", but that cannot be passed as an argument
// to `define_clip_chain()`, so it must be converted into `None`.
let parent = match parent {
ClipChainId::INVALID => None,
parent => Some(parent),
};
builder.define_clip_chain(parent, clips)
}
}
/// Contentful paint, for the purpose of
@ -117,8 +135,9 @@ impl DisplayList {
) -> (DisplayListBuilder, CompositorDisplayListInfo, IsContentful) {
let webrender_pipeline = pipeline_id.to_webrender();
let mut builder = DisplayListBuilder::new(webrender_pipeline);
builder.begin();
let content_size = self.bounds().size;
let content_size = self.bounds().size();
let mut state = ClipScrollState::new(
&mut self.clip_scroll_nodes,
CompositorDisplayListInfo::new(
@ -126,9 +145,8 @@ impl DisplayList {
content_size,
webrender_pipeline,
epoch,
webrender_api::ScrollSensitivity::ScriptAndInputEvents,
ScrollSensitivity::ScriptAndInputEvents,
),
&mut builder,
);
let mut is_contentful = IsContentful(false);
@ -141,6 +159,15 @@ impl DisplayList {
}
impl DisplayItem {
fn get_spatial_tree_item_key(
&self,
builder: &DisplayListBuilder,
node_index: usize,
) -> SpatialTreeItemKey {
let pipeline_tag = (builder.pipeline_id.0 as u64) << 32 | builder.pipeline_id.1 as u64;
SpatialTreeItemKey::new(pipeline_tag, node_index as u64)
}
fn convert_to_webrender(
&mut self,
state: &mut ClipScrollState,
@ -167,7 +194,7 @@ impl DisplayItem {
CommonItemProperties {
clip_rect: base.clip_rect,
spatial_id: current_scroll_node_id.spatial_id,
clip_id: ClipId::ClipChain(current_clip_chain_id),
clip_chain_id: current_clip_chain_id,
// TODO(gw): Make use of the WR backface visibility functionality.
flags: PrimitiveFlags::default(),
}
@ -191,12 +218,10 @@ impl DisplayItem {
);
builder.push_hit_test(
&CommonItemProperties {
clip_rect: bounds,
spatial_id: current_scroll_node_id.spatial_id,
clip_id: ClipId::ClipChain(current_clip_chain_id),
flags: PrimitiveFlags::default(),
},
bounds,
current_clip_chain_id,
current_scroll_node_id.spatial_id,
PrimitiveFlags::default(),
(hit_test_index as u64, state.compositor_info.epoch.as_u16()),
);
};
@ -268,7 +293,7 @@ impl DisplayItem {
builder.push_shadow(
&SpaceAndClipInfo {
spatial_id: common.spatial_id,
clip_id: common.clip_id,
clip_chain_id: common.clip_chain_id,
},
item.shadow,
true,
@ -287,7 +312,7 @@ impl DisplayItem {
common.clip_rect,
&SpaceAndClipInfo {
spatial_id: common.spatial_id,
clip_id: common.clip_id,
clip_chain_id: common.clip_chain_id,
},
item.iframe.to_webrender(),
true,
@ -315,6 +340,7 @@ impl DisplayItem {
ReferenceFrameKind::Transform {
is_2d_scale_translation: false,
should_snap: false,
paired_with_perspective: false,
},
),
(Some(t), Some(p)) => (
@ -326,15 +352,16 @@ impl DisplayItem {
(None, None) => unreachable!(),
};
let index = frame_index.to_index();
let new_spatial_id = builder.push_reference_frame(
stacking_context.bounds.origin,
stacking_context.bounds.min,
current_scroll_node_id.spatial_id,
stacking_context.transform_style,
PropertyBinding::Value(transform),
ref_frame,
self.get_spatial_tree_item_key(builder, index),
);
let index = frame_index.to_index();
state.add_clip_node_mapping(index, current_clip_chain_id);
state.register_spatial_node(
index,
@ -343,37 +370,32 @@ impl DisplayItem {
None,
);
bounds.origin = LayoutPoint::zero();
bounds.min = LayoutPoint::zero();
new_spatial_id
} else {
current_scroll_node_id.spatial_id
};
if !stacking_context.filters.is_empty() {
builder.push_item(&WrDisplayItem::SetFilterOps);
builder.push_iter(&stacking_context.filters);
}
// TODO(jdm): WebRender now requires us to create stacking context items
// with the IS_BLEND_CONTAINER flag enabled if any children
// of the stacking context have a blend mode applied.
// This will require additional tracking during layout
// before we start collecting stacking contexts so that
// information will be available when we reach this point.
let wr_item = PushStackingContextDisplayItem {
origin: bounds.origin,
builder.push_stacking_context(
bounds.min,
spatial_id,
prim_flags: PrimitiveFlags::default(),
stacking_context: StackingContext {
transform_style: stacking_context.transform_style,
mix_blend_mode: stacking_context.mix_blend_mode,
clip_id: None,
raster_space: RasterSpace::Screen,
flags: Default::default(),
},
};
PrimitiveFlags::default(),
None,
stacking_context.transform_style,
stacking_context.mix_blend_mode,
&stacking_context.filters,
&[],
&[],
RasterSpace::Screen,
Default::default(),
);
builder.push_item(&WrDisplayItem::PushStackingContext(wr_item));
IsContentful(false)
},
DisplayItem::PopStackingContext(ref item) => {
@ -392,43 +414,38 @@ impl DisplayItem {
let parent_spatial_id = state.webrender_spatial_id_for_index(parent_index);
let parent_clip_chain_id = state.webrender_clip_id_for_index(parent_index);
let parent_space_and_clip_info = SpaceAndClipInfo {
clip_id: ClipId::root(state.compositor_info.pipeline_id),
spatial_id: parent_spatial_id,
};
match node.node_type {
ClipScrollNodeType::Clip(clip_type) => {
let clip_id = match clip_type {
ClipType::Rect => {
builder.define_clip_rect(&parent_space_and_clip_info, item_rect)
builder.define_clip_rect(parent_spatial_id, item_rect)
},
ClipType::Rounded(complex) => {
builder.define_clip_rounded_rect(parent_spatial_id, complex)
},
ClipType::Rounded(complex) => builder
.define_clip_rounded_rect(&parent_space_and_clip_info, complex),
};
let clip_chain_id =
builder.define_clip_chain(Some(parent_clip_chain_id), [clip_id]);
state.define_clip_chain(builder, parent_clip_chain_id, [clip_id]);
state.add_clip_node_mapping(index, clip_chain_id);
state.add_spatial_node_mapping_to_parent_index(index, parent_index);
},
ClipScrollNodeType::ScrollFrame(scroll_sensitivity, external_id) => {
let clip_id =
builder.define_clip_rect(&parent_space_and_clip_info, item_rect);
let clip_id = builder.define_clip_rect(parent_spatial_id, item_rect);
let clip_chain_id =
builder.define_clip_chain(Some(parent_clip_chain_id), [clip_id]);
state.define_clip_chain(builder, parent_clip_chain_id, [clip_id]);
state.add_clip_node_mapping(index, clip_chain_id);
let spatial_id = builder
.define_scroll_frame(
&parent_space_and_clip_info,
let spatial_id = builder.define_scroll_frame(
parent_spatial_id,
external_id,
node.content_rect,
item_rect,
scroll_sensitivity,
LayoutVector2D::zero(),
)
.spatial_id;
LayoutVector2D::zero(), /* external_scroll_offset */
0, /* scroll_offset_generation */
HasScrollLinkedEffect::No,
self.get_spatial_tree_item_key(builder, index),
);
state.register_spatial_node(
index,
@ -436,7 +453,7 @@ impl DisplayItem {
Some(parent_index),
Some(ScrollableNodeInfo {
external_id,
scrollable_size: node.content_rect.size - item_rect.size,
scrollable_size: node.content_rect.size() - item_rect.size(),
scroll_sensitivity,
offset: LayoutVector2D::zero(),
}),
@ -450,7 +467,8 @@ impl DisplayItem {
sticky_data.margins,
sticky_data.vertical_offset_bounds,
sticky_data.horizontal_offset_bounds,
LayoutVector2D::zero(),
LayoutVector2D::zero(), /* previously_applied_offset */
self.get_spatial_tree_item_key(builder, index),
);
state.add_clip_node_mapping(index, parent_clip_chain_id);

View file

@ -86,6 +86,8 @@ pub fn build_display_list_for_subtree<'a>(
let base = state.create_base_display_item(
bounds,
flow_root.as_block().fragment.node,
// The unique id is the same as the node id because this is the root fragment.
flow_root.as_block().fragment.node.id() as u64,
None,
DisplayListSection::BackgroundAndBorders,
);

View file

@ -66,7 +66,7 @@ impl<'a> BackgroundPainter<'a> {
// The 'backgound-clip' property maps directly to `clip_rect` in `CommonItemProperties`:
let mut common = builder.common_properties(*painting_area, &fb.fragment.style);
if let Some(clip_chain_id) = clip {
common.clip_id = wr::ClipId::ClipChain(clip_chain_id)
common.clip_chain_id = clip_chain_id;
}
(painting_area, common)
}
@ -105,9 +105,9 @@ pub(super) fn layout_layer(
Cover,
}
let size_contain_or_cover = |background_size| {
let mut tile_size = positioning_area.size;
let mut tile_size = positioning_area.size();
if let Some(intrinsic_ratio) = intrinsic.ratio {
let positioning_ratio = positioning_area.size.width / positioning_area.size.height;
let positioning_ratio = positioning_area.size().width / positioning_area.size().height;
// Whether the tile width (as opposed to height)
// is scaled to that of the positioning area
let fit_width = match background_size {
@ -130,10 +130,10 @@ pub(super) fn layout_layer(
Size::Cover => size_contain_or_cover(ContainOrCover::Cover),
Size::ExplicitSize { width, height } => {
let mut width = width.non_auto().map(|lp| {
lp.0.percentage_relative_to(Length::new(positioning_area.size.width))
lp.0.percentage_relative_to(Length::new(positioning_area.size().width))
});
let mut height = height.non_auto().map(|lp| {
lp.0.percentage_relative_to(Length::new(positioning_area.size.height))
lp.0.percentage_relative_to(Length::new(positioning_area.size().height))
});
if width.is_none() && height.is_none() {
@ -152,7 +152,7 @@ pub(super) fn layout_layer(
intrinsic_height.into()
} else {
// Treated as 100%
Au::from_f32_px(positioning_area.size.height).into()
Au::from_f32_px(positioning_area.size().height).into()
};
units::LayoutSize::new(w.px(), h.px())
},
@ -163,7 +163,7 @@ pub(super) fn layout_layer(
intrinsic_width.into()
} else {
// Treated as 100%
Au::from_f32_px(positioning_area.size.width).into()
Au::from_f32_px(positioning_area.size().width).into()
};
units::LayoutSize::new(w.px(), h.px())
},
@ -182,20 +182,20 @@ pub(super) fn layout_layer(
&mut tile_size.width,
repeat_x,
get_cyclic(&b.background_position_x.0, layer_index),
painting_area.origin.x - positioning_area.origin.x,
painting_area.size.width,
positioning_area.size.width,
painting_area.min.x - positioning_area.min.x,
painting_area.size().width,
positioning_area.size().width,
);
let result_y = layout_1d(
&mut tile_size.height,
repeat_y,
get_cyclic(&b.background_position_y.0, layer_index),
painting_area.origin.y - positioning_area.origin.y,
painting_area.size.height,
positioning_area.size.height,
painting_area.min.y - positioning_area.min.y,
painting_area.size().height,
positioning_area.size().height,
);
let bounds = units::LayoutRect::new(
positioning_area.origin + Vector2D::new(result_x.bounds_origin, result_y.bounds_origin),
let bounds = units::LayoutRect::from_origin_and_size(
positioning_area.min + Vector2D::new(result_x.bounds_origin, result_y.bounds_origin),
Size2D::new(result_x.bounds_size, result_y.bounds_size),
);
let tile_spacing = units::LayoutSize::new(result_x.tile_spacing, result_y.tile_spacing);

View file

@ -111,14 +111,20 @@ impl ToWebRender for PhysicalSize<Au> {
impl ToWebRender for PhysicalRect<Length> {
type Type = units::LayoutRect;
fn to_webrender(&self) -> Self::Type {
units::LayoutRect::new(self.origin.to_webrender(), self.size.to_webrender())
units::LayoutRect::from_origin_and_size(
self.origin.to_webrender(),
self.size.to_webrender(),
)
}
}
impl ToWebRender for PhysicalRect<Au> {
type Type = units::LayoutRect;
fn to_webrender(&self) -> Self::Type {
units::LayoutRect::new(self.origin.to_webrender(), self.size.to_webrender())
units::LayoutRect::from_origin_and_size(
self.origin.to_webrender(),
self.size.to_webrender(),
)
}
}

View file

@ -12,7 +12,7 @@ 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};
use script_traits::compositor::{CompositorDisplayListInfo, ScrollSensitivity, ScrollTreeNodeId};
use servo_geometry::MaxRect;
use style::color::{AbsoluteColor, ColorSpace};
use style::computed_values::text_decoration_style::T as ComputedTextDecorationStyle;
@ -23,9 +23,8 @@ use style::values::computed::{BorderStyle, Color, Length, LengthPercentage, Outl
use style::values::specified::text::TextDecorationLine;
use style::values::specified::ui::CursorKind;
use style_traits::CSSPixel;
use webrender_api::{self as wr, units, ClipChainId, ClipId, CommonItemProperties};
use webrender_api::{self as wr, units, BoxShadowClipMode, ClipChainId};
use wr::units::LayoutVector2D;
use wr::{BoxShadowClipMode, ScrollSensitivity};
use crate::context::LayoutContext;
use crate::display_list::conversions::ToWebRender;
@ -69,6 +68,11 @@ pub struct DisplayList {
/// data structure that the compositor uses to map hit tests to information
/// about the item hit.
pub compositor_info: CompositorDisplayListInfo,
/// A count of the number of SpatialTree nodes pushed to the WebRender display
/// list. This is merely to ensure that the currently-unused SpatialTreeItemKey
/// produced for every SpatialTree node is unique.
pub spatial_tree_count: u64,
}
impl DisplayList {
@ -90,8 +94,25 @@ impl DisplayList {
epoch,
root_scroll_sensitivity,
),
spatial_tree_count: 0,
}
}
pub fn define_clip_chain<I>(&mut self, parent: ClipChainId, clips: I) -> ClipChainId
where
I: IntoIterator<Item = wr::ClipId>,
I::IntoIter: ExactSizeIterator + Clone,
{
// WebRender has two different ways of expressing "no clip." ClipChainId::INVALID should be
// used for primitives, but `None` is used for stacking contexts and clip chains. We convert
// to the `Option<ClipChainId>` representation here. Just passing Some(ClipChainId::INVALID)
// leads to a crash.
let parent = match parent {
ClipChainId::INVALID => None,
parent => Some(parent),
};
self.wr.define_clip_chain(parent, clips)
}
}
pub(crate) struct DisplayListBuilder<'a> {
@ -139,7 +160,7 @@ impl DisplayList {
) -> (FnvHashMap<BrowsingContextId, Size2D<f32, CSSPixel>>, bool) {
let mut builder = DisplayListBuilder {
current_scroll_node_id: self.compositor_info.root_reference_frame_id,
current_clip_chain_id: ClipChainId(0, self.compositor_info.pipeline_id),
current_clip_chain_id: ClipChainId::INVALID,
element_for_canvas_background: fragment_tree.canvas_background.from_element,
is_contentful: false,
context,
@ -167,7 +188,7 @@ impl<'a> DisplayListBuilder<'a> {
wr::CommonItemProperties {
clip_rect,
spatial_id: self.current_scroll_node_id.spatial_id,
clip_id: ClipId::ClipChain(self.current_clip_chain_id),
clip_chain_id: self.current_clip_chain_id,
flags: style.get_webrender_primitive_flags(),
}
}
@ -268,7 +289,7 @@ impl Fragment {
common.clip_rect,
&wr::SpaceAndClipInfo {
spatial_id: common.spatial_id,
clip_id: common.clip_id,
clip_chain_id: common.clip_chain_id,
},
iframe.pipeline_id.to_webrender(),
true,
@ -304,12 +325,10 @@ impl Fragment {
let clip_chain_id = builder.current_clip_chain_id;
let spatial_id = builder.current_scroll_node_id.spatial_id;
builder.wr().push_hit_test(
&CommonItemProperties {
clip_rect: rect.to_webrender(),
clip_id: ClipId::ClipChain(clip_chain_id),
rect.to_webrender(),
clip_chain_id,
spatial_id,
flags: style.get_webrender_primitive_flags(),
},
style.get_webrender_primitive_flags(),
hit_info,
);
}
@ -405,7 +424,7 @@ impl Fragment {
color: &AbsoluteColor,
) {
let rect = rect.to_webrender();
let wavy_line_thickness = (0.33 * rect.size.height).ceil();
let wavy_line_thickness = (0.33 * rect.size().height).ceil();
let text_decoration_color = fragment
.parent_style
.clone_text_decoration_color()
@ -452,8 +471,8 @@ impl<'a> BuilderForBoxFragment<'a> {
};
let corner = |corner: &style::values::computed::BorderCornerRadius| {
Size2D::new(
resolve(&corner.0.width.0, border_rect.size.width),
resolve(&corner.0.height.0, border_rect.size.height),
resolve(&corner.0.width.0, border_rect.size().width),
resolve(&corner.0.height.0, border_rect.size().height),
)
};
let b = fragment.style.get_border();
@ -577,9 +596,15 @@ impl<'a> BuilderForBoxFragment<'a> {
let mut common = builder.common_properties(self.border_rect, &self.fragment.style);
if let Some(clip_chain_id) = self.border_edge_clip(builder) {
common.clip_id = ClipId::ClipChain(clip_chain_id);
common.clip_chain_id = clip_chain_id;
}
builder.wr().push_hit_test(&common, hit_info);
builder.wr().push_hit_test(
common.clip_rect,
common.clip_chain_id,
common.spatial_id,
common.flags,
hit_info,
);
}
fn build_background_for_painter(
@ -1011,13 +1036,10 @@ fn clip_for_radii(
if radii.is_zero() {
None
} else {
let clip_chain_id = builder.current_clip_chain_id;
let parent_space_and_clip = wr::SpaceAndClipInfo {
spatial_id: builder.current_scroll_node_id.spatial_id,
clip_id: ClipId::ClipChain(clip_chain_id),
};
let spatial_id = builder.current_scroll_node_id.spatial_id;
let parent_clip_chain_id = builder.current_clip_chain_id;
let new_clip_id = builder.wr().define_clip_rounded_rect(
&parent_space_and_clip,
spatial_id,
wr::ComplexClipRegion {
rect,
radii,
@ -1026,8 +1048,8 @@ fn clip_for_radii(
);
Some(
builder
.wr()
.define_clip_chain(Some(clip_chain_id), [new_clip_id]),
.display_list
.define_clip_chain(parent_clip_chain_id, [new_clip_id]),
)
}
}

View file

@ -9,7 +9,7 @@ use euclid::default::Rect;
use euclid::SideOffsets2D;
use gfx_traits::print_tree::PrintTree;
use log::warn;
use script_traits::compositor::{ScrollTreeNodeId, ScrollableNodeInfo};
use script_traits::compositor::{ScrollSensitivity, ScrollTreeNodeId, ScrollableNodeInfo};
use servo_arc::Arc as ServoArc;
use servo_config::opts::DebugOptions;
use style::computed_values::float::T as ComputedFloat;
@ -23,9 +23,8 @@ use style::values::generics::transform;
use style::values::specified::box_::DisplayOutside;
use webrender_api as wr;
use webrender_api::units::{LayoutPoint, LayoutRect, LayoutTransform, LayoutVector2D};
use webrender_api::ScrollSensitivity;
use wr::units::{LayoutPixel, LayoutSize};
use wr::StickyOffsetBounds;
use wr::{ClipChainId, SpatialTreeItemKey, StickyOffsetBounds};
use super::DisplayList;
use crate::cell::ArcRefCell;
@ -90,26 +89,30 @@ pub(crate) enum StackingContextSection {
}
impl DisplayList {
/// Produce a new SpatialTreeItemKey. This is currently unused by WebRender,
/// but has to be unique to the entire scene.
fn get_next_spatial_tree_item_key(&mut self) -> SpatialTreeItemKey {
self.spatial_tree_count += 1;
let pipeline_tag = (self.wr.pipeline_id.0 as u64) << 32 | self.wr.pipeline_id.1 as u64;
SpatialTreeItemKey::new(pipeline_tag, self.spatial_tree_count)
}
pub fn build_stacking_context_tree(
&mut self,
fragment_tree: &FragmentTree,
debug: &DebugOptions,
) -> StackingContext {
let root_clip_chain_id = self
.wr
.define_clip_chain(None, [wr::ClipId::root(self.wr.pipeline_id)]);
let cb_for_non_fixed_descendants = ContainingBlock::new(
fragment_tree.initial_containing_block,
self.compositor_info.root_scroll_node_id,
Some(self.compositor_info.viewport_size),
root_clip_chain_id,
ClipChainId::INVALID,
);
let cb_for_fixed_descendants = ContainingBlock::new(
fragment_tree.initial_containing_block,
self.compositor_info.root_reference_frame_id,
None,
root_clip_chain_id,
ClipChainId::INVALID,
);
// We need to specify all three containing blocks here, because absolute
@ -146,12 +149,14 @@ impl DisplayList {
transform: wr::PropertyBinding<LayoutTransform>,
kind: wr::ReferenceFrameKind,
) -> ScrollTreeNodeId {
let spatial_tree_item_key = self.get_next_spatial_tree_item_key();
let new_spatial_id = self.wr.push_reference_frame(
origin,
parent_scroll_node_id.spatial_id,
transform_style,
transform,
kind,
spatial_tree_item_key,
);
self.compositor_info.scroll_tree.add_scroll_tree_node(
Some(parent_scroll_node_id),
@ -173,36 +178,29 @@ impl DisplayList {
clip_rect: LayoutRect,
scroll_sensitivity: ScrollSensitivity,
) -> (ScrollTreeNodeId, wr::ClipChainId) {
let parent_space_and_clip_info = wr::SpaceAndClipInfo {
spatial_id: parent_scroll_node_id.spatial_id,
clip_id: wr::ClipId::root(self.wr.pipeline_id),
};
let new_clip_id = self
.wr
.define_clip_rect(&parent_space_and_clip_info, clip_rect);
.define_clip_rect(parent_scroll_node_id.spatial_id, clip_rect);
let new_clip_chain_id = self.define_clip_chain(*parent_clip_chain_id, [new_clip_id]);
let spatial_tree_item_key = self.get_next_spatial_tree_item_key();
let new_clip_chain_id = self
.wr
.define_clip_chain(Some(*parent_clip_chain_id), [new_clip_id]);
let new_spatial_id = self
.wr
.define_scroll_frame(
&parent_space_and_clip_info,
let new_spatial_id = self.wr.define_scroll_frame(
parent_scroll_node_id.spatial_id,
external_id,
content_rect,
clip_rect,
scroll_sensitivity,
LayoutVector2D::zero(), /* external_scroll_offset */
)
.spatial_id;
0, /* scroll_offset_generation */
wr::HasScrollLinkedEffect::No,
spatial_tree_item_key,
);
let new_scroll_node_id = self.compositor_info.scroll_tree.add_scroll_tree_node(
Some(parent_scroll_node_id),
new_spatial_id,
Some(ScrollableNodeInfo {
external_id,
scrollable_size: content_rect.size - clip_rect.size,
scrollable_size: content_rect.size() - clip_rect.size(),
scroll_sensitivity,
offset: LayoutVector2D::zero(),
}),
@ -218,13 +216,15 @@ impl DisplayList {
vertical_offset_bounds: StickyOffsetBounds,
horizontal_offset_bounds: StickyOffsetBounds,
) -> ScrollTreeNodeId {
let spatial_tree_item_key = self.get_next_spatial_tree_item_key();
let new_spatial_id = self.wr.define_sticky_frame(
parent_scroll_node_id.spatial_id,
frame_rect,
margins,
vertical_offset_bounds,
horizontal_offset_bounds,
LayoutVector2D::zero(),
LayoutVector2D::zero(), /* previously_applied_offset */
spatial_tree_item_key,
);
self.compositor_info.scroll_tree.add_scroll_tree_node(
Some(parent_scroll_node_id),
@ -368,10 +368,18 @@ impl StackingContext {
fn create_descendant(
&self,
spatial_id: wr::SpatialId,
clip_chain_id: Option<wr::ClipChainId>,
clip_chain_id: wr::ClipChainId,
initializing_fragment_style: ServoArc<ComputedValues>,
context_type: StackingContextType,
) -> Self {
// WebRender has two different ways of expressing "no clip." ClipChainId::INVALID should be
// used for primitives, but `None` is used for stacking contexts and clip chains. We convert
// to the `Option<ClipChainId>` representation here. Just passing Some(ClipChainId::INVALID)
// leads to a crash.
let clip_chain_id: Option<ClipChainId> = match clip_chain_id {
ClipChainId::INVALID => None,
clip_chain_id => Some(clip_chain_id),
};
Self {
spatial_id,
clip_chain_id,
@ -471,8 +479,6 @@ impl StackingContext {
return false;
}
let clip_id = self.clip_chain_id.map(wr::ClipId::ClipChain);
// Create the filter pipeline.
let current_color = style.clone_color();
let mut filters: Vec<wr::FilterOp> = effects
@ -498,7 +504,7 @@ impl StackingContext {
LayoutPoint::zero(), // origin
self.spatial_id,
style.get_webrender_primitive_flags(),
clip_id,
self.clip_chain_id,
style.get_used_transform_style().to_webrender(),
effects.mix_blend_mode.to_webrender(),
&filters,
@ -621,13 +627,13 @@ impl StackingContext {
if let Some(reference_frame_data) =
box_fragment.reference_frame_data_if_necessary(containing_block_rect)
{
painting_area.origin -= reference_frame_data.origin.to_webrender().to_vector();
painting_area.min -= reference_frame_data.origin.to_webrender().to_vector();
if let Some(transformed) = reference_frame_data
.transform
.inverse()
.and_then(|inversed| inversed.outer_transformed_rect(&painting_area))
.and_then(|inversed| inversed.outer_transformed_rect(&painting_area.to_rect()))
{
painting_area = transformed
painting_area = transformed.to_box2d();
} else {
// The desired rect cannot be represented, so skip painting this background-image
return;
@ -1038,7 +1044,7 @@ impl BoxFragment {
let mut child_stacking_context = parent_stacking_context.create_descendant(
containing_block.scroll_node_id.spatial_id,
Some(containing_block.clip_chain_id),
containing_block.clip_chain_id,
self.style.clone(),
context_type,
);
@ -1219,19 +1225,10 @@ impl BoxFragment {
.translate(containing_block_rect.origin.to_vector())
.to_webrender();
let parent_space_and_clip = &wr::SpaceAndClipInfo {
spatial_id: parent_scroll_node_id.spatial_id,
clip_id: wr::ClipId::root(display_list.wr.pipeline_id),
};
let clip_id = display_list
.wr
.define_clip_rect(parent_space_and_clip, clip_rect);
Some(
display_list
.wr
.define_clip_chain(Some(*parent_clip_chain_id), [clip_id]),
)
.define_clip_rect(parent_scroll_node_id.spatial_id, clip_rect);
Some(display_list.define_clip_chain(*parent_clip_chain_id, [clip_id]))
}
fn build_scroll_frame_if_necessary(
@ -1294,7 +1291,7 @@ impl BoxFragment {
sensitivity,
);
Some((scroll_tree_node_id, clip_chain_id, padding_rect.size))
Some((scroll_tree_node_id, clip_chain_id, padding_rect.size()))
}
fn build_sticky_frame_if_necessary(
@ -1361,12 +1358,12 @@ impl BoxFragment {
// This is the minimum negative offset and then the maximum positive offset. We just
// specify every edge, but if the corresponding margin is None, that offset has no effect.
let vertical_offset_bounds = wr::StickyOffsetBounds::new(
containing_block_rect.min_y() - frame_rect.min_y(),
containing_block_rect.max_y() - frame_rect.max_y(),
containing_block_rect.min.y - frame_rect.min.y,
containing_block_rect.max.y - frame_rect.max.y,
);
let horizontal_offset_bounds = wr::StickyOffsetBounds::new(
containing_block_rect.min_x() - frame_rect.min_x(),
containing_block_rect.max_x() - frame_rect.max_x(),
containing_block_rect.min.x - frame_rect.min.x,
containing_block_rect.max.x - frame_rect.max.x,
);
let margins = SideOffsets2D::new(
@ -1416,6 +1413,7 @@ impl BoxFragment {
wr::ReferenceFrameKind::Transform {
is_2d_scale_translation: false,
should_snap: false,
paired_with_perspective: false,
},
),
(Some(transform), Some(perspective)) => (

View file

@ -7,13 +7,13 @@ use script_layout_interface::wrapper_traits::{
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
};
use script_layout_interface::{LayoutElementType, LayoutNodeType};
use script_traits::compositor::ScrollSensitivity;
use serde::Serialize;
use servo_arc::Arc;
use style::dom::OpaqueNode;
use style::properties::ComputedValues;
use style::values::computed::{Length, Overflow};
use style_traits::CSSPixel;
use webrender_api::ScrollSensitivity;
use crate::cell::ArcRefCell;
use crate::context::LayoutContext;

View file

@ -6,11 +6,12 @@ use app_units::Au;
use euclid::default::{Point2D, Rect, Size2D};
use fxhash::FxHashSet;
use gfx_traits::print_tree::PrintTree;
use script_traits::compositor::ScrollSensitivity;
use serde::Serialize;
use style::animation::AnimationSetKey;
use style::dom::OpaqueNode;
use style::values::computed::Length;
use webrender_api::{units, ScrollSensitivity};
use webrender_api::units;
use super::{ContainingBlockManager, Fragment, Tag};
use crate::cell::ArcRefCell;

View file

@ -836,7 +836,7 @@ impl LayoutThread {
self.epoch.set(epoch);
// TODO: Avoid the temporary conversion and build webrender sc/dl directly!
let (builder, compositor_info, is_contentful) =
let (mut builder, compositor_info, is_contentful) =
display_list.convert_to_webrender(self.id, viewport_size, epoch.into());
// Observe notifications about rendered frames if needed right before
@ -846,7 +846,7 @@ impl LayoutThread {
.maybe_observe_paint_time(self, epoch, is_contentful.0);
self.webrender_api
.send_display_list(compositor_info, builder.finalize().1);
.send_display_list(compositor_info, builder.end().1);
},
);
}
@ -1245,7 +1245,7 @@ impl LayoutThread {
// particular pipeline, so we need to tell WebRender about that.
flags.insert(HitTestFlags::POINT_RELATIVE_TO_PIPELINE_VIEWPORT);
let client_point = units::WorldPoint::from_untyped(client_point);
let client_point = units::DevicePoint::from_untyped(client_point);
let results = self.webrender_api.hit_test(
Some(self.id.to_webrender()),
client_point,
@ -1281,8 +1281,11 @@ impl LayoutThread {
.insert(state.scroll_id, state.scroll_offset);
let point = Point2D::new(-state.scroll_offset.x, -state.scroll_offset.y);
self.webrender_api
.send_scroll_node(units::LayoutPoint::from_untyped(point), state.scroll_id);
self.webrender_api.send_scroll_node(
self.id.to_webrender(),
units::LayoutPoint::from_untyped(point),
state.scroll_id,
);
}
fn set_scroll_states<'a, 'b>(

View file

@ -916,7 +916,7 @@ impl LayoutThread {
// particular pipeline, so we need to tell WebRender about that.
flags.insert(HitTestFlags::POINT_RELATIVE_TO_PIPELINE_VIEWPORT);
let client_point = units::WorldPoint::from_untyped(client_point);
let client_point = units::DevicePoint::from_untyped(client_point);
let results = self.webrender_api.hit_test(
Some(self.id.to_webrender()),
client_point,
@ -949,8 +949,11 @@ impl LayoutThread {
.insert(state.scroll_id, state.scroll_offset);
let point = Point2D::new(-state.scroll_offset.x, -state.scroll_offset.y);
self.webrender_api
.send_scroll_node(units::LayoutPoint::from_untyped(point), state.scroll_id);
self.webrender_api.send_scroll_node(
self.id.to_webrender(),
units::LayoutPoint::from_untyped(point),
state.scroll_id,
);
}
fn set_scroll_states<'a, 'b>(
@ -1028,6 +1031,7 @@ impl LayoutThread {
epoch.into(),
fragment_tree.root_scroll_sensitivity,
);
display_list.wr.begin();
// `dump_serialized_display_list` doesn't actually print anything. It sets up
// the display list for printing the serialized version when `finalize()` is called.
@ -1063,7 +1067,7 @@ impl LayoutThread {
if reflow_goal.needs_display() {
self.webrender_api
.send_display_list(display_list.compositor_info, display_list.wr.finalize().1);
.send_display_list(display_list.compositor_info, display_list.wr.end().1);
}
self.update_iframe_sizes(iframe_sizes);

View file

@ -1174,7 +1174,7 @@ impl Document {
kind,
text,
multiline,
DeviceIntRect::from_untyped(&rect),
DeviceIntRect::from_untyped(&rect.to_box2d()),
));
}
}

View file

@ -21,7 +21,7 @@ media-gstreamer = ["servo-media-gstreamer", "gstreamer"]
multiview = ["compositing/multiview", "constellation/multiview"]
native-bluetooth = ["bluetooth/native-bluetooth"]
no-wgl = ["canvas/no-wgl"]
no_static_freetype = ["webrender/no_static_freetype"]
dynamic_freetype = ["webrender/dynamic_freetype"]
profilemozjs = ["script/profilemozjs"]
refcell_backtrace = ["script/refcell_backtrace"]
webdriver = ["webdriver_server"]

View file

@ -88,7 +88,7 @@ use surfman::{GLApi, GLVersion};
#[cfg(target_os = "linux")]
use surfman::{NativeConnection, NativeContext};
use webrender::{RenderApiSender, ShaderPrecacheFlags};
use webrender_api::{DocumentId, FontInstanceKey, FontKey, ImageKey};
use webrender_api::{ColorF, DocumentId, FontInstanceKey, FontKey, FramePublishId, ImageKey};
use webrender_traits::{
WebrenderExternalImageHandlers, WebrenderExternalImageRegistry, WebrenderImageHandlerType,
};
@ -205,7 +205,7 @@ impl webrender_api::RenderNotifier for RenderNotifier {
_document_id: DocumentId,
_scrolled: bool,
composite_needed: bool,
_render_time_ns: Option<u64>,
_frame_publish_id: FramePublishId,
) {
self.compositor_proxy
.send(CompositorMsg::NewWebRenderFrameReady(composite_needed));
@ -310,7 +310,7 @@ where
let coordinates: compositing::windowing::EmbedderCoordinates = window.get_coordinates();
let device_pixel_ratio = coordinates.hidpi_factor.get();
let viewport_size = coordinates.viewport.size.to_f32() / device_pixel_ratio;
let viewport_size = coordinates.viewport.size().to_f32() / device_pixel_ratio;
let (mut webrender, webrender_api_sender) = {
let mut debug_flags = webrender::DebugFlags::empty();
@ -320,11 +320,17 @@ where
);
let render_notifier = Box::new(RenderNotifier::new(compositor_proxy.clone()));
webrender::Renderer::new(
let clear_color = servo_config::pref!(shell.background_color.rgba);
let clear_color = ColorF::new(
clear_color[0] as f32,
clear_color[1] as f32,
clear_color[2] as f32,
clear_color[3] as f32,
);
webrender::create_webrender_instance(
webrender_gl.clone(),
render_notifier,
webrender::RendererOptions {
device_pixel_ratio,
webrender::WebRenderOptions {
resource_override_path: opts.shaders_dir.clone(),
enable_aa: !opts.debug.disable_text_antialiasing,
debug_flags: debug_flags,
@ -336,7 +342,7 @@ where
enable_subpixel_aa: pref!(gfx.subpixel_text_antialiasing.enabled) &&
!opts.debug.disable_subpixel_text_antialiasing,
allow_texture_swizzling: pref!(gfx.texture_swizzling.enabled),
clear_color: None,
clear_color,
..Default::default()
},
None,
@ -345,7 +351,7 @@ where
};
let webrender_api = webrender_api_sender.create_api();
let webrender_document = webrender_api.add_document(coordinates.get_viewport().size);
let webrender_document = webrender_api.add_document(coordinates.get_viewport().size());
// Important that this call is done in a single-threaded fashion, we
// can't defer it after `create_constellation` has started.
@ -845,7 +851,7 @@ where
}
pub fn pinch_zoom_level(&self) -> f32 {
self.compositor.pinch_zoom_level()
self.compositor.pinch_zoom_level().get()
}
pub fn setup_logging(&self) {

View file

@ -7,9 +7,17 @@
use embedder_traits::Cursor;
use serde::{Deserialize, Serialize};
use webrender_api::units::{LayoutSize, LayoutVector2D};
use webrender_api::{
Epoch, ExternalScrollId, PipelineId, ScrollLocation, ScrollSensitivity, SpatialId,
};
use webrender_api::{Epoch, ExternalScrollId, PipelineId, ScrollLocation, SpatialId};
/// The scroll sensitivity of a scroll node ie whether it can be scrolled due to input event and
/// script events or only script events.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum ScrollSensitivity {
/// This node can be scrolled by input and script events.
ScriptAndInputEvents,
/// This node can only be scrolled by script events.
Script,
}
/// Information that Servo keeps alongside WebRender display items
/// in order to add more context to hit test results.
@ -208,6 +216,25 @@ impl ScrollTree {
parent.and_then(|parent| self.scroll_node_or_ancestor(&parent, scroll_location))
}
/// Given an [`ExternalScrollId`] and an offset, update the scroll offset of the scroll node
/// with the given id.
pub fn set_scroll_offsets_for_node_with_external_scroll_id(
&mut self,
external_scroll_id: ExternalScrollId,
offset: LayoutVector2D,
) -> bool {
for node in self.nodes.iter_mut() {
match node.scroll_info {
Some(ref mut scroll_info) if scroll_info.external_id == external_scroll_id => {
scroll_info.offset = offset;
return true;
},
_ => {},
}
}
false
}
}
/// A data structure which stores compositor-side information about

View file

@ -56,7 +56,7 @@ use servo_atoms::Atom;
use servo_url::{ImmutableOrigin, ServoUrl};
use style_traits::{CSSPixel, SpeculativePainter};
use webgpu::identity::WebGPUMsg;
use webrender_api::units::{DeviceIntSize, DevicePixel, LayoutPixel, LayoutPoint, WorldPoint};
use webrender_api::units::{DeviceIntSize, DevicePixel, DevicePoint, LayoutPixel, LayoutPoint};
use webrender_api::{
BuiltDisplayList, BuiltDisplayListDescriptor, DocumentId, ExternalImageData, ExternalScrollId,
HitTestFlags, ImageData, ImageDescriptor, ImageKey, PipelineId as WebRenderPipelineId,
@ -1121,7 +1121,7 @@ pub enum ScriptToCompositorMsg {
/// Inform WebRender of the existence of this pipeline.
SendInitialTransaction(WebRenderPipelineId),
/// Perform a scroll operation.
SendScrollNode(LayoutPoint, ExternalScrollId),
SendScrollNode(WebRenderPipelineId, LayoutPoint, ExternalScrollId),
/// Inform WebRender of a new display list for the given pipeline.
SendDisplayList {
/// The [CompositorDisplayListInfo] that describes the display list being sent.
@ -1135,7 +1135,7 @@ pub enum ScriptToCompositorMsg {
/// the provided channel sender.
HitTest(
Option<WebRenderPipelineId>,
WorldPoint,
DevicePoint,
HitTestFlags,
IpcSender<Vec<CompositorHitTestResult>>,
),
@ -1167,11 +1167,17 @@ impl WebrenderIpcSender {
}
/// Perform a scroll operation.
pub fn send_scroll_node(&self, point: LayoutPoint, scroll_id: ExternalScrollId) {
if let Err(e) = self
.0
.send(ScriptToCompositorMsg::SendScrollNode(point, scroll_id))
{
pub fn send_scroll_node(
&self,
pipeline_id: WebRenderPipelineId,
point: LayoutPoint,
scroll_id: ExternalScrollId,
) {
if let Err(e) = self.0.send(ScriptToCompositorMsg::SendScrollNode(
pipeline_id,
point,
scroll_id,
)) {
warn!("Error sending scroll node: {}", e);
}
}
@ -1192,8 +1198,14 @@ impl WebrenderIpcSender {
warn!("Error sending display list: {}", e);
}
if let Err(e) = display_list_sender.send(&display_list_data) {
warn!("Error sending display data: {}", e);
if let Err(error) = display_list_sender.send(&display_list_data.items_data) {
warn!("Error sending display list items: {}", error);
}
if let Err(error) = display_list_sender.send(&display_list_data.cache_data) {
warn!("Error sending display list cache data: {}", error);
}
if let Err(error) = display_list_sender.send(&display_list_data.spatial_tree) {
warn!("Error sending display spatial tree: {}", error);
}
}
@ -1202,7 +1214,7 @@ impl WebrenderIpcSender {
pub fn hit_test(
&self,
pipeline: Option<WebRenderPipelineId>,
point: WorldPoint,
point: DevicePoint,
flags: HitTestFlags,
) -> Vec<CompositorHitTestResult> {
let (sender, receiver) = ipc::channel().unwrap();

View file

@ -3,9 +3,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use euclid::Size2D;
use script_traits::compositor::{ScrollTree, ScrollTreeNodeId, ScrollableNodeInfo};
use script_traits::compositor::{
ScrollSensitivity, ScrollTree, ScrollTreeNodeId, ScrollableNodeInfo,
};
use webrender_api::units::LayoutVector2D;
use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, ScrollSensitivity, SpatialId};
use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, SpatialId};
fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId {
let pipeline_id = PipelineId(0, 0);

View file

@ -9,9 +9,7 @@ use std::sync::{Arc, Mutex};
use euclid::default::Size2D;
use webrender_api::units::TexelRect;
use webrender_api::{
ExternalImage, ExternalImageHandler, ExternalImageId, ExternalImageSource, ImageRendering,
};
use webrender_api::{ExternalImage, ExternalImageHandler, ExternalImageId, ExternalImageSource};
/// This trait is used as a bridge between the different GL clients
/// in Servo that handles WebRender ExternalImages and the WebRender
@ -108,12 +106,7 @@ impl ExternalImageHandler for WebrenderExternalImageHandlers {
/// image content.
/// The WR client should not change the image content until the
/// unlock() call.
fn lock(
&mut self,
key: ExternalImageId,
_channel_index: u8,
_rendering: ImageRendering,
) -> ExternalImage {
fn lock(&mut self, key: ExternalImageId, _channel_index: u8) -> ExternalImage {
let external_images = self.external_images.lock().unwrap();
let handler_type = external_images
.get(&key)

View file

@ -44,7 +44,7 @@ js_backtrace = ["libservo/js_backtrace"]
max_log_level = ["log/release_max_level_info"]
media-gstreamer = ["libservo/media-gstreamer"]
native-bluetooth = ["libservo/native-bluetooth"]
no_static_freetype = ["libservo/no_static_freetype"]
dynamic_freetype = ["libservo/dynamic_freetype"]
no-wgl = ["libservo/no-wgl"]
profilemozjs = ["libservo/profilemozjs"]
refcell_backtrace = ["libservo/refcell_backtrace"]

View file

@ -891,7 +891,7 @@ impl WindowMethods for ServoWindowCallbacks {
fn get_coordinates(&self) -> EmbedderCoordinates {
let coords = self.coordinates.borrow();
EmbedderCoordinates {
viewport: coords.viewport,
viewport: coords.viewport.to_box2d(),
framebuffer: coords.framebuffer,
window: (coords.viewport.size, Point2D::new(0, 0)),
screen: coords.viewport.size,

View file

@ -527,12 +527,12 @@ impl WindowMethods for Window {
let viewport_size = inner_size - Size2D::from_lengths(Length::zero(), toolbar_height);
let viewport_origin = DeviceIntPoint::zero(); // bottom left
let viewport = DeviceIntRect::new(viewport_origin, viewport_size.to_i32());
let viewport = DeviceIntRect::from_origin_and_size(viewport_origin, viewport_size.to_i32());
let screen = self.screen_size.to_i32();
EmbedderCoordinates {
viewport,
framebuffer: viewport.size,
framebuffer: viewport.size(),
window: (window_size, window_origin),
screen,
// FIXME: Winit doesn't have API for available size. Fallback to screen size

View file

@ -161,7 +161,7 @@ impl WindowMethods for Window {
.unwrap_or(None)
.map(|info| Size2D::from_untyped(info.size))
.unwrap_or(Size2D::new(0, 0));
let viewport = DeviceIntRect::new(Point2D::zero(), size);
let viewport = DeviceIntRect::from_origin_and_size(Point2D::zero(), size);
EmbedderCoordinates {
viewport,
framebuffer: size,

View file

@ -68,6 +68,10 @@ packages = [
"phf_codegen",
"phf_generator",
"phf_shared",
# These can be removed once winit, font-kit, etc are upgraded
"core-graphics",
"core-text",
]
# Files that are ignored for all tidy and lint checks.
files = [

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blended-element-interposed.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blended-element-overflow-hidden-and-border-radius.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blended-element-with-transparent-pixels.html]
expected: FAIL

View file

@ -1,3 +0,0 @@
[mix-blend-mode-blended-with-3D-transform.html]
type: reftest
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blended-with-transform-and-perspective.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blending-with-sibling.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-canvas-parent.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-canvas-sibling.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-iframe-parent.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-iframe-sibling.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-image.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-mask.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-overflowing-child-of-blended-element.html]
expected: FAIL

View file

@ -1,3 +0,0 @@
[mix-blend-mode-parent-element-overflow-hidden-and-border-radius.html]
type: reftest
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-parent-element-overflow-scroll-blended-position-fixed.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-parent-with-3D-transform.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-script.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-sibling-with-3D-transform.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-simple.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-stacking-context-creates-isolation.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[root-element-blend-mode.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-image-repeat-repeat-001.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-image-slice-fill-001.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-image-slice-fill-002.html]
expected: FAIL

View file

@ -1,3 +0,0 @@
[transform-3d-rotateY-stair-above-001.xht]
type: reftest
expected: FAIL

View file

@ -1,4 +1,3 @@
[transform-3d-rotateY-stair-below-001.xht]
type: reftest
expected: FAIL
bug: https://github.com/servo/webrender/issues/1776

View file

@ -1,2 +0,0 @@
[transform-percent-008.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-table-009.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-table-010.html]
expected: FAIL

View file

@ -1,3 +0,0 @@
[transforms-skewX.html]
type: reftest
expected: FAIL

View file

@ -1,3 +0,0 @@
[transforms-skewY.html]
type: reftest
expected: FAIL

View file

@ -6,3 +6,5 @@
[transformed element at x,y]
expected: FAIL
[no hit target at x,y]
expected: FAIL

View file

@ -1,2 +0,0 @@
[filters-drop-shadow-003.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blended-element-interposed.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blended-element-overflow-hidden-and-border-radius.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blended-element-with-transparent-pixels.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blended-with-3D-transform.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blended-with-transform-and-perspective.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-blending-with-sibling.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-canvas-parent.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-canvas-sibling.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-iframe-parent.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-iframe-sibling.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-image.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-intermediate-element-overflow-hidden-and-border-radius.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-mask.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-overflowing-child-of-blended-element.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-parent-element-overflow-scroll-blended-position-fixed.html]
expected: FAIL

View file

@ -1,2 +1,3 @@
[mix-blend-mode-parent-with-3D-transform.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-script.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-sibling-with-3D-transform.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-simple.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[mix-blend-mode-stacking-context-creates-isolation.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[root-element-blend-mode.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[background-repeat-space.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[perspective-split-by-zero-w.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[transform-3d-rotateY-stair-above-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[transform-3d-rotateY-stair-below-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[transform-percent-008.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-table-009.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-table-010.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[transform-table-011.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[transforms-skewX.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[transforms-skewY.html]
expected: FAIL

View file

@ -4,3 +4,6 @@
[transformed element at x,y]
expected: FAIL
[no hit target at x,y]
expected: FAIL

View file

@ -0,0 +1,2 @@
[drop-shadow-clipped-001.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[filters-drop-shadow-003.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[will-change-blur-filter-under-clip.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[pixel_snapping_position_a.html]
expected: FAIL

Some files were not shown because too many files have changed in this diff Show more