aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/compositing/compositor.rs47
-rw-r--r--components/compositing/lib.rs3
-rw-r--r--components/constellation/constellation.rs6
-rw-r--r--components/embedder_traits/lib.rs3
-rw-r--r--components/servo/lib.rs8
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(