From b2510676b9a7b45b38820da326e27c05b7b2d408 Mon Sep 17 00:00:00 2001 From: Sebastian Urban Date: Sun, 22 May 2022 17:43:30 +0200 Subject: [PATCH] Take Glow context using Arc. (#1640) This allows usage with a Glow context that is passed between threads. --- Cargo.toml | 3 +++ eframe/src/epi.rs | 6 +++--- eframe/src/native/epi_integration.rs | 2 +- eframe/src/native/run.rs | 2 +- eframe/src/web/glow_wrapping.rs | 4 ++-- egui_glow/examples/pure_glow.rs | 2 +- egui_glow/src/painter.rs | 8 ++++---- egui_glow/src/post_process.rs | 4 ++-- egui_glow/src/winit.rs | 2 +- examples/custom_3d_three-d/Cargo.toml | 2 +- examples/custom_3d_three-d/src/main.rs | 23 ++++++++--------------- 11 files changed, 27 insertions(+), 31 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fc26b0625b7..29784afaa34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,3 +37,6 @@ opt-level = 2 # fast and small wasm, basically same as `opt-level = 's'` # opt-level = 3 # unecessarily large wasm for no performance gain # debug = true # include debug symbols, useful when profiling wasm + +[patch.crates-io] +three-d = { git = "https://github.com/asny/three-d.git", rev = "7ac4f3e1e14335290e505a5799a0b88717474678" } diff --git a/eframe/src/epi.rs b/eframe/src/epi.rs index 765286227fa..7d735c06ab8 100644 --- a/eframe/src/epi.rs +++ b/eframe/src/epi.rs @@ -28,7 +28,7 @@ pub struct CreationContext<'s> { /// The [`glow::Context`] allows you to initialize OpenGL resources (e.g. shaders) that /// you might want to use later from a [`egui::PaintCallback`]. #[cfg(feature = "glow")] - pub gl: Option>, + pub gl: Option>, } // ---------------------------------------------------------------------------- @@ -334,7 +334,7 @@ pub struct Frame { /// A reference to the underlying [`glow`] (OpenGL) context. #[cfg(feature = "glow")] #[doc(hidden)] - pub gl: Option>, + pub gl: Option>, } impl Frame { @@ -371,7 +371,7 @@ impl Frame { /// To get a [`glow`] context you need to compile with the `glow` feature flag, /// and run eframe with the glow backend. #[cfg(feature = "glow")] - pub fn gl(&self) -> Option<&std::rc::Rc> { + pub fn gl(&self) -> Option<&std::sync::Arc> { self.gl.as_ref() } diff --git a/eframe/src/native/epi_integration.rs b/eframe/src/native/epi_integration.rs index dd7b729eb4c..cde1d187b1d 100644 --- a/eframe/src/native/epi_integration.rs +++ b/eframe/src/native/epi_integration.rs @@ -185,7 +185,7 @@ impl EpiIntegration { max_texture_side: usize, window: &winit::window::Window, storage: Option>, - #[cfg(feature = "glow")] gl: Option>, + #[cfg(feature = "glow")] gl: Option>, ) -> Self { let egui_ctx = egui::Context::default(); diff --git a/eframe/src/native/run.rs b/eframe/src/native/run.rs index 3c73b6f7e6b..7b0fde59150 100644 --- a/eframe/src/native/run.rs +++ b/eframe/src/native/run.rs @@ -51,7 +51,7 @@ pub fn run_glow( let window_builder = epi_integration::window_builder(native_options, &window_settings).with_title(app_name); let (gl_window, gl) = create_display(native_options, window_builder, &event_loop); - let gl = std::rc::Rc::new(gl); + let gl = std::sync::Arc::new(gl); let mut painter = egui_glow::Painter::new(gl.clone(), None, "") .unwrap_or_else(|error| panic!("some OpenGL error occurred {}\n", error)); diff --git a/eframe/src/web/glow_wrapping.rs b/eframe/src/web/glow_wrapping.rs index a2333423728..f4a96d21cb0 100644 --- a/eframe/src/web/glow_wrapping.rs +++ b/eframe/src/web/glow_wrapping.rs @@ -17,7 +17,7 @@ impl WrappedGlowPainter { let canvas = super::canvas_element_or_die(canvas_id); let (gl, shader_prefix) = init_glow_context_from_canvas(&canvas)?; - let gl = std::rc::Rc::new(gl); + let gl = std::sync::Arc::new(gl); let dimension = [canvas.width() as i32, canvas.height() as i32]; let painter = egui_glow::Painter::new(gl, Some(dimension), shader_prefix) @@ -32,7 +32,7 @@ impl WrappedGlowPainter { } impl WrappedGlowPainter { - pub fn gl(&self) -> &std::rc::Rc { + pub fn gl(&self) -> &std::sync::Arc { self.painter.gl() } diff --git a/egui_glow/examples/pure_glow.rs b/egui_glow/examples/pure_glow.rs index 64f678ce39c..65a1bdaaf5f 100644 --- a/egui_glow/examples/pure_glow.rs +++ b/egui_glow/examples/pure_glow.rs @@ -8,7 +8,7 @@ fn main() { let event_loop = glutin::event_loop::EventLoop::with_user_event(); let (gl_window, gl) = create_display(&event_loop); - let gl = std::rc::Rc::new(gl); + let gl = std::sync::Arc::new(gl); let mut egui_glow = egui_glow::EguiGlow::new(gl_window.window(), gl.clone()); diff --git a/egui_glow/src/painter.rs b/egui_glow/src/painter.rs index 0c75317cfb2..092ac0fdcb0 100644 --- a/egui_glow/src/painter.rs +++ b/egui_glow/src/painter.rs @@ -1,6 +1,6 @@ #![allow(unsafe_code)] -use std::{collections::HashMap, rc::Rc}; +use std::{collections::HashMap, sync::Arc}; use egui::{ emath::Rect, @@ -42,7 +42,7 @@ impl TextureFilterExt for TextureFilter { /// This struct must be destroyed with [`Painter::destroy`] before dropping, to ensure OpenGL /// objects have been properly deleted and are not leaked. pub struct Painter { - gl: Rc, + gl: Arc, max_texture_side: usize, @@ -82,7 +82,7 @@ impl Painter { /// * failed to create postprocess on webgl with `sRGB` support /// * failed to create buffer pub fn new( - gl: Rc, + gl: Arc, pp_fb_extent: Option<[i32; 2]>, shader_prefix: &str, ) -> Result { @@ -219,7 +219,7 @@ impl Painter { } /// Access the shared glow context. - pub fn gl(&self) -> &std::rc::Rc { + pub fn gl(&self) -> &Arc { &self.gl } diff --git a/egui_glow/src/post_process.rs b/egui_glow/src/post_process.rs index d17a61f1998..5f525459b97 100644 --- a/egui_glow/src/post_process.rs +++ b/egui_glow/src/post_process.rs @@ -7,7 +7,7 @@ use glow::HasContext as _; /// Uses a framebuffer to render everything in linear color space and convert it back to `sRGB` /// in a separate "post processing" step pub(crate) struct PostProcess { - gl: std::rc::Rc, + gl: std::sync::Arc, pos_buffer: glow::Buffer, index_buffer: glow::Buffer, vao: crate::vao::VertexArrayObject, @@ -21,7 +21,7 @@ pub(crate) struct PostProcess { impl PostProcess { pub(crate) unsafe fn new( - gl: std::rc::Rc, + gl: std::sync::Arc, shader_prefix: &str, is_webgl_1: bool, [width, height]: [i32; 2], diff --git a/egui_glow/src/winit.rs b/egui_glow/src/winit.rs index 65520d30eff..cf475cf95d4 100644 --- a/egui_glow/src/winit.rs +++ b/egui_glow/src/winit.rs @@ -12,7 +12,7 @@ pub struct EguiGlow { } impl EguiGlow { - pub fn new(window: &winit::window::Window, gl: std::rc::Rc) -> Self { + pub fn new(window: &winit::window::Window, gl: std::sync::Arc) -> Self { let painter = crate::Painter::new(gl, None, "") .map_err(|error| { tracing::error!("error occurred in initializing painter:\n{}", error); diff --git a/examples/custom_3d_three-d/Cargo.toml b/examples/custom_3d_three-d/Cargo.toml index 0fa96aaef6a..906adbc0c43 100644 --- a/examples/custom_3d_three-d/Cargo.toml +++ b/examples/custom_3d_three-d/Cargo.toml @@ -12,4 +12,4 @@ publish = false eframe = { path = "../../eframe", features = ["glow"] } egui_glow = { path = "../../egui_glow" } glow = "0.11" -three-d = { version = "0.11", default-features = false } +three-d = { version = "0.12", default-features = false } diff --git a/examples/custom_3d_three-d/src/main.rs b/examples/custom_3d_three-d/src/main.rs index cf2f9723628..1d88e86b500 100644 --- a/examples/custom_3d_three-d/src/main.rs +++ b/examples/custom_3d_three-d/src/main.rs @@ -80,7 +80,7 @@ impl MyApp { /// to the [`egui::PaintCallback`] because [`three_d::Context`] isn't `Send+Sync`, which /// [`egui::PaintCallback`] is. fn with_three_d_context( - gl: &std::rc::Rc, + gl: &std::sync::Arc, f: impl FnOnce(&three_d::Context) -> R, ) -> R { use std::cell::RefCell; @@ -111,15 +111,12 @@ fn paint_with_three_d(three_d: &three_d::Context, info: &egui::PaintCallbackInfo // Respect the egui clip region (e.g. if we are inside an `egui::ScrollArea`). let clip_rect = info.clip_rect_in_pixels(); - let render_states = RenderStates { - clip: Clip::Enabled { - x: clip_rect.left_px.round() as _, - y: clip_rect.from_bottom_px.round() as _, - width: clip_rect.width_px.round() as _, - height: clip_rect.height_px.round() as _, - }, - ..Default::default() - }; + three_d.set_scissor(ScissorBox { + x: clip_rect.left_px.round() as _, + y: clip_rect.from_bottom_px.round() as _, + width: clip_rect.width_px.round() as _, + height: clip_rect.height_px.round() as _, + }); let camera = Camera::new_perspective( three_d, @@ -150,11 +147,7 @@ fn paint_with_three_d(three_d: &three_d::Context, info: &egui::PaintCallbackInfo ..Default::default() }; - let material = ColorMaterial { - render_states, - ..Default::default() - }; - let mut model = Model::new_with_material(three_d, &cpu_mesh, material).unwrap(); + let mut model = Model::new(three_d, &cpu_mesh).unwrap(); // Set the current transformation of the triangle model.set_transformation(Mat4::from_angle_y(radians(angle)));