mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
separate waking the event loop, from communicating with a compositor
This commit is contained in:
parent
eac4f407e2
commit
3a693c7a23
9 changed files with 103 additions and 108 deletions
|
@ -103,7 +103,7 @@ pub struct IOCompositor<Window: WindowMethods> {
|
|||
window: Rc<Window>,
|
||||
|
||||
/// The port on which we receive messages.
|
||||
port: Box<CompositorReceiver>,
|
||||
port: CompositorReceiver,
|
||||
|
||||
/// The root pipeline.
|
||||
root_pipeline: Option<CompositionPipeline>,
|
||||
|
@ -133,7 +133,7 @@ pub struct IOCompositor<Window: WindowMethods> {
|
|||
/// The device pixel ratio for this window.
|
||||
scale_factor: ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>,
|
||||
|
||||
channel_to_self: Box<CompositorProxy + Send>,
|
||||
channel_to_self: CompositorProxy,
|
||||
|
||||
/// A handle to the delayed composition timer.
|
||||
delayed_composition_timer: DelayedCompositionTimerProxy,
|
||||
|
@ -317,11 +317,11 @@ fn initialize_png(gl: &gl::Gl, width: usize, height: usize) -> RenderTargetInfo
|
|||
}
|
||||
|
||||
struct RenderNotifier {
|
||||
compositor_proxy: Box<CompositorProxy>,
|
||||
compositor_proxy: CompositorProxy,
|
||||
}
|
||||
|
||||
impl RenderNotifier {
|
||||
fn new(compositor_proxy: Box<CompositorProxy>,
|
||||
fn new(compositor_proxy: CompositorProxy,
|
||||
_: Sender<ConstellationMsg>) -> RenderNotifier {
|
||||
RenderNotifier {
|
||||
compositor_proxy: compositor_proxy,
|
||||
|
@ -341,7 +341,7 @@ impl webrender_traits::RenderNotifier for RenderNotifier {
|
|||
|
||||
// Used to dispatch functions from webrender to the main thread's event loop.
|
||||
struct CompositorThreadDispatcher {
|
||||
compositor_proxy: Box<CompositorProxy>
|
||||
compositor_proxy: CompositorProxy
|
||||
}
|
||||
|
||||
impl webrender_traits::RenderDispatcher for CompositorThreadDispatcher {
|
||||
|
|
|
@ -22,32 +22,46 @@ use style_traits::viewport::ViewportConstraints;
|
|||
use webrender;
|
||||
use webrender_traits;
|
||||
|
||||
/// Sends messages to the compositor. This is a trait supplied by the port because the method used
|
||||
/// to communicate with the compositor may have to kick OS event loops awake, communicate cross-
|
||||
/// process, and so forth.
|
||||
pub trait CompositorProxy : 'static + Send {
|
||||
/// Sends a message to the compositor.
|
||||
fn send(&self, msg: Msg);
|
||||
/// Clones the compositor proxy.
|
||||
fn clone_compositor_proxy(&self) -> Box<CompositorProxy + 'static + Send>;
|
||||
|
||||
/// Used to wake up the event loop, provided by the servo port/embedder.
|
||||
pub trait EventLoopWaker : 'static + Send {
|
||||
fn clone(&self) -> Box<EventLoopWaker + Send>;
|
||||
fn wake(&self);
|
||||
}
|
||||
|
||||
/// The port that the compositor receives messages on. As above, this is a trait supplied by the
|
||||
/// Servo port.
|
||||
pub trait CompositorReceiver : 'static {
|
||||
/// Receives the next message inbound for the compositor. This must not block.
|
||||
fn try_recv_compositor_msg(&mut self) -> Option<Msg>;
|
||||
/// Synchronously waits for, and returns, the next message inbound for the compositor.
|
||||
fn recv_compositor_msg(&mut self) -> Msg;
|
||||
/// Sends messages to the compositor.
|
||||
pub struct CompositorProxy {
|
||||
pub sender: Sender<Msg>,
|
||||
pub event_loop_waker: Box<EventLoopWaker>,
|
||||
}
|
||||
|
||||
/// A convenience implementation of `CompositorReceiver` for a plain old Rust `Receiver`.
|
||||
impl CompositorReceiver for Receiver<Msg> {
|
||||
fn try_recv_compositor_msg(&mut self) -> Option<Msg> {
|
||||
self.try_recv().ok()
|
||||
impl CompositorProxy {
|
||||
pub fn send(&self, msg: Msg) {
|
||||
// Send a message and kick the OS event loop awake.
|
||||
if let Err(err) = self.sender.send(msg) {
|
||||
warn!("Failed to send response ({}).", err);
|
||||
}
|
||||
self.event_loop_waker.wake();
|
||||
}
|
||||
fn recv_compositor_msg(&mut self) -> Msg {
|
||||
self.recv().unwrap()
|
||||
pub fn clone_compositor_proxy(&self) -> CompositorProxy {
|
||||
CompositorProxy {
|
||||
sender: self.sender.clone(),
|
||||
event_loop_waker: self.event_loop_waker.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The port that the compositor receives messages on.
|
||||
pub struct CompositorReceiver {
|
||||
pub receiver: Receiver<Msg>
|
||||
}
|
||||
|
||||
impl CompositorReceiver {
|
||||
pub fn try_recv_compositor_msg(&mut self) -> Option<Msg> {
|
||||
self.receiver.try_recv().ok()
|
||||
}
|
||||
pub fn recv_compositor_msg(&mut self) -> Msg {
|
||||
self.receiver.recv().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +69,7 @@ pub trait RenderListener {
|
|||
fn recomposite(&mut self, reason: CompositingReason);
|
||||
}
|
||||
|
||||
impl RenderListener for Box<CompositorProxy + 'static> {
|
||||
impl RenderListener for CompositorProxy {
|
||||
fn recomposite(&mut self, reason: CompositingReason) {
|
||||
self.send(Msg::Recomposite(reason));
|
||||
}
|
||||
|
@ -173,9 +187,9 @@ impl Debug for Msg {
|
|||
/// Data used to construct a compositor.
|
||||
pub struct InitialCompositorState {
|
||||
/// A channel to the compositor.
|
||||
pub sender: Box<CompositorProxy + Send>,
|
||||
pub sender: CompositorProxy,
|
||||
/// A port on which messages inbound to the compositor can be received.
|
||||
pub receiver: Box<CompositorReceiver>,
|
||||
pub receiver: CompositorReceiver,
|
||||
/// A channel to the constellation.
|
||||
pub constellation_chan: Sender<ConstellationMsg>,
|
||||
/// A channel to the time profiler thread.
|
||||
|
|
|
@ -23,7 +23,7 @@ pub struct DelayedCompositionTimerProxy {
|
|||
}
|
||||
|
||||
struct DelayedCompositionTimer {
|
||||
compositor_proxy: Box<CompositorProxy>,
|
||||
compositor_proxy: CompositorProxy,
|
||||
receiver: Receiver<ToDelayedCompositionTimerMsg>,
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ enum ToDelayedCompositionTimerMsg {
|
|||
}
|
||||
|
||||
impl DelayedCompositionTimerProxy {
|
||||
pub fn new(compositor_proxy: Box<CompositorProxy + Send>) -> DelayedCompositionTimerProxy {
|
||||
pub fn new(compositor_proxy: CompositorProxy) -> DelayedCompositionTimerProxy {
|
||||
let (to_timer_sender, to_timer_receiver) = channel();
|
||||
Builder::new().spawn(move || {
|
||||
let mut timer = DelayedCompositionTimer {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
|
||||
|
||||
use compositor_thread::{CompositorProxy, CompositorReceiver};
|
||||
use compositor_thread::EventLoopWaker;
|
||||
use euclid::{Point2D, Size2D};
|
||||
use euclid::point::TypedPoint2D;
|
||||
use euclid::rect::TypedRect;
|
||||
|
@ -144,12 +144,8 @@ pub trait WindowMethods {
|
|||
/// Returns the scale factor of the system (device pixels / device independent pixels).
|
||||
fn hidpi_factor(&self) -> ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>;
|
||||
|
||||
/// Creates a channel to the compositor. The dummy parameter is needed because we don't have
|
||||
/// UFCS in Rust yet.
|
||||
///
|
||||
/// This is part of the windowing system because its implementation often involves OS-specific
|
||||
/// magic to wake the up window's event loop.
|
||||
fn create_compositor_channel(&self) -> (Box<CompositorProxy + Send>, Box<CompositorReceiver>);
|
||||
/// Returns a thread-safe object to wake up the window's event loop.
|
||||
fn create_event_loop_waker(&self) -> Box<EventLoopWaker>;
|
||||
|
||||
/// Requests that the window system prepare a composite. Typically this will involve making
|
||||
/// some type of platform-specific graphics context current. Returns true if the composite may
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue