diff options
Diffstat (limited to 'components/canvas/webxr.rs')
-rw-r--r-- | components/canvas/webxr.rs | 337 |
1 files changed, 0 insertions, 337 deletions
diff --git a/components/canvas/webxr.rs b/components/canvas/webxr.rs deleted file mode 100644 index d43303e7393..00000000000 --- a/components/canvas/webxr.rs +++ /dev/null @@ -1,337 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -use std::collections::HashMap; -use std::num::NonZeroU32; - -use canvas_traits::webgl::{ - WebGLContextId, WebGLMsg, WebGLSender, WebXRCommand, WebXRLayerManagerId, webgl_channel, -}; -use fnv::FnvHashMap; -use surfman::{Context, Device}; -use webxr::SurfmanGL as WebXRSurfman; -use webxr_api::{ - ContextId as WebXRContextId, Error as WebXRError, GLContexts as WebXRContexts, - GLTypes as WebXRTypes, LayerGrandManager as WebXRLayerGrandManager, - LayerGrandManagerAPI as WebXRLayerGrandManagerAPI, LayerId as WebXRLayerId, - LayerInit as WebXRLayerInit, LayerManager as WebXRLayerManager, - LayerManagerAPI as WebXRLayerManagerAPI, LayerManagerFactory as WebXRLayerManagerFactory, - SubImages as WebXRSubImages, -}; - -use crate::webgl_thread::{GLContextData, WebGLThread}; - -/// Bridge between WebGL and WebXR -pub(crate) struct WebXRBridge { - factory_receiver: crossbeam_channel::Receiver<WebXRLayerManagerFactory<WebXRSurfman>>, - managers: HashMap<WebXRLayerManagerId, Box<dyn WebXRLayerManagerAPI<WebXRSurfman>>>, - next_manager_id: NonZeroU32, -} - -impl WebXRBridge { - pub(crate) fn new(init: WebXRBridgeInit) -> WebXRBridge { - let WebXRBridgeInit { - factory_receiver, .. - } = init; - let managers = HashMap::new(); - let next_manager_id = NonZeroU32::MIN; - WebXRBridge { - factory_receiver, - managers, - next_manager_id, - } - } -} - -impl WebXRBridge { - #[allow(unsafe_code)] - pub(crate) fn create_layer_manager( - &mut self, - device: &mut Device, - contexts: &mut dyn WebXRContexts<WebXRSurfman>, - ) -> Result<WebXRLayerManagerId, WebXRError> { - let factory = self - .factory_receiver - .recv() - .map_err(|_| WebXRError::CommunicationError)?; - let manager = factory.build(device, contexts)?; - let manager_id = WebXRLayerManagerId::new(self.next_manager_id); - self.next_manager_id = self - .next_manager_id - .checked_add(1) - .expect("next_manager_id should not overflow"); - self.managers.insert(manager_id, manager); - Ok(manager_id) - } - - pub(crate) fn destroy_layer_manager(&mut self, manager_id: WebXRLayerManagerId) { - self.managers.remove(&manager_id); - } - - pub(crate) fn create_layer( - &mut self, - manager_id: WebXRLayerManagerId, - device: &mut Device, - contexts: &mut dyn WebXRContexts<WebXRSurfman>, - context_id: WebXRContextId, - layer_init: WebXRLayerInit, - ) -> Result<WebXRLayerId, WebXRError> { - let manager = self - .managers - .get_mut(&manager_id) - .ok_or(WebXRError::NoMatchingDevice)?; - manager.create_layer(device, contexts, context_id, layer_init) - } - - pub(crate) fn destroy_layer( - &mut self, - manager_id: WebXRLayerManagerId, - device: &mut Device, - contexts: &mut dyn WebXRContexts<WebXRSurfman>, - context_id: WebXRContextId, - layer_id: WebXRLayerId, - ) { - if let Some(manager) = self.managers.get_mut(&manager_id) { - manager.destroy_layer(device, contexts, context_id, layer_id); - } - } - - pub(crate) fn destroy_all_layers( - &mut self, - device: &mut Device, - contexts: &mut dyn WebXRContexts<WebXRSurfman>, - context_id: WebXRContextId, - ) { - for manager in self.managers.values_mut() { - #[allow(clippy::unnecessary_to_owned)] // Needs mutable borrow later in destroy - for (other_id, layer_id) in manager.layers().to_vec() { - if other_id == context_id { - manager.destroy_layer(device, contexts, context_id, layer_id); - } - } - } - } - - pub(crate) fn begin_frame( - &mut self, - manager_id: WebXRLayerManagerId, - device: &mut Device, - contexts: &mut dyn WebXRContexts<WebXRSurfman>, - layers: &[(WebXRContextId, WebXRLayerId)], - ) -> Result<Vec<WebXRSubImages>, WebXRError> { - let manager = self - .managers - .get_mut(&manager_id) - .ok_or(WebXRError::NoMatchingDevice)?; - manager.begin_frame(device, contexts, layers) - } - - pub(crate) fn end_frame( - &mut self, - manager_id: WebXRLayerManagerId, - device: &mut Device, - contexts: &mut dyn WebXRContexts<WebXRSurfman>, - layers: &[(WebXRContextId, WebXRLayerId)], - ) -> Result<(), WebXRError> { - let manager = self - .managers - .get_mut(&manager_id) - .ok_or(WebXRError::NoMatchingDevice)?; - manager.end_frame(device, contexts, layers) - } -} - -pub(crate) struct WebXRBridgeInit { - sender: WebGLSender<WebGLMsg>, - factory_receiver: crossbeam_channel::Receiver<WebXRLayerManagerFactory<WebXRSurfman>>, - factory_sender: crossbeam_channel::Sender<WebXRLayerManagerFactory<WebXRSurfman>>, -} - -impl WebXRBridgeInit { - pub(crate) fn new(sender: WebGLSender<WebGLMsg>) -> WebXRBridgeInit { - let (factory_sender, factory_receiver) = crossbeam_channel::unbounded(); - WebXRBridgeInit { - sender, - factory_sender, - factory_receiver, - } - } - - pub(crate) fn layer_grand_manager(&self) -> WebXRLayerGrandManager<WebXRSurfman> { - WebXRLayerGrandManager::new(WebXRBridgeGrandManager { - sender: self.sender.clone(), - factory_sender: self.factory_sender.clone(), - }) - } -} - -struct WebXRBridgeGrandManager { - sender: WebGLSender<WebGLMsg>, - // WebXR layer manager factories use generic trait objects under the - // hood, which aren't deserializable (even using typetag) - // so we can't send them over the regular webgl channel. - // Fortunately, the webgl thread runs in the same process as - // the webxr threads, so we can use a crossbeam channel to send - // factories. - factory_sender: crossbeam_channel::Sender<WebXRLayerManagerFactory<WebXRSurfman>>, -} - -impl WebXRLayerGrandManagerAPI<WebXRSurfman> for WebXRBridgeGrandManager { - fn create_layer_manager( - &self, - factory: WebXRLayerManagerFactory<WebXRSurfman>, - ) -> Result<WebXRLayerManager, WebXRError> { - let (sender, receiver) = webgl_channel().ok_or(WebXRError::CommunicationError)?; - let _ = self.factory_sender.send(factory); - let _ = self - .sender - .send(WebGLMsg::WebXRCommand(WebXRCommand::CreateLayerManager( - sender, - ))); - let sender = self.sender.clone(); - let manager_id = receiver - .recv() - .map_err(|_| WebXRError::CommunicationError)??; - let layers = Vec::new(); - Ok(WebXRLayerManager::new(WebXRBridgeManager { - manager_id, - sender, - layers, - })) - } - - fn clone_layer_grand_manager(&self) -> WebXRLayerGrandManager<WebXRSurfman> { - WebXRLayerGrandManager::new(WebXRBridgeGrandManager { - sender: self.sender.clone(), - factory_sender: self.factory_sender.clone(), - }) - } -} - -struct WebXRBridgeManager { - sender: WebGLSender<WebGLMsg>, - manager_id: WebXRLayerManagerId, - layers: Vec<(WebXRContextId, WebXRLayerId)>, -} - -impl<GL: WebXRTypes> WebXRLayerManagerAPI<GL> for WebXRBridgeManager { - fn create_layer( - &mut self, - _: &mut GL::Device, - _: &mut dyn WebXRContexts<GL>, - context_id: WebXRContextId, - init: WebXRLayerInit, - ) -> Result<WebXRLayerId, WebXRError> { - let (sender, receiver) = webgl_channel().ok_or(WebXRError::CommunicationError)?; - let _ = self - .sender - .send(WebGLMsg::WebXRCommand(WebXRCommand::CreateLayer( - self.manager_id, - context_id, - init, - sender, - ))); - let layer_id = receiver - .recv() - .map_err(|_| WebXRError::CommunicationError)??; - self.layers.push((context_id, layer_id)); - Ok(layer_id) - } - - fn destroy_layer( - &mut self, - _: &mut GL::Device, - _: &mut dyn WebXRContexts<GL>, - context_id: WebXRContextId, - layer_id: WebXRLayerId, - ) { - self.layers.retain(|&ids| ids != (context_id, layer_id)); - let _ = self - .sender - .send(WebGLMsg::WebXRCommand(WebXRCommand::DestroyLayer( - self.manager_id, - context_id, - layer_id, - ))); - } - - fn layers(&self) -> &[(WebXRContextId, WebXRLayerId)] { - &self.layers[..] - } - - fn begin_frame( - &mut self, - _: &mut GL::Device, - _: &mut dyn WebXRContexts<GL>, - layers: &[(WebXRContextId, WebXRLayerId)], - ) -> Result<Vec<WebXRSubImages>, WebXRError> { - let (sender, receiver) = webgl_channel().ok_or(WebXRError::CommunicationError)?; - let _ = self - .sender - .send(WebGLMsg::WebXRCommand(WebXRCommand::BeginFrame( - self.manager_id, - layers.to_vec(), - sender, - ))); - receiver - .recv() - .map_err(|_| WebXRError::CommunicationError)? - } - - fn end_frame( - &mut self, - _: &mut GL::Device, - _: &mut dyn WebXRContexts<GL>, - layers: &[(WebXRContextId, WebXRLayerId)], - ) -> Result<(), WebXRError> { - let (sender, receiver) = webgl_channel().ok_or(WebXRError::CommunicationError)?; - let _ = self - .sender - .send(WebGLMsg::WebXRCommand(WebXRCommand::EndFrame( - self.manager_id, - layers.to_vec(), - sender, - ))); - receiver - .recv() - .map_err(|_| WebXRError::CommunicationError)? - } -} - -impl Drop for WebXRBridgeManager { - fn drop(&mut self) { - let _ = self - .sender - .send(WebGLMsg::WebXRCommand(WebXRCommand::DestroyLayerManager( - self.manager_id, - ))); - } -} - -pub(crate) struct WebXRBridgeContexts<'a> { - pub(crate) contexts: &'a mut FnvHashMap<WebGLContextId, GLContextData>, - pub(crate) bound_context_id: &'a mut Option<WebGLContextId>, -} - -impl WebXRContexts<WebXRSurfman> for WebXRBridgeContexts<'_> { - fn context(&mut self, device: &Device, context_id: WebXRContextId) -> Option<&mut Context> { - let data = WebGLThread::make_current_if_needed_mut( - device, - WebGLContextId::from(context_id), - self.contexts, - self.bound_context_id, - )?; - Some(&mut data.ctx) - } - - fn bindings(&mut self, device: &Device, context_id: WebXRContextId) -> Option<&glow::Context> { - let data = WebGLThread::make_current_if_needed( - device, - WebGLContextId::from(context_id), - self.contexts, - self.bound_context_id, - )?; - Some(&data.gl) - } -} |