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;
///
/// 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<Box<dyn Platform + 'static>, 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,
};

View file

@ -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);

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

View file

@ -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 opengl_api =
opengl_api.unwrap_or(OpenGLAPI::GLES(Some(APIVersion { major: 3, minor: 0 })));
let preferred_context_attributes = match opengl_api {
Some(OpenGLAPI::GL) => {
ContextAttributesBuilder::new().build(Some(_window_handle.as_raw()))
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()))
}
Some(OpenGLAPI::GLES) | None => ContextAttributesBuilder::new()
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(Some(_window_handle.as_raw()))
}
};
let gles2_fallback_context_attributes = ContextAttributesBuilder::new()
.with_context_api(ContextApi::Gles(Some(glutin::context::Version {
major: gl_major,
major: 2,
minor: 0,
})))
.build(Some(_window_handle.as_raw())),
};
.build(Some(_window_handle.as_raw()));
let fallback_context_attributes =
ContextAttributesBuilder::new().build(Some(_window_handle.as_raw()));
unsafe {
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 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 attrs = SurfaceAttributesBuilder::<WindowSurface>::new().build(
_window_handle.as_raw(),