Skip to content

Commit e3352a9

Browse files
authored
feat: switch to glutin (#163)
* Add rendering module * Remove swap chain * Generate GL bindings * Add create method * Add surface methods * Replace surfman with glutin context * Fix macOS * Fix wayland multiwindow * Remove unused dependencies * Remove comments * Fix typo --------- Signed-off-by: Ngo Iok Ui (Wu Yu Wei) <yuweiwu@pm.me> Co-authored-by: Wu Yuwei <Wu Yu Wei>
1 parent 7b61d8c commit e3352a9

8 files changed

+304
-153
lines changed

Cargo.lock

+59-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3-6
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ env_logger = "0.10"
5353
euclid = "0.22"
5454
getopts = "0.2.17"
5555
gleam = "0.15"
56+
glutin = "0.32.0"
57+
glutin-winit = "0.5.0"
5658
ipc-channel = "0.18"
5759
keyboard-types = "0.7"
5860
log = "0.4"
5961
raw-window-handle = { version = "0.6", features = ["std"] }
6062
sparkle = "0.1.26"
61-
surfman = { version = "0.9", features = ["chains", "sm-raw-window-handle-06"] }
6263
thiserror = "1.0"
6364
winit = { version = "0.30", features = ["rwh_06"] }
6465
# Servo repo crates
@@ -99,10 +100,6 @@ cargo-packager-resource-resolver = { version = "0.1.1", features = [
99100
], optional = true }
100101
url = "2.5.2"
101102

102-
[target.'cfg(target_os = "windows")'.dependencies]
103-
surfman = { version = "0.9", features = ["sm-angle-default"] }
104-
mozangle = { version = "0.5.1", features = ["egl", "build_dlls"] }
105-
106103
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
107104
objc2 = "0.5"
108105
objc2-app-kit = {version = "0.2", features = ["NSView", "NSResponder", "NSWindow"]}
@@ -117,4 +114,4 @@ lto = true
117114

118115
# Tell clippy to allow e.g. #[cfg(macos)]
119116
[lints.clippy]
120-
mismatched_target_os = "allow"
117+
mismatched_target_os = "allow"

src/compositor.rs

+35-87
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use script_traits::{
2424
};
2525
use servo_geometry::DeviceIndependentPixel;
2626
use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor};
27-
use surfman::Surface;
2827
use webrender::{RenderApi, Transaction};
2928
use webrender_api::units::{
3029
DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, LayoutPoint, LayoutRect, LayoutSize,
@@ -39,11 +38,11 @@ use webrender_api::{
3938
use webrender_traits::display_list::{HitTestInfo, ScrollTree};
4039
use webrender_traits::{
4140
CanvasToCompositorMsg, CompositorHitTestResult, FontToCompositorMsg, ImageUpdate,
42-
NetToCompositorMsg, RenderingContext, ScriptToCompositorMsg, SerializedImageUpdate,
43-
UntrustedNodeAddress,
41+
NetToCompositorMsg, ScriptToCompositorMsg, SerializedImageUpdate, UntrustedNodeAddress,
4442
};
4543
use winit::window::WindowId;
4644

45+
use crate::rendering::RenderingContext;
4746
use crate::touch::{TouchAction, TouchHandler};
4847
use crate::window::Window;
4948

@@ -104,9 +103,6 @@ const MIN_ZOOM: f32 = 0.1;
104103
/// The compositor will communicate with Servo using messages from the Constellation,
105104
/// then composite the WebRender frames and present the surface to the window.
106105
pub struct IOCompositor {
107-
/// All surfaces that Compositor currently owns.
108-
pub surfaces: HashMap<WindowId, Option<Surface>>,
109-
110106
/// The current window that Compositor is handling.
111107
pub current_window: WindowId,
112108

@@ -176,7 +172,7 @@ pub struct IOCompositor {
176172
/// The webrender interface, if enabled.
177173
pub webrender_api: RenderApi,
178174

179-
/// The surfman instance that webrender targets
175+
/// The glutin instance that webrender targets
180176
pub rendering_context: RenderingContext,
181177

182178
/// The GL bindings for webrender
@@ -348,10 +344,7 @@ impl IOCompositor {
348344
exit_after_load: bool,
349345
convert_mouse_to_touch: bool,
350346
) -> Self {
351-
let mut surfaces = HashMap::new();
352-
surfaces.insert(current_window, None);
353347
let compositor = IOCompositor {
354-
surfaces,
355348
current_window,
356349
viewport,
357350
port: state.receiver,
@@ -394,15 +387,7 @@ impl IOCompositor {
394387
}
395388

396389
/// Consume compositor itself and deinit webrender.
397-
pub fn deinit(mut self) {
398-
if let Err(err) = self.rendering_context.make_gl_context_current() {
399-
warn!("Failed to make GL context current: {:?}", err);
400-
}
401-
for surface in self.surfaces.values_mut() {
402-
surface
403-
.take()
404-
.map(|s| self.rendering_context.destroy_surface(s));
405-
}
390+
pub fn deinit(self) {
406391
self.webrender.deinit();
407392
}
408393

@@ -453,34 +438,6 @@ impl IOCompositor {
453438
self.shutdown_state = ShutdownState::FinishedShuttingDown;
454439
}
455440

456-
/// The underlying native surface can be lost during servo's lifetime.
457-
/// On Android, for example, this happens when the app is sent to background.
458-
/// We need to unbind the surface so that we don't try to use it again.
459-
pub fn invalidate_native_surface(&mut self) {
460-
debug!("Invalidating native surface in compositor");
461-
if let Err(e) = self.rendering_context.unbind_native_surface_from_context() {
462-
warn!("Unbinding native surface from context failed ({:?})", e);
463-
}
464-
}
465-
466-
/// On Android, this function will be called when the app moves to foreground
467-
/// and the system creates a new native surface that needs to bound to the current
468-
/// context.
469-
#[allow(unsafe_code)]
470-
#[allow(clippy::not_unsafe_ptr_arg_deref)] // It has an unsafe block inside
471-
pub fn replace_native_surface(&mut self, native_widget: *mut c_void, coords: DeviceIntSize) {
472-
debug!("Replacing native surface in compositor: {native_widget:?}");
473-
let connection = self.rendering_context.connection();
474-
let native_widget =
475-
unsafe { connection.create_native_widget_from_ptr(native_widget, coords.to_untyped()) };
476-
if let Err(e) = self
477-
.rendering_context
478-
.bind_native_surface_to_context(native_widget)
479-
{
480-
warn!("Binding native surface to context failed ({:?})", e);
481-
}
482-
}
483-
484441
fn handle_browser_message(
485442
&mut self,
486443
msg: CompositorMsg,
@@ -1282,23 +1239,16 @@ impl IOCompositor {
12821239
self.current_window,
12831240
window.id()
12841241
);
1285-
if let Some(Some(new_surface)) = self.surfaces.insert(window.id(), None) {
1286-
// Swap the surface
1287-
self.rendering_context.with_front_buffer(|_, old_surface| {
1288-
self.surfaces.insert(self.current_window, Some(old_surface));
1289-
new_surface
1290-
});
1291-
self.current_window = window.id();
1292-
self.scale_factor = Scale::new(window.scale_factor() as f32);
1293-
self.resize(window.size(), window);
1294-
}
1242+
self.current_window = window.id();
1243+
self.scale_factor = Scale::new(window.scale_factor() as f32);
1244+
self.resize(window.size(), window);
12951245
}
12961246
}
12971247

12981248
/// Resize the rendering context and all web views. Return true if the compositor should repaint and present
12991249
/// after this.
13001250
pub fn resize(&mut self, size: Size2D<i32, DevicePixel>, window: &mut Window) -> bool {
1301-
let need_resize = self.on_resize_window_event(size);
1251+
let need_resize = self.on_resize_window_event(size, window);
13021252

13031253
if let Some(panel) = &mut window.panel {
13041254
let rect = DeviceIntRect::from_size(size);
@@ -1319,12 +1269,14 @@ impl IOCompositor {
13191269

13201270
/// Handle the window resize event and return a boolean to tell embedder if it should further
13211271
/// handle the resize event.
1322-
pub fn on_resize_window_event(&mut self, new_viewport: DeviceIntSize) -> bool {
1272+
pub fn on_resize_window_event(&mut self, new_viewport: DeviceIntSize, window: &Window) -> bool {
13231273
if self.shutdown_state != ShutdownState::NotShuttingDown {
13241274
return false;
13251275
}
13261276

1327-
let _ = self.rendering_context.resize(new_viewport.to_untyped());
1277+
let _ = self
1278+
.rendering_context
1279+
.resize(&window.surface, new_viewport.to_untyped());
13281280
self.viewport = new_viewport;
13291281
let mut transaction = Transaction::new();
13301282
transaction.set_document_view(DeviceIntRect::from_size(self.viewport));
@@ -1959,8 +1911,8 @@ impl IOCompositor {
19591911
}
19601912

19611913
/// Composite to the given target if any, or the current target otherwise.
1962-
pub fn composite(&mut self) {
1963-
match self.composite_specific_target() {
1914+
pub fn composite(&mut self, window: &Window) {
1915+
match self.composite_specific_target(window) {
19641916
Ok(_) => {
19651917
if self.exit_after_load {
19661918
println!("Shutting down the Constellation after generating an output file or exit flag specified");
@@ -1974,8 +1926,11 @@ impl IOCompositor {
19741926
}
19751927

19761928
/// Composite to the given target if any, or the current target otherwise.
1977-
fn composite_specific_target(&mut self) -> Result<(), UnableToComposite> {
1978-
if let Err(err) = self.rendering_context.make_gl_context_current() {
1929+
fn composite_specific_target(&mut self, window: &Window) -> Result<(), UnableToComposite> {
1930+
if let Err(err) = self
1931+
.rendering_context
1932+
.make_gl_context_current(&window.surface)
1933+
{
19791934
warn!("Failed to make GL context current: {:?}", err);
19801935
}
19811936
self.assert_no_gl_error();
@@ -1999,17 +1954,6 @@ impl IOCompositor {
19991954
}
20001955
}
20011956

2002-
// Bind the webrender framebuffer
2003-
let framebuffer_object = self
2004-
.rendering_context
2005-
.context_surface_info()
2006-
.unwrap_or(None)
2007-
.map(|info| info.framebuffer_object)
2008-
.unwrap_or(0);
2009-
self.webrender_gl
2010-
.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_object);
2011-
self.assert_gl_framebuffer_complete();
2012-
20131957
profile(
20141958
ProfilerCategory::Compositing,
20151959
None,
@@ -2071,7 +2015,7 @@ impl IOCompositor {
20712015
}
20722016
}
20732017

2074-
if let Err(err) = self.rendering_context.present() {
2018+
if let Err(err) = self.rendering_context.present(&window.surface) {
20752019
warn!("Failed to present surface: {:?}", err);
20762020
}
20772021
self.composition_request = CompositionRequest::NoCompositingNecessary;
@@ -2147,19 +2091,21 @@ impl IOCompositor {
21472091
self.zoom_action = false;
21482092
}
21492093

2150-
match self.composition_request {
2151-
CompositionRequest::NoCompositingNecessary => {}
2152-
CompositionRequest::CompositeNow(_) => self.composite(),
2153-
}
2094+
if let Some(window) = windows.get(&self.current_window) {
2095+
match self.composition_request {
2096+
CompositionRequest::NoCompositingNecessary => {}
2097+
CompositionRequest::CompositeNow(_) => self.composite(window),
2098+
}
21542099

2155-
// Run the WebXR main thread
2156-
self.webxr_main_thread.run_one_frame();
2100+
// Run the WebXR main thread
2101+
self.webxr_main_thread.run_one_frame();
21572102

2158-
// The WebXR thread may make a different context current
2159-
let _ = self.rendering_context.make_gl_context_current();
2103+
// The WebXR thread may make a different context current
2104+
let _ = self
2105+
.rendering_context
2106+
.make_gl_context_current(&window.surface);
21602107

2161-
if !self.pending_scroll_zoom_events.is_empty() {
2162-
if let Some(window) = windows.get(&self.current_window) {
2108+
if !self.pending_scroll_zoom_events.is_empty() {
21632109
self.process_pending_scroll_events(window)
21642110
}
21652111
}
@@ -2175,7 +2121,9 @@ impl IOCompositor {
21752121
let need_recomposite = matches!(msg, CompositorMsg::NewWebRenderFrameReady(_));
21762122
let keep_going = self.handle_browser_message(msg, windows);
21772123
if need_recomposite {
2178-
self.composite();
2124+
if let Some(window) = windows.get(&self.current_window) {
2125+
self.composite(window);
2126+
}
21792127
break;
21802128
}
21812129
if !keep_going {

src/errors.rs

+3
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@ pub enum Error {
1111
/// A general error that may occur while running the Winit event loop.
1212
#[error(transparent)]
1313
EventLoopError(#[from] winit::error::EventLoopError),
14+
/// Glutin errors.
15+
#[error(transparent)]
16+
GlutinError(#[from] glutin::error::Error),
1417
}

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ pub mod config;
1313
pub mod errors;
1414
/// Utilities to handle keyboard inputs and states.
1515
pub mod keyboard;
16+
/// Verso's rendering context.
17+
pub mod rendering;
1618
/// Utilities to handle touch inputs and states.
1719
pub mod touch;
1820
/// Main entry types and functions.

0 commit comments

Comments
 (0)