Skip to content
Open
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
7 changes: 7 additions & 0 deletions src-tauri/src/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::mpsc::Sender;
use std::sync::{Arc, Condvar, Mutex};
use std::time::Instant;

use image::{DynamicImage, GrayImage};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -60,6 +61,7 @@ pub struct GpuImageCache {
pub width: u32,
pub height: u32,
pub transform_hash: u64,
pub staging_buffer: Vec<u8>,
}

pub struct GpuProcessorState {
Expand Down Expand Up @@ -165,8 +167,13 @@ pub struct AppState {
pub thumbnail_geometry_cache: Mutex<HashMap<String, (u64, DynamicImage, f32)>>,
pub lens_db: Mutex<Option<Arc<LensDatabase>>>,
pub load_image_generation: Arc<AtomicUsize>,
pub uncropped_preview_seq: AtomicUsize,
pub uncropped_preview_work_mutex: Mutex<()>,
pub uncropped_last_emit: Mutex<Instant>,
pub full_warped_cache: Mutex<Option<(u64, Arc<DynamicImage>)>>,
pub full_transformed_cache: Mutex<Option<TransformedImageCache>>,
pub preview_cache: Mutex<Option<Arc<DynamicImage>>>,
pub processing_active: AtomicBool,
pub decoded_image_cache: Mutex<DecodedImageCache>,
pub thumbnail_manager: Arc<ThumbnailManager>,
pub metadata_manager: Arc<MetadataManager>,
Expand Down
20 changes: 19 additions & 1 deletion src-tauri/src/file_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,25 @@ pub fn generate_thumbnail_data(
let mut raw_scale_factor = 1.0f32;

let composite_image = if let Some(img) = preloaded_image {
image_loader::composite_patches_on_image(img, &adjustments)?
let has_no_patches = !adjustments
.get("aiPatches")
.and_then(|v| v.as_array())
.is_some_and(|a| !a.is_empty());
if has_no_patches {
let cached_base = state.preview_cache.lock().unwrap().as_ref().map(Arc::clone);
if let Some(cached_img) = cached_base {
let (cw, ch) = cached_img.dimensions();
if cw >= target_res || ch >= target_res {
cached_img.as_ref().clone()
} else {
image_loader::composite_patches_on_image(img, &adjustments)?
}
} else {
image_loader::composite_patches_on_image(img, &adjustments)?
}
} else {
image_loader::composite_patches_on_image(img, &adjustments)?
}
} else {
let mmap_guard;
let vec_guard;
Expand Down
70 changes: 48 additions & 22 deletions src-tauri/src/gpu_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
#[cfg(not(any(target_os = "android", target_os = "linux")))]
let app_handle = _app_handle;

let mut context_lock = state.gpu_context.lock().unwrap();
let mut context_lock = state.gpu_context.lock().unwrap_or_else(|e| e.into_inner());
if let Some(context) = &*context_lock {
return Ok(context.clone());
}
Expand All @@ -152,10 +152,10 @@

#[cfg(target_os = "windows")]
if std::env::var("WGPU_BACKEND").is_err() {
instance_desc.backends = wgpu::Backends::PRIMARY;

Check warning on line 155 in src-tauri/src/gpu_processing.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/RapidRAW/RapidRAW/src-tauri/src/gpu_processing.rs
}

let flag_path = state.gpu_crash_flag_path.lock().unwrap().clone();
let flag_path = state.gpu_crash_flag_path.lock().unwrap_or_else(|e| e.into_inner()).clone();
if let Some(p) = &flag_path {
if let Some(parent) = p.parent() {
let _ = std::fs::create_dir_all(parent);
Expand Down Expand Up @@ -1648,10 +1648,10 @@
);
return Ok(base_image.clone());
}

Check warning on line 1651 in src-tauri/src/gpu_processing.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/RapidRAW/RapidRAW/src-tauri/src/gpu_processing.rs
let mut reallocated = false;

let mut processor_lock = state.gpu_processor.lock().unwrap();
let mut processor_lock = state.gpu_processor.lock().unwrap_or_else(|e| e.into_inner());
let mut needs_new_processor = false;
let new_width = (width + 255) & !255;
let new_height = (height + 255) & !255;
Expand Down Expand Up @@ -1728,31 +1728,56 @@
],
label: Some("Migrated Display Bind Group"),
});
display.current_bind_group = Some(bind_group);

Check warning on line 1731 in src-tauri/src/gpu_processing.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/RapidRAW/RapidRAW/src-tauri/src/gpu_processing.rs
}

let mut cache_lock = state.gpu_image_cache.lock().unwrap();
let mut needs_new_cache = false;

if let Some(cache) = &*cache_lock {
if cache.transform_hash != transform_hash || cache.width != width || cache.height != height
{
needs_new_cache = true;
}
} else {
needs_new_cache = true;
let mut cache_lock = state.gpu_image_cache.lock().unwrap_or_else(|e| e.into_inner());
if let Some(cache) = &*cache_lock
&& (cache.width != width || cache.height != height)
{
*cache_lock = None;
}

if needs_new_cache {
let old_cache = cache_lock.take();
drop(old_cache);

let _ = context.device.poll(wgpu::PollType::Wait {
submission_index: None,
timeout: Some(std::time::Duration::from_millis(500)),
});
let img_rgba_f16 = to_rgba_f16(base_image);

let img_rgba_f16 = to_rgba_f16(base_image);
if let Some(cache) = cache_lock.as_mut() {
let src_bytes = bytemuck::cast_slice(&img_rgba_f16);
let bytes_per_row = ((width as u32 * 8) + 255) & !255;
let (data, data_size) = if bytes_per_row == width as u32 * 8 {
(src_bytes, src_bytes.len())
} else {
let row_bytes = width as u32 as usize * 8;
let needed = bytes_per_row as usize * height as usize;
cache.staging_buffer.resize(needed, 0);
for y in 0..height as usize {
let src_start = y * row_bytes;
let dst_start = y * bytes_per_row as usize;
cache.staging_buffer[dst_start..dst_start + row_bytes]
.copy_from_slice(&src_bytes[src_start..src_start + row_bytes]);
}
let data_ref: &[u8] = &cache.staging_buffer;
(data_ref, needed)
};
queue.write_texture(
wgpu::TexelCopyTextureInfo {
texture: &cache.texture,
mip_level: 0,
origin: wgpu::Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
&data[..data_size],
wgpu::TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(bytes_per_row),
rows_per_image: None,
},
wgpu::Extent3d {
width,
height,
depth_or_array_layers: 1,
},
);
} else {
let texture_size = wgpu::Extent3d {
width,
height,
Expand Down Expand Up @@ -1781,6 +1806,7 @@
width,
height,
transform_hash,
staging_buffer: Vec::new(),
});
}

Expand Down
34 changes: 32 additions & 2 deletions src-tauri/src/image_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use crate::formats::is_raw_file;
use crate::image_processing::ImageMetadata;
use crate::image_processing::{
apply_orientation, apply_srgb_to_linear, remove_raw_artifacts_and_enhance,
apply_orientation, apply_srgb_to_linear, downscale_f32_image, remove_raw_artifacts_and_enhance,
};
use crate::mask_generation::{MaskDefinition, SubMask, generate_mask_bitmap};
use anyhow::{Context, Result, anyhow};
Expand Down Expand Up @@ -739,10 +739,22 @@
let my_generation = state.load_image_generation.fetch_add(1, Ordering::SeqCst) + 1;
let generation_tracker = state.load_image_generation.clone();
let cancel_token = Some((generation_tracker.clone(), my_generation));

Check warning on line 742 in src-tauri/src/image_loader.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/RapidRAW/RapidRAW/src-tauri/src/image_loader.rs
let is_same_image = {
let guard = state.original_image.lock().unwrap();
guard.as_ref().and_then(|img| {
let (source_path, _) = parse_virtual_path(&path);
Some(img.path == source_path.to_string_lossy())
}).unwrap_or(false)
};

{
*state.original_image.lock().unwrap() = None;
*state.cached_preview.lock().unwrap() = None;
if !is_same_image {
*state.preview_cache.lock().unwrap() = None;
}
*state.gpu_processor.lock().unwrap() = None;
*state.gpu_image_cache.lock().unwrap() = None;
*state.full_warped_cache.lock().unwrap() = None;
*state.full_transformed_cache.lock().unwrap() = None;
Expand Down Expand Up @@ -781,7 +793,7 @@
));
}

let (pristine_img, exif_data_loaded) = tokio::task::spawn_blocking(move || {
let (mut pristine_img, exif_data_loaded) = tokio::task::spawn_blocking(move || {
if generation_tracker.load(Ordering::SeqCst) != my_generation {
return Err("Load cancelled".to_string());
}
Expand Down Expand Up @@ -835,6 +847,10 @@
.await
.map_err(|e| e.to_string())??;

if cfg!(target_os = "android") {
pristine_img = DynamicImage::ImageRgb8(pristine_img.to_rgb8());
}

let arc_img = Arc::new(pristine_img);

state.decoded_image_cache.lock().unwrap().insert(
Expand All @@ -858,6 +874,20 @@

let (orig_width, orig_height) = pristine_arc.dimensions();

if cfg!(target_os = "android") {
let mut cache_lock = state.preview_cache.lock().unwrap();
if cache_lock.is_none() {
let settings = load_settings(app_handle.clone()).unwrap_or_default();
let cache_dim = settings.editor_preview_resolution.unwrap_or(1920).max(2560);
if orig_width > cache_dim || orig_height > cache_dim {
let cache_img = downscale_f32_image(&pristine_arc, cache_dim, cache_dim);
*cache_lock = Some(Arc::new(cache_img));
} else {
*cache_lock = Some(Arc::clone(&pristine_arc));
}
}
}

*state.original_image.lock().unwrap() = Some(LoadedImage {
path,
image: pristine_arc,
Expand Down
10 changes: 10 additions & 0 deletions src-tauri/src/inpainting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@

let (base_image, _) = crate::get_original_image(&state)?;
let composited = composite_patches_on_image(&base_image, &source_image_adjustments)
.map_err(|e| format!("Failed to prepare source image: {}", e))?;

Check warning on line 38 in src-tauri/src/inpainting.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/RapidRAW/RapidRAW/src-tauri/src/inpainting.rs

let composited = match composited {
DynamicImage::ImageRgb8(img) => DynamicImage::ImageRgba32F(DynamicImage::ImageRgb8(img).to_rgba32f()),
other => other,
};

let source_image = if is_raw {
apply_linear_to_srgb(composited)
} else {
Expand Down Expand Up @@ -344,8 +349,13 @@

let (base_image, _) = crate::get_original_image(&state)?;
let composited = composite_patches_on_image(&base_image, &source_image_adjustments)
.map_err(|e| format!("Failed to prepare source image: {}", e))?;

Check warning on line 352 in src-tauri/src/inpainting.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/RapidRAW/RapidRAW/src-tauri/src/inpainting.rs

let composited = match composited {
DynamicImage::ImageRgb8(img) => DynamicImage::ImageRgba32F(DynamicImage::ImageRgb8(img).to_rgba32f()),
other => other,
};

let source_image = if is_raw {
apply_linear_to_srgb(composited)
} else {
Expand Down
Loading
Loading