libservo: Rework and clarify the rendering model of the WebView (#35522)

Make the rendering model of the `WebView` clearer:

1. `WebViewDelegate::notify_new_frame_ready()` indicates that the
   WebView has become dirty and needs to be repainted.
2. `WebView::paint()` asks Servo to paint the contents of the `WebView`
   into the `RenderingContext`.
3. `RenderingContext::present()` does a buffer swap if the
   `RenderingContext` is actually double-buffered.

This is documented and all in-tree embedders are updated to work with
this new model.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Ngo Iok Ui (Wu Yu Wei) <yuweiwu@pm.me>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
Martin Robinson 2025-02-19 11:35:56 +01:00 committed by GitHub
parent 56840e0a35
commit e5c9a0365d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 129 additions and 160 deletions

View file

@ -58,7 +58,6 @@ pub(crate) enum PumpResult {
Shutdown,
Continue {
need_update: bool,
new_servo_frame: bool,
need_window_redraw: bool,
},
}
@ -195,23 +194,15 @@ impl App {
},
PumpResult::Continue {
need_update: update,
new_servo_frame,
need_window_redraw,
} => {
// A new Servo frame is ready, so swap the buffer on our `RenderingContext`. In headed mode
// this won't immediately update the widget surface, because we render to an offscreen
// `RenderingContext`.
if new_servo_frame {
state.servo().present();
}
let updated = match (update, &mut self.minibrowser) {
(true, Some(minibrowser)) => minibrowser.update_webview_data(state),
_ => false,
};
// If in headed mode, request a winit redraw event, so we can paint the minibrowser.
if updated || need_window_redraw || new_servo_frame {
if updated || need_window_redraw {
if let Some(window) = window.winit_window() {
window.request_redraw();
}
@ -247,14 +238,7 @@ impl App {
state.shutdown();
self.state = AppState::ShuttingDown;
},
PumpResult::Continue {
new_servo_frame, ..
} => {
if new_servo_frame {
// In headless mode, we present directly.
state.servo().present();
}
},
PumpResult::Continue { .. } => state.repaint_servo_if_necessary(),
}
!matches!(self.state, AppState::ShuttingDown)