Skip to content

Commit a045e40

Browse files
committed
Add VRCompositor commands for WebVR
1 parent 3a6725a commit a045e40

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

webrender/src/render_backend.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use webrender_traits::{ApiMsg, AuxiliaryLists, BuiltDisplayList, IdNamespace, Im
2020
use webrender_traits::{FlushNotifier, RenderNotifier, RenderDispatcher, WebGLCommand, WebGLContextId};
2121
use webrender_traits::{DeviceIntSize};
2222
use webrender_traits::channel::{PayloadHelperMethods, PayloadReceiver, PayloadSender, MsgReceiver};
23+
use webrender_traits::{VRCompositorCommand, VRCompositorHandler};
2324
use tiling::FrameBuilderConfig;
2425
use offscreen_gl_context::GLContextDispatcher;
2526

@@ -50,6 +51,8 @@ pub struct RenderBackend {
5051
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>,
5152

5253
next_webgl_id: usize,
54+
55+
vr_compositor_handler: Arc<Mutex<Option<Box<VRCompositorHandler>>>>
5356
}
5457

5558
impl RenderBackend {
@@ -66,7 +69,8 @@ impl RenderBackend {
6669
config: FrameBuilderConfig,
6770
debug: bool,
6871
enable_recording:bool,
69-
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>) -> RenderBackend {
72+
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>,
73+
vr_compositor_handler: Arc<Mutex<Option<Box<VRCompositorHandler>>>>) -> RenderBackend {
7074

7175
let resource_cache = ResourceCache::new(texture_cache,
7276
enable_aa);
@@ -89,6 +93,7 @@ impl RenderBackend {
8993
enable_recording:enable_recording,
9094
main_thread_dispatcher: main_thread_dispatcher,
9195
next_webgl_id: 0,
96+
vr_compositor_handler: vr_compositor_handler
9297
}
9398
}
9499

@@ -336,6 +341,10 @@ impl RenderBackend {
336341
ctx.make_current();
337342
ctx.apply_command(command);
338343
self.current_bound_webgl_context_id = Some(context_id);
344+
},
345+
346+
ApiMsg::VRCompositorCommand(context_id, command) => {
347+
self.handle_vr_compositor_command(context_id, command);
339348
}
340349
ApiMsg::GenerateFrame => {
341350
let frame = profile_counters.total_time.profile(|| {
@@ -469,6 +478,20 @@ impl RenderBackend {
469478
let mut notifier = self.notifier.lock();
470479
notifier.as_mut().unwrap().as_mut().unwrap().new_scroll_frame_ready(composite_needed);
471480
}
481+
482+
fn handle_vr_compositor_command(&mut self, ctx_id: WebGLContextId, cmd: VRCompositorCommand) {
483+
let texture = match cmd {
484+
VRCompositorCommand::SubmitFrame(..) => {
485+
match self.resource_cache.get_webgl_texture(&ctx_id).texture_id {
486+
SourceTexture::WebGL(texture_id) => Some(texture_id),
487+
_=> None
488+
}
489+
},
490+
_ => None
491+
};
492+
let mut handler = self.vr_compositor_handler.lock();
493+
handler.as_mut().unwrap().as_mut().unwrap().handle(cmd, texture);
494+
}
472495
}
473496

474497
struct WebRenderGLDispatcher {

webrender/src/renderer.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use webrender_traits::{ColorF, Epoch, FlushNotifier, PipelineId, RenderNotifier,
4040
use webrender_traits::{ExternalImageId, ImageFormat, RenderApiSender, RendererKind};
4141
use webrender_traits::{DeviceSize, DevicePoint, DeviceIntPoint, DeviceIntSize, DeviceUintSize};
4242
use webrender_traits::channel;
43+
use webrender_traits::VRCompositorHandler;
4344

4445
pub const MAX_VERTEX_TEXTURE_WIDTH: usize = 1024;
4546

@@ -419,6 +420,10 @@ pub struct Renderer {
419420

420421
/// Map of external image IDs to native textures.
421422
external_images: HashMap<ExternalImageId, TextureId, BuildHasherDefault<FnvHasher>>,
423+
424+
// Optional trait object that handles WebVR commands.
425+
// Some WebVR commands such as SubmitFrame must be synced with the WebGL render thread.
426+
vr_compositor_handler: Arc<Mutex<Option<Box<VRCompositorHandler>>>>
422427
}
423428

424429
impl Renderer {
@@ -680,6 +685,9 @@ impl Renderer {
680685
let backend_main_thread_dispatcher = main_thread_dispatcher.clone();
681686
let backend_flush_notifier = flush_notifier.clone();
682687

688+
let vr_compositor = Arc::new(Mutex::new(None));
689+
let backend_vr_compositor = vr_compositor.clone();
690+
683691
// We need a reference to the webrender context from the render backend in order to share
684692
// texture ids
685693
let context_handle = match options.renderer_kind {
@@ -708,7 +716,8 @@ impl Renderer {
708716
config,
709717
debug,
710718
enable_recording,
711-
backend_main_thread_dispatcher);
719+
backend_main_thread_dispatcher,
720+
backend_vr_compositor);
712721
backend.run();
713722
});
714723

@@ -770,6 +779,7 @@ impl Renderer {
770779
cache_texture_id_map: Vec::new(),
771780
external_image_handler: None,
772781
external_images: HashMap::with_hasher(Default::default()),
782+
vr_compositor_handler: vr_compositor
773783
};
774784

775785
let sender = RenderApiSender::new(api_tx, payload_tx);
@@ -803,6 +813,16 @@ impl Renderer {
803813
*dispatcher_arc = Some(dispatcher);
804814
}
805815

816+
/// Sets the VRCompositorHandler.
817+
///
818+
/// Some WebVR commands such as Vsync and SubmitFrame must be called in the WebGL render thread.
819+
/// VRCompositorCreator is used to create VRCompositor objects that are able to handle WebVR
820+
/// commands that must be called in the render thread.
821+
pub fn set_vr_compositor_handler(&self, creator: Box<VRCompositorHandler>) {
822+
let mut handler_arc = self.vr_compositor_handler.lock().unwrap();
823+
*handler_arc = Some(creator);
824+
}
825+
806826
/// Returns the Epoch of the current frame in a pipeline.
807827
pub fn current_epoch(&self, pipeline_id: PipelineId) -> Option<Epoch> {
808828
self.pipeline_epoch_map.get(&pipeline_id).map(|epoch| *epoch)

webrender_traits/src/api.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use {ApiMsg, ColorF, DisplayListBuilder, Epoch};
1111
use {FontKey, IdNamespace, ImageFormat, ImageKey, NativeFontHandle, PipelineId};
1212
use {RenderApiSender, ResourceId, ScrollEventPhase, ScrollLayerState, ScrollLocation, ServoScrollRootId};
1313
use {GlyphKey, GlyphDimensions, ImageData, WebGLContextId, WebGLCommand};
14+
use VRCompositorCommand;
1415

1516
impl RenderApiSender {
1617
pub fn new(api_sender: MsgSender<ApiMsg>,
@@ -245,6 +246,11 @@ impl RenderApi {
245246
self.api_sender.send(msg).unwrap();
246247
}
247248

249+
pub fn send_vr_compositor_command(&self, context_id: WebGLContextId, command: VRCompositorCommand) {
250+
let msg = ApiMsg::VRCompositorCommand(context_id, command);
251+
self.api_sender.send(msg).unwrap();
252+
}
253+
248254
#[inline]
249255
fn next_unique_id(&self) -> (u32, u32) {
250256
let IdNamespace(namespace) = self.id_namespace;

webrender_traits/src/types.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ pub enum ApiMsg {
5757
ResizeWebGLContext(WebGLContextId, Size2D<i32>),
5858
WebGLCommand(WebGLContextId, WebGLCommand),
5959
GenerateFrame,
60+
// WebVR commands that must be called in the WebGL render thread.
61+
VRCompositorCommand(WebGLContextId, VRCompositorCommand)
6062
}
6163

6264
#[derive(Copy, Clone, Deserialize, Serialize, Debug)]
@@ -792,3 +794,20 @@ pub enum WebGLShaderParameter {
792794
Bool(bool),
793795
Invalid,
794796
}
797+
798+
pub type VRCompositorId = u64;
799+
800+
// WebVR commands that must be called in the WebGL render thread.
801+
#[derive(Clone, Deserialize, Serialize)]
802+
pub enum VRCompositorCommand {
803+
Create(VRCompositorId),
804+
SyncPoses(VRCompositorId, f64, f64, MsgSender<Result<Vec<u8>,()>>),
805+
SubmitFrame(VRCompositorId, [f32; 4], [f32; 4]),
806+
Release(VRCompositorId)
807+
}
808+
809+
// Trait object that handles WebVR commands.
810+
// Receives the texture_id associated to the WebGLContext.
811+
pub trait VRCompositorHandler: Send {
812+
fn handle(&mut self, command: VRCompositorCommand, texture_id: Option<u32>);
813+
}

0 commit comments

Comments
 (0)