mod constellation_msg;
use std::fmt::{Debug, Error, Formatter};
use base::id::{PipelineId, TopLevelBrowsingContextId};
use base::Epoch;
pub use constellation_msg::ConstellationMsg;
use crossbeam_channel::{Receiver, Sender};
use embedder_traits::EventLoopWaker;
use euclid::Rect;
use ipc_channel::ipc::IpcSender;
use log::warn;
use pixels::Image;
use script_traits::{
AnimationState, ConstellationControlMsg, EventResult, MouseButton, MouseEventType,
};
use style_traits::CSSPixel;
use webrender_api::units::DeviceRect;
use webrender_api::DocumentId;
use webrender_traits::{CrossProcessCompositorApi, CrossProcessCompositorMessage};
#[derive(Clone)]
pub struct CompositorProxy {
pub sender: Sender<CompositorMsg>,
pub cross_process_compositor_api: CrossProcessCompositorApi,
pub event_loop_waker: Box<dyn EventLoopWaker>,
}
impl CompositorProxy {
pub fn send(&self, msg: CompositorMsg) {
if let Err(err) = self.sender.send(msg) {
warn!("Failed to send response ({:?}).", err);
}
self.event_loop_waker.wake();
}
}
pub struct CompositorReceiver {
pub receiver: Receiver<CompositorMsg>,
}
impl CompositorReceiver {
pub fn try_recv_compositor_msg(&mut self) -> Option<CompositorMsg> {
self.receiver.try_recv().ok()
}
pub fn recv_compositor_msg(&mut self) -> CompositorMsg {
self.receiver.recv().unwrap()
}
}
pub enum CompositorMsg {
ShutdownComplete,
ChangeRunningAnimationsState(PipelineId, AnimationState),
CreateOrUpdateWebView(SendableFrameTree),
RemoveWebView(TopLevelBrowsingContextId),
MoveResizeWebView(TopLevelBrowsingContextId, DeviceRect),
ShowWebView(TopLevelBrowsingContextId, bool),
HideWebView(TopLevelBrowsingContextId),
RaiseWebViewToTop(TopLevelBrowsingContextId, bool),
TouchEventProcessed(EventResult),
CreatePng(Option<Rect<f32, CSSPixel>>, IpcSender<Option<Image>>),
IsReadyToSaveImageReply(bool),
SetThrottled(PipelineId, bool),
NewWebRenderFrameReady(DocumentId, bool),
PipelineExited(PipelineId, IpcSender<()>),
PendingPaintMetric(PipelineId, Epoch),
LoadComplete(TopLevelBrowsingContextId),
WebDriverMouseButtonEvent(MouseEventType, MouseButton, f32, f32),
WebDriverMouseMoveEvent(f32, f32),
CrossProcess(CrossProcessCompositorMessage),
}
pub struct SendableFrameTree {
pub pipeline: CompositionPipeline,
pub children: Vec<SendableFrameTree>,
}
#[derive(Clone)]
pub struct CompositionPipeline {
pub id: PipelineId,
pub top_level_browsing_context_id: TopLevelBrowsingContextId,
pub script_chan: IpcSender<ConstellationControlMsg>,
}
impl Debug for CompositorMsg {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
match *self {
CompositorMsg::ShutdownComplete => write!(f, "ShutdownComplete"),
CompositorMsg::ChangeRunningAnimationsState(_, state) => {
write!(f, "ChangeRunningAnimationsState({:?})", state)
},
CompositorMsg::CreateOrUpdateWebView(..) => write!(f, "CreateOrUpdateWebView"),
CompositorMsg::RemoveWebView(..) => write!(f, "RemoveWebView"),
CompositorMsg::MoveResizeWebView(..) => write!(f, "MoveResizeWebView"),
CompositorMsg::ShowWebView(..) => write!(f, "ShowWebView"),
CompositorMsg::HideWebView(..) => write!(f, "HideWebView"),
CompositorMsg::RaiseWebViewToTop(..) => write!(f, "RaiseWebViewToTop"),
CompositorMsg::TouchEventProcessed(..) => write!(f, "TouchEventProcessed"),
CompositorMsg::CreatePng(..) => write!(f, "CreatePng"),
CompositorMsg::IsReadyToSaveImageReply(..) => write!(f, "IsReadyToSaveImageReply"),
CompositorMsg::SetThrottled(..) => write!(f, "SetThrottled"),
CompositorMsg::PipelineExited(..) => write!(f, "PipelineExited"),
CompositorMsg::NewWebRenderFrameReady(..) => write!(f, "NewWebRenderFrameReady"),
CompositorMsg::PendingPaintMetric(..) => write!(f, "PendingPaintMetric"),
CompositorMsg::LoadComplete(..) => write!(f, "LoadComplete"),
CompositorMsg::WebDriverMouseButtonEvent(..) => write!(f, "WebDriverMouseButtonEvent"),
CompositorMsg::WebDriverMouseMoveEvent(..) => write!(f, "WebDriverMouseMoveEvent"),
CompositorMsg::CrossProcess(..) => write!(f, "CrossProcess"),
}
}
}