diff --git a/Cargo.lock b/Cargo.lock index 1d7d308c1c0..18a1caed960 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8609,6 +8609,7 @@ dependencies = [ "libc", "log", "serde", + "servo-media", "servo_geometry", "surfman", "webrender_api", diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs index 605e632ddcb..c72c8536e6f 100644 --- a/components/canvas/webgl_mode/inprocess.rs +++ b/components/canvas/webgl_mode/inprocess.rs @@ -48,6 +48,10 @@ impl WebGLComm { let webxr_init = crate::webxr::WebXRBridgeInit::new(sender.clone()); #[cfg(feature = "webxr")] let webxr_layer_grand_manager = webxr_init.layer_grand_manager(); + let connection = surfman::Connection::new().expect("Failed to create connection"); + let adapter = connection + .create_adapter() + .expect("Failed to create adapter"); // This implementation creates a single `WebGLThread` for all the pipelines. let init = WebGLThreadInit { @@ -57,8 +61,8 @@ impl WebGLComm { sender: sender.clone(), receiver, webrender_swap_chains: webrender_swap_chains.clone(), - connection: rendering_context.connection(), - adapter: rendering_context.adapter(), + connection, + adapter, api_type, #[cfg(feature = "webxr")] webxr_init, @@ -100,23 +104,30 @@ impl WebGLExternalImages { debug!("... locking chain {:?}", id); let front_buffer = self.swap_chains.get(id)?.take_surface()?; - let (surface_texture, gl_texture, size) = - self.rendering_context.create_texture(front_buffer); + if let Some((surface_texture, gl_texture, size)) = + self.rendering_context.create_texture(front_buffer) + { + self.locked_front_buffers.insert(id, surface_texture); - self.locked_front_buffers.insert(id, surface_texture); - - Some((gl_texture, size)) + Some((gl_texture, size)) + } else { + None + } } fn unlock_swap_chain(&mut self, id: WebGLContextId) -> Option<()> { - let locked_front_buffer = self.locked_front_buffers.remove(&id)?; - let locked_front_buffer = self.rendering_context.destroy_texture(locked_front_buffer); - debug!("... unlocked chain {:?}", id); - self.swap_chains - .get(id)? - .recycle_surface(locked_front_buffer); - Some(()) + let locked_front_buffer = self.locked_front_buffers.remove(&id)?; + if let Some(locked_front_buffer) = + self.rendering_context.destroy_texture(locked_front_buffer) + { + self.swap_chains + .get(id)? + .recycle_surface(locked_front_buffer); + Some(()) + } else { + None + } } } diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 435860f3453..f882fe9d867 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -479,23 +479,6 @@ impl IOCompositor { self.shutdown_state = ShutdownState::FinishedShuttingDown; } - /// The underlying native surface can be lost during servo's lifetime. - /// On Android, for example, this happens when the app is sent to background. - /// We need to unbind the surface so that we don't try to use it again. - pub fn invalidate_native_surface(&mut self) { - debug!("Invalidating native surface in compositor"); - self.rendering_context.invalidate_native_surface(); - } - - /// On Android, this function will be called when the app moves to foreground - /// and the system creates a new native surface that needs to bound to the current - /// context. - pub fn replace_native_surface(&mut self, native_widget: *mut c_void, coords: DeviceIntSize) { - debug!("Replacing native surface in compositor: {native_widget:?}"); - self.rendering_context - .replace_native_surface(native_widget, coords); - } - fn handle_browser_message(&mut self, msg: CompositorMsg) -> bool { trace_msg_from_constellation!(msg, "{msg:?}"); diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 442499c1eb5..8db640a89a1 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -14,7 +14,6 @@ use embedder_traits::{ }; use euclid::Scale; use keyboard_types::{CompositionEvent, KeyboardEvent}; -use libc::c_void; use net::protocols::ProtocolRegistry; use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize, DeviceIndependentPixel}; use servo_url::ServoUrl; @@ -119,14 +118,6 @@ pub enum EmbedderEvent { SetWebViewThrottled(TopLevelBrowsingContextId, bool), /// Virtual keyboard was dismissed IMEDismissed, - /// Sent on platforms like Android where the native widget surface can be - /// automatically destroyed by the system, for example when the app - /// is sent to background. - InvalidateNativeSurface, - /// Sent on platforms like Android where system recreates a new surface for - /// the native widget when it is brough back to foreground. This event - /// carries the pointer to the native widget and its new size. - ReplaceNativeSurface(*mut c_void, DeviceIntSize), /// Sent when new Gamepad information is available. Gamepad(GamepadEvent), /// Vertical Synchronization tick @@ -190,8 +181,6 @@ impl Debug for EmbedderEvent { EmbedderEvent::SetWebViewThrottled(..) => write!(f, "SetWebViewThrottled"), EmbedderEvent::IMEDismissed => write!(f, "IMEDismissed"), EmbedderEvent::ClearCache => write!(f, "ClearCache"), - EmbedderEvent::InvalidateNativeSurface => write!(f, "InvalidateNativeSurface"), - EmbedderEvent::ReplaceNativeSurface(..) => write!(f, "ReplaceNativeSurface"), EmbedderEvent::Gamepad(..) => write!(f, "Gamepad"), EmbedderEvent::Vsync => write!(f, "Vsync"), EmbedderEvent::ClipboardAction(_) => write!(f, "ClipboardAction"), diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index d0634b45cf3..6efc9c6b51b 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -22,7 +22,7 @@ layout_2013 = ["dep:layout_thread_2013"] media-gstreamer = ["servo-media-gstreamer", "gstreamer"] multiview = ["compositing/multiview", "constellation/multiview"] native-bluetooth = ["bluetooth/native-bluetooth"] -no-wgl = ["mozangle/egl", "mozangle/build_dlls", "surfman/sm-angle-default"] +no-wgl = ["mozangle/egl", "mozangle/build_dlls", "surfman/sm-angle-default", "webrender_traits/no-wgl"] dynamic_freetype = ["webrender/dynamic_freetype"] profilemozjs = ["script/profilemozjs"] refcell_backtrace = ["script/refcell_backtrace"] diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 7e961f35f20..f2928ed93ce 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -92,20 +92,13 @@ use servo_delegate::DefaultServoDelegate; use servo_media::player::context::GlContext; use servo_media::ServoMedia; use servo_url::ServoUrl; -#[cfg(all(target_os = "linux", not(target_env = "ohos")))] -use surfman::platform::generic::multi::connection::NativeConnection as LinuxNativeConnection; -#[cfg(all(target_os = "linux", not(target_env = "ohos")))] -use surfman::platform::generic::multi::context::NativeContext as LinuxNativeContext; -use surfman::{GLApi, GLVersion}; -#[cfg(all(target_os = "linux", not(target_env = "ohos")))] -use surfman::{NativeConnection, NativeContext}; #[cfg(feature = "webgpu")] pub use webgpu; #[cfg(feature = "webgpu")] use webgpu::swapchain::WGPUImageMap; use webrender::{RenderApiSender, ShaderPrecacheFlags, UploadMethod, ONE_TIME_USAGE_HINT}; use webrender_api::{ColorF, DocumentId, FramePublishId}; -use webrender_traits::rendering_context::RenderingContext; +use webrender_traits::rendering_context::{GLVersion, RenderingContext}; use webrender_traits::{ CrossProcessCompositorApi, WebrenderExternalImageHandlers, WebrenderExternalImageRegistry, WebrenderImageHandlerType, @@ -558,58 +551,6 @@ impl Servo { self.delegate = delegate; } - #[cfg(all(target_os = "linux", not(target_env = "ohos")))] - fn get_native_media_display_and_gl_context( - rendering_context: &Rc, - ) -> Option<(NativeDisplay, GlContext)> { - let gl_context = match rendering_context.context() { - NativeContext::Default(LinuxNativeContext::Default(native_context)) => { - GlContext::Egl(native_context.egl_context as usize) - }, - NativeContext::Default(LinuxNativeContext::Alternate(native_context)) => { - GlContext::Egl(native_context.egl_context as usize) - }, - NativeContext::Alternate(_) => return None, - }; - - let native_display = match rendering_context.connection().native_connection() { - NativeConnection::Default(LinuxNativeConnection::Default(connection)) => { - NativeDisplay::Egl(connection.0 as usize) - }, - NativeConnection::Default(LinuxNativeConnection::Alternate(connection)) => { - NativeDisplay::X11(connection.x11_display as usize) - }, - NativeConnection::Alternate(_) => return None, - }; - Some((native_display, gl_context)) - } - - // @TODO(victor): https://github.com/servo/media/pull/315 - #[cfg(target_os = "windows")] - fn get_native_media_display_and_gl_context( - rendering_context: &Rc, - ) -> Option<(NativeDisplay, GlContext)> { - #[cfg(feature = "no-wgl")] - { - let gl_context = GlContext::Egl(rendering_context.context().egl_context as usize); - let native_display = - NativeDisplay::Egl(rendering_context.device().egl_display as usize); - Some((native_display, gl_context)) - } - #[cfg(not(feature = "no-wgl"))] - None - } - - #[cfg(not(any( - target_os = "windows", - all(target_os = "linux", not(target_env = "ohos")) - )))] - fn get_native_media_display_and_gl_context( - _rendering_context: &Rc, - ) -> Option<(NativeDisplay, GlContext)> { - None - } - fn create_media_window_gl_context( external_image_handlers: &mut WebrenderExternalImageHandlers, external_images: Arc>, @@ -627,28 +568,34 @@ impl Servo { ); } - let (native_display, gl_context) = - match Self::get_native_media_display_and_gl_context(rendering_context) { - Some((native_display, gl_context)) => (native_display, gl_context), - None => { - return ( - WindowGLContext { - gl_context: GlContext::Unknown, - gl_api: GlApi::None, - native_display: NativeDisplay::Unknown, - glplayer_chan: None, - }, - None, - ); + let native_display = rendering_context.gl_display(); + let gl_context = rendering_context.gl_context(); + if let (NativeDisplay::Unknown, GlContext::Unknown) = (&native_display, &gl_context) { + return ( + WindowGLContext { + gl_context: GlContext::Unknown, + gl_api: GlApi::None, + native_display: NativeDisplay::Unknown, + glplayer_chan: None, }, - }; - let api = rendering_context.connection().gl_api(); - let GLVersion { major, minor } = rendering_context.gl_version(); - let gl_api = match api { - GLApi::GL if major >= 3 && minor >= 2 => GlApi::OpenGL3, - GLApi::GL => GlApi::OpenGL, - GLApi::GLES if major > 1 => GlApi::Gles2, - GLApi::GLES => GlApi::Gles1, + None, + ); + } + let gl_api = match rendering_context.gl_version() { + GLVersion::GL(major, minor) => { + if major >= 3 && minor >= 2 { + GlApi::OpenGL3 + } else { + GlApi::OpenGL + } + }, + GLVersion::GLES(major, _) => { + if major > 1 { + GlApi::Gles2 + } else { + GlApi::Gles1 + } + }, }; assert!(!matches!(gl_context, GlContext::Unknown)); @@ -682,15 +629,6 @@ impl Servo { ) } }, - EmbedderEvent::InvalidateNativeSurface => { - self.compositor.borrow_mut().invalidate_native_surface(); - }, - EmbedderEvent::ReplaceNativeSurface(native_widget, coords) => { - self.compositor - .borrow_mut() - .replace_native_surface(native_widget, coords); - self.compositor.borrow_mut().composite(); - }, EmbedderEvent::AllowNavigationResponse(pipeline_id, allowed) => { let msg = ConstellationMsg::AllowNavigationResponse(pipeline_id, allowed); if let Err(e) = self.constellation_proxy.try_send(msg) { diff --git a/components/servo/webview.rs b/components/servo/webview.rs index b2a286fad7a..ab9a193438c 100644 --- a/components/servo/webview.rs +++ b/components/servo/webview.rs @@ -3,7 +3,6 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::cell::{Ref, RefCell, RefMut}; -use std::ffi::c_void; use std::hash::Hash; use std::rc::{Rc, Weak}; use std::time::Duration; @@ -18,7 +17,7 @@ use embedder_traits::{ }; use keyboard_types::{CompositionEvent, KeyboardEvent}; use url::Url; -use webrender_api::units::{DeviceIntPoint, DeviceIntSize, DevicePoint, DeviceRect}; +use webrender_api::units::{DeviceIntPoint, DevicePoint, DeviceRect}; use webrender_api::ScrollLocation; use crate::webview_delegate::{DefaultWebViewDelegate, WebViewDelegate}; @@ -431,24 +430,10 @@ impl WebView { self.inner().compositor.borrow_mut().capture_webrender(); } - pub fn invalidate_native_surface(&self) { - self.inner() - .compositor - .borrow_mut() - .invalidate_native_surface(); - } - pub fn composite(&self) { self.inner().compositor.borrow_mut().composite(); } - pub fn replace_native_surface(&self, native_widget: *mut c_void, size: DeviceIntSize) { - self.inner() - .compositor - .borrow_mut() - .replace_native_surface(native_widget, size); - } - pub fn toggle_sampling_profiler(&self, rate: Duration, max_duration: Duration) { self.inner() .constellation_proxy diff --git a/components/shared/webrender/Cargo.toml b/components/shared/webrender/Cargo.toml index 9711237dc7c..291b26487ef 100644 --- a/components/shared/webrender/Cargo.toml +++ b/components/shared/webrender/Cargo.toml @@ -11,6 +11,9 @@ rust-version.workspace = true name = "webrender_traits" path = "lib.rs" +[features] +no-wgl = ["surfman/sm-angle-default"] + [dependencies] base = { workspace = true } embedder_traits = { workspace = true } @@ -22,5 +25,5 @@ gleam = { workspace = true } webrender_api = { workspace = true } serde = { workspace = true } servo_geometry = { path = "../../geometry" } +servo-media = { workspace = true } surfman = { workspace = true } - diff --git a/components/shared/webrender/rendering_context.rs b/components/shared/webrender/rendering_context.rs index 6c8c2803c9c..c65df845321 100644 --- a/components/shared/webrender/rendering_context.rs +++ b/components/shared/webrender/rendering_context.rs @@ -11,35 +11,35 @@ use std::rc::Rc; use euclid::default::Size2D; use gleam::gl; use log::{debug, warn}; +use servo_media::player::context::{GlContext, NativeDisplay}; use surfman::chains::{PreserveBuffer, SwapChain}; +#[cfg(all(target_os = "linux", not(target_env = "ohos")))] +use surfman::platform::generic::multi::connection::NativeConnection as LinuxNativeConnection; +#[cfg(all(target_os = "linux", not(target_env = "ohos")))] +use surfman::platform::generic::multi::context::NativeContext as LinuxNativeContext; pub use surfman::Error; use surfman::{ Adapter, Connection, Context, ContextAttributeFlags, ContextAttributes, Device, GLApi, - GLVersion, NativeContext, NativeDevice, NativeWidget, Surface, SurfaceAccess, SurfaceInfo, - SurfaceTexture, SurfaceType, + NativeContext, NativeDevice, NativeWidget, Surface, SurfaceAccess, SurfaceInfo, SurfaceTexture, + SurfaceType, }; +/// Describes the OpenGL version that is requested when a context is created. +pub enum GLVersion { + GL(u8, u8), + GLES(u8, u8), +} + /// The `RenderingContext` trait defines a set of methods for managing /// an OpenGL or GLES rendering context. /// Implementors of this trait are responsible for handling the creation, /// management, and destruction of the rendering context and its associated /// resources. pub trait RenderingContext { - /// Returns the native OpenGL or GLES device handle - fn device(&self) -> NativeDevice; - /// Returns the native OpenGL or GLES context handle. - fn context(&self) -> NativeContext; /// Resizes the rendering surface to the given size. fn resize(&self, size: Size2D); /// Presents the rendered frame to the screen. fn present(&self); - /// Binds a native widget to the rendering context. - fn bind_native_surface_to_context(&self, native_widget: NativeWidget); - /// The connection to the display server. - fn connection(&self) -> Connection; - /// Represents a hardware display adapter that can be used for - /// rendering (including the CPU). - fn adapter(&self) -> Adapter; /// Makes the context the current OpenGL context for this thread. /// After calling this function, it is valid to use OpenGL rendering /// commands. @@ -50,26 +50,23 @@ pub trait RenderingContext { fn gl_api(&self) -> Rc; /// Describes the OpenGL version that is requested when a context is created. fn gl_version(&self) -> GLVersion; - /// Invalidates the native surface by unbinding it from the context. - /// This is used only on Android for when the underlying native surface - /// can be lost during servo's lifetime. - /// For example, this happens when the app is sent to background. - /// We need to unbind the surface so that we don't try to use it again. - fn invalidate_native_surface(&self); - /// Replaces the native surface with a new one. - /// This is used only on Android for when the app moves to foreground - /// and the system creates a new native surface that needs to bound to - /// the current context. - fn replace_native_surface( - &self, - native_widget: *mut c_void, - coords: euclid::Size2D, - ); + /// Returns the GL Context used by servo media player. Default to `GlContext::Unknown`. + fn gl_context(&self) -> GlContext { + GlContext::Unknown + } + /// Returns the GL Display used by servo media player. Default to `NativeDisplay::Unknown`. + fn gl_display(&self) -> NativeDisplay { + NativeDisplay::Unknown + } /// Creates a texture from a given surface and returns the surface texture, - /// the OpenGL texture object, and the size of the surface. - fn create_texture(&self, surface: Surface) -> (SurfaceTexture, u32, Size2D); - /// Destroys the texture and returns the surface. - fn destroy_texture(&self, surface_texture: SurfaceTexture) -> Surface; + /// the OpenGL texture object, and the size of the surface. Default to `None`. + fn create_texture(&self, _surface: Surface) -> Option<(SurfaceTexture, u32, Size2D)> { + None + } + /// Destroys the texture and returns the surface. Default to `None`. + fn destroy_texture(&self, _surface_texture: SurfaceTexture) -> Option { + None + } } /// A rendering context that uses the Surfman library to create and manage @@ -102,17 +99,65 @@ impl Drop for RenderingContextData { } impl RenderingContext for SurfmanRenderingContext { - fn device(&self) -> NativeDevice { - self.native_device() + fn gl_context(&self) -> GlContext { + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] + { + match self.native_context() { + NativeContext::Default(LinuxNativeContext::Default(native_context)) => { + GlContext::Egl(native_context.egl_context as usize) + }, + NativeContext::Default(LinuxNativeContext::Alternate(native_context)) => { + GlContext::Egl(native_context.egl_context as usize) + }, + NativeContext::Alternate(_) => GlContext::Unknown, + } + } + #[cfg(target_os = "windows")] + { + #[cfg(feature = "no-wgl")] + { + GlContext::Egl(self.native_context().egl_context as usize) + } + #[cfg(not(feature = "no-wgl"))] + GlContext::Unknown + } + #[cfg(not(any( + target_os = "windows", + all(target_os = "linux", not(target_env = "ohos")) + )))] + { + GlContext::Unknown + } } - fn context(&self) -> NativeContext { - self.native_context() - } - fn connection(&self) -> Connection { - self.connection() - } - fn adapter(&self) -> Adapter { - self.adapter() + fn gl_display(&self) -> NativeDisplay { + #[cfg(all(target_os = "linux", not(target_env = "ohos")))] + { + match self.connection().native_connection() { + surfman::NativeConnection::Default(LinuxNativeConnection::Default(connection)) => { + NativeDisplay::Egl(connection.0 as usize) + }, + surfman::NativeConnection::Default(LinuxNativeConnection::Alternate( + connection, + )) => NativeDisplay::X11(connection.x11_display as usize), + surfman::NativeConnection::Alternate(_) => NativeDisplay::Unknown, + } + } + #[cfg(target_os = "windows")] + { + #[cfg(feature = "no-wgl")] + { + NativeDisplay::Egl(self.native_device().egl_display as usize) + } + #[cfg(not(feature = "no-wgl"))] + NativeDisplay::Unknown + } + #[cfg(not(any( + target_os = "windows", + all(target_os = "linux", not(target_env = "ohos")) + )))] + { + NativeDisplay::Unknown + } } fn resize(&self, size: Size2D) { if let Err(err) = self.resize(size) { @@ -124,11 +169,6 @@ impl RenderingContext for SurfmanRenderingContext { warn!("Failed to present surface: {:?}", err); } } - fn bind_native_surface_to_context(&self, native_widget: NativeWidget) { - if let Err(err) = self.bind_native_surface_to_context(native_widget) { - warn!("Failed to bind native surface to context: {:?}", err); - } - } fn make_current(&self) -> Result<(), Error> { self.make_gl_context_current() } @@ -155,29 +195,15 @@ impl RenderingContext for SurfmanRenderingContext { let context = self.0.context.borrow(); let descriptor = device.context_descriptor(&context); let attributes = device.context_descriptor_attributes(&descriptor); - attributes.version - } - fn invalidate_native_surface(&self) { - if let Err(e) = self.unbind_native_surface_from_context() { - warn!("Unbinding native surface from context failed ({:?})", e); - } - } - #[allow(unsafe_code)] - #[allow(clippy::not_unsafe_ptr_arg_deref)] // It has an unsafe block inside - fn replace_native_surface( - &self, - native_widget: *mut c_void, - coords: euclid::Size2D, - ) { - let connection = self.connection(); - let native_widget = - unsafe { connection.create_native_widget_from_ptr(native_widget, coords.to_untyped()) }; - if let Err(e) = self.bind_native_surface_to_context(native_widget) { - warn!("Binding native surface to context failed ({:?})", e); + let major = attributes.version.major; + let minor = attributes.version.minor; + match self.connection().gl_api() { + GLApi::GL => GLVersion::GL(major, minor), + GLApi::GLES => GLVersion::GLES(major, minor), } } - fn create_texture(&self, surface: Surface) -> (SurfaceTexture, u32, Size2D) { + fn create_texture(&self, surface: Surface) -> Option<(SurfaceTexture, u32, Size2D)> { let device = &self.0.device.borrow(); let context = &mut self.0.context.borrow_mut(); let SurfaceInfo { @@ -187,16 +213,15 @@ impl RenderingContext for SurfmanRenderingContext { } = device.surface_info(&surface); debug!("... getting texture for surface {:?}", front_buffer_id); let surface_texture = device.create_surface_texture(context, surface).unwrap(); - let gl_texture = device.surface_texture_object(&surface_texture); - ( - surface_texture, - gl_texture.map(|tex| tex.0.get()).unwrap_or(0), - size, - ) + let gl_texture = device + .surface_texture_object(&surface_texture) + .map(|tex| tex.0.get()) + .unwrap_or(0); + Some((surface_texture, gl_texture, size)) } - fn destroy_texture(&self, surface_texture: SurfaceTexture) -> Surface { - self.destroy_surface_texture(surface_texture).unwrap() + fn destroy_texture(&self, surface_texture: SurfaceTexture) -> Option { + self.destroy_surface_texture(surface_texture).ok() } } @@ -211,8 +236,8 @@ impl SurfmanRenderingContext { ContextAttributeFlags::DEPTH | ContextAttributeFlags::STENCIL; let version = match connection.gl_api() { - GLApi::GLES => GLVersion { major: 3, minor: 0 }, - GLApi::GL => GLVersion { major: 3, minor: 2 }, + GLApi::GLES => surfman::GLVersion { major: 3, minor: 0 }, + GLApi::GL => surfman::GLVersion { major: 3, minor: 2 }, }; let context_attributes = ContextAttributes { flags, version }; let context_descriptor = device.create_context_descriptor(&context_attributes)?; diff --git a/ports/servoshell/egl/servo_glue.rs b/ports/servoshell/egl/servo_glue.rs index ca1397f6747..7986388b35b 100644 --- a/ports/servoshell/egl/servo_glue.rs +++ b/ports/servoshell/egl/servo_glue.rs @@ -405,7 +405,9 @@ impl ServoGlue { } pub fn pause_compositor(&mut self) { - self.active_webview().invalidate_native_surface(); + if let Err(e) = self.rendering_context.unbind_native_surface_from_context() { + warn!("Unbinding native surface from context failed ({:?})", e); + } self.maybe_perform_updates(); } @@ -413,8 +415,17 @@ impl ServoGlue { if native_surface.is_null() { panic!("null passed for native_surface"); } - self.active_webview() - .replace_native_surface(native_surface, coords.framebuffer); + let connection = self.rendering_context.connection(); + let native_widget = unsafe { + connection + .create_native_widget_from_ptr(native_surface, coords.framebuffer.to_untyped()) + }; + if let Err(e) = self + .rendering_context + .bind_native_surface_to_context(native_widget) + { + warn!("Binding native surface to context failed ({:?})", e); + } self.maybe_perform_updates() }