mirror of
https://github.com/servo/servo.git
synced 2025-09-30 08:39:16 +01:00
libservo: Add a WebView::take_screenshot()
API and use it for reftests
Co-authored-by: Delan Azabani <dazabani@igalia.com> Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
92dd54b1ec
commit
ebb12cb298
25 changed files with 481 additions and 414 deletions
|
@ -26,8 +26,9 @@ use bluetooth_traits::BluetoothRequest;
|
|||
use canvas_traits::webgl::WebGLChan;
|
||||
use compositing_traits::CrossProcessCompositorApi;
|
||||
use constellation_traits::{
|
||||
DocumentState, LoadData, LoadOrigin, NavigationHistoryBehavior, ScriptToConstellationChan,
|
||||
ScriptToConstellationMessage, StructuredSerializedData, WindowSizeType,
|
||||
LoadData, LoadOrigin, NavigationHistoryBehavior, ScreenshotReadinessResponse,
|
||||
ScriptToConstellationChan, ScriptToConstellationMessage, StructuredSerializedData,
|
||||
WindowSizeType,
|
||||
};
|
||||
use crossbeam_channel::{Sender, unbounded};
|
||||
use cssparser::SourceLocation;
|
||||
|
@ -42,7 +43,7 @@ use embedder_traits::{
|
|||
use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect, Size2D as UntypedSize2D};
|
||||
use euclid::{Point2D, Scale, Size2D, Vector2D};
|
||||
use fonts::FontContext;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use js::glue::DumpJSStack;
|
||||
use js::jsapi::{
|
||||
GCReason, Heap, JS_GC, JSAutoRealm, JSContext as RawJSContext, JSObject, JSPROP_ENUMERATE,
|
||||
|
@ -80,9 +81,10 @@ use script_bindings::root::Root;
|
|||
use script_traits::{ConstellationInputEvent, ScriptThreadMessage};
|
||||
use selectors::attr::CaseSensitivity;
|
||||
use servo_arc::Arc as ServoArc;
|
||||
use servo_config::{opts, pref};
|
||||
use servo_config::pref;
|
||||
use servo_geometry::{DeviceIndependentIntRect, f32_rect_to_au_rect};
|
||||
use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
|
||||
use style::Zero;
|
||||
use style::error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||
use style::properties::PropertyId;
|
||||
use style::properties::style_structs::Font;
|
||||
|
@ -441,6 +443,10 @@ pub(crate) struct Window {
|
|||
/// <https://w3c.github.io/reporting/#windoworworkerglobalscope-endpoints>
|
||||
#[no_trace]
|
||||
endpoints_list: DomRefCell<Vec<ReportingEndpoint>>,
|
||||
|
||||
/// The number of pending screenshot readiness requests that we have received. We need
|
||||
/// to send a response for each of these.
|
||||
pending_screenshot_readiness_requests: Cell<usize>,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
|
@ -2328,17 +2334,19 @@ impl Window {
|
|||
}
|
||||
|
||||
document.update_animations_post_reflow();
|
||||
self.update_constellation_epoch();
|
||||
|
||||
reflow_result.reflow_phases_run
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_send_idle_document_state_to_constellation(&self) {
|
||||
if !opts::get().wait_for_stable_image {
|
||||
return;
|
||||
}
|
||||
pub(crate) fn request_screenshot_readiness(&self) {
|
||||
self.pending_screenshot_readiness_requests
|
||||
.set(self.pending_screenshot_readiness_requests.get() + 1);
|
||||
self.maybe_resolve_pending_screenshot_readiness_requests();
|
||||
}
|
||||
|
||||
if self.has_sent_idle_message.get() {
|
||||
pub(crate) fn maybe_resolve_pending_screenshot_readiness_requests(&self) {
|
||||
let pending_requests = self.pending_screenshot_readiness_requests.get();
|
||||
if pending_requests.is_zero() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2371,17 +2379,20 @@ impl Window {
|
|||
return;
|
||||
}
|
||||
|
||||
// When all these conditions are met, notify the constellation
|
||||
// that this pipeline is ready to write the image (from the script thread
|
||||
// perspective at least).
|
||||
debug!(
|
||||
"{:?}: Sending DocumentState::Idle to Constellation",
|
||||
self.pipeline_id()
|
||||
);
|
||||
self.send_to_constellation(ScriptToConstellationMessage::SetDocumentState(
|
||||
DocumentState::Idle,
|
||||
));
|
||||
self.has_sent_idle_message.set(true);
|
||||
// When all these conditions are met, notify the Constellation that we are ready to
|
||||
// have our screenshot taken, when the given layout Epoch has been rendered.
|
||||
let epoch = self.layout.borrow().current_epoch();
|
||||
let pipeline_id = self.pipeline_id();
|
||||
debug!("Ready to take screenshot of {pipeline_id:?} at epoch={epoch:?}");
|
||||
|
||||
for _ in 0..pending_requests {
|
||||
self.send_to_constellation(
|
||||
ScriptToConstellationMessage::RespondToScreenshotReadinessRequest(
|
||||
ScreenshotReadinessResponse::Ready(epoch),
|
||||
),
|
||||
);
|
||||
}
|
||||
self.pending_screenshot_readiness_requests.set(0);
|
||||
}
|
||||
|
||||
/// If parsing has taken a long time and reflows are still waiting for the `load` event,
|
||||
|
@ -2445,24 +2456,6 @@ impl Window {
|
|||
self.layout_blocker.get().layout_blocked()
|
||||
}
|
||||
|
||||
/// If writing a screenshot, synchronously update the layout epoch that it set
|
||||
/// in the constellation.
|
||||
pub(crate) fn update_constellation_epoch(&self) {
|
||||
if !opts::get().wait_for_stable_image {
|
||||
return;
|
||||
}
|
||||
|
||||
let epoch = self.layout.borrow().current_epoch();
|
||||
debug!(
|
||||
"{:?}: Updating constellation epoch: {epoch:?}",
|
||||
self.pipeline_id()
|
||||
);
|
||||
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!");
|
||||
let event = ScriptToConstellationMessage::SetLayoutEpoch(epoch, sender);
|
||||
self.send_to_constellation(event);
|
||||
let _ = receiver.recv();
|
||||
}
|
||||
|
||||
/// Trigger a reflow that is required by a certain queries.
|
||||
pub(crate) fn layout_reflow(&self, query_msg: QueryMsg) {
|
||||
self.reflow(ReflowGoal::LayoutQuery(query_msg));
|
||||
|
@ -3192,9 +3185,7 @@ impl Window {
|
|||
node.dirty(NodeDamage::Other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
#[allow(unsafe_code)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn new(
|
||||
|
@ -3325,6 +3316,7 @@ impl Window {
|
|||
reporting_observer_list: Default::default(),
|
||||
report_list: Default::default(),
|
||||
endpoints_list: Default::default(),
|
||||
pending_screenshot_readiness_requests: Default::default(),
|
||||
});
|
||||
|
||||
WindowBinding::Wrap::<crate::DomTypeHolder>(GlobalScope::get_cx(), win)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue