layout: Remove LayoutRPC and query layout via the Layout trait (#31937)

Instead of the tricky `LayoutRPC` interface, query layout using the
`Layout` trait. This means that now queries will requires calling layout
and then running the query. During layout an enum is used to indicate
what kind of layout is necessary.

This change also removes the mutex-locked `rw_data` from both layout
threads. It's no longer necessary since layout runs synchronously. The
one downside here is that for resolved style queries, we now have to
create two StyleContexts. One for layout and one for the query itself.
The creation of this context should not be very expensive though.

`LayoutRPC` used to be necessary because layout used to run
asynchronously from script, but that no longer happens. With this
change, it becomes possible to safely pass nodes to layout from script
-- a cleanup that can happen in a followup change.
This commit is contained in:
Martin Robinson 2024-03-29 17:25:47 +01:00 committed by GitHub
parent 07391e346b
commit b7d089930e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 667 additions and 1174 deletions

View file

@ -9,7 +9,6 @@
#![deny(unsafe_code)]
pub mod message;
pub mod rpc;
pub mod wrapper_traits;
use std::any::Any;
@ -17,15 +16,19 @@ use std::borrow::Cow;
use std::sync::atomic::AtomicIsize;
use std::sync::Arc;
use app_units::Au;
use atomic_refcell::AtomicRefCell;
use canvas_traits::canvas::{CanvasId, CanvasMsg};
use euclid::default::{Point2D, Rect};
use euclid::Size2D;
use gfx::font_cache_thread::FontCacheThread;
use gfx_traits::Epoch;
use ipc_channel::ipc::IpcSender;
use libc::c_void;
use malloc_size_of_derive::MallocSizeOf;
use message::NodesFromPointQueryType;
use metrics::PaintTimeMetrics;
use msg::constellation_msg::PipelineId;
use msg::constellation_msg::{BrowsingContextId, PipelineId};
use net_traits::image_cache::{ImageCache, PendingImageId};
use profile_traits::time;
use script_traits::{
@ -34,9 +37,15 @@ use script_traits::{
};
use servo_arc::Arc as ServoArc;
use servo_url::{ImmutableOrigin, ServoUrl};
use style::animation::DocumentAnimationSet;
use style::data::ElementData;
use style::dom::OpaqueNode;
use style::properties::style_structs::Font;
use style::properties::PropertyId;
use style::selector_parser::PseudoElement;
use style::stylesheets::Stylesheet;
use webrender_api::ImageKey;
use style_traits::CSSPixel;
use webrender_api::{ExternalScrollId, ImageKey};
#[derive(MallocSizeOf)]
pub struct StyleData {
@ -195,11 +204,6 @@ pub trait Layout {
/// Handle a a single mesasge from the FontCacheThread.
fn handle_font_cache_msg(&mut self);
/// Return the interface used for scipt queries.
/// TODO: Make this part of the the Layout interface itself now that the
/// layout thread has been removed.
fn rpc(&self) -> Box<dyn rpc::LayoutRPC>;
/// Whether or not this layout is waiting for fonts from loaded stylesheets to finish loading.
fn waiting_for_web_fonts_to_load(&self) -> bool;
@ -221,6 +225,39 @@ pub trait Layout {
/// Removes a stylesheet from the Layout.
fn remove_stylesheet(&mut self, stylesheet: ServoArc<Stylesheet>);
fn query_content_box(&self, node: OpaqueNode) -> Option<Rect<Au>>;
fn query_content_boxes(&self, node: OpaqueNode) -> Vec<Rect<Au>>;
fn query_client_rect(&self, node: OpaqueNode) -> Rect<i32>;
fn query_element_inner_text(&self, node: TrustedNodeAddress) -> String;
fn query_inner_window_dimension(
&self,
context: BrowsingContextId,
) -> Option<Size2D<f32, CSSPixel>>;
fn query_nodes_from_point(
&self,
point: Point2D<f32>,
query_type: NodesFromPointQueryType,
) -> Vec<UntrustedNodeAddress>;
fn query_offset_parent(&self, node: OpaqueNode) -> OffsetParentResponse;
fn query_resolved_style(
&self,
node: TrustedNodeAddress,
pseudo: Option<PseudoElement>,
property_id: PropertyId,
animations: DocumentAnimationSet,
animation_timeline_value: f64,
) -> String;
fn query_resolved_font_style(
&self,
node: TrustedNodeAddress,
value: &str,
animations: DocumentAnimationSet,
animation_timeline_value: f64,
) -> Option<ServoArc<Font>>;
fn query_scroll_id(&self, node: TrustedNodeAddress) -> ExternalScrollId;
fn query_scrolling_area(&self, node: Option<OpaqueNode>) -> Rect<i32>;
fn query_text_indext(&self, node: OpaqueNode, point: Point2D<f32>) -> Option<usize>;
}
/// This trait is part of `script_layout_interface` because it depends on both `script_traits`
@ -236,3 +273,8 @@ pub trait ScriptThreadFactory {
user_agent: Cow<'static, str>,
);
}
#[derive(Clone, Default)]
pub struct OffsetParentResponse {
pub node_address: Option<UntrustedNodeAddress>,
pub rect: Rect<Au>,
}