From cb2b2abdeedfd54debf6a63275257583358e2547 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sun, 15 Nov 2020 11:13:44 -0500 Subject: [PATCH 1/3] Expose non-widget rendering to embedders. --- ports/libsimpleservo/api/src/lib.rs | 30 +++++++++++++++++++++------- ports/libsimpleservo/capi/src/lib.rs | 3 ++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 4c1523b6067..78c229ba47c 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -63,10 +63,18 @@ pub struct InitOptions { pub xr_discovery: Option, pub gl_context_pointer: Option<*const c_void>, pub native_display_pointer: Option<*const c_void>, - pub native_widget: *mut c_void, + pub surfman_integration: SurfmanIntegration, pub prefs: Option>, } +/// Controls how this embedding's rendering will integrate with the embedder. +pub enum SurfmanIntegration { + /// Render directly to a provided native widget (see surfman::NativeWidget). + Widget(*mut c_void), + /// Render to an offscreen surface. + Surface, +} + #[derive(Clone, Debug)] pub struct Coordinates { pub viewport: Rect, @@ -253,13 +261,21 @@ pub fn init( .create_adapter() .or(Err("Failed to create adapter"))?, }; - let native_widget = unsafe { - connection.create_native_widget_from_ptr( - init_opts.native_widget, - init_opts.coordinates.framebuffer.to_untyped(), - ) + let surface_type = match init_opts.surfman_integration { + SurfmanIntegration::Widget(native_widget) => { + let native_widget = unsafe { + connection.create_native_widget_from_ptr( + native_widget, + init_opts.coordinates.framebuffer.to_untyped(), + ) + }; + SurfaceType::Widget { native_widget } + }, + SurfmanIntegration::Surface => { + let size = init_opts.coordinates.framebuffer.to_untyped(); + SurfaceType::Generic { size } + }, }; - let surface_type = SurfaceType::Widget { native_widget }; let webrender_surfman = WebrenderSurfman::create(&connection, &adapter, surface_type) .or(Err("Failed to create surface manager"))?; diff --git a/ports/libsimpleservo/capi/src/lib.rs b/ports/libsimpleservo/capi/src/lib.rs index 0ea0e83e12f..4fa94965502 100644 --- a/ports/libsimpleservo/capi/src/lib.rs +++ b/ports/libsimpleservo/capi/src/lib.rs @@ -21,6 +21,7 @@ use simpleservo::{self, gl_glue, ServoGlue, SERVO}; use simpleservo::{ ContextMenuResult, Coordinates, DeviceIntRect, EventLoopWaker, HostTrait, InitOptions, InputMethodType, MediaSessionActionType, MediaSessionPlaybackState, MouseButton, PromptResult, + SurfmanIntegration, }; use std::ffi::{CStr, CString}; #[cfg(target_os = "windows")] @@ -463,7 +464,7 @@ unsafe fn init( xr_discovery: None, gl_context_pointer: gl_context, native_display_pointer: display, - native_widget: opts.native_widget, + surfman_integration: SurfmanIntegration::Widget(opts.native_widget), }; let wakeup = Box::new(WakeupCallback::new(wakeup)); From d9484d5d06cde0b6a954d539331810fbd7d5878c Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sun, 15 Nov 2020 11:14:26 -0500 Subject: [PATCH 2/3] Expose WebrenderSurfman interface to embedders. --- ports/libsimpleservo/api/src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index 78c229ba47c..c87a63f4445 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -161,6 +161,7 @@ pub trait HostTrait { } pub struct ServoGlue { + webrender_surfman: WebrenderSurfman, servo: Servo, batch_mode: bool, callbacks: Rc, @@ -285,7 +286,7 @@ pub fn init( density: init_opts.density, gl_context_pointer: init_opts.gl_context_pointer, native_display_pointer: init_opts.native_display_pointer, - webrender_surfman, + webrender_surfman: webrender_surfman.clone(), }); let embedder_callbacks = Box::new(ServoEmbedderCallbacks { @@ -298,6 +299,7 @@ pub fn init( SERVO.with(|s| { let mut servo_glue = ServoGlue { + webrender_surfman, servo, batch_mode: false, callbacks: window_callbacks, @@ -338,6 +340,12 @@ impl ServoGlue { self.servo.deinit(); } + /// Returns the webrender surface management integration interface. + /// This provides the embedder access to the current front buffer. + pub fn surfman(&self) -> WebrenderSurfman { + self.webrender_surfman.clone() + } + /// This is the Servo heartbeat. This needs to be called /// everytime wakeup is called or when embedder wants Servo /// to act on its pending events. From bd2d4596b0eacee380f6b71353c340aae49d0fd5 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sun, 15 Nov 2020 11:14:43 -0500 Subject: [PATCH 3/3] Allow embedders to access front buffer surface. --- components/webrender_surfman/lib.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/components/webrender_surfman/lib.rs b/components/webrender_surfman/lib.rs index 533614256c1..472aabbad18 100644 --- a/components/webrender_surfman/lib.rs +++ b/components/webrender_surfman/lib.rs @@ -159,6 +159,23 @@ impl WebrenderSurfman { }) } + /// Invoke a closure with the surface associated with the current front buffer. + /// This can be used to create a surfman::SurfaceTexture to blit elsewhere. + pub fn with_front_buffer Surface>(&self, mut f: F) { + let ref mut device = self.0.device.borrow_mut(); + let ref mut context = self.0.context.borrow_mut(); + let surface = device + .unbind_surface_from_context(context) + .unwrap() + .unwrap(); + let surface = f(device, surface); + device.bind_surface_to_context(context, surface).unwrap(); + } + + pub fn device(&self) -> std::cell::Ref { + self.0.device.borrow() + } + pub fn connection(&self) -> Connection { let ref device = self.0.device.borrow(); device.connection()