Add version to OpenGLAPI

This commit is contained in:
Ian Hattendorf 2024-10-16 18:30:29 -07:00 committed by Simon Hausmann
parent 97927ccee9
commit 3cc44dc670
4 changed files with 77 additions and 48 deletions

View file

@ -84,17 +84,16 @@ impl PlatformBuilder {
/// use i_slint_backend_selector::PlatformBuilder; /// use i_slint_backend_selector::PlatformBuilder;
/// ///
/// let platform = PlatformBuilder::new() /// let platform = PlatformBuilder::new()
/// .with_opengl_api(OpenGLAPI::GL) /// .with_opengl_api(OpenGLAPI::GL(None))
/// .build() /// .build()
/// .unwrap(); /// .unwrap();
/// slint::platform::set_platform(platform).unwrap(); /// platform::set_platform(platform).unwrap();
/// ``` /// ```
pub fn build(self) -> Result<Box<dyn Platform + 'static>, PlatformError> { pub fn build(self) -> Result<Box<dyn Platform + 'static>, PlatformError> {
let builder = i_slint_backend_winit::Backend::builder().with_allow_fallback(false); let builder = i_slint_backend_winit::Backend::builder().with_allow_fallback(false);
let builder = match self.opengl_api { let builder = match self.opengl_api {
Some(OpenGLAPI::GL) => builder.with_opengl_api(OpenGLAPI::GL), Some(api) => builder.with_opengl_api(api),
Some(OpenGLAPI::GLES) => builder.with_opengl_api(OpenGLAPI::GLES),
None => builder, None => builder,
}; };

View file

@ -10,7 +10,7 @@ use glutin::{
prelude::*, prelude::*,
surface::{SurfaceAttributesBuilder, WindowSurface}, 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}; use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
pub struct OpenGLContext { pub struct OpenGLContext {
@ -122,16 +122,28 @@ impl OpenGLContext {
})? })?
.map(|h| h.as_raw()); .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 { let preferred_context_attributes = match opengl_api {
Some(OpenGLAPI::GL) => ContextAttributesBuilder::new() OpenGLAPI::GL(version) => {
.with_context_api(ContextApi::OpenGl(None)) let version = version.map(|version| glutin::context::Version {
.build(raw_window_handle), major: version.major,
Some(OpenGLAPI::GLES) | None => ContextAttributesBuilder::new() minor: version.minor,
.with_context_api(ContextApi::Gles(Some(glutin::context::Version { });
major: 3, ContextAttributesBuilder::new()
minor: 2, .with_context_api(ContextApi::OpenGl(version))
}))) .build(raw_window_handle)
.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); let fallback_context_attributes = ContextAttributesBuilder::new().build(raw_window_handle);

View file

@ -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. /// This enum specifies which OpenGL API should be used.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum OpenGLAPI { pub enum OpenGLAPI {
/// OpenGL /// OpenGL
GL, GL(Option<APIVersion>),
/// OpenGL ES /// OpenGL ES
GLES, GLES(Option<APIVersion>),
} }
/// This enum specifies which OpenGL API should be used. /// This enum specifies which OpenGL API should be used.

View file

@ -12,8 +12,11 @@ use glutin::{
prelude::*, prelude::*,
surface::{SurfaceAttributesBuilder, WindowSurface}, 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::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. /// This surface type renders into the given window with OpenGL, using glutin and glow libraries.
pub struct OpenGLSurface { pub struct OpenGLSurface {
@ -283,12 +286,6 @@ impl OpenGLSurface {
let config_template_builder = let config_template_builder =
config_template_builder.compatible_with_native_window(_window_handle.as_raw()); 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_template = config_template_builder.build();
let config = unsafe { let config = unsafe {
@ -309,35 +306,47 @@ impl OpenGLSurface {
.ok_or("Unable to find suitable GL config")? .ok_or("Unable to find suitable GL config")?
}; };
let create_gl_context = |gl_major| { let opengl_api =
let preferred_context_attributes = match opengl_api { opengl_api.unwrap_or(OpenGLAPI::GLES(Some(APIVersion { major: 3, minor: 0 })));
Some(OpenGLAPI::GL) => { let preferred_context_attributes = match opengl_api {
ContextAttributesBuilder::new().build(Some(_window_handle.as_raw())) OpenGLAPI::GL(version) => {
} let version = version.map(|version| glutin::context::Version {
Some(OpenGLAPI::GLES) | None => ContextAttributesBuilder::new() major: version.major,
.with_context_api(ContextApi::Gles(Some(glutin::context::Version { minor: version.minor,
major: gl_major, });
minor: 0, ContextAttributesBuilder::new()
}))) .with_context_api(ContextApi::OpenGl(version))
.build(Some(_window_handle.as_raw())), .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()
ContextAttributesBuilder::new().build(Some(_window_handle.as_raw())); .with_context_api(ContextApi::Gles(version))
.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}"))
} }
}; };
let not_current_gl_context = if let Some(OpenGLAPI::GL) = opengl_api { let gles2_fallback_context_attributes = ContextAttributesBuilder::new()
create_gl_context(4)? .with_context_api(ContextApi::Gles(Some(glutin::context::Version {
} else { major: 2,
create_gl_context(3).or_else(|_| create_gl_context(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::<WindowSurface>::new().build( let attrs = SurfaceAttributesBuilder::<WindowSurface>::new().build(
_window_handle.as_raw(), _window_handle.as_raw(),