Skip to content

Commit

Permalink
Renderer feature refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
ogoffart authored Jul 27, 2023
1 parent f2af831 commit 3a807e4
Show file tree
Hide file tree
Showing 36 changed files with 250 additions and 202 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/embedded_build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
- name: Enable Skia build
if: matrix.target != 'riscv64gc-unknown-linux-gnu'
run: |
echo "EXTRA_ARGS=--features slint/renderer-winit-skia" >> $GITHUB_ENV
echo "EXTRA_ARGS=--features slint/renderer-skia" >> $GITHUB_ENV
- uses: baptiste0928/cargo-install@v2
with:
crate: cross
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ All notable changes to this project are documented in this file.
- Added `ReverseModel` and `ModelExt::reverse`
- Added `fn set_visible(&self, _visible: bool)` to the `slint::platform::WindowAdapter` trait.
- Added ways to create a `SoftwareRenderer` without a `MinimalSoftwareWindow`
- The features `renderer-winit-*` were renamed to `renderer-*`

### C++

- Added `SLINT_TARGET_CARGO_FLAGS` cmake variable
- Added `ReverseModel`
- Added functions in Window to dispatch pointer events
- The `slint_interpreter.h` file was renamed `slint-interpreter.h`, a deprecated header was added
- The features `SLINT_FEATURE_RENDERER_WINIT_*` were renamed to `SLINT_FEATURE_RENDERER_*`

## [1.1.1] - 2023-07-10

Expand Down
46 changes: 21 additions & 25 deletions api/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@ if (MSVC)
target_compile_options(Slint INTERFACE /bigobj)
endif()

# Compat options
function(define_renderer_winit_compat_option renderer)
string(TOUPPER "${renderer}" cmake_option)
string(REPLACE "-" "_" cmake_option "${cmake_option}")
cmake_dependent_option("SLINT_FEATURE_RENDERER_WINIT_${cmake_option}" "Compat option equivalent to SLINT_FEATURE_RENDERER_${cmake_option}" OFF SLINT_FEATURE_STD OFF)
if(SLINT_FEATURE_RENDERER_WINIT_${cmake_option})
set("SLINT_FEATURE_RENDERER_${cmake_option}" ON PARENT_SCOPE)
message("SLINT_FEATURE_RENDERER_WINIT_${cmake_option} is deprecated, use SLINT_FEATURE_RENDERER_${cmake_option} instead")
endif()
endfunction()
define_renderer_winit_compat_option(femtovg)
define_renderer_winit_compat_option(skia)
define_renderer_winit_compat_option(skia-opengl)
define_renderer_winit_compat_option(skia-vulkan)
define_renderer_winit_compat_option(software)

function(define_cargo_feature cargo-feature description default)
# turn foo-bar into SLINT_FEATURE_FOO_BAR
string(TOUPPER "${cargo-feature}" cmake_option)
Expand Down Expand Up @@ -119,38 +135,18 @@ define_cargo_dependent_feature(backend-winit "Enable support for the winit crate
define_cargo_dependent_feature(backend-winit-x11 "Enable support for the winit create to interact only with the X11 windowing system on Unix. Enable this option and turn off SLINT_FEATURE_BACKEND_WINIT for a smaller build with just X11 support on Unix." OFF SLINT_FEATURE_STD)
define_cargo_dependent_feature(backend-winit-wayland "Enable support for the winit create to interact only with the wayland windowing system on Unix. Enable this option and turn off SLINT_FEATURE_BACKEND_WINIT for a smaller build with just wayland support." OFF SLINT_FEATURE_STD)

define_cargo_dependent_feature(renderer-winit-femtovg "Enable support for the OpenGL ES 2.0 based FemtoVG rendering engine." ON SLINT_FEATURE_STD)
define_cargo_dependent_feature(renderer-winit-skia "Enable support for the Skia based rendering engine." OFF SLINT_FEATURE_STD)
define_cargo_dependent_feature(renderer-winit-skia-opengl "Enable support for the Skia based rendering engine with its OpenGL backend." OFF SLINT_FEATURE_STD)
define_cargo_dependent_feature(renderer-winit-skia-vulkan "Enable support for the Skia based rendering engine with its Vulkan backend." OFF SLINT_FEATURE_STD)
define_cargo_dependent_feature(renderer-winit-software "Enable support for the software renderer with the winit backend" OFF SLINT_FEATURE_STD)
define_cargo_dependent_feature(renderer-femtovg "Enable support for the OpenGL ES 2.0 based FemtoVG rendering engine." ON SLINT_FEATURE_STD)
define_cargo_dependent_feature(renderer-skia "Enable support for the Skia based rendering engine." OFF SLINT_FEATURE_STD)
define_cargo_dependent_feature(renderer-skia-opengl "Enable support for the Skia based rendering engine with its OpenGL backend." OFF SLINT_FEATURE_STD)
define_cargo_dependent_feature(renderer-skia-vulkan "Enable support for the Skia based rendering engine with its Vulkan backend." OFF SLINT_FEATURE_STD)
define_cargo_feature(renderer-software "Enable support for the software renderer" OFF)

define_cargo_dependent_feature(backend-qt "Enable Qt based rendering backend" ON SLINT_FEATURE_STD)

define_cargo_feature(experimental "Enable experimental features (no compatibility guarantees)" OFF)
define_cargo_dependent_feature(gettext "Enable support of translations using gettext" OFF SLINT_FEATURE_STD)
define_cargo_dependent_feature(accessibility "Enable integration with operating system provided accessibility APIs" ON SLINT_FEATURE_STD)

# Compat options
option(SLINT_FEATURE_BACKEND_GL_ALL "This feature is an alias for SLINT_FEATURE_BACKEND_WINIT and SLINT_FEATURE_RENDERER_WINIT_FEMTOVG." OFF)
option(SLINT_FEATURE_BACKEND_GL_X11 "This feature is an alias for SLINT_FEATURE_BACKEND_WINIT_X11 and SLINT_FEATURE_RENDERER_WINIT_FEMTOVG." OFF)
option(SLINT_FEATURE_BACKEND_GL_WAYLAND "This feature is an alias for SLINT_FEATURE_BACKEND_WINIT_WAYLAND and SLINT_FEATURE_RENDERER_WINIT_FEMTOVG." OFF)

if(SLINT_FEATURE_BACKEND_GL_ALL)
set(SLINT_FEATURE_BACKEND_WINIT ON)
set(SLINT_FEATURE_RENDERER_WINIT_FEMTOVG ON)
endif()

if(SLINT_FEATURE_BACKEND_GL_X11)
set(SLINT_FEATURE_BACKEND_WINIT_X11 ON)
set(SLINT_FEATURE_RENDERER_WINIT_FEMTOVG ON)
endif()

if(SLINT_FEATURE_BACKEND_GL_WAYLAND)
set(SLINT_FEATURE_BACKEND_WINIT_WAYLAND ON)
set(SLINT_FEATURE_RENDERER_WINIT_FEMTOVG ON)
endif()

if (NOT SLINT_FEATURE_STD)
list(APPEND features i-slint-core/libm i-slint-core/unsafe-single-threaded)

Expand Down
14 changes: 7 additions & 7 deletions api/cpp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ backend-qt = ["i-slint-backend-selector/i-slint-backend-qt", "std"]
backend-winit = ["i-slint-backend-selector/backend-winit", "std"]
backend-winit-x11 = ["i-slint-backend-selector/backend-winit-x11", "std"]
backend-winit-wayland = ["i-slint-backend-selector/backend-winit-wayland", "std"]
renderer-winit-femtovg = ["i-slint-backend-selector/renderer-winit-femtovg"]
renderer-winit-skia = ["i-slint-backend-selector/renderer-winit-skia"]
renderer-winit-skia-opengl = ["i-slint-backend-selector/renderer-winit-skia-opengl"]
renderer-winit-skia-vulkan = ["i-slint-backend-selector/renderer-winit-skia-vulkan"]
renderer-winit-software = ["i-slint-backend-selector/renderer-winit-software"]
renderer-femtovg = ["i-slint-backend-selector/renderer-femtovg"]
renderer-skia = ["i-slint-backend-selector/renderer-skia"]
renderer-skia-opengl = ["i-slint-backend-selector/renderer-skia-opengl"]
renderer-skia-vulkan = ["i-slint-backend-selector/renderer-skia-vulkan"]
renderer-software = ["i-slint-backend-selector/renderer-software"]
gettext = ["i-slint-core/gettext-rs"]
accessibility = ["i-slint-backend-selector/accessibility"]

Expand All @@ -43,14 +43,14 @@ experimental-skia = ["i-slint-renderer-skia", "raw-window-handle", "experimental

std = ["image", "i-slint-core/default", "i-slint-backend-selector"]

default = ["std", "backend-winit", "renderer-winit-femtovg", "backend-qt", "experimental"]
default = ["std", "backend-winit", "renderer-femtovg", "backend-qt", "experimental"]

[dependencies]
i-slint-backend-selector = { version = "=1.2.0", path="../../internal/backends/selector", optional = true }
i-slint-backend-testing = { version = "=1.2.0", path="../../internal/backends/testing", optional = true }
i-slint-renderer-skia = { version = "=1.2.0", path="../../internal/renderers/skia", optional = true, features = ["x11", "wayland"] }
i-slint-core = { version = "=1.2.0", path="../../internal/core", default-features = false, features = ["ffi"] }
slint-interpreter = { version = "=1.2.0", path="../../internal/interpreter", default-features = false, features = ["ffi", "compat-1-0"], optional = true }
slint-interpreter = { version = "=1.2.0", path="../../internal/interpreter", default-features = false, features = ["ffi", "compat-1-2"], optional = true }
raw-window-handle = { version = "0.5", optional = true }
# Enable image-rs' default features to make all image formats to C++ users
image = { version = "0.24.0", optional = true }
Expand Down
1 change: 1 addition & 0 deletions api/cpp/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fn main() -> Result<(), anyhow::Error> {
experimental: std::env::var("CARGO_FEATURE_EXPERIMENTAL").is_ok(),
backend_qt: std::env::var("CARGO_FEATURE_BACKEND_QT").is_ok(),
std: std::env::var("CARGO_FEATURE_STD").is_ok(),
renderer_software: std::env::var("CARGO_FEATURE_RENDERER_SOFTWARE").is_ok(),
};

let dependencies = cbindgen::gen_all(&root_dir, &output_dir, enabled_features)?;
Expand Down
4 changes: 4 additions & 0 deletions api/cpp/cbindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ pub struct EnabledFeatures {
pub experimental: bool,
pub backend_qt: bool,
pub std: bool,
pub renderer_software: bool,
}

impl EnabledFeatures {
Expand All @@ -743,6 +744,9 @@ impl EnabledFeatures {
if self.std {
defines += "#define SLINT_FEATURE_STD\n";
}
if self.renderer_software {
defines += "#define SLINT_FEATURE_RENDERER_SOFTWARE\n";
}
defines
}
}
Expand Down
2 changes: 2 additions & 0 deletions api/cpp/include/slint-platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ inline void set_platform(std::unique_ptr<Platform> platform)
});
}

# ifdef SLINT_FEATURE_RENDERER_SOFTWARE
/// Represents a region on the screen, used for partial rendering.
///
/// The region may be composed of multiple sub-regions.
Expand Down Expand Up @@ -358,6 +359,7 @@ class SoftwareRenderer : public AbstractRenderer
return PhysicalRegion { r };
}
};
# endif

/// An opaque, low-level window handle that internalizes everything necessary to exchange messages
/// with the windowing system. This includes the connection to the display server, if necessary.
Expand Down
105 changes: 57 additions & 48 deletions api/cpp/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ use alloc::boxed::Box;
use alloc::rc::Rc;
use core::ffi::c_void;
use i_slint_core::api::{PhysicalSize, Window};
use i_slint_core::graphics::{IntRect, IntSize, Rgb8Pixel};
use i_slint_core::graphics::IntSize;
use i_slint_core::platform::{Platform, PlatformError};
use i_slint_core::renderer::Renderer;
use i_slint_core::software_renderer::{RepaintBufferType, Rgb565Pixel, SoftwareRenderer};
use i_slint_core::window::ffi::WindowAdapterRcOpaque;
use i_slint_core::window::WindowAdapter;

Expand Down Expand Up @@ -246,62 +245,72 @@ pub unsafe extern "C" fn slint_platform_task_run(event: PlatformTaskOpaque) {
f();
}

type SoftwareRendererOpaque = *const c_void;
#[cfg(feature = "renderer-software")]
mod software_renderer {
use super::*;
type SoftwareRendererOpaque = *const c_void;
use i_slint_core::software_renderer::{RepaintBufferType, Rgb565Pixel, SoftwareRenderer};

#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_new(buffer_age: u32) -> SoftwareRendererOpaque {
let repaint_buffer_type = match buffer_age {
0 => RepaintBufferType::NewBuffer,
1 => RepaintBufferType::ReusedBuffer,
2 => RepaintBufferType::SwappedBuffers,
_ => unreachable!(),
};
Box::into_raw(Box::new(SoftwareRenderer::new_with_repaint_buffer_type(repaint_buffer_type)))
as SoftwareRendererOpaque
}
#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_new(
buffer_age: u32,
) -> SoftwareRendererOpaque {
let repaint_buffer_type = match buffer_age {
0 => RepaintBufferType::NewBuffer,
1 => RepaintBufferType::ReusedBuffer,
2 => RepaintBufferType::SwappedBuffers,
_ => unreachable!(),
};
Box::into_raw(Box::new(SoftwareRenderer::new_with_repaint_buffer_type(repaint_buffer_type)))
as SoftwareRendererOpaque
}

#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_drop(r: SoftwareRendererOpaque) {
drop(Box::from_raw(r as *mut SoftwareRenderer));
}
#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_drop(r: SoftwareRendererOpaque) {
drop(Box::from_raw(r as *mut SoftwareRenderer));
}

#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_render_rgb8(
r: SoftwareRendererOpaque,
buffer: *mut Rgb8Pixel,
buffer_len: usize,
pixel_stride: usize,
) -> IntRect {
let buffer = core::slice::from_raw_parts_mut(buffer, buffer_len);
let renderer = &*(r as *const SoftwareRenderer);
let r = renderer.render(buffer, pixel_stride);
let (orig, size) = (r.bounding_box_origin(), r.bounding_box_size());
i_slint_core::graphics::euclid::rect(orig.x, orig.y, size.width as i32, size.height as i32)
}
#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_render_rgb8(
r: SoftwareRendererOpaque,
buffer: *mut Rgb8Pixel,
buffer_len: usize,
pixel_stride: usize,
) -> IntRect {
let buffer = core::slice::from_raw_parts_mut(buffer, buffer_len);
let renderer = &*(r as *const SoftwareRenderer);
let r = renderer.render(buffer, pixel_stride);
let (orig, size) = (r.bounding_box_origin(), r.bounding_box_size());
i_slint_core::graphics::euclid::rect(orig.x, orig.y, size.width as i32, size.height as i32)
}

#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_render_rgb565(
r: SoftwareRendererOpaque,
buffer: *mut u16,
buffer_len: usize,
pixel_stride: usize,
) -> IntRect {
let buffer = core::slice::from_raw_parts_mut(buffer as *mut Rgb565Pixel, buffer_len);
let renderer = &*(r as *const SoftwareRenderer);
let r = renderer.render(buffer, pixel_stride);
let (orig, size) = (r.bounding_box_origin(), r.bounding_box_size());
i_slint_core::graphics::euclid::rect(orig.x, orig.y, size.width as i32, size.height as i32)
}
#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_render_rgb565(
r: SoftwareRendererOpaque,
buffer: *mut u16,
buffer_len: usize,
pixel_stride: usize,
) -> IntRect {
let buffer = core::slice::from_raw_parts_mut(buffer as *mut Rgb565Pixel, buffer_len);
let renderer = &*(r as *const SoftwareRenderer);
let r = renderer.render(buffer, pixel_stride);
let (orig, size) = (r.bounding_box_origin(), r.bounding_box_size());
i_slint_core::graphics::euclid::rect(orig.x, orig.y, size.width as i32, size.height as i32)
}

#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_handle(r: SoftwareRendererOpaque) -> RendererPtr {
let r = (r as *const SoftwareRenderer) as *const dyn Renderer;
core::mem::transmute(r)
#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_handle(
r: SoftwareRendererOpaque,
) -> RendererPtr {
let r = (r as *const SoftwareRenderer) as *const dyn Renderer;
core::mem::transmute(r)
}
}

#[cfg(all(feature = "i-slint-renderer-skia", feature = "raw-window-handle"))]
pub mod skia {
use super::*;
use i_slint_core::graphics::{IntRect, IntSize, Rgb8Pixel};
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};

struct CppRawHandle(RawWindowHandle, RawDisplayHandle);
Expand Down
46 changes: 26 additions & 20 deletions api/rs/slint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ path = "lib.rs"
default = [
"std",
"backend-winit",
"renderer-winit-femtovg",
"renderer-femtovg",
"renderer-software",
"backend-qt",
"accessibility",
"compat-1-0",
"compat-1-2",
]

## Mandatory feature:
## This feature is required to keep the compatibility with Slint 1.0
## This feature is required to keep the compatibility with Slint 1.2
## Newer patch version may put current functionality behind a new feature
## that would be enabled by default only if this feature was added.
## [More info in this blog post](https://slint.dev/blog/rust-adding-default-cargo-feature.html)
"compat-1-0" = []
"compat-1-2" = []
"compat-1-0" = ["compat-1-2", "renderer-software"]

## Enable use of the Rust standard library.
std = ["i-slint-core/std"]
Expand All @@ -55,7 +57,7 @@ libm = ["i-slint-core/libm"]
log = ["dep:log"]

## This feature enables the software renderer to pick up fonts from the operating system for text rendering.
software-renderer-systemfonts = ["i-slint-core/software-renderer-systemfonts"]
software-renderer-systemfonts = ["renderer-software", "i-slint-core/software-renderer-systemfonts"]

## Slint uses internally some `thread_local` state.
##
Expand Down Expand Up @@ -83,7 +85,7 @@ accessibility = ["i-slint-backend-selector/accessibility"]
#! with [`platform::set_platform()`].
#!
#! If you enable the Winit backend, you need to also include a renderer.
#! `renderer-winit-femtovg` is the only stable renderer, the other ones are experimental
#! `renderer-femtovg` is the only stable renderer, the other ones are experimental
#!
#! It is also possible to select the backend and renderer at runtime when several
#! are enabled, using the `SLINT_BACKEND` environment variable.
Expand Down Expand Up @@ -117,23 +119,27 @@ backend-winit-x11 = ["i-slint-backend-selector/backend-winit-x11", "std"]
## with support for the Wayland window system on Unix.
backend-winit-wayland = ["i-slint-backend-selector/backend-winit-wayland", "std"]

## Make the winit backend capable of rendering using the [femtovg](https://crates.io/crates/femtovg) crate.
## Must be used in combination with `backend-winit`, `backend-winit-x11`, or `backend-winit-wayland`.
renderer-winit-femtovg = ["i-slint-backend-selector/renderer-winit-femtovg", "std"]
# deprecated aliases
renderer-winit-femtovg = ["renderer-femtovg"]
renderer-winit-skia = ["renderer-skia"]
renderer-winit-skia-opengl= ["renderer-skia-opengl"]
renderer-winit-skia-vulkan= ["renderer-skia-vulkan"]
renderer-winit-software = ["renderer-software"]

## Make the winit backend capable of rendering using [Skia](https://skia.org/).
## Must be used in combination with `backend-winit`, `backend-winit-x11`, or `backend-winit-wayland`.
renderer-winit-skia = ["i-slint-backend-selector/renderer-winit-skia", "std"]
## Render using the [femtovg](https://crates.io/crates/femtovg) crate.
renderer-femtovg = ["i-slint-backend-selector/renderer-femtovg", "std"]

## Same as `renderer-winit-skia`, but Skia will always use OpenGL.
renderer-winit-skia-opengl = ["i-slint-backend-selector/renderer-winit-skia-opengl", "std"]
## Render using [Skia](https://skia.org/).
renderer-skia = ["i-slint-backend-selector/renderer-skia", "std"]

## Same as `renderer-winit-skia`, but Skia will always use Vulkan.
renderer-winit-skia-vulkan = ["i-slint-backend-selector/renderer-winit-skia-vulkan", "std"]
## Same as `renderer-skia`, but Skia will always use OpenGL.
renderer-skia-opengl = ["i-slint-backend-selector/renderer-skia-opengl", "std"]

## Make the winit backend capable of rendering using the software renderer.
## Must be used in combination with `backend-winit`, `backend-winit-x11`, or `backend-winit-wayland`.
renderer-winit-software = ["i-slint-backend-selector/renderer-winit-software"]
## Same as `renderer-skia`, but Skia will always use Vulkan.
renderer-skia-vulkan = ["i-slint-backend-selector/renderer-skia-vulkan", "std"]

## Render using the software renderer.
renderer-software = ["i-slint-backend-selector/renderer-software", "i-slint-core/software-renderer"]

[dependencies]
i-slint-core = { version = "=1.2.0", path = "../../../internal/core", default-features = false }
Expand Down Expand Up @@ -163,4 +169,4 @@ rustdoc-args = [
"--html-in-header",
"docs/resources/slint-docs-highlight.html",
]
features = ["document-features", "log", "gettext"]
features = ["document-features", "log", "gettext", "renderer-software", "renderer-femtovg"]
Loading

0 comments on commit 3a807e4

Please sign in to comment.