diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/compositing/compositor.rs | 47 | ||||
-rw-r--r-- | components/compositing/lib.rs | 3 | ||||
-rw-r--r-- | components/constellation/constellation.rs | 6 | ||||
-rw-r--r-- | components/embedder_traits/lib.rs | 3 | ||||
-rw-r--r-- | components/servo/lib.rs | 8 |
5 files changed, 61 insertions, 6 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 67cecd6a4a0..8eed1ed3f66 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -230,6 +230,13 @@ pub struct IOCompositor<Window: WindowMethods + ?Sized> { /// taken before the render is complete will not reflect the /// most up to date rendering. waiting_on_pending_frame: bool, + + /// Whether to send a ReadyToPresent message to the constellation after rendering a new frame, + /// allowing external code to draw to the framebuffer and decide when to present the frame. + external_present: bool, + + /// Waiting for external code to call present. + waiting_on_present: bool, } #[derive(Clone, Copy)] @@ -382,6 +389,8 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { exit_after_load, convert_mouse_to_touch, waiting_on_pending_frame: false, + external_present: false, + waiting_on_present: false, } } @@ -1525,6 +1534,12 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { target: CompositeTarget, rect: Option<Rect<f32, CSSPixel>>, ) -> Result<Option<Image>, UnableToComposite> { + if self.waiting_on_present { + return Err(UnableToComposite::NotReadyToPaintImage( + NotReadyToPaint::WaitingOnConstellation, + )); + } + let size = self.embedder_coordinates.framebuffer.to_u32(); if let Err(err) = self.webrender_surfman.make_gl_context_current() { @@ -1703,8 +1718,15 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { }; // Perform the page flip. This will likely block for a while. - if let Err(err) = self.webrender_surfman.present() { - warn!("Failed to present surface: {:?}", err); + if self.external_present { + self.waiting_on_present = true; + let msg = + ConstellationMsg::ReadyToPresent(self.root_pipeline.top_level_browsing_context_id); + if let Err(e) = self.constellation_chan.send(msg) { + warn!("Sending event to constellation failed ({:?}).", e); + } + } else { + self.present(); } self.composition_request = CompositionRequest::NoCompositingNecessary; @@ -1715,6 +1737,13 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { Ok(rv) } + pub fn present(&mut self) { + if let Err(err) = self.webrender_surfman.present() { + warn!("Failed to present surface: {:?}", err); + } + self.waiting_on_present = false; + } + fn composite_if_necessary(&mut self, reason: CompositingReason) { if self.composition_request == CompositionRequest::NoCompositingNecessary { if self.is_running_problem_test { @@ -1733,10 +1762,12 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { let gl = &self.webrender_gl; self.assert_gl_framebuffer_complete(); - // Make framebuffer fully transparent. - gl.clear_color(0.0, 0.0, 0.0, 0.0); - gl.clear(gleam::gl::COLOR_BUFFER_BIT); - self.assert_gl_framebuffer_complete(); + if !self.external_present { + // Make framebuffer fully transparent. + gl.clear_color(0.0, 0.0, 0.0, 0.0); + gl.clear(gleam::gl::COLOR_BUFFER_BIT); + self.assert_gl_framebuffer_complete(); + } // Make the viewport white. let viewport = self.embedder_coordinates.get_flipped_viewport(); @@ -1919,6 +1950,10 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { None => eprintln!("Unable to locate path to save captures"), } } + + pub fn set_external_present(&mut self, value: bool) { + self.external_present = value; + } } /// Why we performed a composite. This is used for debugging. diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index 4f29cfc1662..554f36df833 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -109,6 +109,8 @@ pub enum ConstellationMsg { ChangeBrowserVisibility(TopLevelBrowsingContextId, bool), /// Virtual keyboard was dismissed IMEDismissed, + /// Compositing done, but external code needs to present. + ReadyToPresent(TopLevelBrowsingContextId), } impl fmt::Debug for ConstellationMsg { @@ -142,6 +144,7 @@ impl fmt::Debug for ConstellationMsg { ChangeBrowserVisibility(..) => "ChangeBrowserVisibility", IMEDismissed => "IMEDismissed", ClearCache => "ClearCache", + ReadyToPresent(..) => "ReadyToPresent", }; write!(formatter, "ConstellationMsg::{}", variant) } diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 5982f5ce76d..cf4ca3eb41b 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -1551,6 +1551,12 @@ where FromCompositorMsg::ChangeBrowserVisibility(top_level_browsing_context_id, visible) => { self.handle_change_browser_visibility(top_level_browsing_context_id, visible); }, + FromCompositorMsg::ReadyToPresent(top_level_browsing_context_id) => { + self.embedder_proxy.send(( + Some(top_level_browsing_context_id), + EmbedderMsg::ReadyToPresent, + )); + }, } } diff --git a/components/embedder_traits/lib.rs b/components/embedder_traits/lib.rs index 8654732735d..da117823340 100644 --- a/components/embedder_traits/lib.rs +++ b/components/embedder_traits/lib.rs @@ -212,6 +212,8 @@ pub enum EmbedderMsg { MediaSessionEvent(MediaSessionEvent), /// Report the status of Devtools Server with a token that can be used to bypass the permission prompt. OnDevtoolsStarted(Result<u16, ()>, String), + /// Compositing done, but external code needs to present. + ReadyToPresent, } impl Debug for EmbedderMsg { @@ -248,6 +250,7 @@ impl Debug for EmbedderMsg { EmbedderMsg::MediaSessionEvent(..) => write!(f, "MediaSessionEvent"), EmbedderMsg::OnDevtoolsStarted(..) => write!(f, "OnDevtoolsStarted"), EmbedderMsg::ShowContextMenu(..) => write!(f, "ShowContextMenu"), + EmbedderMsg::ReadyToPresent => write!(f, "ReadyToPresent"), } } } diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 51df1f0c991..91a263d450e 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -801,6 +801,14 @@ where pub fn deinit(self) { self.compositor.deinit(); } + + pub fn set_external_present(&mut self, value: bool) { + self.compositor.set_external_present(value) + } + + pub fn present(&mut self) { + self.compositor.present(); + } } fn create_embedder_channel( |