mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Use surfman with glow bindings (#34328)
* Use glowing surfman Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Port https://github.com/servo/webxr/pull/255 Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * fixups rebase Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * fmt Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Update surfman Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> * Fix stale TODO Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
fdbfecf7dd
commit
503bb10c5b
13 changed files with 70 additions and 97 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -7328,7 +7328,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "surfman"
|
name = "surfman"
|
||||||
version = "0.9.8"
|
version = "0.9.8"
|
||||||
source = "git+https://github.com/servo/surfman?rev=300789ddbda45c89e9165c31118bf1c4c07f89f6#300789ddbda45c89e9165c31118bf1c4c07f89f6"
|
source = "git+https://github.com/servo/surfman?rev=a8079ee2708619926d07c5a2088b8c9af99abdb3#a8079ee2708619926d07c5a2088b8c9af99abdb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.8.0",
|
"bitflags 2.8.0",
|
||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
|
|
|
@ -133,7 +133,7 @@ style_config = { git = "https://github.com/servo/stylo", branch = "2025-02-03" }
|
||||||
style_dom = { git = "https://github.com/servo/stylo", package = "dom", branch = "2025-02-03" }
|
style_dom = { git = "https://github.com/servo/stylo", package = "dom", branch = "2025-02-03" }
|
||||||
style_malloc_size_of = { package = "malloc_size_of", git = "https://github.com/servo/stylo", branch = "2025-02-03", features = ["servo"] }
|
style_malloc_size_of = { package = "malloc_size_of", git = "https://github.com/servo/stylo", branch = "2025-02-03", features = ["servo"] }
|
||||||
style_traits = { git = "https://github.com/servo/stylo", branch = "2025-02-03", features = ["servo"] }
|
style_traits = { git = "https://github.com/servo/stylo", branch = "2025-02-03", features = ["servo"] }
|
||||||
surfman = { git = "https://github.com/servo/surfman", rev = "300789ddbda45c89e9165c31118bf1c4c07f89f6", features = ["chains"] }
|
surfman = { git = "https://github.com/servo/surfman", rev = "a8079ee2708619926d07c5a2088b8c9af99abdb3", features = ["chains"] }
|
||||||
syn = { version = "2", default-features = false, features = ["clone-impls", "derive", "parsing"] }
|
syn = { version = "2", default-features = false, features = ["clone-impls", "derive", "parsing"] }
|
||||||
synstructure = "0.13"
|
synstructure = "0.13"
|
||||||
taffy = { version = "0.7.5", default-features = false, features = ["detailed_layout_info", "grid", "serde", "std"] }
|
taffy = { version = "0.7.5", default-features = false, features = ["detailed_layout_info", "grid", "serde", "std"] }
|
||||||
|
|
|
@ -26,8 +26,8 @@ use euclid::default::Size2D;
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use glow::{
|
use glow::{
|
||||||
self as gl, bytes_per_type, components_per_format, ActiveTransformFeedback, Context as Gl,
|
self as gl, bytes_per_type, components_per_format, ActiveTransformFeedback, Context as Gl,
|
||||||
HasContext, NativeFramebuffer, NativeTransformFeedback, NativeUniformLocation,
|
HasContext, NativeTransformFeedback, NativeUniformLocation, NativeVertexArray, PixelUnpackData,
|
||||||
NativeVertexArray, PixelUnpackData, ShaderPrecisionFormat,
|
ShaderPrecisionFormat,
|
||||||
};
|
};
|
||||||
use half::f16;
|
use half::f16;
|
||||||
use log::{debug, error, trace, warn};
|
use log::{debug, error, trace, warn};
|
||||||
|
@ -49,7 +49,6 @@ use crate::webgl_limits::GLLimitsDetect;
|
||||||
#[cfg(feature = "webxr")]
|
#[cfg(feature = "webxr")]
|
||||||
use crate::webxr::{WebXRBridge, WebXRBridgeContexts, WebXRBridgeInit};
|
use crate::webxr::{WebXRBridge, WebXRBridgeContexts, WebXRBridgeInit};
|
||||||
|
|
||||||
type GLuint = u32;
|
|
||||||
type GLint = i32;
|
type GLint = i32;
|
||||||
|
|
||||||
fn native_uniform_location(location: i32) -> Option<NativeUniformLocation> {
|
fn native_uniform_location(location: i32) -> Option<NativeUniformLocation> {
|
||||||
|
@ -606,10 +605,7 @@ impl WebGLThread {
|
||||||
.framebuffer_object;
|
.framebuffer_object;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.bind_framebuffer(
|
gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer);
|
||||||
gl::FRAMEBUFFER,
|
|
||||||
NonZeroU32::new(framebuffer).map(NativeFramebuffer),
|
|
||||||
);
|
|
||||||
gl.viewport(0, 0, size.width as i32, size.height as i32);
|
gl.viewport(0, 0, size.width as i32, size.height as i32);
|
||||||
gl.scissor(0, 0, size.width as i32, size.height as i32);
|
gl.scissor(0, 0, size.width as i32, size.height as i32);
|
||||||
gl.clear_color(0., 0., 0., !has_alpha as u32 as f32);
|
gl.clear_color(0., 0., 0., !has_alpha as u32 as f32);
|
||||||
|
@ -839,7 +835,7 @@ impl WebGLThread {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
debug!(
|
debug!(
|
||||||
"... rebound framebuffer {}, new back buffer surface is {:?}",
|
"... rebound framebuffer {:?}, new back buffer surface is {:?}",
|
||||||
framebuffer_object, id
|
framebuffer_object, id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2698,14 +2694,13 @@ impl WebGLImpl {
|
||||||
) {
|
) {
|
||||||
let id = match request {
|
let id = match request {
|
||||||
WebGLFramebufferBindingRequest::Explicit(id) => Some(id.glow()),
|
WebGLFramebufferBindingRequest::Explicit(id) => Some(id.glow()),
|
||||||
WebGLFramebufferBindingRequest::Default => NonZeroU32::new(
|
WebGLFramebufferBindingRequest::Default => {
|
||||||
device
|
device
|
||||||
.context_surface_info(ctx)
|
.context_surface_info(ctx)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.expect("No surface attached!")
|
.expect("No surface attached!")
|
||||||
.framebuffer_object,
|
.framebuffer_object
|
||||||
)
|
},
|
||||||
.map(NativeFramebuffer),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("WebGLImpl::bind_framebuffer: {:?}", id);
|
debug!("WebGLImpl::bind_framebuffer: {:?}", id);
|
||||||
|
@ -3188,9 +3183,8 @@ struct FramebufferRebindingInfo {
|
||||||
impl FramebufferRebindingInfo {
|
impl FramebufferRebindingInfo {
|
||||||
fn detect(device: &Device, context: &Context, gl: &Gl) -> FramebufferRebindingInfo {
|
fn detect(device: &Device, context: &Context, gl: &Gl) -> FramebufferRebindingInfo {
|
||||||
unsafe {
|
unsafe {
|
||||||
let (mut read_framebuffer, mut draw_framebuffer) = ([0], [0]);
|
let read_framebuffer = gl.get_parameter_framebuffer(gl::READ_FRAMEBUFFER_BINDING);
|
||||||
gl.get_parameter_i32_slice(gl::READ_FRAMEBUFFER_BINDING, &mut read_framebuffer);
|
let draw_framebuffer = gl.get_parameter_framebuffer(gl::DRAW_FRAMEBUFFER_BINDING);
|
||||||
gl.get_parameter_i32_slice(gl::DRAW_FRAMEBUFFER_BINDING, &mut draw_framebuffer);
|
|
||||||
|
|
||||||
let context_surface_framebuffer = device
|
let context_surface_framebuffer = device
|
||||||
.context_surface_info(context)
|
.context_surface_info(context)
|
||||||
|
@ -3199,10 +3193,10 @@ impl FramebufferRebindingInfo {
|
||||||
.framebuffer_object;
|
.framebuffer_object;
|
||||||
|
|
||||||
let mut flags = FramebufferRebindingFlags::empty();
|
let mut flags = FramebufferRebindingFlags::empty();
|
||||||
if context_surface_framebuffer == read_framebuffer[0] as GLuint {
|
if context_surface_framebuffer == read_framebuffer {
|
||||||
flags.insert(FramebufferRebindingFlags::REBIND_READ_FRAMEBUFFER);
|
flags.insert(FramebufferRebindingFlags::REBIND_READ_FRAMEBUFFER);
|
||||||
}
|
}
|
||||||
if context_surface_framebuffer == draw_framebuffer[0] as GLuint {
|
if context_surface_framebuffer == draw_framebuffer {
|
||||||
flags.insert(FramebufferRebindingFlags::REBIND_DRAW_FRAMEBUFFER);
|
flags.insert(FramebufferRebindingFlags::REBIND_DRAW_FRAMEBUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3227,23 +3221,13 @@ impl FramebufferRebindingInfo {
|
||||||
.flags
|
.flags
|
||||||
.contains(FramebufferRebindingFlags::REBIND_READ_FRAMEBUFFER)
|
.contains(FramebufferRebindingFlags::REBIND_READ_FRAMEBUFFER)
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe { gl.bind_framebuffer(gl::READ_FRAMEBUFFER, context_surface_framebuffer) };
|
||||||
gl.bind_framebuffer(
|
|
||||||
gl::READ_FRAMEBUFFER,
|
|
||||||
NonZeroU32::new(context_surface_framebuffer).map(NativeFramebuffer),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if self
|
if self
|
||||||
.flags
|
.flags
|
||||||
.contains(FramebufferRebindingFlags::REBIND_DRAW_FRAMEBUFFER)
|
.contains(FramebufferRebindingFlags::REBIND_DRAW_FRAMEBUFFER)
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe { gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, context_surface_framebuffer) };
|
||||||
gl.bind_framebuffer(
|
|
||||||
gl::DRAW_FRAMEBUFFER,
|
|
||||||
NonZeroU32::new(context_surface_framebuffer).map(NativeFramebuffer),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
use canvas_traits::webgl::{
|
use canvas_traits::webgl::{
|
||||||
webgl_channel, WebGLContextId, WebGLMsg, WebGLSender, WebXRCommand, WebXRLayerManagerId,
|
webgl_channel, WebGLContextId, WebGLMsg, WebGLSender, WebXRCommand, WebXRLayerManagerId,
|
||||||
|
@ -25,7 +26,7 @@ use crate::webgl_thread::{GLContextData, WebGLThread};
|
||||||
pub(crate) struct WebXRBridge {
|
pub(crate) struct WebXRBridge {
|
||||||
factory_receiver: crossbeam_channel::Receiver<WebXRLayerManagerFactory<WebXRSurfman>>,
|
factory_receiver: crossbeam_channel::Receiver<WebXRLayerManagerFactory<WebXRSurfman>>,
|
||||||
managers: HashMap<WebXRLayerManagerId, Box<dyn WebXRLayerManagerAPI<WebXRSurfman>>>,
|
managers: HashMap<WebXRLayerManagerId, Box<dyn WebXRLayerManagerAPI<WebXRSurfman>>>,
|
||||||
next_manager_id: u32,
|
next_manager_id: NonZeroU32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebXRBridge {
|
impl WebXRBridge {
|
||||||
|
@ -34,7 +35,7 @@ impl WebXRBridge {
|
||||||
factory_receiver, ..
|
factory_receiver, ..
|
||||||
} = init;
|
} = init;
|
||||||
let managers = HashMap::new();
|
let managers = HashMap::new();
|
||||||
let next_manager_id = 1;
|
let next_manager_id = NonZeroU32::MIN;
|
||||||
WebXRBridge {
|
WebXRBridge {
|
||||||
factory_receiver,
|
factory_receiver,
|
||||||
managers,
|
managers,
|
||||||
|
@ -55,8 +56,11 @@ impl WebXRBridge {
|
||||||
.recv()
|
.recv()
|
||||||
.map_err(|_| WebXRError::CommunicationError)?;
|
.map_err(|_| WebXRError::CommunicationError)?;
|
||||||
let manager = factory.build(device, contexts)?;
|
let manager = factory.build(device, contexts)?;
|
||||||
let manager_id = unsafe { WebXRLayerManagerId::new(self.next_manager_id) };
|
let manager_id = WebXRLayerManagerId::new(self.next_manager_id);
|
||||||
self.next_manager_id += 1;
|
self.next_manager_id = self
|
||||||
|
.next_manager_id
|
||||||
|
.checked_add(1)
|
||||||
|
.expect("next_manager_id should not overflow");
|
||||||
self.managers.insert(manager_id, manager);
|
self.managers.insert(manager_id, manager);
|
||||||
Ok(manager_id)
|
Ok(manager_id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,8 +152,7 @@ impl XRWebGLLayer {
|
||||||
let sub_images = frame.get_sub_images(self.layer_id()?)?;
|
let sub_images = frame.get_sub_images(self.layer_id()?)?;
|
||||||
let session = self.session();
|
let session = self.session();
|
||||||
// TODO: Cache this texture
|
// TODO: Cache this texture
|
||||||
let color_texture_id =
|
let color_texture_id = WebGLTextureId::new(sub_images.sub_image.as_ref()?.color_texture?);
|
||||||
WebGLTextureId::maybe_new(sub_images.sub_image.as_ref()?.color_texture)?;
|
|
||||||
let color_texture = WebGLTexture::new_webxr(context, color_texture_id, session);
|
let color_texture = WebGLTexture::new_webxr(context, color_texture_id, session);
|
||||||
let target = self.texture_target();
|
let target = self.texture_target();
|
||||||
|
|
||||||
|
@ -187,7 +186,7 @@ impl XRWebGLLayer {
|
||||||
.ok()?;
|
.ok()?;
|
||||||
if let Some(id) = sub_images.sub_image.as_ref()?.depth_stencil_texture {
|
if let Some(id) = sub_images.sub_image.as_ref()?.depth_stencil_texture {
|
||||||
// TODO: Cache this texture
|
// TODO: Cache this texture
|
||||||
let depth_stencil_texture_id = WebGLTextureId::maybe_new(id)?;
|
let depth_stencil_texture_id = WebGLTextureId::new(id);
|
||||||
let depth_stencil_texture =
|
let depth_stencil_texture =
|
||||||
WebGLTexture::new_webxr(context, depth_stencil_texture_id, session);
|
WebGLTexture::new_webxr(context, depth_stencil_texture_id, session);
|
||||||
framebuffer
|
framebuffer
|
||||||
|
|
|
@ -570,15 +570,9 @@ macro_rules! define_resource_id {
|
||||||
pub struct $name(nonzero_type!($type));
|
pub struct $name(nonzero_type!($type));
|
||||||
|
|
||||||
impl $name {
|
impl $name {
|
||||||
#[allow(unsafe_code)]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Create a new $name.
|
pub fn new(id: nonzero_type!($type)) -> Self {
|
||||||
///
|
Self(id)
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// Using an invalid OpenGL id may result in undefined behavior.
|
|
||||||
pub unsafe fn new(id: $type) -> Self {
|
|
||||||
$name(<nonzero_type!($type)>::new_unchecked(id))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -599,10 +593,10 @@ macro_rules! define_resource_id {
|
||||||
D: ::serde::Deserializer<'de>,
|
D: ::serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let id = <$type>::deserialize(deserializer)?;
|
let id = <$type>::deserialize(deserializer)?;
|
||||||
if id == 0 {
|
if let Some(id) = <nonzero_type!($type)>::new(id) {
|
||||||
Err(::serde::de::Error::custom("expected a non-zero value"))
|
Ok($name(id))
|
||||||
} else {
|
} else {
|
||||||
Ok(unsafe { $name::new(id) })
|
Err(::serde::de::Error::custom("expected a non-zero value"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,8 @@ impl RenderingContext for SurfmanRenderingContext {
|
||||||
fn framebuffer_object(&self) -> u32 {
|
fn framebuffer_object(&self) -> u32 {
|
||||||
self.context_surface_info()
|
self.context_surface_info()
|
||||||
.unwrap_or(None)
|
.unwrap_or(None)
|
||||||
.map(|info| info.framebuffer_object)
|
.and_then(|info| info.framebuffer_object)
|
||||||
|
.map(|fbo| fbo.0.get())
|
||||||
.unwrap_or(0)
|
.unwrap_or(0)
|
||||||
}
|
}
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
|
@ -187,7 +188,11 @@ impl RenderingContext for SurfmanRenderingContext {
|
||||||
debug!("... getting texture for surface {:?}", front_buffer_id);
|
debug!("... getting texture for surface {:?}", front_buffer_id);
|
||||||
let surface_texture = device.create_surface_texture(context, surface).unwrap();
|
let surface_texture = device.create_surface_texture(context, surface).unwrap();
|
||||||
let gl_texture = device.surface_texture_object(&surface_texture);
|
let gl_texture = device.surface_texture_object(&surface_texture);
|
||||||
(surface_texture, gl_texture, size)
|
(
|
||||||
|
surface_texture,
|
||||||
|
gl_texture.map(|tex| tex.0.get()).unwrap_or(0),
|
||||||
|
size,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_texture(&self, surface_texture: SurfaceTexture) -> Surface {
|
fn destroy_texture(&self, surface_texture: SurfaceTexture) -> Surface {
|
||||||
|
@ -390,7 +395,10 @@ impl SurfmanRenderingContext {
|
||||||
|
|
||||||
pub fn surface_texture_object(&self, surface: &SurfaceTexture) -> u32 {
|
pub fn surface_texture_object(&self, surface: &SurfaceTexture) -> u32 {
|
||||||
let device = &self.0.device.borrow();
|
let device = &self.0.device.borrow();
|
||||||
device.surface_texture_object(surface)
|
device
|
||||||
|
.surface_texture_object(surface)
|
||||||
|
.map(|t| t.0.get())
|
||||||
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_proc_address(&self, name: &str) -> *const c_void {
|
pub fn get_proc_address(&self, name: &str) -> *const c_void {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::num::NonZeroU32;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
use euclid::{Rect, Size2D};
|
use euclid::{Rect, Size2D};
|
||||||
|
@ -286,9 +287,8 @@ pub struct SubImages {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(feature = "ipc", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "ipc", derive(Deserialize, Serialize))]
|
||||||
pub struct SubImage {
|
pub struct SubImage {
|
||||||
pub color_texture: u32,
|
pub color_texture: Option<NonZeroU32>,
|
||||||
// TODO: make this Option<NonZeroU32>
|
pub depth_stencil_texture: Option<NonZeroU32>,
|
||||||
pub depth_stencil_texture: Option<u32>,
|
|
||||||
pub texture_array_index: Option<u32>,
|
pub texture_array_index: Option<u32>,
|
||||||
pub viewport: Rect<i32, Viewport>,
|
pub viewport: Rect<i32, Viewport>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::num::NonZero;
|
|
||||||
|
|
||||||
use glow as gl;
|
use glow as gl;
|
||||||
use glow::{Context as Gl, HasContext};
|
use glow::{Context as Gl, HasContext};
|
||||||
|
@ -12,10 +11,6 @@ use webxr_api::{ContextId, GLContexts, LayerId};
|
||||||
|
|
||||||
use crate::SurfmanGL;
|
use crate::SurfmanGL;
|
||||||
|
|
||||||
pub(crate) fn framebuffer(framebuffer: u32) -> Option<gl::NativeFramebuffer> {
|
|
||||||
NonZero::new(framebuffer).map(gl::NativeFramebuffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A utility to clear a color texture and optional depth/stencil texture
|
// A utility to clear a color texture and optional depth/stencil texture
|
||||||
pub(crate) struct GlClearer {
|
pub(crate) struct GlClearer {
|
||||||
fbos: HashMap<
|
fbos: HashMap<
|
||||||
|
@ -52,10 +47,9 @@ impl GlClearer {
|
||||||
.entry((layer_id, color, depth_stencil))
|
.entry((layer_id, color, depth_stencil))
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
// Save the current GL state
|
// Save the current GL state
|
||||||
let mut bound_fbos = [0, 0];
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.get_parameter_i32_slice(gl::DRAW_FRAMEBUFFER_BINDING, &mut bound_fbos[0..]);
|
let draw_fbo = gl.get_parameter_framebuffer(gl::DRAW_FRAMEBUFFER_BINDING);
|
||||||
gl.get_parameter_i32_slice(gl::READ_FRAMEBUFFER_BINDING, &mut bound_fbos[1..]);
|
let read_fbo = gl.get_parameter_framebuffer(gl::READ_FRAMEBUFFER_BINDING);
|
||||||
|
|
||||||
// Generate and set attachments of a new FBO
|
// Generate and set attachments of a new FBO
|
||||||
let fbo = gl.create_framebuffer().ok();
|
let fbo = gl.create_framebuffer().ok();
|
||||||
|
@ -83,8 +77,8 @@ impl GlClearer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the GL state
|
// Restore the GL state
|
||||||
gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, framebuffer(bound_fbos[0] as _));
|
gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, draw_fbo);
|
||||||
gl.bind_framebuffer(gl::READ_FRAMEBUFFER, framebuffer(bound_fbos[1] as _));
|
gl.bind_framebuffer(gl::READ_FRAMEBUFFER, read_fbo);
|
||||||
debug_assert_eq!(gl.get_error(), gl::NO_ERROR);
|
debug_assert_eq!(gl.get_error(), gl::NO_ERROR);
|
||||||
|
|
||||||
fbo
|
fbo
|
||||||
|
@ -110,7 +104,6 @@ impl GlClearer {
|
||||||
let fbo = self.fbo(gl, layer_id, color, color_target, depth_stencil);
|
let fbo = self.fbo(gl, layer_id, color, color_target, depth_stencil);
|
||||||
unsafe {
|
unsafe {
|
||||||
// Save the current GL state
|
// Save the current GL state
|
||||||
let mut bound_fbos = [0, 0];
|
|
||||||
let mut clear_color = [0., 0., 0., 0.];
|
let mut clear_color = [0., 0., 0., 0.];
|
||||||
let mut clear_depth = [0.];
|
let mut clear_depth = [0.];
|
||||||
let mut clear_stencil = [0];
|
let mut clear_stencil = [0];
|
||||||
|
@ -118,8 +111,8 @@ impl GlClearer {
|
||||||
let scissor_enabled = gl.is_enabled(gl::SCISSOR_TEST);
|
let scissor_enabled = gl.is_enabled(gl::SCISSOR_TEST);
|
||||||
let rasterizer_enabled = gl.is_enabled(gl::RASTERIZER_DISCARD);
|
let rasterizer_enabled = gl.is_enabled(gl::RASTERIZER_DISCARD);
|
||||||
|
|
||||||
gl.get_parameter_i32_slice(gl::DRAW_FRAMEBUFFER_BINDING, &mut bound_fbos[0..]);
|
let draw_fbo = gl.get_parameter_framebuffer(gl::DRAW_FRAMEBUFFER_BINDING);
|
||||||
gl.get_parameter_i32_slice(gl::READ_FRAMEBUFFER_BINDING, &mut bound_fbos[1..]);
|
let read_fbo = gl.get_parameter_framebuffer(gl::READ_FRAMEBUFFER_BINDING);
|
||||||
gl.get_parameter_f32_slice(gl::COLOR_CLEAR_VALUE, &mut clear_color[..]);
|
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_f32_slice(gl::DEPTH_CLEAR_VALUE, &mut clear_depth[..]);
|
||||||
gl.get_parameter_i32_slice(gl::STENCIL_CLEAR_VALUE, &mut clear_stencil[..]);
|
gl.get_parameter_i32_slice(gl::STENCIL_CLEAR_VALUE, &mut clear_stencil[..]);
|
||||||
|
@ -140,8 +133,8 @@ impl GlClearer {
|
||||||
gl.clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
|
gl.clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
// Restore the GL state
|
// Restore the GL state
|
||||||
gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, framebuffer(bound_fbos[0] as _));
|
gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, draw_fbo);
|
||||||
gl.bind_framebuffer(gl::READ_FRAMEBUFFER, framebuffer(bound_fbos[1] as _));
|
gl.bind_framebuffer(gl::READ_FRAMEBUFFER, read_fbo);
|
||||||
gl.clear_color(
|
gl.clear_color(
|
||||||
clear_color[0],
|
clear_color[0],
|
||||||
clear_color[1],
|
clear_color[1],
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use core::slice;
|
use core::slice;
|
||||||
use std::num::NonZeroU32;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use euclid::{
|
use euclid::{
|
||||||
|
@ -25,7 +24,6 @@ use webxr_api::{
|
||||||
VIEWER,
|
VIEWER,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::gl_utils::framebuffer;
|
|
||||||
use crate::{SurfmanGL, SurfmanLayerManager};
|
use crate::{SurfmanGL, SurfmanLayerManager};
|
||||||
|
|
||||||
// How far off the ground are the viewer's eyes?
|
// How far off the ground are the viewer's eyes?
|
||||||
|
@ -222,11 +220,10 @@ impl DeviceAPI for GlWindowDevice {
|
||||||
.device
|
.device
|
||||||
.context_surface_info(&self.context)
|
.context_surface_info(&self.context)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|info| info.framebuffer_object)
|
.and_then(|info| info.framebuffer_object);
|
||||||
.unwrap_or(0);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
self.gl
|
self.gl
|
||||||
.bind_framebuffer(gl::FRAMEBUFFER, framebuffer(framebuffer_object));
|
.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_object);
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
(
|
(
|
||||||
self.gl.get_error(),
|
self.gl.get_error(),
|
||||||
|
@ -254,10 +251,9 @@ impl DeviceAPI for GlWindowDevice {
|
||||||
.device
|
.device
|
||||||
.create_surface_texture(&mut self.context, surface)
|
.create_surface_texture(&mut self.context, surface)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let raw_texture_id = self.device.surface_texture_object(&surface_texture);
|
let texture_id = self.device.surface_texture_object(&surface_texture);
|
||||||
let texture_id = NonZeroU32::new(raw_texture_id).map(gl::NativeTexture);
|
|
||||||
let texture_target = self.device.surface_gl_texture_target();
|
let texture_target = self.device.surface_gl_texture_target();
|
||||||
log::debug!("Presenting texture {}", raw_texture_id);
|
log::debug!("Presenting texture {:?}", texture_id);
|
||||||
|
|
||||||
if let Some(ref shader) = self.shader {
|
if let Some(ref shader) = self.shader {
|
||||||
shader.draw_texture(
|
shader.draw_texture(
|
||||||
|
@ -392,9 +388,8 @@ impl GlWindowDevice {
|
||||||
let framebuffer_object = device
|
let framebuffer_object = device
|
||||||
.context_surface_info(&context)
|
.context_surface_info(&context)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|info| info.framebuffer_object)
|
.and_then(|info| info.framebuffer_object);
|
||||||
.unwrap_or(0);
|
gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_object);
|
||||||
gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer(framebuffer_object));
|
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
(gl.get_error(), gl.check_framebuffer_status(gl::FRAMEBUFFER)),
|
(gl.get_error(), gl.check_framebuffer_status(gl::FRAMEBUFFER)),
|
||||||
(gl::NO_ERROR, gl::FRAMEBUFFER_COMPLETE)
|
(gl::NO_ERROR, gl::FRAMEBUFFER_COMPLETE)
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::num::NonZeroU32;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -767,15 +766,13 @@ impl LayerManagerAPI<SurfmanGL> for OpenXrLayerManager {
|
||||||
})?;
|
})?;
|
||||||
let color_texture = device.surface_texture_object(color_surface_texture);
|
let color_texture = device.surface_texture_object(color_surface_texture);
|
||||||
let color_target = device.surface_gl_texture_target();
|
let color_target = device.surface_gl_texture_target();
|
||||||
let depth_stencil_texture = openxr_layer
|
let depth_stencil_texture = openxr_layer.depth_stencil_texture;
|
||||||
.depth_stencil_texture
|
|
||||||
.map(|texture| texture.0.get());
|
|
||||||
let texture_array_index = None;
|
let texture_array_index = None;
|
||||||
let origin = Point2D::new(0, 0);
|
let origin = Point2D::new(0, 0);
|
||||||
let texture_size = openxr_layer.size;
|
let texture_size = openxr_layer.size;
|
||||||
let sub_image = Some(SubImage {
|
let sub_image = Some(SubImage {
|
||||||
color_texture,
|
color_texture: color_texture.map(|t| t.0),
|
||||||
depth_stencil_texture,
|
depth_stencil_texture: depth_stencil_texture.map(|t| t.0),
|
||||||
texture_array_index,
|
texture_array_index,
|
||||||
viewport: Rect::new(origin, texture_size),
|
viewport: Rect::new(origin, texture_size),
|
||||||
});
|
});
|
||||||
|
@ -784,8 +781,8 @@ impl LayerManagerAPI<SurfmanGL> for OpenXrLayerManager {
|
||||||
.viewports
|
.viewports
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&viewport| SubImage {
|
.map(|&viewport| SubImage {
|
||||||
color_texture,
|
color_texture: color_texture.map(|t| t.0),
|
||||||
depth_stencil_texture,
|
depth_stencil_texture: depth_stencil_texture.map(|t| t.0),
|
||||||
texture_array_index,
|
texture_array_index,
|
||||||
viewport,
|
viewport,
|
||||||
})
|
})
|
||||||
|
@ -795,7 +792,7 @@ impl LayerManagerAPI<SurfmanGL> for OpenXrLayerManager {
|
||||||
contexts,
|
contexts,
|
||||||
context_id,
|
context_id,
|
||||||
layer_id,
|
layer_id,
|
||||||
NonZeroU32::new(color_texture).map(glow::NativeTexture),
|
color_texture,
|
||||||
color_target,
|
color_target,
|
||||||
openxr_layer.depth_stencil_texture,
|
openxr_layer.depth_stencil_texture,
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//! An implementation of layer management using surfman
|
//! An implementation of layer management using surfman
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::num::NonZeroU32;
|
|
||||||
|
|
||||||
use euclid::{Point2D, Rect, Size2D};
|
use euclid::{Point2D, Rect, Size2D};
|
||||||
use glow::{self as gl, Context as Gl, HasContext, PixelUnpackData};
|
use glow::{self as gl, Context as Gl, HasContext, PixelUnpackData};
|
||||||
|
@ -165,8 +164,8 @@ impl LayerManagerAPI<SurfmanGL> for SurfmanLayerManager {
|
||||||
let texture_array_index = None;
|
let texture_array_index = None;
|
||||||
let origin = Point2D::new(0, 0);
|
let origin = Point2D::new(0, 0);
|
||||||
let sub_image = Some(SubImage {
|
let sub_image = Some(SubImage {
|
||||||
color_texture,
|
color_texture: color_texture.map(|nt| nt.0),
|
||||||
depth_stencil_texture: depth_stencil_texture.map(|nt| nt.0.get()),
|
depth_stencil_texture: depth_stencil_texture.map(|nt| nt.0),
|
||||||
texture_array_index,
|
texture_array_index,
|
||||||
viewport: Rect::new(origin, surface_size),
|
viewport: Rect::new(origin, surface_size),
|
||||||
});
|
});
|
||||||
|
@ -175,8 +174,8 @@ impl LayerManagerAPI<SurfmanGL> for SurfmanLayerManager {
|
||||||
.viewports
|
.viewports
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&viewport| SubImage {
|
.map(|&viewport| SubImage {
|
||||||
color_texture,
|
color_texture: color_texture.map(|nt| nt.0),
|
||||||
depth_stencil_texture: depth_stencil_texture.map(|texture| texture.0.get()),
|
depth_stencil_texture: depth_stencil_texture.map(|texture| texture.0),
|
||||||
texture_array_index,
|
texture_array_index,
|
||||||
viewport,
|
viewport,
|
||||||
})
|
})
|
||||||
|
@ -187,7 +186,7 @@ impl LayerManagerAPI<SurfmanGL> for SurfmanLayerManager {
|
||||||
contexts,
|
contexts,
|
||||||
context_id,
|
context_id,
|
||||||
layer_id,
|
layer_id,
|
||||||
NonZeroU32::new(color_texture).map(gl::NativeTexture),
|
color_texture,
|
||||||
color_target,
|
color_target,
|
||||||
depth_stencil_texture,
|
depth_stencil_texture,
|
||||||
);
|
);
|
||||||
|
|
|
@ -94,7 +94,7 @@ impl Minibrowser {
|
||||||
.options_mut(|options| options.zoom_with_keyboard = false);
|
.options_mut(|options| options.zoom_with_keyboard = false);
|
||||||
|
|
||||||
let widget_surface_fbo = match rendering_context.context_surface_info() {
|
let widget_surface_fbo = match rendering_context.context_surface_info() {
|
||||||
Ok(Some(info)) => NonZeroU32::new(info.framebuffer_object).map(NativeFramebuffer),
|
Ok(Some(info)) => info.framebuffer_object,
|
||||||
Ok(None) => panic!("Failed to get widget surface info from surfman!"),
|
Ok(None) => panic!("Failed to get widget surface info from surfman!"),
|
||||||
Err(error) => panic!("Failed to get widget surface info from surfman! {error:?}"),
|
Err(error) => panic!("Failed to get widget surface info from surfman! {error:?}"),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue