aboutsummaryrefslogtreecommitdiffstats
path: root/components/compositing/compositor.rs
diff options
context:
space:
mode:
authorDelan Azabani <dazabani@igalia.com>2023-08-15 08:08:50 +0000
committerGitHub <noreply@github.com>2023-08-15 08:08:50 +0000
commit2778beeb7a623e0150e5084da14afa884b76f656 (patch)
tree4a227f7e718bf54dd38f9cb56d28559fa87feba6 /components/compositing/compositor.rs
parenta7bd9f0d43f4de13c958eaea53709e8fc0d162c8 (diff)
downloadservo-2778beeb7a623e0150e5084da14afa884b76f656.tar.gz
servo-2778beeb7a623e0150e5084da14afa884b76f656.zip
winit: initial minibrowser (#29976)
* winit: add minibrowser feature that depends on egui{,-winit} * winit: carve out some space at the top of headed windows * winit: minimal toolbar and egui/winit integration (but no painting) * winit: try to paint with egui_glow (doesn’t work yet) * winit: add comment about toolbar size * Add framebuffer object, set it as glow's target * compositing: clear only the viewport, not the whole framebuffer * plumb the actual size of the egui toolbar to webrender * fix formatting * winit: fix crash when fbo is zero * winit: don’t bother binding the framebuffer object * winit: remove unsafe and get toolbar_height * winit: location field should reflect the current top-level url * [NFC] winit: move Minibrowser out of App::run * winit: clean up toolbar height code * winit: make App own the Minibrowser if any * winit: make the go button work * winit:make the location field reflect the current top-level url * winit: allow enabling minibrowser from command line * winit: tell compositor to repaint WR and flush when we repaint * winit: fix bug where location field edits would get overridden * winit: borrow the minibrowser once in App::handle_events * winit: address todo about viewport origin coordinates * winit: fix some minor problems with comments and errors * winit: update location field once per HistoryChanged event * winit: rename Window::set_toolbar_size to set_toolbar_height * winit: take toolbar height into account in hit testing * winit: pass egui only relevant CursorMoved events * winit: scratch that, coalesce minibrowser updates instead * ensure both minibrowser and WR are repainted on every frame * compositing: only skip framebuffer clear in external present mode * winit: destroy egui glow Painter when shutting down * winit: clean up and fix license lint * fix duplicate versions lint by downgrading bytemuck_derive was egui_glow ^0.22.0 (0.22.0) → egui/bytemuck ^0.22.0 (0.22.0) → epaint/bytemuck ^0.22.0 (0.22.0) → bytemuck ^1.7.2 (1.13.1) → bytemuck_derive ^1.4 (1.4.1) → syn ^2.0.1 (2.0.28) now lock has bytemuck_derive 1.4.0 → syn ^1.0.99 (1.0.103) * fix duplicate versions lint by disabling egui-winit/links (we don’t need support for hyperlinks in our use of egui) * squelch duplicate versions lint by excluding clipboard-win * winit: fix compile warnings * winit: make gleam an optional dependency under /minibrowser * winit: remove cargo feature, since it’s not really optional * winit: extract Minibrowser and related code to separate module * winit: remove unnecessary trailing comma * winit: simplify the ServoUrl serialisation optimisation --------- Co-authored-by: atbrakhi <atbrakhi@igalia.com>
Diffstat (limited to 'components/compositing/compositor.rs')
-rw-r--r--components/compositing/compositor.rs47
1 files changed, 41 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.