@@ -10,7 +10,7 @@ use crate::cache::DiskCache; |
| 10 | use crate::config::{Config, ScaleMode}; | 10 | use crate::config::{Config, ScaleMode}; |
| 11 | use crate::ipc::{Command, GarEvent, GarIpcClient, IpcServer, Response}; | 11 | use crate::ipc::{Command, GarEvent, GarIpcClient, IpcServer, Response}; |
| 12 | use crate::ipc::server::IpcClient; | 12 | use crate::ipc::server::IpcClient; |
| 13 | -use crate::media::{scale_image, AnimatedGif, AnimatedPng, AnimatedWebP, AnimationFrame, ImageLoader}; | 13 | +use crate::media::{scale_image, scale_image_fast, AnimatedGif, AnimatedPng, AnimatedWebP, AnimationFrame, ImageLoader}; |
| 14 | #[cfg(feature = "video")] | 14 | #[cfg(feature = "video")] |
| 15 | use crate::media::{VideoDecoder, is_video_file}; | 15 | use crate::media::{VideoDecoder, is_video_file}; |
| 16 | use crate::state::{detect_source_type, PlaylistState}; | 16 | use crate::state::{detect_source_type, PlaylistState}; |
@@ -93,7 +93,7 @@ pub struct ActiveAnimation { |
| 93 | } | 93 | } |
| 94 | | 94 | |
| 95 | impl ActiveAnimation { | 95 | impl ActiveAnimation { |
| 96 | - /// Create from animation frames | 96 | + /// Create from animation frames (scales in parallel with fast filter) |
| 97 | fn from_frames( | 97 | fn from_frames( |
| 98 | frames: &[AnimationFrame], | 98 | frames: &[AnimationFrame], |
| 99 | renderer: AnimationRenderer, | 99 | renderer: AnimationRenderer, |
@@ -103,10 +103,18 @@ impl ActiveAnimation { |
| 103 | screen_width: u32, | 103 | screen_width: u32, |
| 104 | screen_height: u32, | 104 | screen_height: u32, |
| 105 | ) -> Self { | 105 | ) -> Self { |
| 106 | - let scaled_frames: Vec<image::RgbaImage> = frames | 106 | + // Scale frames in parallel using thread::scope for multi-core speedup |
| 107 | - .iter() | 107 | + let scaled_frames: Vec<image::RgbaImage> = std::thread::scope(|s| { |
| 108 | - .map(|frame| scale_image(&frame.image, screen_width, screen_height, scale_mode)) | 108 | + let handles: Vec<_> = frames |
| 109 | - .collect(); | 109 | + .iter() |
| | 110 | + .map(|frame| { |
| | 111 | + s.spawn(move || { |
| | 112 | + scale_image_fast(&frame.image, screen_width, screen_height, scale_mode) |
| | 113 | + }) |
| | 114 | + }) |
| | 115 | + .collect(); |
| | 116 | + handles.into_iter().map(|h| h.join().unwrap()).collect() |
| | 117 | + }); |
| 110 | | 118 | |
| 111 | let frame_delays: Vec<Duration> = frames | 119 | let frame_delays: Vec<Duration> = frames |
| 112 | .iter() | 120 | .iter() |