From 3cc44dc6703b9fc01e7bac3cc311c80385f1c16f Mon Sep 17 00:00:00 2001 From: Ian Hattendorf Date: Wed, 16 Oct 2024 18:30:29 -0700 Subject: [PATCH] Add version to OpenGLAPI --- internal/backends/selector/lib.rs | 7 +- .../winit/renderer/femtovg/glcontext.rs | 32 +++++--- internal/core/api.rs | 13 +++- internal/renderers/skia/opengl_surface.rs | 73 +++++++++++-------- 4 files changed, 77 insertions(+), 48 deletions(-) diff --git a/internal/backends/selector/lib.rs b/internal/backends/selector/lib.rs index 3b1528eed..81cf702a8 100644 --- a/internal/backends/selector/lib.rs +++ b/internal/backends/selector/lib.rs @@ -84,17 +84,16 @@ impl PlatformBuilder { /// use i_slint_backend_selector::PlatformBuilder; /// /// let platform = PlatformBuilder::new() - /// .with_opengl_api(OpenGLAPI::GL) + /// .with_opengl_api(OpenGLAPI::GL(None)) /// .build() /// .unwrap(); - /// slint::platform::set_platform(platform).unwrap(); + /// platform::set_platform(platform).unwrap(); /// ``` pub fn build(self) -> Result, PlatformError> { let builder = i_slint_backend_winit::Backend::builder().with_allow_fallback(false); let builder = match self.opengl_api { - Some(OpenGLAPI::GL) => builder.with_opengl_api(OpenGLAPI::GL), - Some(OpenGLAPI::GLES) => builder.with_opengl_api(OpenGLAPI::GLES), + Some(api) => builder.with_opengl_api(api), None => builder, }; diff --git a/internal/backends/winit/renderer/femtovg/glcontext.rs b/internal/backends/winit/renderer/femtovg/glcontext.rs index bf7c8aacf..036000ce3 100644 --- a/internal/backends/winit/renderer/femtovg/glcontext.rs +++ b/internal/backends/winit/renderer/femtovg/glcontext.rs @@ -10,7 +10,7 @@ use glutin::{ prelude::*, surface::{SurfaceAttributesBuilder, WindowSurface}, }; -use i_slint_core::{platform::PlatformError, OpenGLAPI}; +use i_slint_core::{api::APIVersion, platform::PlatformError, OpenGLAPI}; use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; pub struct OpenGLContext { @@ -122,16 +122,28 @@ impl OpenGLContext { })? .map(|h| h.as_raw()); + let opengl_api = + opengl_api.unwrap_or(OpenGLAPI::GLES(Some(APIVersion { major: 2, minor: 0 }))); let preferred_context_attributes = match opengl_api { - Some(OpenGLAPI::GL) => ContextAttributesBuilder::new() - .with_context_api(ContextApi::OpenGl(None)) - .build(raw_window_handle), - Some(OpenGLAPI::GLES) | None => ContextAttributesBuilder::new() - .with_context_api(ContextApi::Gles(Some(glutin::context::Version { - major: 3, - minor: 2, - }))) - .build(raw_window_handle), + OpenGLAPI::GL(version) => { + let version = version.map(|version| glutin::context::Version { + major: version.major, + minor: version.minor, + }); + ContextAttributesBuilder::new() + .with_context_api(ContextApi::OpenGl(version)) + .build(raw_window_handle) + } + OpenGLAPI::GLES(version) => { + let version = version.map(|version| glutin::context::Version { + major: version.major, + minor: version.minor, + }); + + ContextAttributesBuilder::new() + .with_context_api(ContextApi::Gles(version)) + .build(raw_window_handle) + } }; let fallback_context_attributes = ContextAttributesBuilder::new().build(raw_window_handle); diff --git a/internal/core/api.rs b/internal/core/api.rs index 425052ae8..dabd11572 100644 --- a/internal/core/api.rs +++ b/internal/core/api.rs @@ -283,13 +283,22 @@ impl<'a> core::fmt::Debug for GraphicsAPI<'a> { } } +/// API Version +#[derive(Debug, Clone, PartialEq)] +pub struct APIVersion { + /// Major API version + pub major: u8, + /// Minor API version + pub minor: u8, +} + /// This enum specifies which OpenGL API should be used. #[derive(Debug, Clone, PartialEq)] pub enum OpenGLAPI { /// OpenGL - GL, + GL(Option), /// OpenGL ES - GLES, + GLES(Option), } /// This enum specifies which OpenGL API should be used. diff --git a/internal/renderers/skia/opengl_surface.rs b/internal/renderers/skia/opengl_surface.rs index 67c7475a8..feaaeca13 100644 --- a/internal/renderers/skia/opengl_surface.rs +++ b/internal/renderers/skia/opengl_surface.rs @@ -12,8 +12,11 @@ use glutin::{ prelude::*, surface::{SurfaceAttributesBuilder, WindowSurface}, }; -use i_slint_core::{api::GraphicsAPI, platform::PlatformError}; use i_slint_core::{api::PhysicalSize as PhysicalWindowSize, OpenGLAPI}; +use i_slint_core::{ + api::{APIVersion, GraphicsAPI}, + platform::PlatformError, +}; /// This surface type renders into the given window with OpenGL, using glutin and glow libraries. pub struct OpenGLSurface { @@ -283,12 +286,6 @@ impl OpenGLSurface { let config_template_builder = config_template_builder.compatible_with_native_window(_window_handle.as_raw()); - let config_template_builder = if let Some(OpenGLAPI::GL) = opengl_api { - config_template_builder.with_api(glutin::config::Api::OPENGL) - } else { - config_template_builder - }; - let config_template = config_template_builder.build(); let config = unsafe { @@ -309,35 +306,47 @@ impl OpenGLSurface { .ok_or("Unable to find suitable GL config")? }; - let create_gl_context = |gl_major| { - let preferred_context_attributes = match opengl_api { - Some(OpenGLAPI::GL) => { - ContextAttributesBuilder::new().build(Some(_window_handle.as_raw())) - } - Some(OpenGLAPI::GLES) | None => ContextAttributesBuilder::new() - .with_context_api(ContextApi::Gles(Some(glutin::context::Version { - major: gl_major, - minor: 0, - }))) - .build(Some(_window_handle.as_raw())), - }; + let opengl_api = + opengl_api.unwrap_or(OpenGLAPI::GLES(Some(APIVersion { major: 3, minor: 0 }))); + let preferred_context_attributes = match opengl_api { + OpenGLAPI::GL(version) => { + let version = version.map(|version| glutin::context::Version { + major: version.major, + minor: version.minor, + }); + ContextAttributesBuilder::new() + .with_context_api(ContextApi::OpenGl(version)) + .build(Some(_window_handle.as_raw())) + } + OpenGLAPI::GLES(version) => { + let version = version.map(|version| glutin::context::Version { + major: version.major, + minor: version.minor, + }); - let fallback_context_attributes = - ContextAttributesBuilder::new().build(Some(_window_handle.as_raw())); - - unsafe { - gl_display - .create_context(&config, &preferred_context_attributes) - .or_else(|_| gl_display.create_context(&config, &fallback_context_attributes)) - .map_err(|e| format!("Error creating OpenGL context: {e}")) + ContextAttributesBuilder::new() + .with_context_api(ContextApi::Gles(version)) + .build(Some(_window_handle.as_raw())) } }; - let not_current_gl_context = if let Some(OpenGLAPI::GL) = opengl_api { - create_gl_context(4)? - } else { - create_gl_context(3).or_else(|_| create_gl_context(2))? - }; + let gles2_fallback_context_attributes = ContextAttributesBuilder::new() + .with_context_api(ContextApi::Gles(Some(glutin::context::Version { + major: 2, + minor: 0, + }))) + .build(Some(_window_handle.as_raw())); + + let fallback_context_attributes = + ContextAttributesBuilder::new().build(Some(_window_handle.as_raw())); + + let not_current_gl_context = unsafe { + gl_display + .create_context(&config, &preferred_context_attributes) + .or_else(|_| gl_display.create_context(&config, &gles2_fallback_context_attributes)) + .or_else(|_| gl_display.create_context(&config, &fallback_context_attributes)) + .map_err(|e| format!("Error creating OpenGL context: {e}")) + }?; let attrs = SurfaceAttributesBuilder::::new().build( _window_handle.as_raw(),