diff options
author | Delan Azabani <dazabani@igalia.com> | 2023-08-15 08:08:50 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-15 08:08:50 +0000 |
commit | 2778beeb7a623e0150e5084da14afa884b76f656 (patch) | |
tree | 4a227f7e718bf54dd38f9cb56d28559fa87feba6 /components/compositing/compositor.rs | |
parent | a7bd9f0d43f4de13c958eaea53709e8fc0d162c8 (diff) | |
download | servo-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.rs | 47 |
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. |