mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
libservo: Don't bounce ready-to-present frame notifications to the Constellation (#35369)
Instead of telling the Constellation to tell the embedder that new frames are ready, have the compositor tell the embedder directly. This should reduce frame latency. Now, after processing compositor updates, run any pending `WebView::new_frame_ready` delegate methods. This change also removes the `refresh` call from the Java interface as that was the only other place that the compositor was rendering the WebRender scene outside of event looping spinning. This `refresh` call was completely unused. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
8c46749740
commit
71bfd2d13f
11 changed files with 26 additions and 63 deletions
|
@ -3,6 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::OnceCell;
|
||||
use std::collections::hash_set::Iter;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::{create_dir_all, File};
|
||||
|
@ -212,8 +213,9 @@ pub struct IOCompositor {
|
|||
/// The number of frames pending to receive from WebRender.
|
||||
pending_frames: usize,
|
||||
|
||||
/// Waiting for external code to call present.
|
||||
waiting_on_present: bool,
|
||||
/// A list of [`WebViewId`]s of WebViews that have new frames ready that are waiting to
|
||||
/// be presented.
|
||||
webviews_waiting_on_present: FnvHashSet<WebViewId>,
|
||||
|
||||
/// The [`Instant`] of the last animation tick, used to avoid flooding the Constellation and
|
||||
/// ScriptThread with a deluge of animation ticks.
|
||||
|
@ -403,7 +405,7 @@ impl IOCompositor {
|
|||
exit_after_load,
|
||||
convert_mouse_to_touch,
|
||||
pending_frames: 0,
|
||||
waiting_on_present: false,
|
||||
webviews_waiting_on_present: Default::default(),
|
||||
last_animation_tick: Instant::now(),
|
||||
version_string,
|
||||
};
|
||||
|
@ -424,6 +426,10 @@ impl IOCompositor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn webviews_waiting_on_present(&self) -> Iter<'_, WebViewId> {
|
||||
self.webviews_waiting_on_present.iter()
|
||||
}
|
||||
|
||||
fn update_cursor(&mut self, result: CompositorHitTestResult) {
|
||||
let cursor = match result.cursor {
|
||||
Some(cursor) if cursor != self.cursor => cursor,
|
||||
|
@ -1976,7 +1982,7 @@ impl IOCompositor {
|
|||
target: CompositeTarget,
|
||||
page_rect: Option<Rect<f32, CSSPixel>>,
|
||||
) -> Result<Option<Image>, UnableToComposite> {
|
||||
if self.waiting_on_present {
|
||||
if !self.webviews_waiting_on_present.is_empty() {
|
||||
debug!("tried to composite while waiting on present");
|
||||
return Err(UnableToComposite::NotReadyToPaintImage(
|
||||
NotReadyToPaint::WaitingOnConstellation,
|
||||
|
@ -2146,15 +2152,11 @@ impl IOCompositor {
|
|||
let _span =
|
||||
tracing::trace_span!("ConstellationMsg::ReadyToPresent", servo_profiling = true)
|
||||
.entered();
|
||||
|
||||
// Notify embedder that servo is ready to present.
|
||||
// Embedder should call `present` to tell compositor to continue rendering.
|
||||
self.waiting_on_present = true;
|
||||
let webview_ids = self.webviews.painting_order().map(|(&id, _)| id);
|
||||
let msg = ConstellationMsg::ReadyToPresent(webview_ids.collect());
|
||||
if let Err(e) = self.constellation_chan.send(msg) {
|
||||
warn!("Sending event to constellation failed ({:?}).", e);
|
||||
}
|
||||
|
||||
self.webviews_waiting_on_present
|
||||
.extend(self.webviews.painting_order().map(|(&id, _)| id));
|
||||
self.composition_request = CompositionRequest::NoCompositingNecessary;
|
||||
|
||||
self.process_animations(true);
|
||||
|
@ -2245,7 +2247,7 @@ impl IOCompositor {
|
|||
let _span =
|
||||
tracing::trace_span!("Compositor Present Surface", servo_profiling = true).entered();
|
||||
self.rendering_context.present();
|
||||
self.waiting_on_present = false;
|
||||
self.webviews_waiting_on_present.clear();
|
||||
}
|
||||
|
||||
fn composite_if_necessary(&mut self, reason: CompositingReason) {
|
||||
|
|
|
@ -1459,16 +1459,6 @@ where
|
|||
FromCompositorMsg::SetWebViewThrottled(webview_id, throttled) => {
|
||||
self.set_webview_throttled(webview_id, throttled);
|
||||
},
|
||||
FromCompositorMsg::ReadyToPresent(webview_ids) => {
|
||||
#[cfg(feature = "tracing")]
|
||||
let _span = tracing::trace_span!(
|
||||
"FromCompositorMsg::ReadyToPresent",
|
||||
servo_profiling = true,
|
||||
)
|
||||
.entered();
|
||||
self.embedder_proxy
|
||||
.send(EmbedderMsg::ReadyToPresent(webview_ids));
|
||||
},
|
||||
FromCompositorMsg::Gamepad(gamepad_event) => {
|
||||
self.handle_gamepad_msg(gamepad_event);
|
||||
},
|
||||
|
|
|
@ -90,7 +90,6 @@ mod from_compositor {
|
|||
Self::MediaSessionAction(_) => target!("MediaSessionAction"),
|
||||
Self::SetWebViewThrottled(_, _) => target!("SetWebViewThrottled"),
|
||||
Self::IMEDismissed => target!("IMEDismissed"),
|
||||
Self::ReadyToPresent(..) => target!("ReadyToPresent"),
|
||||
Self::Gamepad(..) => target!("Gamepad"),
|
||||
Self::Clipboard(..) => target!("Clipboard"),
|
||||
}
|
||||
|
@ -248,7 +247,6 @@ mod from_script {
|
|||
Self::MediaSessionEvent(..) => target_variant!("MediaSessionEvent"),
|
||||
Self::OnDevtoolsStarted(..) => target_variant!("OnDevtoolsStarted"),
|
||||
Self::RequestDevtoolsConnection(..) => target_variant!("RequestDevtoolsConnection"),
|
||||
Self::ReadyToPresent(..) => target_variant!("ReadyToPresent"),
|
||||
Self::EventDelivered(..) => target_variant!("EventDelivered"),
|
||||
Self::PlayGamepadHapticEffect(..) => target_variant!("PlayGamepadHapticEffect"),
|
||||
Self::StopGamepadHapticEffect(..) => target_variant!("StopGamepadHapticEffect"),
|
||||
|
|
|
@ -643,6 +643,7 @@ impl Servo {
|
|||
}
|
||||
|
||||
self.compositor.borrow_mut().perform_updates();
|
||||
self.send_new_frame_ready_messages();
|
||||
|
||||
if self.compositor.borrow().shutdown_state == ShutdownState::FinishedShuttingDown {
|
||||
return false;
|
||||
|
@ -651,6 +652,17 @@ impl Servo {
|
|||
true
|
||||
}
|
||||
|
||||
fn send_new_frame_ready_messages(&self) {
|
||||
for webview in self
|
||||
.compositor
|
||||
.borrow()
|
||||
.webviews_waiting_on_present()
|
||||
.filter_map(|id| self.get_webview_handle(*id))
|
||||
{
|
||||
webview.delegate().notify_new_frame_ready(webview);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pinch_zoom_level(&self) -> f32 {
|
||||
self.compositor.borrow_mut().pinch_zoom_level().get()
|
||||
}
|
||||
|
@ -987,13 +999,6 @@ impl Servo {
|
|||
},
|
||||
);
|
||||
},
|
||||
EmbedderMsg::ReadyToPresent(webview_ids) => {
|
||||
for webview_id in webview_ids {
|
||||
if let Some(webview) = self.get_webview_handle(webview_id) {
|
||||
webview.delegate().notify_new_frame_ready(webview);
|
||||
}
|
||||
}
|
||||
},
|
||||
EmbedderMsg::EventDelivered(webview_id, event) => {
|
||||
if let Some(webview) = self.get_webview_handle(webview_id) {
|
||||
webview.delegate().notify_event_delivered(webview, event);
|
||||
|
|
|
@ -441,10 +441,6 @@ impl WebView {
|
|||
self.inner().compositor.borrow_mut().capture_webrender();
|
||||
}
|
||||
|
||||
pub fn composite(&self) {
|
||||
self.inner().compositor.borrow_mut().composite();
|
||||
}
|
||||
|
||||
pub fn toggle_sampling_profiler(&self, rate: Duration, max_duration: Duration) {
|
||||
self.inner()
|
||||
.constellation_proxy
|
||||
|
|
|
@ -84,8 +84,6 @@ pub enum ConstellationMsg {
|
|||
SetWebViewThrottled(TopLevelBrowsingContextId, bool),
|
||||
/// Virtual keyboard was dismissed
|
||||
IMEDismissed,
|
||||
/// Notify the embedder that it needs to present a new frame.
|
||||
ReadyToPresent(Vec<WebViewId>),
|
||||
/// Gamepad state has changed
|
||||
Gamepad(GamepadEvent),
|
||||
/// Inform the constellation of a clipboard event.
|
||||
|
@ -133,7 +131,6 @@ impl ConstellationMsg {
|
|||
SetWebViewThrottled(..) => "SetWebViewThrottled",
|
||||
IMEDismissed => "IMEDismissed",
|
||||
ClearCache => "ClearCache",
|
||||
ReadyToPresent(..) => "ReadyToPresent",
|
||||
Gamepad(..) => "Gamepad",
|
||||
Clipboard(..) => "Clipboard",
|
||||
}
|
||||
|
|
|
@ -250,8 +250,6 @@ pub enum EmbedderMsg {
|
|||
OnDevtoolsStarted(Result<u16, ()>, String),
|
||||
/// Ask the user to allow a devtools client to connect.
|
||||
RequestDevtoolsConnection(IpcSender<AllowOrDeny>),
|
||||
/// Notify the embedder that it needs to present a new frame.
|
||||
ReadyToPresent(Vec<WebViewId>),
|
||||
/// The given event was delivered to a pipeline in the given browser.
|
||||
EventDelivered(WebViewId, CompositorEventVariant),
|
||||
/// Request to play a haptic effect on a connected gamepad.
|
||||
|
@ -314,7 +312,6 @@ impl Debug for EmbedderMsg {
|
|||
EmbedderMsg::OnDevtoolsStarted(..) => write!(f, "OnDevtoolsStarted"),
|
||||
EmbedderMsg::RequestDevtoolsConnection(..) => write!(f, "RequestDevtoolsConnection"),
|
||||
EmbedderMsg::ShowContextMenu(..) => write!(f, "ShowContextMenu"),
|
||||
EmbedderMsg::ReadyToPresent(..) => write!(f, "ReadyToPresent"),
|
||||
EmbedderMsg::EventDelivered(..) => write!(f, "HitTestedEvent"),
|
||||
EmbedderMsg::PlayGamepadHapticEffect(..) => write!(f, "PlayGamepadHapticEffect"),
|
||||
EmbedderMsg::StopGamepadHapticEffect(..) => write!(f, "StopGamepadHapticEffect"),
|
||||
|
|
|
@ -222,15 +222,6 @@ pub extern "C" fn Java_org_servo_servoview_JNIServo_stop<'local>(
|
|||
call(&mut env, |s| s.stop());
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Java_org_servo_servoview_JNIServo_refresh<'local>(
|
||||
mut env: JNIEnv<'local>,
|
||||
_class: JClass<'local>,
|
||||
) {
|
||||
debug!("refresh");
|
||||
call(&mut env, |s| s.refresh());
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Java_org_servo_servoview_JNIServo_goBack<'local>(
|
||||
mut env: JNIEnv<'local>,
|
||||
|
|
|
@ -401,13 +401,6 @@ impl RunningAppState {
|
|||
self.perform_updates();
|
||||
}
|
||||
|
||||
/// Redraw the page.
|
||||
pub fn refresh(&self) {
|
||||
info!("refresh");
|
||||
self.active_webview().composite();
|
||||
self.perform_updates();
|
||||
}
|
||||
|
||||
/// Stop loading the page.
|
||||
pub fn stop(&self) {
|
||||
warn!("TODO can't stop won't stop");
|
||||
|
|
|
@ -35,8 +35,6 @@ public class JNIServo {
|
|||
|
||||
public native void stop();
|
||||
|
||||
public native void refresh();
|
||||
|
||||
public native void goBack();
|
||||
|
||||
public native void goForward();
|
||||
|
|
|
@ -87,10 +87,6 @@ public class Servo {
|
|||
mRunCallback.inGLThread(() -> mJNI.resize(coords));
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
mRunCallback.inGLThread(() -> mJNI.refresh());
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
mRunCallback.inGLThread(() -> mJNI.reload());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue