Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .github/workflows/release-windows.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
---

name: Release Windows

"on":
Expand All @@ -9,14 +8,24 @@ name: Release Windows

jobs:
build:
runs-on: windows-2022
runs-on: windows-2025
permissions:
# needed for uploading release artifact
contents: write
defaults:
run:
shell: msys2 {0}
steps:
- name: Install Inno 6
id: install_inno
shell: pwsh
run: |
winget install -e --id JRSoftware.InnoSetup -v 6.4.3 --accept-package-agreements --accept-source-agreements --disable-interactivity --scope machine
if (Test-Path "C:\Program Files (x86)\Inno Setup 6\") {
echo "inno installed successfully"
} else {
throw "could not find inno's installation folder"
}

- name: Set installer name
id: set_installer_name
Expand Down
25 changes: 25 additions & 0 deletions crates/rnote-engine/src/engine/rendering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ use p2d::bounding_volume::Aabb;
use piet::RenderContext;
use rnote_compose::color;
use tracing::error;
use std::time::Instant;

impl Engine {
/// Update the background rendering for the current viewport.
///
/// If the background pattern or zoom has changed, the background pattern needs to be regenerated first.
pub fn update_background_rendering_current_viewport(&mut self) -> WidgetFlags {
let start_time = Instant::now();
let mut widget_flags = WidgetFlags::default();

#[cfg(feature = "ui")]
Expand Down Expand Up @@ -85,11 +87,17 @@ impl Engine {
}

widget_flags.redraw = true;
let elapsed = start_time.elapsed();
println!(
"update_background_rendering_current_viewport completed in {:.2?}",
elapsed
);
widget_flags
}

/// Update the content rendering for the current viewport.
pub fn update_content_rendering_current_viewport(&mut self) -> WidgetFlags {
let start_time = Instant::now();
let mut widget_flags = WidgetFlags::default();
self.store.regenerate_rendering_in_viewport_threaded(
self.engine_tasks_tx(),
Expand All @@ -98,6 +106,11 @@ impl Engine {
self.camera.image_scale(),
);
widget_flags.redraw = true;
let elapsed = start_time.elapsed();
println!(
"update_content_rendering_current_viewport completed in {:.2?}",
elapsed
);
widget_flags
}

Expand Down Expand Up @@ -126,6 +139,7 @@ impl Engine {

/// Regenerate the background tile image, origin indicator and updates the background rendering.
pub fn background_rendering_regenerate(&mut self) -> WidgetFlags {
let start_time = Instant::now();
let mut widget_flags = WidgetFlags::default();
let image_scale = self.camera.image_scale();
let scale_factor = self.camera.scale_factor();
Expand Down Expand Up @@ -153,6 +167,11 @@ impl Engine {

widget_flags |= self.update_background_rendering_current_viewport();
widget_flags.redraw = true;
let elapsed = start_time.elapsed();
println!(
"background_rendering_regenerate completed in {:.2?}",
elapsed
);
widget_flags
}

Expand All @@ -163,6 +182,7 @@ impl Engine {
snapshot: &gtk4::Snapshot,
surface_bounds: p2d::bounding_volume::Aabb,
) -> anyhow::Result<()> {
let start_time = Instant::now();
use crate::drawable::DrawableOnDoc;
use crate::engine::visual_debug;
use crate::engine_view;
Expand Down Expand Up @@ -204,6 +224,11 @@ impl Engine {
visual_debug::draw_statistics_to_gtk_snapshot(snapshot, self, surface_bounds)?;
}

let elapsed = start_time.elapsed();
println!(
"draw_to_gtk_snapshot completed in {:.2?}",
elapsed
);
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion crates/rnote-engine/src/pens/penholder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ impl PenHolder {
.current_style_w_override(&engine_view.config.pens_config);

self.backlog_policy = match current_style {
PenStyle::Brush => BacklogPolicy::Limit(Duration::from_millis(4)),
PenStyle::Brush => BacklogPolicy::Disable,
PenStyle::Shaper => BacklogPolicy::Limit(Duration::from_millis(8)),
PenStyle::Typewriter => BacklogPolicy::Limit(Duration::from_millis(33)),
PenStyle::Eraser => BacklogPolicy::Limit(Duration::from_millis(33)),
Expand Down
68 changes: 55 additions & 13 deletions crates/rnote-engine/src/store/render_comp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use p2d::bounding_volume::{Aabb, BoundingVolume};
use rnote_compose::ext::AabbExt;
use rnote_compose::shapes::Shapeable;
use tracing::error;
use std::time::{Duration, Instant};

/// The tolerance where check between scale-factors are considered "equal".
pub(crate) const RENDER_IMAGE_SCALE_TOLERANCE: f64 = 0.01;
Expand Down Expand Up @@ -242,19 +243,46 @@ impl StrokeStore {
viewport: Aabb,
image_scale: f64,
) {
let t0 = Instant::now();
let keys = self.render_components.keys().collect::<Vec<StrokeKey>>();

println!(
"render_component completed in {:.2?}",
t0.elapsed()
);

let t1 = Instant::now();
let mut total_t2 = Duration::ZERO;
let mut total_t3 = Duration::ZERO;
let mut total_t4 = Duration::ZERO;
let mut total_t5 = Duration::ZERO;
let mut total_t6 = Duration::ZERO;
let mut cycle_count = 0;
for key in keys {
if let (Some(stroke), Some(render_comp)) = (
self.stroke_components.get(key),
self.render_components.get_mut(key),
) {
cycle_count += 1;

let t2 = Instant::now();
let tasks_tx = tasks_tx.clone();
let elapsed_t2 = t2.elapsed();
total_t2 += elapsed_t2;
//println!("task_tx completed in {:.2?}", elapsed_t2);

let t3 = Instant::now();
let stroke_bounds = stroke.bounds();
let elapsed_t3 = t3.elapsed();
total_t3 += elapsed_t3;
//println!("stroke_bounds completed in {:.2?}", elapsed_t3);

let t4 = Instant::now();
let viewport_extended =
viewport.extend_by(viewport.extents() * render::VIEWPORT_EXTENTS_MARGIN_FACTOR);

// skip and clear image buffer if stroke is not in viewport
let elapsed_t4 = t4.elapsed();
total_t4 += elapsed_t4;
//println!("viewport_extend completed in {:.2?}", elapsed_t4);

if !viewport_extended.intersects(&stroke_bounds) {
#[cfg(feature = "ui")]
{
Expand All @@ -264,19 +292,15 @@ impl StrokeStore {
render_comp.state = RenderCompState::Dirty;
continue;
}

// only check if rerendering is not forced

if !force_regenerate {
match render_comp.state {
RenderCompState::Complete | RenderCompState::BusyRenderingInTask => {
continue;
}
RenderCompState::ForViewport(old_viewport) => {
/// This factor is applied on top of the viewport extents margin factor,
/// so that rerendering is started a bit earlier to reaching
/// the edges of the viewport of the current rendered images.
const VIEWPORT_EXTENTS_MARGIN_RERENDER_THRESHOLD: f64 = 0.7;

if old_viewport.contains(
&(viewport.extend_by(
viewport.extents()
Expand All @@ -290,12 +314,15 @@ impl StrokeStore {
RenderCompState::Dirty => {}
}
}

// indicates that a task has now started to render the stroke
let t5 = Instant::now();
render_comp.state = RenderCompState::BusyRenderingInTask;
let stroke = stroke.clone();

// Spawn a new thread for image rendering
let elapsed_t5 = t5.elapsed();
total_t5 += elapsed_t5;
//println!("clone completed in {:.2?}", elapsed_t5);

let t6 = Instant::now();
rayon::spawn(
move || match stroke.gen_images(viewport_extended, image_scale) {
Ok(images) => {
Expand All @@ -312,8 +339,23 @@ impl StrokeStore {
}
},
);
let elapsed_t6 = t6.elapsed();
total_t6 += elapsed_t6;
//println!("spawn completed in {:.2?}", elapsed_t6);
}
}

println!("\nSummary for {} cycle(s):", cycle_count);
println!("Total task_tx time: {:.2?}", total_t2);
println!("Total stroke_bounds time: {:.2?}", total_t3);
println!("Total viewport_extend time:{:.2?}", total_t4);
println!("Total clone time: {:.2?}", total_t5);
println!("Total spawn time: {:.2?}", total_t6);
println!();
println!(
"for keys completed in {:.2?}",
t1.elapsed()
);
}

/// Clear all rendering for all strokes.
Expand Down
21 changes: 14 additions & 7 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@

# Either 'true' or 'false'
ci := "false"
linux_distr := `lsb_release -ds | tr '[:upper:]' '[:lower:]'`
log_level := "debug"
build_folder := "_mesonbuild"
flatpak_app_folder := "_flatpak_app"
flatpak_repo_folder := "_flatpak_repo"
mingw64_prefix_path := "C:/msys64/mingw64"

[private]
linux_distr := `lsb_release -ds | tr '[:upper:]' '[:lower:]'`
[private]
sudo_cmd := "sudo"

export LANG := "C"
Expand All @@ -28,7 +26,8 @@ default:
prerequisites:
#!/usr/bin/env bash
set -euxo pipefail
if [[ ('{{linux_distr}}' =~ 'fedora') ]]; then

if [[ ('{{linux_distr}}' =~ 'fedora') || ('{{linux_distr}}' =~ 'rhel') || ('{{linux_distr}}' =~ 'alma') ]]; then
{{sudo_cmd}} dnf install -y \
gcc gcc-c++ clang clang-devel python3 make cmake meson just git appstream gettext desktop-file-utils \
shared-mime-info kernel-devel gtk4-devel libadwaita-devel poppler-glib-devel poppler-data alsa-lib-devel \
Expand All @@ -42,13 +41,15 @@ prerequisites:
echo "Unable to install system dependencies, unsupported distro."
exit 1
fi

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
export PATH="$HOME/.cargo/bin:$PATH"

prerequisites-flatpak: prerequisites
#!/usr/bin/env bash
set -euxo pipefail
if [[ ('{{linux_distr}}' =~ 'fedora') ]]; then

if [[ ('{{linux_distr}}' =~ 'fedora') || ('{{linux_distr}}' =~ 'rhel') || ('{{linux_distr}}' =~ 'alma') ]]; then
{{sudo_cmd}} dnf install -y \
flatpak flatpak-builder
elif [[ '{{linux_distr}}' =~ 'debian' || '{{linux_distr}}' =~ 'ubuntu' ]]; then
Expand All @@ -59,14 +60,16 @@ prerequisites-flatpak: prerequisites
echo "Unable to install system dependencies, unsupported distro."
exit 1
fi

flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak install -y org.gnome.Platform//48 org.gnome.Sdk//48 org.freedesktop.Sdk.Extension.rust-stable//24.08 \
org.freedesktop.Sdk.Extension.llvm19//24.08

prerequisites-dev: prerequisites
#!/usr/bin/env bash
set -euxo pipefail
if [[ ('{{linux_distr}}' =~ 'fedora') ]]; then

if [[ ('{{linux_distr}}' =~ 'fedora') || ('{{linux_distr}}' =~ 'rhel') || ('{{linux_distr}}' =~ 'alma') ]]; then
{{sudo_cmd}} dnf install -y \
yamllint yq opencc-tools
elif [[ '{{linux_distr}}' =~ 'debian' || '{{linux_distr}}' =~ 'ubuntu' ]]; then
Expand All @@ -77,9 +80,11 @@ prerequisites-dev: prerequisites
echo "Unable to install system dependencies, unsupported distro."
exit 1
fi

if [[ "{{ci}}" != "true" ]]; then
ln -sf build-aux/git-hooks/pre-commit.hook .git/hooks/pre-commit
fi

curl -L --proto '=https' --tlsv1.2 -sSf \
https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
cargo binstall -y cargo-nextest cargo-edit cargo-deny
Expand All @@ -92,7 +97,9 @@ prerequisites-win:
mingw-w64-x86_64-meson mingw-w64-x86_64-diffutils mingw-w64-x86_64-desktop-file-utils \
mingw-w64-x86_64-appstream mingw-w64-x86_64-gtk4 mingw-w64-x86_64-libadwaita mingw-w64-x86_64-poppler \
mingw-w64-x86_64-poppler-data mingw-w64-x86_64-angleproject

mv /mingw64/lib/libpthread.dll.a /mingw64/lib/libpthread.dll.a.bak

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
export PATH="$HOME/.cargo/bin:$PATH"

Expand All @@ -116,7 +123,7 @@ setup-win-installer installer_name="rnote-win-installer":
meson setup \
--prefix={{ mingw64_prefix_path }} \
-Dprofile=default \
-Dcli=false \
-Dcli=true \
-Dwin-installer-name={{ installer_name }} \
-Dci={{ ci }} \
{{ build_folder }}
Expand Down
Loading