mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
script: Consolidate step 22 of per-Document
rendering update (#37703)
The parts of step 22 were a bit scattered throughout the codebase, so this change moves them all to a single method which does three things: 1. Update all animating images 2. Flush all dirty canvases (2D, WebGL, and WebGPU) 3. Calls reflow on the `Document` Testing: This shouldn't change behavior in any major way so it should be covered by existing WPT tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
152eb63fb3
commit
f745bad37d
3 changed files with 40 additions and 57 deletions
|
@ -42,7 +42,7 @@ use hyper_serde::Serde;
|
|||
use ipc_channel::ipc;
|
||||
use js::rust::{HandleObject, HandleValue};
|
||||
use keyboard_types::{Code, Key, KeyState, Modifiers};
|
||||
use layout_api::{PendingRestyle, TrustedNodeAddress, node_id_from_scroll_id};
|
||||
use layout_api::{PendingRestyle, ReflowGoal, TrustedNodeAddress, node_id_from_scroll_id};
|
||||
use metrics::{InteractiveFlag, InteractiveWindow, ProgressiveWebMetrics};
|
||||
use net_traits::CookieSource::NonHTTP;
|
||||
use net_traits::CoreResourceMsg::{GetCookiesForUrl, SetCookiesForUrl};
|
||||
|
@ -3495,30 +3495,6 @@ impl Document {
|
|||
.or_insert_with(|| Dom::from_ref(context));
|
||||
}
|
||||
|
||||
pub(crate) fn flush_dirty_webgl_canvases(&self) {
|
||||
let dirty_context_ids: Vec<_> = self
|
||||
.dirty_webgl_contexts
|
||||
.borrow_mut()
|
||||
.drain()
|
||||
.filter(|(_, context)| context.onscreen())
|
||||
.map(|(id, _)| id)
|
||||
.collect();
|
||||
|
||||
if dirty_context_ids.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
let mut time = 0;
|
||||
let (sender, receiver) = webgl::webgl_channel().unwrap();
|
||||
self.window
|
||||
.webgl_chan()
|
||||
.expect("Where's the WebGL channel?")
|
||||
.send(WebGLMsg::SwapBuffers(dirty_context_ids, sender, time))
|
||||
.unwrap();
|
||||
receiver.recv().unwrap();
|
||||
}
|
||||
|
||||
pub(crate) fn add_dirty_2d_canvas(&self, context: &CanvasRenderingContext2D) {
|
||||
self.dirty_2d_contexts
|
||||
.borrow_mut()
|
||||
|
@ -3526,28 +3502,54 @@ impl Document {
|
|||
.or_insert_with(|| Dom::from_ref(context));
|
||||
}
|
||||
|
||||
pub(crate) fn flush_dirty_2d_canvases(&self) {
|
||||
self.dirty_2d_contexts
|
||||
.borrow_mut()
|
||||
.drain()
|
||||
.filter(|(_, context)| context.onscreen())
|
||||
.for_each(|(_, context)| context.update_rendering());
|
||||
}
|
||||
|
||||
#[cfg(feature = "webgpu")]
|
||||
pub(crate) fn webgpu_contexts(&self) -> WebGPUContextsMap {
|
||||
self.webgpu_contexts.clone()
|
||||
}
|
||||
|
||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||
#[cfg(feature = "webgpu")]
|
||||
pub(crate) fn update_rendering_of_webgpu_canvases(&self) {
|
||||
/// An implementation of step 22 from
|
||||
/// <https://html.spec.whatwg.org/multipage/#update-the-rendering>:
|
||||
///
|
||||
// > Step 22: For each doc of docs, update the rendering or user interface of
|
||||
// > doc and its node navigable to reflect the current state.
|
||||
//
|
||||
// Returns true if a reflow occured.
|
||||
pub(crate) fn update_the_rendering(&self, can_gc: CanGc) -> bool {
|
||||
self.update_animating_images();
|
||||
|
||||
// All dirty canvases are flushed before updating the rendering.
|
||||
#[cfg(feature = "webgpu")]
|
||||
self.webgpu_contexts
|
||||
.borrow_mut()
|
||||
.iter()
|
||||
.filter_map(|(_, context)| context.root())
|
||||
.filter(|context| context.onscreen())
|
||||
.for_each(|context| context.update_rendering());
|
||||
|
||||
self.dirty_2d_contexts
|
||||
.borrow_mut()
|
||||
.drain()
|
||||
.filter(|(_, context)| context.onscreen())
|
||||
.for_each(|(_, context)| context.update_rendering());
|
||||
|
||||
let dirty_webgl_context_ids: Vec<_> = self
|
||||
.dirty_webgl_contexts
|
||||
.borrow_mut()
|
||||
.drain()
|
||||
.filter(|(_, context)| context.onscreen())
|
||||
.map(|(id, _)| id)
|
||||
.collect();
|
||||
if !dirty_webgl_context_ids.is_empty() {
|
||||
let (sender, receiver) = webgl::webgl_channel().unwrap();
|
||||
self.window
|
||||
.webgl_chan()
|
||||
.expect("Where's the WebGL channel?")
|
||||
.send(WebGLMsg::SwapBuffers(dirty_webgl_context_ids, sender, 0))
|
||||
.unwrap();
|
||||
receiver.recv().unwrap();
|
||||
}
|
||||
|
||||
self.window().reflow(ReflowGoal::UpdateTheRendering, can_gc)
|
||||
}
|
||||
|
||||
pub(crate) fn id_map(&self) -> Ref<HashMapTracedValues<Atom, Vec<Dom<Element>>>> {
|
||||
|
|
|
@ -2173,17 +2173,8 @@ impl Window {
|
|||
let document = self.Document();
|
||||
|
||||
let stylesheets_changed = document.flush_stylesheets_for_reflow();
|
||||
|
||||
// If this reflow is for display, ensure webgl canvases are composited with
|
||||
// up-to-date contents.
|
||||
let for_display = reflow_goal.needs_display();
|
||||
if for_display {
|
||||
document.flush_dirty_webgl_canvases();
|
||||
document.flush_dirty_2d_canvases();
|
||||
}
|
||||
|
||||
let pending_restyles = document.drain_pending_restyles();
|
||||
|
||||
let dirty_root = document
|
||||
.take_dirty_root()
|
||||
.filter(|_| !stylesheets_changed)
|
||||
|
|
|
@ -68,7 +68,7 @@ use js::jsapi::{
|
|||
};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::ParentRuntime;
|
||||
use layout_api::{LayoutConfig, LayoutFactory, ReflowGoal, ScriptThreadFactory};
|
||||
use layout_api::{LayoutConfig, LayoutFactory, ScriptThreadFactory};
|
||||
use media::WindowGLContext;
|
||||
use metrics::MAX_TASK_NS;
|
||||
use net_traits::image_cache::{ImageCache, ImageCacheResponseMessage};
|
||||
|
@ -1328,19 +1328,9 @@ impl ScriptThread {
|
|||
|
||||
// TODO: Mark paint timing from https://w3c.github.io/paint-timing.
|
||||
|
||||
// Update the rendering of those does not require a reflow.
|
||||
// e.g. animated images.
|
||||
document.update_animating_images();
|
||||
|
||||
#[cfg(feature = "webgpu")]
|
||||
document.update_rendering_of_webgpu_canvases();
|
||||
|
||||
// > Step 22: For each doc of docs, update the rendering or user interface of
|
||||
// > doc and its node navigable to reflect the current state.
|
||||
saw_any_reflows = document
|
||||
.window()
|
||||
.reflow(ReflowGoal::UpdateTheRendering, can_gc) ||
|
||||
saw_any_reflows;
|
||||
saw_any_reflows = document.update_the_rendering(can_gc) || saw_any_reflows;
|
||||
|
||||
// TODO: Process top layer removals according to
|
||||
// https://drafts.csswg.org/css-position-4/#process-top-layer-removals.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue