From e76c919c7e70c208c9a6209b9fe3369e7b6db99d Mon Sep 17 00:00:00 2001 From: Aiden Date: Fri, 8 Jul 2022 16:40:44 +0800 Subject: [PATCH] Added WebGlContextOption for eframe::WebOptions (#1803) * Added WebGlContextOption for eframe::WebOptions * Fix doclink * Fix minor doc issue Co-authored-by: xxvvii Co-authored-by: Emil Ernerfeldt --- eframe/src/epi.rs | 22 ++++++++++++++++++++++ eframe/src/web/backend.rs | 3 ++- eframe/src/web/glow_wrapping.rs | 22 +++++++++++++--------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/eframe/src/epi.rs b/eframe/src/epi.rs index 2e36c7057ca..2bbe82f8d15 100644 --- a/eframe/src/epi.rs +++ b/eframe/src/epi.rs @@ -330,6 +330,11 @@ pub struct WebOptions { /// /// Default: `Theme::Dark`. pub default_theme: Theme, + + /// Which version of WebGl context to select + /// + /// Default: [`WebGlContextOption::BestFirst`]. + pub webgl_context_option: WebGlContextOption, } #[cfg(target_arch = "wasm32")] @@ -338,6 +343,7 @@ impl Default for WebOptions { Self { follow_system_theme: true, default_theme: Theme::Dark, + webgl_context_option: WebGlContextOption::BestFirst, } } } @@ -368,6 +374,22 @@ impl Theme { // ---------------------------------------------------------------------------- +/// WebGl Context options +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +pub enum WebGlContextOption { + /// Force Use WebGL1. + WebGl1, + /// Force use WebGL2. + WebGl2, + /// Use WebGl2 first. + BestFirst, + /// Use WebGl1 first + CompatibilityFirst, +} + +// ---------------------------------------------------------------------------- + /// What rendering backend to use. /// /// You need to enable the "glow" and "wgpu" features to have a choice. diff --git a/eframe/src/web/backend.rs b/eframe/src/web/backend.rs index 465c16e1100..4416eeaa7b5 100644 --- a/eframe/src/web/backend.rs +++ b/eframe/src/web/backend.rs @@ -160,7 +160,8 @@ impl AppRunner { web_options: crate::WebOptions, app_creator: epi::AppCreator, ) -> Result { - let painter = WrappedGlowPainter::new(canvas_id).map_err(JsValue::from)?; // fail early + let painter = WrappedGlowPainter::new(canvas_id, web_options.webgl_context_option) + .map_err(JsValue::from)?; // fail early let system_theme = if web_options.follow_system_theme { super::system_theme() diff --git a/eframe/src/web/glow_wrapping.rs b/eframe/src/web/glow_wrapping.rs index f4a96d21cb0..ead1d599120 100644 --- a/eframe/src/web/glow_wrapping.rs +++ b/eframe/src/web/glow_wrapping.rs @@ -1,3 +1,4 @@ +use crate::WebGlContextOption; use egui::{ClippedPrimitive, Rgba}; use egui_glow::glow; use wasm_bindgen::JsCast; @@ -13,10 +14,10 @@ pub(crate) struct WrappedGlowPainter { } impl WrappedGlowPainter { - pub fn new(canvas_id: &str) -> Result { + pub fn new(canvas_id: &str, options: WebGlContextOption) -> Result { let canvas = super::canvas_element_or_die(canvas_id); - let (gl, shader_prefix) = init_glow_context_from_canvas(&canvas)?; + let (gl, shader_prefix) = init_glow_context_from_canvas(&canvas, options)?; let gl = std::sync::Arc::new(gl); let dimension = [canvas.width() as i32, canvas.height() as i32]; @@ -91,16 +92,19 @@ impl WrappedGlowPainter { /// Returns glow context and shader prefix. fn init_glow_context_from_canvas( canvas: &HtmlCanvasElement, + options: WebGlContextOption, ) -> Result<(glow::Context, &'static str), String> { - const BEST_FIRST: bool = true; - - let result = if BEST_FIRST { + let result = match options { + // Force use WebGl1 + WebGlContextOption::WebGl1 => init_webgl1(canvas), + // Force use WebGl2 + WebGlContextOption::WebGl2 => init_webgl2(canvas), // Trying WebGl2 first - init_webgl2(canvas).or_else(|| init_webgl1(canvas)) - } else { + WebGlContextOption::BestFirst => init_webgl2(canvas).or_else(|| init_webgl1(canvas)), // Trying WebGl1 first (useful for testing). - tracing::warn!("Looking for WebGL1 first"); - init_webgl1(canvas).or_else(|| init_webgl2(canvas)) + WebGlContextOption::CompatibilityFirst => { + init_webgl1(canvas).or_else(|| init_webgl2(canvas)) + } }; if let Some(result) = result {