Skip to content

Commit

Permalink
Use glow instead of sparkle
Browse files Browse the repository at this point in the history
Signed-off-by: sagudev <[email protected]>
  • Loading branch information
sagudev committed Sep 25, 2024
1 parent 845ae9c commit ebfbde1
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 317 deletions.
1 change: 1 addition & 0 deletions webxr-api/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ pub struct SubImages {
#[cfg_attr(feature = "ipc", derive(Deserialize, Serialize))]
pub struct SubImage {
pub color_texture: u32,
// TODO: make this Option<NonZeroU32>
pub depth_stencil_texture: Option<u32>,
pub texture_array_index: Option<u32>,
pub viewport: Rect<i32, Viewport>,
Expand Down
2 changes: 1 addition & 1 deletion webxr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ euclid = "0.22"
log = "0.4.6"
openxr = { version = "0.19", optional = true }
serde = { version = "1.0", optional = true }
sparkle = "0.1"
glow = "0.14"
surfman = { version = "0.9", features = ["chains"] }

[target.'cfg(target_os = "windows")'.dependencies]
Expand Down
210 changes: 112 additions & 98 deletions webxr/gl_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,30 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::SurfmanGL;
use sparkle::gl;
use sparkle::gl::GLuint;
use sparkle::gl::Gl;
use glow as gl;
use glow::Context as Gl;
use glow::HasContext;
use std::collections::HashMap;
use std::num::NonZero;
use surfman::Device as SurfmanDevice;
use webxr_api::ContextId;
use webxr_api::GLContexts;
use webxr_api::LayerId;

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
pub(crate) struct GlClearer {
fbos: HashMap<(LayerId, GLuint, Option<GLuint>), GLuint>,
fbos: HashMap<
(
LayerId,
Option<gl::NativeTexture>,
Option<gl::NativeTexture>,
),
Option<gl::NativeFramebuffer>,
>,
should_reverse_winding: bool,
}

Expand All @@ -31,10 +43,10 @@ impl GlClearer {
&mut self,
gl: &Gl,
layer_id: LayerId,
color: GLuint,
color_target: GLuint,
depth_stencil: Option<GLuint>,
) -> GLuint {
color: Option<gl::NativeTexture>,
color_target: u32,
depth_stencil: Option<gl::NativeTexture>,
) -> Option<gl::NativeFramebuffer> {
let should_reverse_winding = self.should_reverse_winding;
*self
.fbos
Expand All @@ -43,41 +55,41 @@ impl GlClearer {
// Save the current GL state
let mut bound_fbos = [0, 0];
unsafe {
gl.get_integer_v(gl::DRAW_FRAMEBUFFER_BINDING, &mut bound_fbos[0..]);
gl.get_integer_v(gl::READ_FRAMEBUFFER_BINDING, &mut bound_fbos[1..]);
}
gl.get_parameter_i32_slice(gl::DRAW_FRAMEBUFFER_BINDING, &mut bound_fbos[0..]);
gl.get_parameter_i32_slice(gl::READ_FRAMEBUFFER_BINDING, &mut bound_fbos[1..]);

// Generate and set attachments of a new FBO
let fbo = gl.gen_framebuffers(1)[0];
// Generate and set attachments of a new FBO
let fbo = gl.create_framebuffer().ok();

gl.bind_framebuffer(gl::FRAMEBUFFER, fbo);
gl.framebuffer_texture_2d(
gl::FRAMEBUFFER,
gl::COLOR_ATTACHMENT0,
color_target,
color,
0,
);
gl.framebuffer_texture_2d(
gl::FRAMEBUFFER,
gl::DEPTH_STENCIL_ATTACHMENT,
gl::TEXTURE_2D,
depth_stencil.unwrap_or(0),
0,
);
gl.bind_framebuffer(gl::FRAMEBUFFER, fbo);
gl.framebuffer_texture_2d(
gl::FRAMEBUFFER,
gl::COLOR_ATTACHMENT0,
color_target,
color,
0,
);
gl.framebuffer_texture_2d(
gl::FRAMEBUFFER,
gl::DEPTH_STENCIL_ATTACHMENT,
gl::TEXTURE_2D,
depth_stencil,
0,
);

// Necessary if using an OpenXR runtime that does not support mutable FOV,
// as flipping the projection matrix necessitates reversing the winding order.
if should_reverse_winding {
gl.front_face(gl::CW);
}
// Necessary if using an OpenXR runtime that does not support mutable FOV,
// as flipping the projection matrix necessitates reversing the winding order.
if should_reverse_winding {
gl.front_face(gl::CW);
}

// Restore the GL state
gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, bound_fbos[0] as GLuint);
gl.bind_framebuffer(gl::READ_FRAMEBUFFER, bound_fbos[1] as GLuint);
debug_assert_eq!(gl.get_error(), gl::NO_ERROR);
// Restore the GL state
gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, framebuffer(bound_fbos[0] as _));
gl.bind_framebuffer(gl::READ_FRAMEBUFFER, framebuffer(bound_fbos[1] as _));
debug_assert_eq!(gl.get_error(), gl::NO_ERROR);

fbo
fbo
}
})
}

Expand All @@ -87,75 +99,75 @@ impl GlClearer {
contexts: &mut dyn GLContexts<SurfmanGL>,
context_id: ContextId,
layer_id: LayerId,
color: GLuint,
color_target: GLuint,
depth_stencil: Option<GLuint>,
color: Option<glow::NativeTexture>,
color_target: u32,
depth_stencil: Option<glow::NativeTexture>,
) {
let gl = match contexts.bindings(device, context_id) {
None => return,
Some(gl) => gl,
};
let fbo = self.fbo(gl, layer_id, color, color_target, depth_stencil);

// Save the current GL state
let mut bound_fbos = [0, 0];
let mut clear_color = [0., 0., 0., 0.];
let mut clear_depth = [0.];
let mut clear_stencil = [0];
let mut color_mask = [0, 0, 0, 0];
let mut depth_mask = [0];
let mut stencil_mask = [0];
let scissor_enabled = gl.is_enabled(gl::SCISSOR_TEST);
let rasterizer_enabled = gl.is_enabled(gl::RASTERIZER_DISCARD);
unsafe {
gl.get_integer_v(gl::DRAW_FRAMEBUFFER_BINDING, &mut bound_fbos[0..]);
gl.get_integer_v(gl::READ_FRAMEBUFFER_BINDING, &mut bound_fbos[1..]);
gl.get_float_v(gl::COLOR_CLEAR_VALUE, &mut clear_color[..]);
gl.get_float_v(gl::DEPTH_CLEAR_VALUE, &mut clear_depth[..]);
gl.get_integer_v(gl::STENCIL_CLEAR_VALUE, &mut clear_stencil[..]);
gl.get_boolean_v(gl::DEPTH_WRITEMASK, &mut depth_mask[..]);
gl.get_integer_v(gl::STENCIL_WRITEMASK, &mut stencil_mask[..]);
gl.get_boolean_v(gl::COLOR_WRITEMASK, &mut color_mask[..]);
}
// Save the current GL state
let mut bound_fbos = [0, 0];
let mut clear_color = [0., 0., 0., 0.];
let mut clear_depth = [0.];
let mut clear_stencil = [0];
let mut color_mask = [0, 0, 0, 0];
let mut depth_mask = [0];
let mut stencil_mask = [0];
let scissor_enabled = gl.is_enabled(gl::SCISSOR_TEST);
let rasterizer_enabled = gl.is_enabled(gl::RASTERIZER_DISCARD);

// Clear it
gl.bind_framebuffer(gl::FRAMEBUFFER, fbo);
gl.clear_color(0., 0., 0., 1.);
gl.clear_depth(1.);
gl.clear_stencil(0);
gl.disable(gl::SCISSOR_TEST);
gl.disable(gl::RASTERIZER_DISCARD);
gl.depth_mask(true);
gl.stencil_mask(0xFFFFFFFF);
gl.color_mask(true, true, true, true);
gl.clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
gl.get_parameter_i32_slice(gl::DRAW_FRAMEBUFFER_BINDING, &mut bound_fbos[0..]);
gl.get_parameter_i32_slice(gl::READ_FRAMEBUFFER_BINDING, &mut bound_fbos[1..]);
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[..]);
gl.get_parameter_i32_slice(gl::DEPTH_WRITEMASK, &mut depth_mask[..]);
gl.get_parameter_i32_slice(gl::STENCIL_WRITEMASK, &mut stencil_mask[..]);
gl.get_parameter_i32_slice(gl::COLOR_WRITEMASK, &mut color_mask[..]);

// Restore the GL state
gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, bound_fbos[0] as GLuint);
gl.bind_framebuffer(gl::READ_FRAMEBUFFER, bound_fbos[1] as GLuint);
gl.clear_color(
clear_color[0],
clear_color[1],
clear_color[2],
clear_color[3],
);
gl.color_mask(
color_mask[0] != 0,
color_mask[1] != 0,
color_mask[2] != 0,
color_mask[3] != 0,
);
gl.clear_depth(clear_depth[0] as f64);
gl.clear_stencil(clear_stencil[0]);
gl.depth_mask(depth_mask[0] != 0);
gl.stencil_mask(stencil_mask[0] as gl::GLuint);
if scissor_enabled {
gl.enable(gl::SCISSOR_TEST);
}
if rasterizer_enabled {
gl.enable(gl::RASTERIZER_DISCARD);
// Clear it
gl.bind_framebuffer(gl::FRAMEBUFFER, fbo);
gl.clear_color(0., 0., 0., 1.);
gl.clear_depth_f64(1.);
gl.clear_stencil(0);
gl.disable(gl::SCISSOR_TEST);
gl.disable(gl::RASTERIZER_DISCARD);
gl.depth_mask(true);
gl.stencil_mask(0xFFFFFFFF);
gl.color_mask(true, true, true, true);
gl.clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);

// Restore the GL state
gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, framebuffer(bound_fbos[0] as _));
gl.bind_framebuffer(gl::READ_FRAMEBUFFER, framebuffer(bound_fbos[1] as _));
gl.clear_color(
clear_color[0],
clear_color[1],
clear_color[2],
clear_color[3],
);
gl.color_mask(
color_mask[0] != 0,
color_mask[1] != 0,
color_mask[2] != 0,
color_mask[3] != 0,
);
gl.clear_depth_f64(clear_depth[0] as f64);
gl.clear_stencil(clear_stencil[0]);
gl.depth_mask(depth_mask[0] != 0);
gl.stencil_mask(stencil_mask[0] as _);
if scissor_enabled {
gl.enable(gl::SCISSOR_TEST);
}
if rasterizer_enabled {
gl.enable(gl::RASTERIZER_DISCARD);
}
debug_assert_eq!(gl.get_error(), gl::NO_ERROR);
}
debug_assert_eq!(gl.get_error(), gl::NO_ERROR);
}

pub(crate) fn destroy_layer(
Expand All @@ -173,7 +185,9 @@ impl GlClearer {
if layer_id != other_id {
true
} else {
gl.delete_framebuffers(&[fbo]);
if let Some(fbo) = fbo {
unsafe { gl.delete_framebuffer(fbo) };
}
false
}
})
Expand Down
Loading

0 comments on commit ebfbde1

Please sign in to comment.