refactor(servo): extract paint coordination into runtime_paint
`runtime.rs` had grown past the 500-line ceiling enforced by `scripts/audit_source_lines.sh` once the grid-pref comment landed (522 lines). Peel the repaint/present pair — `paint_without_readback`, `paint_without_readback_with_completion`, the private `paint_webview`, and `paint_with_readback` — into a sibling `runtime_paint.rs`, exactly the `paint.rs` boundary the embedding architecture doc prescribes. `runtime_paint` is a child module of `runtime` (declared via `#[path]`, mirroring `runtime_context`), so it keeps access to the private `SoftwareServoHost` fields and the `webview()` / `wait_for_paint_completion` / `read_rendered_frame` helpers without widening any visibility. No behaviour change: public API and call sites are identical. runtime.rs 522 -> 469 lines. Build + clippy clean; full workspace test suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,8 @@ use servo::{
|
||||
|
||||
#[path = "runtime_context.rs"]
|
||||
mod runtime_context;
|
||||
#[path = "runtime_paint.rs"]
|
||||
mod runtime_paint;
|
||||
|
||||
use runtime_context::hidpi_scale_from_factor;
|
||||
pub use runtime_context::{RenderingContextKind, ServoSurfaceSize};
|
||||
@@ -109,19 +111,6 @@ impl SoftwareServoHost {
|
||||
self.create_webview_in_context(tab_id, profile_id, handles)
|
||||
}
|
||||
|
||||
/// 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(|_| ())
|
||||
}
|
||||
|
||||
pub fn close_webview(&mut self, webview_id: &WebViewId) -> bool {
|
||||
let Some(webview) = self.webviews.remove(webview_id) else {
|
||||
return false;
|
||||
@@ -173,48 +162,6 @@ impl SoftwareServoHost {
|
||||
})
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
let rendered_frame = if capture_frame {
|
||||
Some(Self::read_rendered_frame(rendering_context.as_ref())?)
|
||||
} else {
|
||||
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 {
|
||||
return Err(ServoHostError::RenderedFrameUnavailable);
|
||||
};
|
||||
self.last_rendered_frame = Some(rendered_frame);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the current snapshot and acknowledges metadata-only
|
||||
/// updates without clearing Servo's frame-ready signal.
|
||||
pub fn snapshot_and_mark_metadata_observed(
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
use ely_domain::WebViewId;
|
||||
|
||||
use super::SoftwareServoHost;
|
||||
use crate::{RenderedFrame, ServoHostError};
|
||||
|
||||
/// Repaint and present coordination for [`SoftwareServoHost`].
|
||||
///
|
||||
/// Servo's rendering contract is: `notify_new_frame_ready` flags the
|
||||
/// session, then a single `WebView::paint` + `RenderingContext::present`
|
||||
/// pair lands that frame. These methods own that pair (plus the optional
|
||||
/// RGBA readback used by the software path); the rest of the host
|
||||
/// lifecycle stays in `runtime.rs`.
|
||||
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(|_| ())
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
let rendered_frame = if capture_frame {
|
||||
Some(Self::read_rendered_frame(rendering_context.as_ref())?)
|
||||
} else {
|
||||
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 {
|
||||
return Err(ServoHostError::RenderedFrameUnavailable);
|
||||
};
|
||||
self.last_rendered_frame = Some(rendered_frame);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user