Skip to content

Commit

Permalink
Switch to using glow as the default renderer both on native and the w…
Browse files Browse the repository at this point in the history
…eb (#1020)

* Switch to using glow as the default renderer both on native and the web
* Simplify code to find WebGL context for glow
* egui_web: make webgl an opt-in feature
* Stop using deprecated WEBGL_debug_renderer_info
  • Loading branch information
emilk committed Dec 31, 2021
1 parent 8da592c commit b1fd6a4
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 65 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ If you have questions, use [GitHub Discussions](https://github.com/emilk/egui/di

To test the demo app locally, run `cargo run --release -p egui_demo_app`.

The native backend is [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium) (using [`glium`](https://github.com/glium/glium)) and should work out-of-the-box on Mac and Windows, but on Linux you need to first run:
The native backend is [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow) (using [`glow`](https://crates.io/crates/glow)) and should work out-of-the-box on Mac and Windows, but on Linux you need to first run:

`sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libspeechd-dev libxkbcommon-dev libssl-dev`

Expand Down Expand Up @@ -322,7 +322,7 @@ On Linux and Mac, Firefox will copy the WebGL render target from GPU, to CPU and
To alleviate the above mentioned performance issues the default max-width of an egui web app is 1024 points. You can change this by overriding the `fn max_size_points` of [`epi::App`](https://docs.rs/epi/latest/epi/trait.App.html).

### How do I render 3D stuff in an egui area?
egui can't do 3D graphics itself, but if you use a 3D library (e.g. [`glium`](https://github.com/glium/glium) using [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium), or [`miniquad`](https://github.com/not-fl3/miniquad) using [`egui-miniquad`](https://github.com/not-fl3/egui-miniquad)) you can render your 3D content to a texture, then display it using [`ui.image(…)`](https://docs.rs/egui/latest/egui/struct.Ui.html#method.image). You first need to convert the native texture to an [`egui::TextureId`](https://docs.rs/egui/latest/egui/enum.TextureId.html), and how to do this depends on the integration you use (e.g. [`register_glium_texture`](https://docs.rs/egui_glium/latest/egui_glium/struct.Painter.html#method.register_glium_texture)).
egui can't do 3D graphics itself, but if you use a 3D library (e.g. [`glium`](https://github.com/glium/glium) using [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium), or [`miniquad`](https://github.com/not-fl3/miniquad) using [`egui-miniquad`](https://github.com/not-fl3/egui-miniquad)) you can render your 3D content to a texture, then display it using [`ui.image(…)`](https://docs.rs/egui/latest/egui/struct.Ui.html#method.image). You first need to convert the native texture to an [`egui::TextureId`](https://docs.rs/egui/latest/egui/enum.TextureId.html), and how to do this depends on the integration you use (e.g. [`register_glium_texture`](https://docs.rs/epi/latest/epi/trait.NativeTexture.html#tymethod.register_native_texture)).

There is an example for showing a native glium texture in an egui window at <https://github.com/emilk/egui/blob/master/egui_glium/examples/native_texture.rs>.

Expand Down
2 changes: 2 additions & 0 deletions eframe/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ NOTE: [`egui_web`](egui_web/CHANGELOG.md), [`egui-winit`](egui-winit/CHANGELOG.m


## Unreleased
* The default native backend is now `egui_glow` (instead of `egui_glium`) ([#1020](https://github.com/emilk/egui/pull/1020)).
* The default web painter is now `egui_glow` (instead of WebGL) ([#1020](https://github.com/emilk/egui/pull/1020)).


## 0.16.0 - 2021-12-29
Expand Down
4 changes: 2 additions & 2 deletions eframe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ egui_glow = { version = "0.16.0", path = "../egui_glow", default-features = fals

# web:
[target.'cfg(target_arch = "wasm32")'.dependencies]
egui_web = { version = "0.16.0", path = "../egui_web", default-features = false }
egui_web = { version = "0.16.0", path = "../egui_web", default-features = false, features = ["glow"] }

[dev-dependencies]
image = { version = "0.23", default-features = false, features = ["png"] }
rfd = "0.6"

[features]
default = ["default_fonts", "egui_glium"]
default = ["default_fonts", "egui_glow"]

# If set, egui will use `include_bytes!` to bundle some fonts.
# If you plan on specifying your own fonts you may disable this feature.
Expand Down
4 changes: 2 additions & 2 deletions eframe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev lib


## Alternatives
The default native backend for `eframe` is currently [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium), but you can try out the new [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow) backend by putting this in your `Cargo.toml`:
The default native backend for `eframe` is currently [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow), but you can switch to the previous [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium) backend by putting this in your `Cargo.toml`:

``` toml
eframe = { version = "*", default-features = false, features = ["default_fonts", "egui_glow"] }
eframe = { version = "*", default-features = false, features = ["default_fonts", "egui_glium"] }
```

`eframe` is not the only way to write an app using `egui`! You can also try [`egui-miniquad`](https://github.com/not-fl3/egui-miniquad) and [`egui_sdl2_gl`](https://github.com/ArjunNair/egui_sdl2_gl).
Expand Down
21 changes: 19 additions & 2 deletions eframe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub fn start_web(canvas_id: &str, app: Box<dyn epi::App>) -> Result<(), wasm_bin
// ----------------------------------------------------------------------------
// When compiling natively

/// Call from `fn main` like this: `
/// Call from `fn main` like this:
/// ``` no_run
/// use eframe::{epi, egui};
///
Expand Down Expand Up @@ -148,8 +148,25 @@ pub fn run_native(app: Box<dyn epi::App>, native_options: epi::NativeOptions) ->
egui_glium::run(app, &native_options)
}

/// Call from `fn main` like this: `
/// Call from `fn main` like this:
/// ``` no_run
/// use eframe::{epi, egui};
///
/// #[derive(Default)]
/// struct MyEguiApp {}
///
/// impl epi::App for MyEguiApp {
/// fn name(&self) -> &str {
/// "My egui App"
/// }
///
/// fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) {
/// egui::CentralPanel::default().show(ctx, |ui| {
/// ui.heading("Hello World!");
/// });
/// }
///}
///
/// fn main() {
/// let app = MyEguiApp::default();
/// let native_options = eframe::NativeOptions::default();
Expand Down
2 changes: 1 addition & 1 deletion egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl CtxRef {
/// This will modify the internal reference to point to a new generation of [`Context`].
/// Any old clones of this [`CtxRef`] will refer to the old [`Context`], which will not get new input.
///
/// You can alternatively run [`Self::begin_single_pass_frame`] and [`Self::end_single_pass_frame`].
/// You can alternatively run [`Self::begin_frame`] and [`Self::end_frame`].
///
/// ``` rust
/// // One egui context that you keep reusing:
Expand Down
4 changes: 3 additions & 1 deletion egui_demo_app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ crate-type = ["cdylib", "rlib"]

[dependencies]
eframe = { version = "0.16.0", path = "../eframe" }
# eframe = { version = "0.16.0", path = "../eframe", default-features = false, features = ["default_fonts", "egui_glow"] }

# To use the old glium backend instead:
# eframe = { version = "0.16.0", path = "../eframe", default-features = false, features = ["default_fonts", "egui_glium"] }

egui_demo_lib = { version = "0.16.0", path = "../egui_demo_lib", features = ["extra_debug_asserts"] }

Expand Down
2 changes: 2 additions & 0 deletions egui_web/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ All notable changes to the `egui_web` integration will be noted in this file.


## Unreleased
* The default painter is now glow instead of WebGL ([#1020](https://github.com/emilk/egui/pull/1020)).
* Made the WebGL painter opt-in ([#1020](https://github.com/emilk/egui/pull/1020)).


## 0.16.0 - 2021-12-29
Expand Down
9 changes: 7 additions & 2 deletions egui_web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,18 @@ wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"

[features]
default = ["default_fonts"]
default = ["default_fonts", "glow"]

# If set, egui will use `include_bytes!` to bundle some fonts.
# If you plan on specifying your own fonts you may disable this feature.
default_fonts = ["egui/default_fonts"]
# Use glow as the renderer

# Use glow as the renderer.
glow = ["egui_glow", "egui_glow/epi"]

# Alternative to the glow renderer.
webgl = []

persistence = ["egui/persistence", "ron", "serde"]
screen_reader = ["tts"] # experimental

Expand Down
9 changes: 7 additions & 2 deletions egui_web/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ pub use egui::{pos2, Color32};
// ----------------------------------------------------------------------------

fn create_painter(canvas_id: &str) -> Result<Box<dyn Painter>, JsValue> {
#[cfg(feature = "glow")]
// Glow takes precedence:
#[cfg(all(feature = "glow"))]
return Ok(Box::new(crate::glow_wrapping::WrappedGlowPainter::new(
canvas_id,
)));
#[cfg(not(feature = "glow"))]

#[cfg(all(feature = "webgl", not(feature = "glow")))]
if let Ok(webgl2_painter) = webgl2::WebGl2Painter::new(canvas_id) {
console_log("Using WebGL2 backend");
Ok(Box::new(webgl2_painter))
Expand All @@ -18,6 +20,9 @@ fn create_painter(canvas_id: &str) -> Result<Box<dyn Painter>, JsValue> {
let webgl1_painter = webgl1::WebGlPainter::new(canvas_id)?;
Ok(Box::new(webgl1_painter))
}

#[cfg(all(not(feature = "webgl"), not(feature = "glow")))]
compile_error!("Either the 'glow' or 'webgl' feature of egui_web must be enabled!");
}

// ----------------------------------------------------------------------------
Expand Down
46 changes: 21 additions & 25 deletions egui_web/src/glow_wrapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn requires_brightening(canvas: &web_sys::HtmlCanvasElement) -> bool {
.dyn_into::<WebGlRenderingContext>()
.unwrap();
let user_agent = web_sys::window().unwrap().navigator().user_agent().unwrap();
crate::webgl1::is_safari_and_webkit_gtk(&gl) && !user_agent.contains("Mac OS X")
crate::is_safari_and_webkit_gtk(&gl) && !user_agent.contains("Mac OS X")
}

impl crate::Painter for WrappedGlowPainter {
Expand Down Expand Up @@ -116,32 +116,28 @@ impl crate::Painter for WrappedGlowPainter {
}

pub fn init_glow_context_from_canvas(canvas: &HtmlCanvasElement) -> glow::Context {
let ctx = canvas.get_context("webgl2");
if let Ok(ctx) = ctx {
crate::console_log("webgl found");
if let Some(ctx) = ctx {
crate::console_log("webgl 2 selected");
let gl_ctx = ctx.dyn_into::<web_sys::WebGl2RenderingContext>().unwrap();
glow::Context::from_webgl2_context(gl_ctx)
let gl2_ctx = canvas
.get_context("webgl2")
.expect("Failed to query about WebGL2 context");

if let Some(gl2_ctx) = gl2_ctx {
crate::console_log("WebGL2 found");
let gl2_ctx = gl2_ctx
.dyn_into::<web_sys::WebGl2RenderingContext>()
.unwrap();
glow::Context::from_webgl2_context(gl2_ctx)
} else {
let gl1 = canvas
.get_context("webgl")
.expect("Failed to query about WebGL1 context");

if let Some(gl1) = gl1 {
crate::console_log("WebGL2 not available - falling back to WebGL2");
let gl1_ctx = gl1.dyn_into::<web_sys::WebGlRenderingContext>().unwrap();
glow::Context::from_webgl1_context(gl1_ctx)
} else {
let ctx = canvas.get_context("webgl");
if let Ok(ctx) = ctx {
crate::console_log("falling back to webgl1");
if let Some(ctx) = ctx {
crate::console_log("webgl1 selected");

let gl_ctx = ctx.dyn_into::<web_sys::WebGlRenderingContext>().unwrap();
crate::console_log("success");
glow::Context::from_webgl1_context(gl_ctx)
} else {
panic!("tried webgl1 but can't get context");
}
} else {
panic!("tried webgl1 but can't get context");
}
panic!("Failed to get WebGL context.");
}
} else {
panic!("tried webgl2 but something went wrong");
}
}

Expand Down
23 changes: 23 additions & 0 deletions egui_web/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ pub mod backend;
mod glow_wrapping;
mod painter;
pub mod screen_reader;

#[cfg(feature = "webgl")]
pub mod webgl1;
#[cfg(feature = "webgl")]
pub mod webgl2;

pub use backend::*;
Expand Down Expand Up @@ -1234,3 +1237,23 @@ fn move_text_cursor(cursor: &Option<egui::Pos2>, canvas_id: &str) -> Option<()>
style.set_property("left", "0px").ok()
}
}

/// detecting Safari and webkitGTK.
///
/// Safari and webkitGTK use unmasked renderer :Apple GPU
///
/// If we detect safari or webkitGTK returns true.
///
/// This function used to avoid displaying linear color with `sRGB` supported systems.
pub(crate) fn is_safari_and_webkit_gtk(gl: &web_sys::WebGlRenderingContext) -> bool {
if let Ok(renderer) = gl.get_parameter(web_sys::WebglDebugRendererInfo::UNMASKED_RENDERER_WEBGL)
{
if let Some(renderer) = renderer.as_string() {
if renderer.contains("Apple") {
return true;
}
}
}

false
}
27 changes: 2 additions & 25 deletions egui_web/src/webgl1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use {
wasm_bindgen::{prelude::*, JsCast},
web_sys::{
ExtSRgb, WebGlBuffer, WebGlFramebuffer, WebGlProgram, WebGlRenderingContext, WebGlShader,
WebGlTexture, WebglDebugRendererInfo,
WebGlTexture,
},
};

Expand Down Expand Up @@ -479,7 +479,7 @@ fn requires_brightening(gl: &web_sys::WebGlRenderingContext) -> bool {
// See https://github.com/emilk/egui/issues/794

let user_agent = web_sys::window().unwrap().navigator().user_agent().unwrap();
crate::webgl1::is_safari_and_webkit_gtk(gl) && !user_agent.contains("Mac OS X")
crate::is_safari_and_webkit_gtk(gl) && !user_agent.contains("Mac OS X")
}

impl PostProcess {
Expand Down Expand Up @@ -688,26 +688,3 @@ fn link_program<'a, T: IntoIterator<Item = &'a WebGlShader>>(
.unwrap_or_else(|| "Unknown error creating program object".into()))
}
}

/// detecting Safari and webkitGTK.
///
/// Safari and webkitGTK use unmasked renderer :Apple GPU
///
/// If we detect safari or webkitGTK returns true.
///
/// This function used to avoid displaying linear color with `sRGB` supported systems.
pub(crate) fn is_safari_and_webkit_gtk(gl: &web_sys::WebGlRenderingContext) -> bool {
if gl
.get_extension("WEBGL_debug_renderer_info")
.unwrap()
.is_some()
{
let renderer: JsValue = gl
.get_parameter(WebglDebugRendererInfo::UNMASKED_RENDERER_WEBGL)
.unwrap();
if renderer.as_string().unwrap().contains("Apple") {
return true;
}
}
false
}
2 changes: 1 addition & 1 deletion sh/check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ cargo doc -p egui_web --target wasm32-unknown-unknown --lib --no-deps --all-feat
(cd egui && cargo check --no-default-features --features "multi_threaded,serialize")
(cd eframe && cargo check --no-default-features --features "egui_glow")
(cd epi && cargo check --no-default-features)
(cd egui_web && cargo check --no-default-features)
# (cd egui_web && cargo check --no-default-features) # we need to pick webgl or glow backend
# (cd egui-winit && cargo check --no-default-features) # we don't pick singlethreaded or multithreaded
(cd egui_glium && cargo check --no-default-features)
(cd egui_glow && cargo check --no-default-features)
Expand Down

0 comments on commit b1fd6a4

Please sign in to comment.