diff options
author | Martin Robinson <mrobinson@igalia.com> | 2024-12-10 09:54:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-10 08:54:42 +0000 |
commit | 2b8a8f74985300e7a2407384f60fc304922a05a5 (patch) | |
tree | d9fc1c5a94a0f6eb1363f342ee2dfb5d738b8b58 /components/script/dom | |
parent | bc2def0582ff374d72633f2a06b47842483bac47 (diff) | |
download | servo-2b8a8f74985300e7a2407384f60fc304922a05a5.tar.gz servo-2b8a8f74985300e7a2407384f60fc304922a05a5.zip |
script: Do not prioritize *update-the-rendering* in `ScriptThread` message loop (#34539)
Instead run *update the rendering* at the end of every process of
gathering messages sent to the `ScriptThread`. This ensures that the
thread is in a consistent state when the update is finally run and
prevents running more than one instance of *update the rendering* per
spin of the message loop.
In addition:
- Move the *run the resize steps* implementation to `Window` and ensure
that the realm is active when it is run.
- Profile the queueing of the resize message instead of handling it. I
think this makes more sense as the profiling seems to be targeting
message handling and not *update the rendering*. Additionally, it's
difficult to profile from the context of `Window`.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/window.rs | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index f903aa87a57..cfe92775043 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -117,7 +117,7 @@ use crate::dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration use crate::dom::customelementregistry::CustomElementRegistry; use crate::dom::document::{AnimationFrameCallback, Document, ReflowTriggerCondition}; use crate::dom::element::Element; -use crate::dom::event::{Event, EventStatus}; +use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::hashchangeevent::HashChangeEvent; @@ -136,6 +136,7 @@ use crate::dom::screen::Screen; use crate::dom::selection::Selection; use crate::dom::storage::Storage; use crate::dom::testrunner::TestRunner; +use crate::dom::types::UIEvent; use crate::dom::webglrenderingcontext::WebGLCommandSender; #[cfg(feature = "webgpu")] use crate::dom::webgpu::identityhub::IdentityHub; @@ -144,7 +145,7 @@ use crate::dom::worklet::Worklet; use crate::dom::workletglobalscope::WorkletGlobalScopeType; use crate::layout_image::fetch_image_for_layout; use crate::microtask::MicrotaskQueue; -use crate::realms::InRealm; +use crate::realms::{enter_realm, InRealm}; use crate::script_runtime::{ CanGc, CommonScriptMsg, JSContext, Runtime, ScriptChan, ScriptPort, ScriptThreadEventCategory, }; @@ -2482,9 +2483,52 @@ impl Window { self.parent_info.is_none() } + /// An implementation of: + /// <https://drafts.csswg.org/cssom-view/#document-run-the-resize-steps> + /// + /// Returns true if there were any pending resize events. + pub(crate) fn run_the_resize_steps(&self, can_gc: CanGc) -> bool { + let Some((new_size, size_type)) = self.take_unhandled_resize_event() else { + return false; + }; + + if self.window_size() == new_size { + return false; + } + + let _realm = enter_realm(self); + debug!( + "Resizing Window for pipeline {:?} from {:?} to {new_size:?}", + self.pipeline_id(), + self.window_size(), + ); + self.set_window_size(new_size); + + // TODO: This should just trigger a pending reflow instead of forcing one now. + self.force_reflow(ReflowGoal::Full, ReflowReason::WindowResize, None); + + // http://dev.w3.org/csswg/cssom-view/#resizing-viewports + if size_type == WindowSizeType::Resize { + let uievent = UIEvent::new( + self, + DOMString::from("resize"), + EventBubbles::DoesNotBubble, + EventCancelable::NotCancelable, + Some(self), + 0i32, + can_gc, + ); + uievent.upcast::<Event>().fire(self.upcast(), can_gc); + } + + true + } + /// Evaluate media query lists and report changes /// <https://drafts.csswg.org/cssom-view/#evaluate-media-queries-and-report-changes> pub fn evaluate_media_queries_and_report_changes(&self, can_gc: CanGc) { + let _realm = enter_realm(self); + rooted_vec!(let mut mql_list); self.media_query_lists.for_each(|mql| { if let MediaQueryListMatchState::Changed = mql.evaluate_changes() { |