mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
libservo: Let libservo manage compositor message reception (#37372)
Instead of receiving message in the compositor during a spin of the Servo event loop, receive them in libservo and then send them to the compositor. This is preparation for allowing libservo to wait for messages without spinning the main application event loop. This is useful for two situations: 1. Allowing a blocking shutdown mode, which can be used to ensure clean shutdown, regardless of how the API is used. 2. Allowing unit tests to wait until message are received instead of using a timer like they do now. Testing: This should not change behavior and is thus covered by existing tests. Fixes: This is part of #37371. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
15eadb56a4
commit
048d4a2a5a
2 changed files with 32 additions and 20 deletions
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cell::{Cell, Ref, RefCell};
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::create_dir_all;
|
||||
|
@ -1651,40 +1651,45 @@ impl IOCompositor {
|
|||
);
|
||||
}
|
||||
|
||||
/// Get the message receiver for this [`IOCompositor`].
|
||||
pub fn receiver(&self) -> Ref<Receiver<CompositorMsg>> {
|
||||
Ref::map(self.global.borrow(), |global| &global.compositor_receiver)
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
|
||||
)]
|
||||
pub fn receive_messages(&mut self) {
|
||||
pub fn handle_messages(&mut self, mut messages: Vec<CompositorMsg>) {
|
||||
// Check for new messages coming from the other threads in the system.
|
||||
let mut compositor_messages = vec![];
|
||||
let mut found_recomposite_msg = false;
|
||||
while let Ok(msg) = self.global.borrow_mut().compositor_receiver.try_recv() {
|
||||
match msg {
|
||||
messages.retain(|message| {
|
||||
match message {
|
||||
CompositorMsg::NewWebRenderFrameReady(..) if found_recomposite_msg => {
|
||||
// Only take one of duplicate NewWebRendeFrameReady messages, but do subtract
|
||||
// one frame from the pending frames.
|
||||
self.pending_frames -= 1;
|
||||
false
|
||||
},
|
||||
CompositorMsg::NewWebRenderFrameReady(..) => {
|
||||
found_recomposite_msg = true;
|
||||
compositor_messages.push(msg);
|
||||
|
||||
// Process all pending events
|
||||
// FIXME: Shouldn't `webview_frame_ready` be stored globally and why can't `pending_frames`
|
||||
// be used here?
|
||||
self.webview_renderers.iter().for_each(|webview| {
|
||||
webview.dispatch_pending_point_input_events();
|
||||
webview.webrender_frame_ready.set(true);
|
||||
});
|
||||
|
||||
true
|
||||
},
|
||||
_ => compositor_messages.push(msg),
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
if found_recomposite_msg {
|
||||
// Process all pending events
|
||||
self.webview_renderers.iter().for_each(|webview| {
|
||||
webview.dispatch_pending_point_input_events();
|
||||
webview.webrender_frame_ready.set(true);
|
||||
});
|
||||
}
|
||||
|
||||
for msg in compositor_messages {
|
||||
self.handle_browser_message(msg);
|
||||
});
|
||||
|
||||
for message in messages {
|
||||
self.handle_browser_message(message);
|
||||
if self.global.borrow().shutdown_state() == ShutdownState::FinishedShuttingDown {
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue