compositing: Rename WebView to WebViewRenderer (#36574)

There is a `WebView` in libservo (new) and a `WebView` in compositing
(old). Nowadays, the "real" `WebView` is the one in the libservo. The
`WebView` in `compositing` is really about rendering the contents of a
`WebView` from libservo. In addition there is also a trait exposed by
the compositor called `RendererWebView` which is a way for the
compositor to talk to libservo without a circular dependency.

This changes does some renames to make things clearer and so that there
is One Less WebView™:

- `compositing::WebView` -> `compositing::WebViewRenderer` (this is the
  same kind of naming as `ServoRenderer`).
- `compositing::RendererWebView` -> `compositing::WebViewTrait`

Testing: This is just a couple renames so should be covered by existing
tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-04-21 10:47:39 +02:00 committed by GitHub
parent a0419faa85
commit 70f19c749f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 123 additions and 107 deletions

View file

@ -19,7 +19,7 @@ use bitflags::bitflags;
use compositing_traits::display_list::{CompositorDisplayListInfo, HitTestInfo, ScrollTree}; use compositing_traits::display_list::{CompositorDisplayListInfo, HitTestInfo, ScrollTree};
use compositing_traits::rendering_context::RenderingContext; use compositing_traits::rendering_context::RenderingContext;
use compositing_traits::{ use compositing_traits::{
CompositionPipeline, CompositorMsg, ImageUpdate, RendererWebView, SendableFrameTree, CompositionPipeline, CompositorMsg, ImageUpdate, SendableFrameTree, WebViewTrait,
}; };
use constellation_traits::{AnimationTickType, EmbedderToConstellationMessage, PaintMetricEvent}; use constellation_traits::{AnimationTickType, EmbedderToConstellationMessage, PaintMetricEvent};
use crossbeam_channel::{Receiver, Sender}; use crossbeam_channel::{Receiver, Sender};
@ -54,8 +54,8 @@ use webrender_api::{
}; };
use crate::InitialCompositorState; use crate::InitialCompositorState;
use crate::webview::{UnknownWebView, WebView};
use crate::webview_manager::WebViewManager; use crate::webview_manager::WebViewManager;
use crate::webview_renderer::{UnknownWebView, WebViewRenderer};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
enum UnableToComposite { enum UnableToComposite {
@ -133,8 +133,8 @@ pub struct IOCompositor {
/// Data that is shared by all WebView renderers. /// Data that is shared by all WebView renderers.
global: Rc<RefCell<ServoRenderer>>, global: Rc<RefCell<ServoRenderer>>,
/// Our top-level browsing contexts. /// Our [`WebViewRenderer`]s, one for every `WebView`.
webviews: WebViewManager<WebView>, webview_renderers: WebViewManager<WebViewRenderer>,
/// Tracks whether or not the view needs to be repainted. /// Tracks whether or not the view needs to be repainted.
needs_repaint: Cell<RepaintReason>, needs_repaint: Cell<RepaintReason>,
@ -424,7 +424,7 @@ impl IOCompositor {
cursor: Cursor::None, cursor: Cursor::None,
cursor_pos: DevicePoint::new(0.0, 0.0), cursor_pos: DevicePoint::new(0.0, 0.0),
})), })),
webviews: WebViewManager::default(), webview_renderers: WebViewManager::default(),
needs_repaint: Cell::default(), needs_repaint: Cell::default(),
ready_to_save_state: ReadyState::Unknown, ready_to_save_state: ReadyState::Unknown,
webrender: Some(state.webrender), webrender: Some(state.webrender),
@ -544,9 +544,9 @@ impl IOCompositor {
animation_state, animation_state,
) => { ) => {
let mut throttled = true; let mut throttled = true;
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
throttled = throttled = webview_renderer
webview.change_running_animations_state(pipeline_id, animation_state); .change_running_animations_state(pipeline_id, animation_state);
} }
// These operations should eventually happen per-WebView, but they are global now as rendering // These operations should eventually happen per-WebView, but they are global now as rendering
@ -557,8 +557,8 @@ impl IOCompositor {
if !throttled && animation_state == AnimationState::AnimationCallbacksPresent { if !throttled && animation_state == AnimationState::AnimationCallbacksPresent {
// We need to fetch the WebView again in order to avoid a double borrow. // We need to fetch the WebView again in order to avoid a double borrow.
if let Some(webview) = self.webviews.get(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get(webview_id) {
webview.tick_animations_for_pipeline(pipeline_id, self); webview_renderer.tick_animations_for_pipeline(pipeline_id, self);
} }
} }
}, },
@ -572,11 +572,11 @@ impl IOCompositor {
}, },
CompositorMsg::TouchEventProcessed(webview_id, result) => { CompositorMsg::TouchEventProcessed(webview_id, result) => {
let Some(webview) = self.webviews.get_mut(webview_id) else { let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
warn!("Handling input event for unknown webview: {webview_id}"); warn!("Handling input event for unknown webview: {webview_id}");
return; return;
}; };
webview.on_touch_event_processed(result); webview_renderer.on_touch_event_processed(result);
}, },
CompositorMsg::CreatePng(webview_id, page_rect, reply) => { CompositorMsg::CreatePng(webview_id, page_rect, reply) => {
@ -604,8 +604,8 @@ impl IOCompositor {
}, },
CompositorMsg::SetThrottled(webview_id, pipeline_id, throttled) => { CompositorMsg::SetThrottled(webview_id, pipeline_id, throttled) => {
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
webview.set_throttled(pipeline_id, throttled); webview_renderer.set_throttled(pipeline_id, throttled);
self.process_animations(true); self.process_animations(true);
} }
}, },
@ -615,8 +615,8 @@ impl IOCompositor {
"Compositor got pipeline exited: {:?} {:?}", "Compositor got pipeline exited: {:?} {:?}",
webview_id, pipeline_id webview_id, pipeline_id
); );
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
webview.remove_pipeline(pipeline_id); webview_renderer.remove_pipeline(pipeline_id);
} }
let _ = sender.send(()); let _ = sender.send(());
}, },
@ -648,13 +648,13 @@ impl IOCompositor {
}, },
CompositorMsg::WebDriverMouseButtonEvent(webview_id, action, button, x, y) => { CompositorMsg::WebDriverMouseButtonEvent(webview_id, action, button, x, y) => {
let Some(webview) = self.webviews.get_mut(webview_id) else { let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
warn!("Handling input event for unknown webview: {webview_id}"); warn!("Handling input event for unknown webview: {webview_id}");
return; return;
}; };
let dppx = webview.device_pixels_per_page_pixel(); let dppx = webview_renderer.device_pixels_per_page_pixel();
let point = dppx.transform_point(Point2D::new(x, y)); let point = dppx.transform_point(Point2D::new(x, y));
webview.dispatch_input_event(InputEvent::MouseButton(MouseButtonEvent { webview_renderer.dispatch_input_event(InputEvent::MouseButton(MouseButtonEvent {
point, point,
action, action,
button, button,
@ -662,13 +662,14 @@ impl IOCompositor {
}, },
CompositorMsg::WebDriverMouseMoveEvent(webview_id, x, y) => { CompositorMsg::WebDriverMouseMoveEvent(webview_id, x, y) => {
let Some(webview) = self.webviews.get_mut(webview_id) else { let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
warn!("Handling input event for unknown webview: {webview_id}"); warn!("Handling input event for unknown webview: {webview_id}");
return; return;
}; };
let dppx = webview.device_pixels_per_page_pixel(); let dppx = webview_renderer.device_pixels_per_page_pixel();
let point = dppx.transform_point(Point2D::new(x, y)); let point = dppx.transform_point(Point2D::new(x, y));
webview.dispatch_input_event(InputEvent::MouseMove(MouseMoveEvent { point })); webview_renderer
.dispatch_input_event(InputEvent::MouseMove(MouseMoveEvent { point }));
}, },
CompositorMsg::SendInitialTransaction(pipeline) => { CompositorMsg::SendInitialTransaction(pipeline) => {
@ -679,12 +680,13 @@ impl IOCompositor {
}, },
CompositorMsg::SendScrollNode(webview_id, pipeline_id, point, external_scroll_id) => { CompositorMsg::SendScrollNode(webview_id, pipeline_id, point, external_scroll_id) => {
let Some(webview) = self.webviews.get_mut(webview_id) else { let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
return; return;
}; };
let pipeline_id = pipeline_id.into(); let pipeline_id = pipeline_id.into();
let Some(pipeline_details) = webview.pipelines.get_mut(&pipeline_id) else { let Some(pipeline_details) = webview_renderer.pipelines.get_mut(&pipeline_id)
else {
return; return;
}; };
@ -771,12 +773,12 @@ impl IOCompositor {
) )
.entered(); .entered();
let Some(webview) = self.webviews.get_mut(webview_id) else { let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
return warn!("Could not find WebView for incoming display list"); return warn!("Could not find WebView for incoming display list");
}; };
let pipeline_id = display_list_info.pipeline_id; let pipeline_id = display_list_info.pipeline_id;
let details = webview.ensure_pipeline_details(pipeline_id.into()); let details = webview_renderer.ensure_pipeline_details(pipeline_id.into());
details.most_recent_display_list_epoch = Some(display_list_info.epoch); details.most_recent_display_list_epoch = Some(display_list_info.epoch);
details.hit_test_items = display_list_info.hit_test_info; details.hit_test_items = display_list_info.hit_test_info;
details.install_new_scroll_tree(display_list_info.scroll_tree); details.install_new_scroll_tree(display_list_info.scroll_tree);
@ -900,9 +902,11 @@ impl IOCompositor {
}, },
CompositorMsg::GetClientWindowRect(webview_id, response_sender) => { CompositorMsg::GetClientWindowRect(webview_id, response_sender) => {
let client_window_rect = self let client_window_rect = self
.webviews .webview_renderers
.get(webview_id) .get(webview_id)
.map(|webview| webview.client_window_rect(self.rendering_context.size2d())) .map(|webview_renderer| {
webview_renderer.client_window_rect(self.rendering_context.size2d())
})
.unwrap_or_default(); .unwrap_or_default();
if let Err(error) = response_sender.send(client_window_rect) { if let Err(error) = response_sender.send(client_window_rect) {
warn!("Sending response to get client window failed ({error:?})."); warn!("Sending response to get client window failed ({error:?}).");
@ -910,9 +914,9 @@ impl IOCompositor {
}, },
CompositorMsg::GetScreenSize(webview_id, response_sender) => { CompositorMsg::GetScreenSize(webview_id, response_sender) => {
let screen_size = self let screen_size = self
.webviews .webview_renderers
.get(webview_id) .get(webview_id)
.map(WebView::screen_size) .map(WebViewRenderer::screen_size)
.unwrap_or_default(); .unwrap_or_default();
if let Err(error) = response_sender.send(screen_size) { if let Err(error) = response_sender.send(screen_size) {
warn!("Sending response to get screen size failed ({error:?})."); warn!("Sending response to get screen size failed ({error:?}).");
@ -920,9 +924,9 @@ impl IOCompositor {
}, },
CompositorMsg::GetAvailableScreenSize(webview_id, response_sender) => { CompositorMsg::GetAvailableScreenSize(webview_id, response_sender) => {
let available_screen_size = self let available_screen_size = self
.webviews .webview_renderers
.get(webview_id) .get(webview_id)
.map(WebView::available_screen_size) .map(WebViewRenderer::available_screen_size)
.unwrap_or_default(); .unwrap_or_default();
if let Err(error) = response_sender.send(available_screen_size) { if let Err(error) = response_sender.send(available_screen_size) {
warn!("Sending response to get screen size failed ({error:?})."); warn!("Sending response to get screen size failed ({error:?}).");
@ -947,8 +951,8 @@ impl IOCompositor {
"Compositor got pipeline exited: {:?} {:?}", "Compositor got pipeline exited: {:?} {:?}",
webview_id, pipeline_id webview_id, pipeline_id
); );
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
webview.remove_pipeline(pipeline_id); webview_renderer.remove_pipeline(pipeline_id);
} }
let _ = sender.send(()); let _ = sender.send(());
}, },
@ -1040,12 +1044,12 @@ impl IOCompositor {
let root_clip_id = builder.define_clip_rect(root_reference_frame, viewport_rect); let root_clip_id = builder.define_clip_rect(root_reference_frame, viewport_rect);
let clip_chain_id = builder.define_clip_chain(None, [root_clip_id]); let clip_chain_id = builder.define_clip_chain(None, [root_clip_id]);
for (_, webview) in self.webviews.painting_order() { for (_, webview_renderer) in self.webview_renderers.painting_order() {
let Some(pipeline_id) = webview.root_pipeline_id else { let Some(pipeline_id) = webview_renderer.root_pipeline_id else {
continue; continue;
}; };
let device_pixels_per_page_pixel = webview.device_pixels_per_page_pixel().0; let device_pixels_per_page_pixel = webview_renderer.device_pixels_per_page_pixel().0;
let webview_reference_frame = builder.push_reference_frame( let webview_reference_frame = builder.push_reference_frame(
LayoutPoint::zero(), LayoutPoint::zero(),
root_reference_frame, root_reference_frame,
@ -1063,7 +1067,7 @@ impl IOCompositor {
SpatialTreeItemKey::new(0, 0), SpatialTreeItemKey::new(0, 0),
); );
let scaled_webview_rect = webview.rect / device_pixels_per_page_pixel; let scaled_webview_rect = webview_renderer.rect / device_pixels_per_page_pixel;
builder.push_iframe( builder.push_iframe(
LayoutRect::from_untyped(&scaled_webview_rect.to_untyped()), LayoutRect::from_untyped(&scaled_webview_rect.to_untyped()),
LayoutRect::from_untyped(&scaled_webview_rect.to_untyped()), LayoutRect::from_untyped(&scaled_webview_rect.to_untyped()),
@ -1094,8 +1098,8 @@ impl IOCompositor {
/// TODO(mrobinson): Could we only send offsets for the branch being modified /// TODO(mrobinson): Could we only send offsets for the branch being modified
/// and not the entire scene? /// and not the entire scene?
fn update_transaction_with_all_scroll_offsets(&self, transaction: &mut Transaction) { fn update_transaction_with_all_scroll_offsets(&self, transaction: &mut Transaction) {
for webview in self.webviews.iter() { for webview_renderer in self.webview_renderers.iter() {
for details in webview.pipelines.values() { for details in webview_renderer.pipelines.values() {
for node in details.scroll_tree.nodes.iter() { for node in details.scroll_tree.nodes.iter() {
let (Some(offset), Some(external_id)) = (node.offset(), node.external_id()) let (Some(offset), Some(external_id)) = (node.offset(), node.external_id())
else { else {
@ -1117,34 +1121,36 @@ impl IOCompositor {
pub fn add_webview( pub fn add_webview(
&mut self, &mut self,
webview: Box<dyn RendererWebView>, webview: Box<dyn WebViewTrait>,
viewport_details: ViewportDetails, viewport_details: ViewportDetails,
) { ) {
self.webviews.entry(webview.id()).or_insert(WebView::new( self.webview_renderers
self.global.clone(), .entry(webview.id())
webview, .or_insert(WebViewRenderer::new(
viewport_details, self.global.clone(),
)); webview,
viewport_details,
));
} }
fn set_frame_tree_for_webview(&mut self, frame_tree: &SendableFrameTree) { fn set_frame_tree_for_webview(&mut self, frame_tree: &SendableFrameTree) {
debug!("{}: Setting frame tree for webview", frame_tree.pipeline.id); debug!("{}: Setting frame tree for webview", frame_tree.pipeline.id);
let webview_id = frame_tree.pipeline.webview_id; let webview_id = frame_tree.pipeline.webview_id;
let Some(webview) = self.webviews.get_mut(webview_id) else { let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
warn!( warn!(
"Attempted to set frame tree on unknown WebView (perhaps closed?): {webview_id:?}" "Attempted to set frame tree on unknown WebView (perhaps closed?): {webview_id:?}"
); );
return; return;
}; };
webview.set_frame_tree(frame_tree); webview_renderer.set_frame_tree(frame_tree);
self.send_root_pipeline_display_list(); self.send_root_pipeline_display_list();
} }
fn remove_webview(&mut self, webview_id: WebViewId) { fn remove_webview(&mut self, webview_id: WebViewId) {
debug!("{}: Removing", webview_id); debug!("{}: Removing", webview_id);
if self.webviews.remove(webview_id).is_err() { if self.webview_renderers.remove(webview_id).is_err() {
warn!("{webview_id}: Removing unknown webview"); warn!("{webview_id}: Removing unknown webview");
return; return;
}; };
@ -1160,15 +1166,15 @@ impl IOCompositor {
debug!("{webview_id}: Showing webview; hide_others={hide_others}"); debug!("{webview_id}: Showing webview; hide_others={hide_others}");
let painting_order_changed = if hide_others { let painting_order_changed = if hide_others {
let result = self let result = self
.webviews .webview_renderers
.painting_order() .painting_order()
.map(|(&id, _)| id) .map(|(&id, _)| id)
.ne(once(webview_id)); .ne(once(webview_id));
self.webviews.hide_all(); self.webview_renderers.hide_all();
self.webviews.show(webview_id)?; self.webview_renderers.show(webview_id)?;
result result
} else { } else {
self.webviews.show(webview_id)? self.webview_renderers.show(webview_id)?
}; };
if painting_order_changed { if painting_order_changed {
self.send_root_pipeline_display_list(); self.send_root_pipeline_display_list();
@ -1178,7 +1184,7 @@ impl IOCompositor {
pub fn hide_webview(&mut self, webview_id: WebViewId) -> Result<(), UnknownWebView> { pub fn hide_webview(&mut self, webview_id: WebViewId) -> Result<(), UnknownWebView> {
debug!("{webview_id}: Hiding webview"); debug!("{webview_id}: Hiding webview");
if self.webviews.hide(webview_id)? { if self.webview_renderers.hide(webview_id)? {
self.send_root_pipeline_display_list(); self.send_root_pipeline_display_list();
} }
Ok(()) Ok(())
@ -1192,15 +1198,15 @@ impl IOCompositor {
debug!("{webview_id}: Raising webview to top; hide_others={hide_others}"); debug!("{webview_id}: Raising webview to top; hide_others={hide_others}");
let painting_order_changed = if hide_others { let painting_order_changed = if hide_others {
let result = self let result = self
.webviews .webview_renderers
.painting_order() .painting_order()
.map(|(&id, _)| id) .map(|(&id, _)| id)
.ne(once(webview_id)); .ne(once(webview_id));
self.webviews.hide_all(); self.webview_renderers.hide_all();
self.webviews.raise_to_top(webview_id)?; self.webview_renderers.raise_to_top(webview_id)?;
result result
} else { } else {
self.webviews.raise_to_top(webview_id)? self.webview_renderers.raise_to_top(webview_id)?
}; };
if painting_order_changed { if painting_order_changed {
self.send_root_pipeline_display_list(); self.send_root_pipeline_display_list();
@ -1212,10 +1218,10 @@ impl IOCompositor {
if self.global.borrow().shutdown_state() != ShutdownState::NotShuttingDown { if self.global.borrow().shutdown_state() != ShutdownState::NotShuttingDown {
return; return;
} }
let Some(webview) = self.webviews.get_mut(webview_id) else { let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
return; return;
}; };
if !webview.set_rect(rect) { if !webview_renderer.set_rect(rect) {
return; return;
} }
@ -1231,10 +1237,10 @@ impl IOCompositor {
if self.global.borrow().shutdown_state() != ShutdownState::NotShuttingDown { if self.global.borrow().shutdown_state() != ShutdownState::NotShuttingDown {
return; return;
} }
let Some(webview) = self.webviews.get_mut(webview_id) else { let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
return; return;
}; };
if !webview.set_hidpi_scale_factor(new_scale_factor) { if !webview_renderer.set_hidpi_scale_factor(new_scale_factor) {
return; return;
} }
@ -1277,8 +1283,8 @@ impl IOCompositor {
} }
self.last_animation_tick = Instant::now(); self.last_animation_tick = Instant::now();
for webview in self.webviews.iter() { for webview_renderer in self.webview_renderers.iter() {
webview.tick_all_animations(self); webview_renderer.tick_all_animations(self);
} }
} }
@ -1287,8 +1293,8 @@ impl IOCompositor {
return; return;
} }
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
webview.set_page_zoom(1.0); webview_renderer.set_page_zoom(1.0);
} }
self.send_root_pipeline_display_list(); self.send_root_pipeline_display_list();
} }
@ -1298,8 +1304,8 @@ impl IOCompositor {
return; return;
} }
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
webview.set_page_zoom(magnification); webview_renderer.set_page_zoom(magnification);
} }
self.send_root_pipeline_display_list(); self.send_root_pipeline_display_list();
} }
@ -1311,21 +1317,24 @@ impl IOCompositor {
.pipeline_to_webview_map .pipeline_to_webview_map
.get(&pipeline_id) .get(&pipeline_id)
.cloned()?; .cloned()?;
self.webviews.get(webview_id)?.pipelines.get(&pipeline_id) self.webview_renderers
.get(webview_id)?
.pipelines
.get(&pipeline_id)
} }
// Check if any pipelines currently have active animations or animation callbacks. // Check if any pipelines currently have active animations or animation callbacks.
fn animations_or_animation_callbacks_running(&self) -> bool { fn animations_or_animation_callbacks_running(&self) -> bool {
self.webviews self.webview_renderers
.iter() .iter()
.any(WebView::animations_or_animation_callbacks_running) .any(WebViewRenderer::animations_or_animation_callbacks_running)
} }
/// Returns true if any animation callbacks (ie `requestAnimationFrame`) are waiting for a response. /// Returns true if any animation callbacks (ie `requestAnimationFrame`) are waiting for a response.
fn animation_callbacks_running(&self) -> bool { fn animation_callbacks_running(&self) -> bool {
self.webviews self.webview_renderers
.iter() .iter()
.any(WebView::animation_callbacks_running) .any(WebViewRenderer::animation_callbacks_running)
} }
/// Query the constellation to see if the current compositor /// Query the constellation to see if the current compositor
@ -1341,7 +1350,11 @@ impl IOCompositor {
// This gets sent to the constellation for comparison with the current // This gets sent to the constellation for comparison with the current
// frame tree. // frame tree.
let mut pipeline_epochs = HashMap::new(); let mut pipeline_epochs = HashMap::new();
for id in self.webviews.iter().flat_map(WebView::pipeline_ids) { for id in self
.webview_renderers
.iter()
.flat_map(WebViewRenderer::pipeline_ids)
{
if let Some(WebRenderEpoch(epoch)) = self if let Some(WebRenderEpoch(epoch)) = self
.webrender .webrender
.as_ref() .as_ref()
@ -1408,9 +1421,9 @@ impl IOCompositor {
let size = self.rendering_context.size2d().to_i32(); let size = self.rendering_context.size2d().to_i32();
let rect = if let Some(rect) = page_rect { let rect = if let Some(rect) = page_rect {
let scale = self let scale = self
.webviews .webview_renderers
.get(webview_id) .get(webview_id)
.map(WebView::device_pixels_per_page_pixel) .map(WebViewRenderer::device_pixels_per_page_pixel)
.unwrap_or_else(|| Scale::new(1.0)); .unwrap_or_else(|| Scale::new(1.0));
let rect = scale.transform_rect(&rect); let rect = scale.transform_rect(&rect);
@ -1507,8 +1520,8 @@ impl IOCompositor {
fn send_pending_paint_metrics_messages_after_composite(&mut self) { fn send_pending_paint_metrics_messages_after_composite(&mut self) {
let paint_time = CrossProcessInstant::now(); let paint_time = CrossProcessInstant::now();
let document_id = self.webrender_document(); let document_id = self.webrender_document();
for webview_details in self.webviews.iter_mut() { for webview_renderer in self.webview_renderers.iter_mut() {
for (pipeline_id, pipeline) in webview_details.pipelines.iter_mut() { for (pipeline_id, pipeline) in webview_renderer.pipelines.iter_mut() {
let Some(current_epoch) = self let Some(current_epoch) = self
.webrender .webrender
.as_ref() .as_ref()
@ -1646,11 +1659,11 @@ impl IOCompositor {
if let Err(err) = self.rendering_context.make_current() { if let Err(err) = self.rendering_context.make_current() {
warn!("Failed to make the rendering context current: {:?}", err); warn!("Failed to make the rendering context current: {:?}", err);
} }
let mut webviews = take(&mut self.webviews); let mut webview_renderers = take(&mut self.webview_renderers);
for webview in webviews.iter_mut() { for webview_renderer in webview_renderers.iter_mut() {
webview.process_pending_scroll_events(self); webview_renderer.process_pending_scroll_events(self);
} }
self.webviews = webviews; self.webview_renderers = webview_renderers;
self.global.borrow().shutdown_state() != ShutdownState::FinishedShuttingDown self.global.borrow().shutdown_state() != ShutdownState::FinishedShuttingDown
} }
@ -1735,8 +1748,8 @@ impl IOCompositor {
} }
pub fn notify_input_event(&mut self, webview_id: WebViewId, event: InputEvent) { pub fn notify_input_event(&mut self, webview_id: WebViewId, event: InputEvent) {
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
webview.notify_input_event(event); webview_renderer.notify_input_event(event);
} }
} }
@ -1747,20 +1760,20 @@ impl IOCompositor {
cursor: DeviceIntPoint, cursor: DeviceIntPoint,
event_type: TouchEventType, event_type: TouchEventType,
) { ) {
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
webview.notify_scroll_event(scroll_location, cursor, event_type); webview_renderer.notify_scroll_event(scroll_location, cursor, event_type);
} }
} }
pub fn on_vsync(&mut self, webview_id: WebViewId) { pub fn on_vsync(&mut self, webview_id: WebViewId) {
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
webview.on_vsync(); webview_renderer.on_vsync();
} }
} }
pub fn set_pinch_zoom(&mut self, webview_id: WebViewId, magnification: f32) { pub fn set_pinch_zoom(&mut self, webview_id: WebViewId, magnification: f32) {
if let Some(webview) = self.webviews.get_mut(webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
webview.set_pinch_zoom(magnification); webview_renderer.set_pinch_zoom(magnification);
} }
} }

View file

@ -23,8 +23,8 @@ mod tracing;
mod compositor; mod compositor;
mod touch; mod touch;
pub mod webview;
pub mod webview_manager; pub mod webview_manager;
pub mod webview_renderer;
/// Data used to construct a compositor. /// Data used to construct a compositor.
pub struct InitialCompositorState { pub struct InitialCompositorState {

View file

@ -7,7 +7,7 @@ use std::collections::hash_map::{Entry, Values, ValuesMut};
use base::id::WebViewId; use base::id::WebViewId;
use crate::webview::UnknownWebView; use crate::webview_renderer::UnknownWebView;
#[derive(Debug)] #[derive(Debug)]
pub struct WebViewManager<WebView> { pub struct WebViewManager<WebView> {
@ -117,8 +117,8 @@ mod test {
BrowsingContextId, BrowsingContextIndex, PipelineNamespace, PipelineNamespaceId, WebViewId, BrowsingContextId, BrowsingContextIndex, PipelineNamespace, PipelineNamespaceId, WebViewId,
}; };
use crate::webview::UnknownWebView;
use crate::webview_manager::WebViewManager; use crate::webview_manager::WebViewManager;
use crate::webview_renderer::UnknownWebView;
fn top_level_id(namespace_id: u32, index: u32) -> WebViewId { fn top_level_id(namespace_id: u32, index: u32) -> WebViewId {
WebViewId(BrowsingContextId { WebViewId(BrowsingContextId {

View file

@ -8,7 +8,7 @@ use std::collections::hash_map::Keys;
use std::rc::Rc; use std::rc::Rc;
use base::id::{PipelineId, WebViewId}; use base::id::{PipelineId, WebViewId};
use compositing_traits::{RendererWebView, SendableFrameTree}; use compositing_traits::{SendableFrameTree, WebViewTrait};
use constellation_traits::{EmbedderToConstellationMessage, ScrollState, WindowSizeType}; use constellation_traits::{EmbedderToConstellationMessage, ScrollState, WindowSizeType};
use embedder_traits::{ use embedder_traits::{
AnimationState, CompositorHitTestResult, InputEvent, MouseButton, MouseButtonAction, AnimationState, CompositorHitTestResult, InputEvent, MouseButton, MouseButtonAction,
@ -55,13 +55,16 @@ enum ScrollZoomEvent {
Scroll(ScrollEvent), Scroll(ScrollEvent),
} }
pub(crate) struct WebView { /// A renderer for a libservo `WebView`. This is essentially the [`ServoRenderer`]'s interface to a
/// libservo `WebView`, but the code here cannot depend on libservo in order to prevent circular
/// dependencies, which is why we store a `dyn WebViewTrait` here instead of the `WebView` itself.
pub(crate) struct WebViewRenderer {
/// The [`WebViewId`] of the `WebView` associated with this [`WebViewDetails`]. /// The [`WebViewId`] of the `WebView` associated with this [`WebViewDetails`].
pub id: WebViewId, pub id: WebViewId,
/// The renderer's view of the embedding layer `WebView` as a trait implementation, /// The renderer's view of the embedding layer `WebView` as a trait implementation,
/// so that the renderer doesn't need to depend on the embedding layer. This avoids /// so that the renderer doesn't need to depend on the embedding layer. This avoids
/// a dependency cycle. /// a dependency cycle.
pub renderer_webview: Box<dyn RendererWebView>, pub webview: Box<dyn WebViewTrait>,
/// The root [`PipelineId`] of the currently displayed page in this WebView. /// The root [`PipelineId`] of the currently displayed page in this WebView.
pub root_pipeline_id: Option<PipelineId>, pub root_pipeline_id: Option<PipelineId>,
pub rect: DeviceRect, pub rect: DeviceRect,
@ -85,7 +88,7 @@ pub(crate) struct WebView {
hidpi_scale_factor: Scale<f32, DeviceIndependentPixel, DevicePixel>, hidpi_scale_factor: Scale<f32, DeviceIndependentPixel, DevicePixel>,
} }
impl Drop for WebView { impl Drop for WebViewRenderer {
fn drop(&mut self) { fn drop(&mut self) {
self.global self.global
.borrow_mut() .borrow_mut()
@ -94,17 +97,17 @@ impl Drop for WebView {
} }
} }
impl WebView { impl WebViewRenderer {
pub(crate) fn new( pub(crate) fn new(
global: Rc<RefCell<ServoRenderer>>, global: Rc<RefCell<ServoRenderer>>,
renderer_webview: Box<dyn RendererWebView>, renderer_webview: Box<dyn WebViewTrait>,
viewport_details: ViewportDetails, viewport_details: ViewportDetails,
) -> Self { ) -> Self {
let hidpi_scale_factor = viewport_details.hidpi_scale_factor; let hidpi_scale_factor = viewport_details.hidpi_scale_factor;
let size = viewport_details.size * viewport_details.hidpi_scale_factor; let size = viewport_details.size * viewport_details.hidpi_scale_factor;
Self { Self {
id: renderer_webview.id(), id: renderer_webview.id(),
renderer_webview, webview: renderer_webview,
root_pipeline_id: None, root_pipeline_id: None,
rect: DeviceRect::from_origin_and_size(DevicePoint::origin(), size), rect: DeviceRect::from_origin_and_size(DevicePoint::origin(), size),
pipelines: Default::default(), pipelines: Default::default(),
@ -269,7 +272,7 @@ impl WebView {
}; };
let animating = self.pipelines.values().any(PipelineDetails::animating); let animating = self.pipelines.values().any(PipelineDetails::animating);
self.renderer_webview.set_animating(animating); self.webview.set_animating(animating);
throttled throttled
} }
@ -954,7 +957,7 @@ impl WebView {
&self, &self,
rendering_context_size: Size2D<u32, DevicePixel>, rendering_context_size: Size2D<u32, DevicePixel>,
) -> Box2D<i32, DeviceIndependentPixel> { ) -> Box2D<i32, DeviceIndependentPixel> {
let screen_geometry = self.renderer_webview.screen_geometry().unwrap_or_default(); let screen_geometry = self.webview.screen_geometry().unwrap_or_default();
let rect = DeviceIntRect::from_origin_and_size( let rect = DeviceIntRect::from_origin_and_size(
screen_geometry.offset, screen_geometry.offset,
rendering_context_size.to_i32(), rendering_context_size.to_i32(),
@ -965,12 +968,12 @@ impl WebView {
} }
pub(crate) fn screen_size(&self) -> Size2D<i32, DeviceIndependentPixel> { pub(crate) fn screen_size(&self) -> Size2D<i32, DeviceIndependentPixel> {
let screen_geometry = self.renderer_webview.screen_geometry().unwrap_or_default(); let screen_geometry = self.webview.screen_geometry().unwrap_or_default();
(screen_geometry.size.to_f32() / self.hidpi_scale_factor).to_i32() (screen_geometry.size.to_f32() / self.hidpi_scale_factor).to_i32()
} }
pub(crate) fn available_screen_size(&self) -> Size2D<i32, DeviceIndependentPixel> { pub(crate) fn available_screen_size(&self) -> Size2D<i32, DeviceIndependentPixel> {
let screen_geometry = self.renderer_webview.screen_geometry().unwrap_or_default(); let screen_geometry = self.webview.screen_geometry().unwrap_or_default();
(screen_geometry.available_size.to_f32() / self.hidpi_scale_factor).to_i32() (screen_geometry.available_size.to_f32() / self.hidpi_scale_factor).to_i32()
} }
} }

View file

@ -9,7 +9,7 @@ use std::time::Duration;
use base::id::WebViewId; use base::id::WebViewId;
use compositing::IOCompositor; use compositing::IOCompositor;
use compositing_traits::RendererWebView; use compositing_traits::WebViewTrait;
use constellation_traits::{EmbedderToConstellationMessage, TraversalDirection}; use constellation_traits::{EmbedderToConstellationMessage, TraversalDirection};
use dpi::PhysicalSize; use dpi::PhysicalSize;
use embedder_traits::{ use embedder_traits::{
@ -558,7 +558,7 @@ struct ServoRendererWebView {
weak_handle: Weak<RefCell<WebViewInner>>, weak_handle: Weak<RefCell<WebViewInner>>,
} }
impl RendererWebView for ServoRendererWebView { impl WebViewTrait for ServoRendererWebView {
fn id(&self) -> WebViewId { fn id(&self) -> WebViewId {
self.id self.id
} }

View file

@ -541,7 +541,7 @@ impl From<SerializableImageData> for ImageData {
/// A trait that exposes the embedding layer's `WebView` to the Servo renderer. /// A trait that exposes the embedding layer's `WebView` to the Servo renderer.
/// This is to prevent a dependency cycle between the renderer and the embedding /// This is to prevent a dependency cycle between the renderer and the embedding
/// layer. /// layer.
pub trait RendererWebView { pub trait WebViewTrait {
fn id(&self) -> WebViewId; fn id(&self) -> WebViewId;
fn screen_geometry(&self) -> Option<ScreenGeometry>; fn screen_geometry(&self) -> Option<ScreenGeometry>;
fn set_animating(&self, new_value: bool); fn set_animating(&self, new_value: bool);