mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Finish the integration of webxr
into the Cargo workspace (#35229)
- Run `cargo fmt` on `webxr` and `webxr-api` - Fix clippy warnings in the existing `webxr` code - Integrate the new crates into the workspace - Expose `webxr` via the libservo API rather than requiring embedders to depend on it explicitly. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
a4c6c205d2
commit
5466c27f6f
41 changed files with 448 additions and 649 deletions
|
@ -1,14 +1,12 @@
|
|||
[package]
|
||||
name = "webxr"
|
||||
version = "0.0.1"
|
||||
authors = ["The Servo Project Developers"]
|
||||
edition = "2018"
|
||||
|
||||
homepage = "https://github.com/servo/webxr"
|
||||
repository = "https://github.com/servo/webxr"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
rust-version.workspace = true
|
||||
keywords = ["ar", "headset", "openxr", "vr", "webxr"]
|
||||
license = "MPL-2.0"
|
||||
|
||||
description = '''A safe Rust API that provides a way to interact with
|
||||
virtual reality and augmented reality devices and integration with OpenXR.
|
||||
The API is inspired by the WebXR Device API (https://www.w3.org/TR/webxr/)
|
||||
|
@ -27,23 +25,16 @@ ipc = ["webxr-api/ipc", "serde"]
|
|||
openxr-api = ["angle", "openxr", "winapi", "wio", "surfman/sm-angle-default"]
|
||||
|
||||
[dependencies]
|
||||
webxr-api = { path = "../shared/webxr" }
|
||||
crossbeam-channel = "0.5"
|
||||
euclid = "0.22"
|
||||
log = "0.4.6"
|
||||
openxr = { version = "0.19", optional = true }
|
||||
serde = { version = "1.0", optional = true }
|
||||
glow = "0.16"
|
||||
raw-window-handle = "0.6"
|
||||
surfman = { git = "https://github.com/servo/surfman", rev = "300789ddbda45c89e9165c31118bf1c4c07f89f6", features = [
|
||||
"chains",
|
||||
"sm-raw-window-handle-06",
|
||||
] }
|
||||
webxr-api = { workspace = true }
|
||||
crossbeam-channel = { workspace = true }
|
||||
euclid = { workspace = true }
|
||||
log = { workspace = true }
|
||||
openxr = { workspace = true, optional = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
glow = { workspace = true }
|
||||
raw-window-handle = { workspace = true }
|
||||
surfman = { workspace = true, features = ["chains", "sm-raw-window-handle-06"] }
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winapi = { version = "0.3", features = [
|
||||
"dxgi",
|
||||
"d3d11",
|
||||
"winerror",
|
||||
], optional = true }
|
||||
wio = { version = "0.2", optional = true }
|
||||
winapi = { workspace = true, features = ["dxgi", "d3d11", "winerror"], optional = true }
|
||||
wio = { workspace = true, optional = true }
|
||||
|
|
|
@ -2,16 +2,15 @@
|
|||
* 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 crate::SurfmanGL;
|
||||
use glow as gl;
|
||||
use glow::Context as Gl;
|
||||
use glow::HasContext;
|
||||
use std::collections::HashMap;
|
||||
use std::num::NonZero;
|
||||
|
||||
use glow as gl;
|
||||
use glow::{Context as Gl, HasContext};
|
||||
use surfman::Device as SurfmanDevice;
|
||||
use webxr_api::ContextId;
|
||||
use webxr_api::GLContexts;
|
||||
use webxr_api::LayerId;
|
||||
use webxr_api::{ContextId, GLContexts, LayerId};
|
||||
|
||||
use crate::SurfmanGL;
|
||||
|
||||
pub(crate) fn framebuffer(framebuffer: u32) -> Option<gl::NativeFramebuffer> {
|
||||
NonZero::new(framebuffer).map(gl::NativeFramebuffer)
|
||||
|
@ -93,6 +92,7 @@ impl GlClearer {
|
|||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn clear(
|
||||
&mut self,
|
||||
device: &mut SurfmanDevice,
|
||||
|
@ -114,8 +114,6 @@ impl GlClearer {
|
|||
let mut clear_color = [0., 0., 0., 0.];
|
||||
let mut clear_depth = [0.];
|
||||
let mut clear_stencil = [0];
|
||||
let color_mask;
|
||||
let depth_mask;
|
||||
let mut stencil_mask = [0];
|
||||
let scissor_enabled = gl.is_enabled(gl::SCISSOR_TEST);
|
||||
let rasterizer_enabled = gl.is_enabled(gl::RASTERIZER_DISCARD);
|
||||
|
@ -125,9 +123,9 @@ impl GlClearer {
|
|||
gl.get_parameter_f32_slice(gl::COLOR_CLEAR_VALUE, &mut clear_color[..]);
|
||||
gl.get_parameter_f32_slice(gl::DEPTH_CLEAR_VALUE, &mut clear_depth[..]);
|
||||
gl.get_parameter_i32_slice(gl::STENCIL_CLEAR_VALUE, &mut clear_stencil[..]);
|
||||
depth_mask = gl.get_parameter_bool(gl::DEPTH_WRITEMASK);
|
||||
let depth_mask = gl.get_parameter_bool(gl::DEPTH_WRITEMASK);
|
||||
gl.get_parameter_i32_slice(gl::STENCIL_WRITEMASK, &mut stencil_mask[..]);
|
||||
color_mask = gl.get_parameter_bool_array::<4>(gl::COLOR_WRITEMASK);
|
||||
let color_mask = gl.get_parameter_bool_array::<4>(gl::COLOR_WRITEMASK);
|
||||
|
||||
// Clear it
|
||||
gl.bind_framebuffer(gl::FRAMEBUFFER, fbo);
|
||||
|
|
|
@ -2,16 +2,15 @@
|
|||
* 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 crate::gl_utils::framebuffer;
|
||||
use crate::{SurfmanGL, SurfmanLayerManager};
|
||||
use core::slice;
|
||||
use std::num::NonZeroU32;
|
||||
use std::rc::Rc;
|
||||
|
||||
use euclid::{
|
||||
Angle, Point2D, Rect, RigidTransform3D, Rotation3D, Size2D, Transform3D, UnknownUnit, Vector3D,
|
||||
};
|
||||
use glow::{self as gl, Context as Gl, HasContext};
|
||||
use raw_window_handle::DisplayHandle;
|
||||
use std::num::NonZeroU32;
|
||||
use std::rc::Rc;
|
||||
use surfman::chains::{PreserveBuffer, SwapChain, SwapChainAPI, SwapChains, SwapChainsAPI};
|
||||
use surfman::{
|
||||
Adapter, Connection, Context as SurfmanContext, ContextAttributeFlags, ContextAttributes,
|
||||
|
@ -26,6 +25,9 @@ use webxr_api::{
|
|||
VIEWER,
|
||||
};
|
||||
|
||||
use crate::gl_utils::framebuffer;
|
||||
use crate::{SurfmanGL, SurfmanLayerManager};
|
||||
|
||||
// How far off the ground are the viewer's eyes?
|
||||
const HEIGHT: f32 = 1.0;
|
||||
|
||||
|
@ -55,7 +57,7 @@ pub trait GlWindow {
|
|||
fn display_handle(&self) -> DisplayHandle;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum GlWindowMode {
|
||||
Blit,
|
||||
StereoLeftRight,
|
||||
|
@ -80,9 +82,9 @@ impl GlWindowDiscovery {
|
|||
pub fn new(window: Rc<dyn GlWindow>) -> GlWindowDiscovery {
|
||||
let connection = Connection::from_display_handle(window.display_handle()).unwrap();
|
||||
let adapter = connection.create_adapter().unwrap();
|
||||
let flags = ContextAttributeFlags::ALPHA
|
||||
| ContextAttributeFlags::DEPTH
|
||||
| ContextAttributeFlags::STENCIL;
|
||||
let flags = ContextAttributeFlags::ALPHA |
|
||||
ContextAttributeFlags::DEPTH |
|
||||
ContextAttributeFlags::STENCIL;
|
||||
let version = match connection.gl_api() {
|
||||
GLApi::GLES => GLVersion { major: 3, minor: 0 },
|
||||
GLApi::GL => GLVersion { major: 3, minor: 2 },
|
||||
|
@ -108,7 +110,7 @@ impl DiscoveryAPI<SurfmanGL> for GlWindowDiscovery {
|
|||
let granted_features = init.validate(mode, &["local-floor".into()])?;
|
||||
let connection = self.connection.clone();
|
||||
let adapter = self.adapter.clone();
|
||||
let context_attributes = self.context_attributes.clone();
|
||||
let context_attributes = self.context_attributes;
|
||||
let window = self.window.clone();
|
||||
xr.run_on_main_thread(move |grand_manager| {
|
||||
GlWindowDevice::new(
|
||||
|
@ -155,6 +157,7 @@ impl DeviceAPI for GlWindowDevice {
|
|||
fn viewports(&self) -> Viewports {
|
||||
let size = self.viewport_size();
|
||||
let viewports = match self.window.get_mode() {
|
||||
#[allow(clippy::erasing_op, clippy::identity_op)]
|
||||
GlWindowMode::Cubemap | GlWindowMode::Spherical => vec![
|
||||
Rect::new(Point2D::new(size.width * 1, size.height * 1), size),
|
||||
Rect::new(Point2D::new(size.width * 0, size.height * 1), size),
|
||||
|
@ -168,7 +171,7 @@ impl DeviceAPI for GlWindowDevice {
|
|||
Rect::new(Point2D::default(), size),
|
||||
Rect::new(Point2D::new(size.width, 0), size),
|
||||
]
|
||||
}
|
||||
},
|
||||
};
|
||||
Viewports { viewports }
|
||||
}
|
||||
|
@ -282,7 +285,7 @@ impl DeviceAPI for GlWindowDevice {
|
|||
target_swap_chain
|
||||
.swap_buffers(&mut self.device, &mut self.context, PreserveBuffer::No)
|
||||
.unwrap();
|
||||
}
|
||||
},
|
||||
None => {
|
||||
// Rendering to a native widget
|
||||
let mut surface = self
|
||||
|
@ -296,7 +299,7 @@ impl DeviceAPI for GlWindowDevice {
|
|||
self.device
|
||||
.bind_surface_to_context(&mut self.context, surface)
|
||||
.unwrap();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
debug_assert_eq!(unsafe { self.gl.get_error() }, gl::NO_ERROR);
|
||||
|
@ -377,11 +380,11 @@ impl GlWindowDevice {
|
|||
.bind_surface_to_context(&mut context, surface)
|
||||
.unwrap();
|
||||
None
|
||||
}
|
||||
},
|
||||
GlWindowRenderTarget::SwapChain(target_swap_chain) => {
|
||||
debug_assert!(target_swap_chain.is_attached());
|
||||
Some(target_swap_chain)
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let read_fbo = unsafe { gl.create_framebuffer().ok() };
|
||||
|
@ -496,20 +499,20 @@ impl GlWindowDevice {
|
|||
// (The wasted pixels are on the right of the left eye and vice versa.)
|
||||
let wasted_pixels = (INTER_PUPILLARY_DISTANCE / PIXELS_PER_METRE) as i32;
|
||||
Size2D::new(window_size.width + wasted_pixels, window_size.height)
|
||||
}
|
||||
},
|
||||
GlWindowMode::Cubemap => {
|
||||
// Cubemap viewports should be square
|
||||
let size = 1.max(window_size.width / 3).max(window_size.height / 2);
|
||||
Size2D::new(size, size)
|
||||
}
|
||||
},
|
||||
GlWindowMode::Spherical => {
|
||||
// Cubemap viewports should be square
|
||||
let size = 1.max(window_size.width / 2).max(window_size.height);
|
||||
Size2D::new(size, size)
|
||||
}
|
||||
},
|
||||
GlWindowMode::StereoLeftRight | GlWindowMode::Blit => {
|
||||
Size2D::new(window_size.width / 2, window_size.height)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,7 +528,7 @@ impl GlWindowDevice {
|
|||
),
|
||||
GlWindowMode::Blit | GlWindowMode::StereoLeftRight | GlWindowMode::StereoRedCyan => {
|
||||
Views::Stereo(self.view(viewer, LEFT_EYE), self.view(viewer, RIGHT_EYE))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -583,7 +586,7 @@ impl GlWindowDevice {
|
|||
GlWindowMode::Spherical | GlWindowMode::Cubemap => Angle::degrees(45.0),
|
||||
GlWindowMode::Blit | GlWindowMode::StereoLeftRight | GlWindowMode::StereoRedCyan => {
|
||||
Angle::degrees(FOV_UP)
|
||||
}
|
||||
},
|
||||
};
|
||||
let f = 1.0 / fov_up.radians.tan();
|
||||
let nf = 1.0 / (near - far);
|
||||
|
@ -723,13 +726,13 @@ impl GlWindowShader {
|
|||
let (vertex_source, fragment_source) = match mode {
|
||||
GlWindowMode::Blit => {
|
||||
return None;
|
||||
}
|
||||
},
|
||||
GlWindowMode::StereoLeftRight | GlWindowMode::Cubemap => {
|
||||
(PASSTHROUGH_VERTEX_SHADER, PASSTHROUGH_FRAGMENT_SHADER)
|
||||
}
|
||||
},
|
||||
GlWindowMode::StereoRedCyan => {
|
||||
(ANAGLYPH_VERTEX_SHADER, ANAGLYPH_RED_CYAN_FRAGMENT_SHADER)
|
||||
}
|
||||
},
|
||||
GlWindowMode::Spherical => (SPHERICAL_VERTEX_SHADER, SPHERICAL_FRAGMENT_SHADER),
|
||||
};
|
||||
|
||||
|
@ -839,17 +842,15 @@ impl GlWindowShader {
|
|||
|
||||
match self.mode {
|
||||
GlWindowMode::StereoRedCyan => {
|
||||
let wasted = 1.0
|
||||
- (texture_size.width as f32 / viewport_size.width as f32)
|
||||
.max(0.0)
|
||||
.min(1.0);
|
||||
let wasted = 1.0 -
|
||||
(texture_size.width as f32 / viewport_size.width as f32).clamp(0.0, 1.0);
|
||||
let wasted_location = self.gl.get_uniform_location(self.program, "wasted");
|
||||
self.gl.uniform_1_f32(wasted_location.as_ref(), wasted);
|
||||
}
|
||||
GlWindowMode::Blit
|
||||
| GlWindowMode::Cubemap
|
||||
| GlWindowMode::Spherical
|
||||
| GlWindowMode::StereoLeftRight => {}
|
||||
},
|
||||
GlWindowMode::Blit |
|
||||
GlWindowMode::Cubemap |
|
||||
GlWindowMode::Spherical |
|
||||
GlWindowMode::StereoLeftRight => {},
|
||||
}
|
||||
|
||||
self.gl
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
* 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 crate::SurfmanGL;
|
||||
use crate::SurfmanLayerManager;
|
||||
use euclid::{Point2D, RigidTransform3D};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
|
||||
use euclid::{Point2D, RigidTransform3D};
|
||||
use surfman::chains::SwapChains;
|
||||
use webxr_api::util::{self, ClipPlanes, HitTestList};
|
||||
use webxr_api::{
|
||||
|
@ -18,6 +17,9 @@ use webxr_api::{
|
|||
SessionMode, Space, SubImages, View, Viewer, ViewerPose, Viewports, Views,
|
||||
};
|
||||
|
||||
use crate::{SurfmanGL, SurfmanLayerManager};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct HeadlessMockDiscovery {}
|
||||
|
||||
struct HeadlessDiscovery {
|
||||
|
@ -74,7 +76,7 @@ impl MockDiscoveryAPI<SurfmanGL> for HeadlessMockDiscovery {
|
|||
init: MockDeviceInit,
|
||||
receiver: Receiver<MockDeviceMsg>,
|
||||
) -> Result<Box<dyn DiscoveryAPI<SurfmanGL>>, Error> {
|
||||
let viewer_origin = init.viewer_origin.clone();
|
||||
let viewer_origin = init.viewer_origin;
|
||||
let floor_transform = init.floor_origin.map(|f| f.inverse());
|
||||
let views = init.views.clone();
|
||||
let data = HeadlessDeviceData {
|
||||
|
@ -209,7 +211,7 @@ impl HeadlessDevice {
|
|||
|
||||
impl DeviceAPI for HeadlessDevice {
|
||||
fn floor_transform(&self) -> Option<RigidTransform3D<f32, Native, Floor>> {
|
||||
self.data.lock().unwrap().floor_transform.clone()
|
||||
self.data.lock().unwrap().floor_transform
|
||||
}
|
||||
|
||||
fn viewports(&self) -> Viewports {
|
||||
|
@ -264,9 +266,9 @@ impl DeviceAPI for HeadlessDevice {
|
|||
}
|
||||
|
||||
if data.needs_floor_update {
|
||||
frame.events.push(FrameUpdateEvent::UpdateFloorTransform(
|
||||
data.floor_transform.clone(),
|
||||
));
|
||||
frame
|
||||
.events
|
||||
.push(FrameUpdateEvent::UpdateFloorTransform(data.floor_transform));
|
||||
data.needs_floor_update = false;
|
||||
}
|
||||
Some(frame)
|
||||
|
@ -315,12 +317,6 @@ impl DeviceAPI for HeadlessDevice {
|
|||
}
|
||||
}
|
||||
|
||||
impl HeadlessMockDiscovery {
|
||||
pub fn new() -> HeadlessMockDiscovery {
|
||||
HeadlessMockDiscovery {}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! with_all_sessions {
|
||||
($self:ident, |$s:ident| $e:expr) => {
|
||||
for $s in &mut $self.sessions {
|
||||
|
@ -401,20 +397,20 @@ impl HeadlessDeviceData {
|
|||
MockDeviceMsg::ClearWorld => self.world = None,
|
||||
MockDeviceMsg::SetViewerOrigin(viewer_origin) => {
|
||||
self.viewer_origin = viewer_origin;
|
||||
}
|
||||
},
|
||||
MockDeviceMsg::SetFloorOrigin(floor_origin) => {
|
||||
self.floor_transform = floor_origin.map(|f| f.inverse());
|
||||
self.needs_floor_update = true;
|
||||
}
|
||||
},
|
||||
MockDeviceMsg::SetViews(views) => {
|
||||
self.views = views;
|
||||
with_all_sessions!(self, |s| {
|
||||
s.needs_vp_update = true;
|
||||
})
|
||||
}
|
||||
},
|
||||
MockDeviceMsg::VisibilityChange(v) => {
|
||||
with_all_sessions!(self, |s| s.events.callback(Event::VisibilityChange(v)))
|
||||
}
|
||||
},
|
||||
MockDeviceMsg::AddInputSource(init) => {
|
||||
self.inputs.push(InputInfo {
|
||||
source: init.source.clone(),
|
||||
|
@ -427,7 +423,7 @@ impl HeadlessDeviceData {
|
|||
with_all_sessions!(self, |s| s
|
||||
.events
|
||||
.callback(Event::AddInput(init.source.clone())))
|
||||
}
|
||||
},
|
||||
MockDeviceMsg::MessageInputSource(id, msg) => {
|
||||
if let Some(ref mut input) = self.inputs.iter_mut().find(|i| i.source.id == id) {
|
||||
match msg {
|
||||
|
@ -437,21 +433,21 @@ impl HeadlessDeviceData {
|
|||
s.events
|
||||
.callback(Event::UpdateInput(id, input.source.clone()))
|
||||
});
|
||||
}
|
||||
},
|
||||
MockInputMsg::SetProfiles(p) => {
|
||||
input.source.profiles = p;
|
||||
with_all_sessions!(self, |s| {
|
||||
s.events
|
||||
.callback(Event::UpdateInput(id, input.source.clone()))
|
||||
});
|
||||
}
|
||||
},
|
||||
MockInputMsg::SetTargetRayMode(t) => {
|
||||
input.source.target_ray_mode = t;
|
||||
with_all_sessions!(self, |s| {
|
||||
s.events
|
||||
.callback(Event::UpdateInput(id, input.source.clone()))
|
||||
});
|
||||
}
|
||||
},
|
||||
MockInputMsg::SetPointerOrigin(p) => input.pointer = p,
|
||||
MockInputMsg::SetGripOrigin(p) => input.grip = p,
|
||||
MockInputMsg::TriggerSelect(kind, event) => {
|
||||
|
@ -463,20 +459,20 @@ impl HeadlessDeviceData {
|
|||
match event {
|
||||
SelectEvent::Start => {
|
||||
self.trigger_select(id, kind, event);
|
||||
}
|
||||
},
|
||||
SelectEvent::End => {
|
||||
if clicking {
|
||||
self.trigger_select(id, kind, SelectEvent::Select);
|
||||
} else {
|
||||
self.trigger_select(id, kind, SelectEvent::End);
|
||||
}
|
||||
}
|
||||
},
|
||||
SelectEvent::Select => {
|
||||
self.trigger_select(id, kind, SelectEvent::Start);
|
||||
self.trigger_select(id, kind, SelectEvent::Select);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
MockInputMsg::Disconnect => {
|
||||
if input.active {
|
||||
with_all_sessions!(self, |s| s
|
||||
|
@ -485,7 +481,7 @@ impl HeadlessDeviceData {
|
|||
input.active = false;
|
||||
input.clicking = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
MockInputMsg::Reconnect => {
|
||||
if !input.active {
|
||||
with_all_sessions!(self, |s| s
|
||||
|
@ -493,14 +489,14 @@ impl HeadlessDeviceData {
|
|||
.callback(Event::AddInput(input.source.clone())));
|
||||
input.active = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
MockInputMsg::SetSupportedButtons(buttons) => {
|
||||
input.buttons = buttons;
|
||||
with_all_sessions!(self, |s| s.events.callback(Event::UpdateInput(
|
||||
input.source.id,
|
||||
input.source.clone()
|
||||
)));
|
||||
}
|
||||
},
|
||||
MockInputMsg::UpdateButtonState(state) => {
|
||||
if let Some(button) = input
|
||||
.buttons
|
||||
|
@ -509,26 +505,26 @@ impl HeadlessDeviceData {
|
|||
{
|
||||
*button = state;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MockDeviceMsg::Disconnect(s) => {
|
||||
self.disconnected = true;
|
||||
with_all_sessions!(self, |s| s.quitter.as_ref().map(|q| q.quit()));
|
||||
// notify the client that we're done disconnecting
|
||||
let _ = s.send(());
|
||||
return false;
|
||||
}
|
||||
},
|
||||
MockDeviceMsg::SetBoundsGeometry(g) => {
|
||||
self.bounds_geometry = g;
|
||||
}
|
||||
},
|
||||
MockDeviceMsg::SimulateResetPose => {
|
||||
with_all_sessions!(self, |s| s.events.callback(Event::ReferenceSpaceChanged(
|
||||
BaseSpace::Local,
|
||||
RigidTransform3D::identity()
|
||||
)));
|
||||
}
|
||||
},
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
|
@ -14,8 +14,7 @@ pub mod headless;
|
|||
pub mod openxr;
|
||||
|
||||
pub mod surfman_layer_manager;
|
||||
pub use surfman_layer_manager::SurfmanGL;
|
||||
pub use surfman_layer_manager::SurfmanLayerManager;
|
||||
pub use surfman_layer_manager::{SurfmanGL, SurfmanLayerManager};
|
||||
pub type MainThreadRegistry = webxr_api::MainThreadRegistry<surfman_layer_manager::SurfmanGL>;
|
||||
pub type Discovery = Box<dyn webxr_api::DiscoveryAPI<SurfmanGL>>;
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
/* 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 euclid::{Size2D, UnknownUnit};
|
||||
use openxr::{ExtensionSet, FrameStream, FrameWaiter, Graphics, Instance, Session, SystemId};
|
||||
use surfman::Context as SurfmanContext;
|
||||
use surfman::Device as SurfmanDevice;
|
||||
use surfman::Error as SurfmanError;
|
||||
use surfman::SurfaceTexture;
|
||||
use surfman::{
|
||||
Context as SurfmanContext, Device as SurfmanDevice, Error as SurfmanError, SurfaceTexture,
|
||||
};
|
||||
use webxr_api::Error;
|
||||
|
||||
pub enum GraphicsProvider {}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* 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::{mem, ptr};
|
||||
|
||||
use euclid::{Size2D, UnknownUnit};
|
||||
|
@ -6,11 +10,10 @@ use openxr::d3d::{Requirements, SessionCreateInfoD3D11, D3D11};
|
|||
use openxr::{
|
||||
ExtensionSet, FormFactor, FrameStream, FrameWaiter, Graphics, Instance, Session, SystemId,
|
||||
};
|
||||
use surfman::Adapter as SurfmanAdapter;
|
||||
use surfman::Context as SurfmanContext;
|
||||
use surfman::Device as SurfmanDevice;
|
||||
use surfman::Error as SurfmanError;
|
||||
use surfman::SurfaceTexture;
|
||||
use surfman::{
|
||||
Adapter as SurfmanAdapter, Context as SurfmanContext, Device as SurfmanDevice,
|
||||
Error as SurfmanError, SurfaceTexture,
|
||||
};
|
||||
use webxr_api::Error;
|
||||
use winapi::shared::winerror::{DXGI_ERROR_NOT_FOUND, S_OK};
|
||||
use winapi::shared::{dxgi, dxgiformat};
|
||||
|
@ -40,7 +43,7 @@ impl GraphicsProviderMethods<D3D11> for GraphicsProvider {
|
|||
//dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM => return *format,
|
||||
f => {
|
||||
warn!("Backend requested unsupported format {:?}", f);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,8 +119,8 @@ fn get_matching_adapter(
|
|||
let result = adapter.GetDesc1(&mut adapter_desc);
|
||||
assert_eq!(result, S_OK);
|
||||
let adapter_luid = &adapter_desc.AdapterLuid;
|
||||
if adapter_luid.LowPart == requirements.adapter_luid.LowPart
|
||||
&& adapter_luid.HighPart == requirements.adapter_luid.HighPart
|
||||
if adapter_luid.LowPart == requirements.adapter_luid.LowPart &&
|
||||
adapter_luid.HighPart == requirements.adapter_luid.HighPart
|
||||
{
|
||||
return Ok(adapter);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* 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::ffi::c_void;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
|
@ -12,22 +16,13 @@ use openxr::{
|
|||
HandJointLocation, HandTracker, HandTrackingAimFlagsFB, Instance, Path, Posef, Session, Space,
|
||||
SpaceLocationFlags, HAND_JOINT_COUNT,
|
||||
};
|
||||
use webxr_api::Finger;
|
||||
use webxr_api::Hand;
|
||||
use webxr_api::Handedness;
|
||||
use webxr_api::Input;
|
||||
use webxr_api::InputFrame;
|
||||
use webxr_api::InputId;
|
||||
use webxr_api::InputSource;
|
||||
use webxr_api::JointFrame;
|
||||
use webxr_api::Native;
|
||||
use webxr_api::SelectEvent;
|
||||
use webxr_api::TargetRayMode;
|
||||
use webxr_api::Viewer;
|
||||
use webxr_api::{
|
||||
Finger, Hand, Handedness, Input, InputFrame, InputId, InputSource, JointFrame, Native,
|
||||
SelectEvent, TargetRayMode, Viewer,
|
||||
};
|
||||
|
||||
use super::interaction_profiles::InteractionProfile;
|
||||
use super::IDENTITY_POSE;
|
||||
|
||||
use crate::ext_string;
|
||||
use crate::openxr::interaction_profiles::INTERACTION_PROFILES;
|
||||
|
||||
|
@ -54,7 +49,7 @@ macro_rules! bind_inputs {
|
|||
};
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum ClickState {
|
||||
Clicking,
|
||||
Done,
|
||||
|
@ -95,15 +90,15 @@ impl ClickState {
|
|||
*self = ClickState::Done;
|
||||
// Cancel the select, we're showing a menu
|
||||
Some(SelectEvent::End)
|
||||
}
|
||||
},
|
||||
(true, ClickState::Done) => {
|
||||
*self = ClickState::Clicking;
|
||||
Some(SelectEvent::Start)
|
||||
}
|
||||
},
|
||||
(false, ClickState::Clicking) => {
|
||||
*self = ClickState::Done;
|
||||
Some(SelectEvent::Select)
|
||||
}
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
} else if *self == ClickState::Clicking {
|
||||
|
@ -506,7 +501,7 @@ impl OpenXRInput {
|
|||
let (button_values, buttons_changed) = {
|
||||
let mut changed = false;
|
||||
let mut values = Vec::<f32>::new();
|
||||
let mut sync_buttons = |actions: &Vec<Action<f32>>| {
|
||||
let mut sync_buttons = |actions: &[Action<f32>]| {
|
||||
let buttons = actions
|
||||
.iter()
|
||||
.map(|action| {
|
||||
|
@ -678,7 +673,7 @@ fn locate_hand<G: Graphics>(
|
|||
openxr::sys::Result::SUCCESS if location_info.is_active.into() => {
|
||||
aim_state.replace(state.assume_init());
|
||||
Some(locations.assume_init())
|
||||
}
|
||||
},
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
use openxr::{
|
||||
sys::{
|
||||
BD_CONTROLLER_INTERACTION_EXTENSION_NAME, EXT_HAND_INTERACTION_EXTENSION_NAME,
|
||||
EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME,
|
||||
EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME, FB_HAND_TRACKING_AIM_EXTENSION_NAME,
|
||||
FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME,
|
||||
HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME,
|
||||
HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME,
|
||||
META_TOUCH_CONTROLLER_PLUS_EXTENSION_NAME, ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME,
|
||||
},
|
||||
ExtensionSet,
|
||||
/* 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 openxr::sys::{
|
||||
BD_CONTROLLER_INTERACTION_EXTENSION_NAME, EXT_HAND_INTERACTION_EXTENSION_NAME,
|
||||
EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME, EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME,
|
||||
FB_HAND_TRACKING_AIM_EXTENSION_NAME, FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME,
|
||||
HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME,
|
||||
HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME,
|
||||
META_TOUCH_CONTROLLER_PLUS_EXTENSION_NAME, ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME,
|
||||
};
|
||||
use openxr::ExtensionSet;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! ext_string {
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use crate::gl_utils::GlClearer;
|
||||
use crate::SurfmanGL;
|
||||
/* 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 euclid::Box2D;
|
||||
use euclid::Point2D;
|
||||
use euclid::Rect;
|
||||
use euclid::RigidTransform3D;
|
||||
use euclid::Rotation3D;
|
||||
use euclid::Size2D;
|
||||
use euclid::Transform3D;
|
||||
use euclid::Vector3D;
|
||||
use glow::PixelUnpackData;
|
||||
use glow::{self as gl, HasContext};
|
||||
use std::collections::HashMap;
|
||||
use std::num::NonZeroU32;
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use std::{mem, thread};
|
||||
|
||||
use euclid::{Box2D, Point2D, Rect, RigidTransform3D, Rotation3D, Size2D, Transform3D, Vector3D};
|
||||
use glow::{self as gl, HasContext, PixelUnpackData};
|
||||
use interaction_profiles::{get_profiles_from_path, get_supported_interaction_profiles};
|
||||
use log::{error, warn};
|
||||
use openxr::sys::CompositionLayerPassthroughFB;
|
||||
|
@ -22,56 +22,21 @@ use openxr::{
|
|||
ReferenceSpaceType, SecondaryEndInfo, Session, Space, Swapchain, SwapchainCreateFlags,
|
||||
SwapchainCreateInfo, SwapchainUsageFlags, SystemId, Vector3f, Version, ViewConfigurationType,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
use std::num::NonZeroU32;
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use surfman::Context as SurfmanContext;
|
||||
use surfman::Device as SurfmanDevice;
|
||||
use surfman::Error as SurfmanError;
|
||||
use surfman::SurfaceTexture;
|
||||
use surfman::{
|
||||
Context as SurfmanContext, Device as SurfmanDevice, Error as SurfmanError, SurfaceTexture,
|
||||
};
|
||||
use webxr_api;
|
||||
use webxr_api::util::{self, ClipPlanes};
|
||||
use webxr_api::BaseSpace;
|
||||
use webxr_api::Capture;
|
||||
use webxr_api::ContextId;
|
||||
use webxr_api::DeviceAPI;
|
||||
use webxr_api::DiscoveryAPI;
|
||||
use webxr_api::Display;
|
||||
use webxr_api::Error;
|
||||
use webxr_api::Event;
|
||||
use webxr_api::EventBuffer;
|
||||
use webxr_api::Floor;
|
||||
use webxr_api::Frame;
|
||||
use webxr_api::GLContexts;
|
||||
use webxr_api::InputId;
|
||||
use webxr_api::InputSource;
|
||||
use webxr_api::LayerGrandManager;
|
||||
use webxr_api::LayerId;
|
||||
use webxr_api::LayerInit;
|
||||
use webxr_api::LayerManager;
|
||||
use webxr_api::LayerManagerAPI;
|
||||
use webxr_api::LeftEye;
|
||||
use webxr_api::Native;
|
||||
use webxr_api::Quitter;
|
||||
use webxr_api::RightEye;
|
||||
use webxr_api::SelectKind;
|
||||
use webxr_api::Sender;
|
||||
use webxr_api::Session as WebXrSession;
|
||||
use webxr_api::SessionBuilder;
|
||||
use webxr_api::SessionInit;
|
||||
use webxr_api::SessionMode;
|
||||
use webxr_api::SubImage;
|
||||
use webxr_api::SubImages;
|
||||
use webxr_api::View;
|
||||
use webxr_api::ViewerPose;
|
||||
use webxr_api::Viewport;
|
||||
use webxr_api::Viewports;
|
||||
use webxr_api::Views;
|
||||
use webxr_api::Visibility;
|
||||
use webxr_api::{
|
||||
BaseSpace, Capture, ContextId, DeviceAPI, DiscoveryAPI, Display, Error, Event, EventBuffer,
|
||||
Floor, Frame, GLContexts, InputId, InputSource, LayerGrandManager, LayerId, LayerInit,
|
||||
LayerManager, LayerManagerAPI, LeftEye, Native, Quitter, RightEye, SelectKind, Sender,
|
||||
Session as WebXrSession, SessionBuilder, SessionInit, SessionMode, SubImage, SubImages, View,
|
||||
ViewerPose, Viewport, Viewports, Views, Visibility,
|
||||
};
|
||||
|
||||
use crate::gl_utils::GlClearer;
|
||||
use crate::SurfmanGL;
|
||||
|
||||
mod input;
|
||||
use input::OpenXRInput;
|
||||
|
@ -173,10 +138,10 @@ struct ViewInfo<Eye> {
|
|||
impl<Eye> ViewInfo<Eye> {
|
||||
fn set_view(&mut self, view: openxr::View, clip_planes: ClipPlanes) {
|
||||
self.view.pose = view.pose;
|
||||
if self.view.fov.angle_left != view.fov.angle_left
|
||||
|| self.view.fov.angle_right != view.fov.angle_right
|
||||
|| self.view.fov.angle_up != view.fov.angle_up
|
||||
|| self.view.fov.angle_down != view.fov.angle_down
|
||||
if self.view.fov.angle_left != view.fov.angle_left ||
|
||||
self.view.fov.angle_right != view.fov.angle_right ||
|
||||
self.view.fov.angle_up != view.fov.angle_up ||
|
||||
self.view.fov.angle_down != view.fov.angle_down
|
||||
{
|
||||
// It's fine if this happens occasionally, but if this happening very
|
||||
// often we should stop caching
|
||||
|
@ -239,9 +204,9 @@ pub fn create_instance(
|
|||
warn!("Available extensions:\n{:?}", supported);
|
||||
let mut supports_hands = needs_hands && supported.ext_hand_tracking;
|
||||
let supports_passthrough = needs_passthrough && supported.fb_passthrough;
|
||||
let supports_secondary = needs_secondary
|
||||
&& supported.msft_secondary_view_configuration
|
||||
&& supported.msft_first_person_observer;
|
||||
let supports_secondary = needs_secondary &&
|
||||
supported.msft_secondary_view_configuration &&
|
||||
supported.msft_first_person_observer;
|
||||
let supports_updating_framerate = supported.fb_display_refresh_rate;
|
||||
|
||||
let app_info = ApplicationInfo {
|
||||
|
@ -364,9 +329,9 @@ impl DiscoveryAPI<SurfmanGL> for OpenXrDiscovery {
|
|||
ViewConfigurationType::PRIMARY_STEREO,
|
||||
) {
|
||||
if mode == SessionMode::ImmersiveAR {
|
||||
supports = blend_modes.contains(&EnvironmentBlendMode::ADDITIVE)
|
||||
|| blend_modes.contains(&EnvironmentBlendMode::ALPHA_BLEND)
|
||||
|| instance.supports_passthrough;
|
||||
supports = blend_modes.contains(&EnvironmentBlendMode::ADDITIVE) ||
|
||||
blend_modes.contains(&EnvironmentBlendMode::ALPHA_BLEND) ||
|
||||
instance.supports_passthrough;
|
||||
} else if mode == SessionMode::ImmersiveVR {
|
||||
// Immersive VR sessions are not precluded by non-opaque blending
|
||||
supports = blend_modes.len() > 0;
|
||||
|
@ -568,7 +533,7 @@ impl LayerManagerAPI<SurfmanGL> for OpenXrLayerManager {
|
|||
None
|
||||
};
|
||||
|
||||
let layer_id = LayerId::new();
|
||||
let layer_id = LayerId::default();
|
||||
let openxr_layer = OpenXrLayer::new(swapchain, depth_stencil_texture, texture_size)?;
|
||||
self.layers.push((context_id, layer_id));
|
||||
self.openxr_layers.insert(layer_id, openxr_layer);
|
||||
|
@ -1101,14 +1066,14 @@ impl OpenXrDevice {
|
|||
Err(e) => {
|
||||
error!("Error polling events: {:?}", e);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
};
|
||||
match event {
|
||||
Some(SessionStateChanged(session_change)) => match session_change.state() {
|
||||
openxr::SessionState::EXITING | openxr::SessionState::LOSS_PENDING => {
|
||||
self.events.callback(Event::SessionEnd);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
openxr::SessionState::STOPPING => {
|
||||
self.events
|
||||
.callback(Event::VisibilityChange(Visibility::Hidden));
|
||||
|
@ -1116,7 +1081,7 @@ impl OpenXrDevice {
|
|||
error!("Session failed to end on STOPPING: {:?}", e);
|
||||
}
|
||||
stopped = true;
|
||||
}
|
||||
},
|
||||
openxr::SessionState::READY if stopped => {
|
||||
self.events
|
||||
.callback(Event::VisibilityChange(Visibility::Visible));
|
||||
|
@ -1124,23 +1089,23 @@ impl OpenXrDevice {
|
|||
error!("Session failed to begin on READY: {:?}", e);
|
||||
}
|
||||
stopped = false;
|
||||
}
|
||||
},
|
||||
openxr::SessionState::FOCUSED => {
|
||||
self.events
|
||||
.callback(Event::VisibilityChange(Visibility::Visible));
|
||||
}
|
||||
},
|
||||
openxr::SessionState::VISIBLE => {
|
||||
self.events
|
||||
.callback(Event::VisibilityChange(Visibility::VisibleBlurred));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
// FIXME: Handle other states
|
||||
}
|
||||
},
|
||||
},
|
||||
Some(InstanceLossPending(_)) => {
|
||||
self.events.callback(Event::SessionEnd);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
Some(InteractionProfileChanged(_)) => {
|
||||
let path = self.instance.string_to_path("/user/hand/right").unwrap();
|
||||
let profile_path = self.session.current_interaction_profile(path).unwrap();
|
||||
|
@ -1162,12 +1127,12 @@ impl OpenXrDevice {
|
|||
new_right.profiles.clone_from(&profiles);
|
||||
self.events
|
||||
.callback(Event::UpdateInput(new_right.id, new_right));
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Failed to get interaction profile: {:?}", e);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(ReferenceSpaceChangePending(e)) => {
|
||||
let base_space = match e.reference_space_type() {
|
||||
ReferenceSpaceType::VIEW => BaseSpace::Viewer,
|
||||
|
@ -1181,18 +1146,18 @@ impl OpenXrDevice {
|
|||
let transform = transform(&e.pose_in_previous_space());
|
||||
self.events
|
||||
.callback(Event::ReferenceSpaceChanged(base_space, transform));
|
||||
}
|
||||
},
|
||||
Some(_) => {
|
||||
// FIXME: Handle other events
|
||||
}
|
||||
},
|
||||
None if stopped => {
|
||||
// XXXManishearth be able to handle exits during this time
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
}
|
||||
},
|
||||
None => {
|
||||
// No more events to process
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
true
|
||||
|
@ -1225,8 +1190,8 @@ impl SharedData {
|
|||
if let Some(ref secondary) = self.secondary {
|
||||
let secondary_vp = Rect::new(
|
||||
Point2D::new(self.left.extent.width + self.right.extent.width, 0),
|
||||
Size2D::new(secondary.extent.width, secondary.extent.height)
|
||||
/ SECONDARY_VIEW_DOWNSCALE,
|
||||
Size2D::new(secondary.extent.width, secondary.extent.height) /
|
||||
SECONDARY_VIEW_DOWNSCALE,
|
||||
);
|
||||
viewports.push(secondary_vp)
|
||||
}
|
||||
|
@ -1268,7 +1233,7 @@ impl DeviceAPI for OpenXrDevice {
|
|||
ContextMenuResult::ExitSession => {
|
||||
self.quit();
|
||||
return None;
|
||||
}
|
||||
},
|
||||
ContextMenuResult::Dismissed => self.context_menu_future = None,
|
||||
ContextMenuResult::Pending => (),
|
||||
}
|
||||
|
@ -1280,7 +1245,7 @@ impl DeviceAPI for OpenXrDevice {
|
|||
Err(e) => {
|
||||
error!("Error waiting on frame: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
|
@ -1294,7 +1259,7 @@ impl DeviceAPI for OpenXrDevice {
|
|||
Err(e) => {
|
||||
error!("Error waiting on frame: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1315,7 +1280,7 @@ impl DeviceAPI for OpenXrDevice {
|
|||
Err(e) => {
|
||||
error!("Error locating views: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
};
|
||||
if !self.supports_mutable_fov {
|
||||
views.iter_mut().for_each(|v| {
|
||||
|
@ -1332,7 +1297,7 @@ impl DeviceAPI for OpenXrDevice {
|
|||
Err(e) => {
|
||||
error!("Error locating viewer space: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
};
|
||||
let transform = transform(&pose.pose);
|
||||
|
||||
|
@ -1349,7 +1314,7 @@ impl DeviceAPI for OpenXrDevice {
|
|||
Err(e) => {
|
||||
error!("Error locating views: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
};
|
||||
secondary.set_view(view, self.clip_planes);
|
||||
}
|
||||
|
@ -1472,22 +1437,22 @@ impl DeviceAPI for OpenXrDevice {
|
|||
Err(e) => {
|
||||
error!("Error polling for event while quitting: {:?}", e);
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
match event {
|
||||
Some(openxr::Event::SessionStateChanged(session_change)) => {
|
||||
match session_change.state() {
|
||||
openxr::SessionState::EXITING => {
|
||||
break;
|
||||
}
|
||||
},
|
||||
openxr::SessionState::STOPPING => {
|
||||
if let Err(e) = self.session.end() {
|
||||
error!("Session failed to end while STOPPING: {:?}", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
thread::sleep(Duration::from_millis(30));
|
||||
|
@ -1565,7 +1530,7 @@ impl DeviceAPI for OpenXrDevice {
|
|||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
//! An implementation of layer management using surfman
|
||||
|
||||
use crate::gl_utils::GlClearer;
|
||||
use euclid::{Point2D, Rect, Size2D};
|
||||
use glow::{self as gl, Context as Gl, HasContext, PixelUnpackData};
|
||||
use std::collections::HashMap;
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use euclid::{Point2D, Rect, Size2D};
|
||||
use glow::{self as gl, Context as Gl, HasContext, PixelUnpackData};
|
||||
use surfman::chains::{PreserveBuffer, SwapChains, SwapChainsAPI};
|
||||
use surfman::{Context as SurfmanContext, Device as SurfmanDevice, SurfaceAccess, SurfaceTexture};
|
||||
use webxr_api::{
|
||||
|
@ -16,7 +16,9 @@ use webxr_api::{
|
|||
SubImages, Viewports,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
use crate::gl_utils::GlClearer;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum SurfmanGL {}
|
||||
|
||||
impl GLTypes for SurfmanGL {
|
||||
|
@ -63,7 +65,7 @@ impl LayerManagerAPI<SurfmanGL> for SurfmanLayerManager {
|
|||
init: LayerInit,
|
||||
) -> Result<LayerId, Error> {
|
||||
let texture_size = init.texture_size(&self.viewports);
|
||||
let layer_id = LayerId::new();
|
||||
let layer_id = LayerId::default();
|
||||
let access = SurfaceAccess::GPUOnly;
|
||||
let size = texture_size.to_untyped();
|
||||
// TODO: Treat depth and stencil separately?
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue