feat(servo): isolate profiles with hardware sidecars
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use ely_domain::WebViewId;
|
||||
|
||||
use super::SoftwareServoHost;
|
||||
use crate::{RenderedFrame, ServoHostError};
|
||||
use crate::{RenderedFrame, ServoHostError, runtime_webview::HostWebViewDelegate};
|
||||
|
||||
/// Repaint and present coordination for [`SoftwareServoHost`].
|
||||
///
|
||||
@@ -13,35 +13,20 @@ use crate::{RenderedFrame, ServoHostError};
|
||||
impl SoftwareServoHost {
|
||||
/// Paint and present the current surface without RGBA readback.
|
||||
pub fn paint_without_readback(&mut self, webview_id: &WebViewId) -> Result<(), ServoHostError> {
|
||||
self.paint_without_readback_with_completion(webview_id, true)
|
||||
}
|
||||
|
||||
pub fn paint_without_readback_with_completion(
|
||||
&mut self,
|
||||
webview_id: &WebViewId,
|
||||
wait_for_completion: bool,
|
||||
) -> Result<(), ServoHostError> {
|
||||
self.paint_webview(webview_id, false, wait_for_completion).map(|_| ())
|
||||
self.paint_webview(webview_id, false).map(|_| ())
|
||||
}
|
||||
|
||||
fn paint_webview(
|
||||
&mut self,
|
||||
webview_id: &WebViewId,
|
||||
capture_frame: bool,
|
||||
wait_for_completion: bool,
|
||||
) -> Result<Option<RenderedFrame>, ServoHostError> {
|
||||
let rendering_context = self.webview(webview_id)?.rendering_context.clone();
|
||||
rendering_context.make_current().map_err(|_| ServoHostError::RenderingContextNotCurrent)?;
|
||||
rendering_context.prepare_for_rendering();
|
||||
// Clear the pending-frame flag before `paint()` so barrier callers observe
|
||||
// the next Servo frame-ready notification for this paint.
|
||||
{
|
||||
let webview = self.webview(webview_id)?;
|
||||
webview.delegate.mark_frame_presented();
|
||||
webview.webview.paint();
|
||||
}
|
||||
if wait_for_completion {
|
||||
self.wait_for_paint_completion(webview_id);
|
||||
consume_pending_then_paint(&webview.delegate, || webview.webview.paint());
|
||||
}
|
||||
let rendered_frame = if capture_frame {
|
||||
Some(Self::read_rendered_frame(rendering_context.as_ref())?)
|
||||
@@ -49,20 +34,39 @@ impl SoftwareServoHost {
|
||||
None
|
||||
};
|
||||
rendering_context.present();
|
||||
self.webview(webview_id)?.delegate.mark_frame_presented();
|
||||
Ok(rendered_frame)
|
||||
}
|
||||
|
||||
pub fn paint_with_readback(
|
||||
&mut self,
|
||||
webview_id: &WebViewId,
|
||||
wait_for_completion: bool,
|
||||
) -> Result<(), ServoHostError> {
|
||||
let Some(rendered_frame) = self.paint_webview(webview_id, true, wait_for_completion)?
|
||||
else {
|
||||
pub fn paint_with_readback(&mut self, webview_id: &WebViewId) -> Result<(), ServoHostError> {
|
||||
let Some(rendered_frame) = self.paint_webview(webview_id, true)? else {
|
||||
return Err(ServoHostError::RenderedFrameUnavailable);
|
||||
};
|
||||
self.last_rendered_frame = Some(rendered_frame);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn consume_pending_then_paint(delegate: &HostWebViewDelegate, paint: impl FnOnce()) {
|
||||
delegate.mark_frame_presented();
|
||||
paint();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
|
||||
use ely_domain::ProfileId;
|
||||
|
||||
use super::{HostWebViewDelegate, consume_pending_then_paint};
|
||||
|
||||
#[test]
|
||||
fn frame_arriving_during_paint_remains_pending() {
|
||||
let delegate =
|
||||
HostWebViewDelegate::new(ProfileId::new(), Rc::new(RefCell::new(HashMap::new())));
|
||||
delegate.mark_frame_ready();
|
||||
|
||||
consume_pending_then_paint(&delegate, || delegate.mark_frame_ready());
|
||||
|
||||
assert!(delegate.has_pending_frame());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user