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"]
|
#[path = "runtime_context.rs"]
|
||||||
mod runtime_context;
|
mod runtime_context;
|
||||||
|
#[path = "runtime_paint.rs"]
|
||||||
|
mod runtime_paint;
|
||||||
|
|
||||||
use runtime_context::hidpi_scale_from_factor;
|
use runtime_context::hidpi_scale_from_factor;
|
||||||
pub use runtime_context::{RenderingContextKind, ServoSurfaceSize};
|
pub use runtime_context::{RenderingContextKind, ServoSurfaceSize};
|
||||||
@@ -109,19 +111,6 @@ impl SoftwareServoHost {
|
|||||||
self.create_webview_in_context(tab_id, profile_id, handles)
|
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 {
|
pub fn close_webview(&mut self, webview_id: &WebViewId) -> bool {
|
||||||
let Some(webview) = self.webviews.remove(webview_id) else {
|
let Some(webview) = self.webviews.remove(webview_id) else {
|
||||||
return false;
|
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
|
/// Returns the current snapshot and acknowledges metadata-only
|
||||||
/// updates without clearing Servo's frame-ready signal.
|
/// updates without clearing Servo's frame-ready signal.
|
||||||
pub fn snapshot_and_mark_metadata_observed(
|
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