Skip to content

Commit

Permalink
feat: load timeout and size limit
Browse files Browse the repository at this point in the history
  • Loading branch information
EYHN committed Apr 10, 2022
1 parent e2c758f commit 68ad544
Show file tree
Hide file tree
Showing 15 changed files with 249 additions and 97 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ Generates preview thumbnails for 3D model files. Provide a Windows Explorer exte

**Ensure thumbnails are generally enabled.** Are thumbnails working with other file types on your system, e.g. photos? If not, you may have disabled them altogether.


1. open any folder
2. open the `Folder Options`

Expand All @@ -38,15 +37,23 @@ Generates preview thumbnails for 3D model files. Provide a Windows Explorer exte
3. Select the `View` tab
4. in `Advanced settings`, make sure the `Always show icons, never thumbnails` option is not checked



**Clear your thumbnail cache.** This forces Explorer to request new thumbnails instead of relying on outdated data.

1. click the `Start` button and type `cleanmgr.exe`
2. select drive `C:` and confirm
3. check `Thumbnails` and confirm
4. reboot

### Speed

Rendering thumbnails for 3D models may not be that fast. To keep your explorer smooth and available, we have made some limits here, if the model file size is larger than `300MB` or takes longer than `5 seconds` to load and render, it will be cancelled and display this image below.

<img src="crates/windows/assets/timeout256x256.png" width="100px" />

If there is an error loading the file (corrupt or illegal file), it will display this image below.

<img src="crates/windows/assets/error256x256.png" width="100px" />

## Links

* [google / filament](https://github.com/google/filament): 3D rendering engine, and [the rust bindings](https://github.com/EYHN/rust-filament)
Expand Down
2 changes: 1 addition & 1 deletion crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.1"
edition = "2021"

[dependencies]
filament-bindings = "0.2.1"
filament-bindings = "0.2.2"

[dev-dependencies]
image = "0.24"
Expand Down
31 changes: 24 additions & 7 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::panic;
use std::{cell::Cell, ffi::OsStr, fs, path::Path, rc::Rc};

use filament_bindings::{
assimp::AssimpAsset,
assimp::{post_process, AssimpAsset},
backend::{Backend, PixelBufferDescriptor, PixelDataFormat, PixelDataType},
filament::{
self, sRGBColor, Aabb, Camera, ClearOptions, Engine, Fov, IndirectLight,
Expand All @@ -19,6 +19,15 @@ use filament_bindings::{

const IDL_TEXTURE_DATA: &'static [u8] = include_bytes!("lightroom_14b_ibl.ktx");

const ASSIMP_FLAGS: u32 = post_process::GEN_SMOOTH_NORMALS
| post_process::CALC_TANGENT_SPACE
| post_process::GEN_UV_COORDS
| post_process::FIND_INSTANCES
| post_process::OPTIMIZE_MESHES
| post_process::IMPROVE_CACHE_LOCALITY
| post_process::SORT_BY_P_TYPE
| post_process::TRIANGULATE;

pub struct SpaceThumbnailsRenderer {
// need release
engine: Engine,
Expand Down Expand Up @@ -142,7 +151,8 @@ impl SpaceThumbnailsRenderer {
Some(filepath.as_ref()),
)
} else {
let asset = AssimpAsset::from_file(&mut self.engine, filepath).ok()?;
let asset =
AssimpAsset::from_file_with_flags(&mut self.engine, filepath, ASSIMP_FLAGS).ok()?;
self.load_assimp_asset(asset)
}
}
Expand All @@ -156,9 +166,13 @@ impl SpaceThumbnailsRenderer {
{
self.load_gltf_asset(buffer, filename.as_ref(), None)
} else {
let asset =
AssimpAsset::from_memory(&mut self.engine, buffer, filename.as_ref().to_str()?)
.ok()?;
let asset = AssimpAsset::from_memory_with_flags(
&mut self.engine,
buffer,
filename.as_ref().to_str()?,
ASSIMP_FLAGS,
)
.ok()?;
self.load_assimp_asset(asset)
}
}
Expand Down Expand Up @@ -423,8 +437,6 @@ mod test {
)
.unwrap();

let mut renderer = SpaceThumbnailsRenderer::new(RendererBackend::Vulkan, 800, 800);

for entry in models {
let entry = entry.unwrap();

Expand All @@ -435,6 +447,11 @@ mod test {
let filepath = entry.path();
let filename = filepath.file_name().unwrap().to_str().unwrap();

let now = Instant::now();
let mut renderer = SpaceThumbnailsRenderer::new(RendererBackend::Vulkan, 800, 800);
let elapsed = now.elapsed();
println!("Initialize renderer, Elapsed: {:.2?}", elapsed);

let now = Instant::now();
renderer.load_asset_from_file(&filepath).unwrap();
let elapsed = now.elapsed();
Expand Down
3 changes: 3 additions & 0 deletions crates/windows/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ features = [
"Win32_UI_Shell",
"Win32_UI_Shell_PropertiesSystem"
]

[build-dependencies]
image = "0.24"
Binary file added crates/windows/assets/error256x256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added crates/windows/assets/timeout256x256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added crates/windows/assets/toolarge256x256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions crates/windows/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::{
env, fs,
path::{Path, PathBuf},
};

fn main() {
println!("cargo:rerun-if-changed=assets/error256x256.png");
png2argb(
"assets/error256x256.png",
PathBuf::from(env::var("OUT_DIR").unwrap()).join("error256x256.bin"),
);

println!("cargo:rerun-if-changed=assets/timeout256x256.png");
png2argb(
"assets/timeout256x256.png",
PathBuf::from(env::var("OUT_DIR").unwrap()).join("timeout256x256.bin"),
);

println!("cargo:rerun-if-changed=assets/toolarge256x256.png");
png2argb(
"assets/toolarge256x256.png",
PathBuf::from(env::var("OUT_DIR").unwrap()).join("toolarge256x256.bin"),
);
}

fn png2argb(source: impl AsRef<Path>, out: impl AsRef<Path>) {
let img = image::open(source).unwrap();
let rgba = img.to_rgba8();
let mut argb = Vec::with_capacity(rgba.len());

for (_, _, pixel) in rgba.enumerate_pixels() {
argb.push(pixel.0[2]);
argb.push(pixel.0[1]);
argb.push(pixel.0[0]);
argb.push(pixel.0[3]);
}

fs::write(out, argb).unwrap();
}
4 changes: 4 additions & 0 deletions crates/windows/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ lazy_static! {
))
];
}

pub const ERROR_256X256_ARGB: &'static [u8] = include_bytes!(concat!(env!("OUT_DIR"), "/error256x256.bin"));
pub const TIMEOUT_256X256_ARGB: &'static [u8] = include_bytes!(concat!(env!("OUT_DIR"), "/timeout256x256.bin"));
pub const TOOLARGE_256X256_ARGB: &'static [u8] = include_bytes!(concat!(env!("OUT_DIR"), "/toolarge256x256.bin"));
1 change: 0 additions & 1 deletion crates/windows/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ extern crate lazy_static;

pub mod providers;
pub mod registry;
pub mod win_stream;
pub mod constant;
pub mod utils;
75 changes: 50 additions & 25 deletions crates/windows/src/providers/thumbnail.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::Cell, io::Read, mem::size_of, time::Duration};
use std::{cell::Cell, io, time::Duration};

use space_thumbnails::{RendererBackend, SpaceThumbnailsRenderer};
use windows::{
Expand All @@ -12,9 +12,9 @@ use windows::{
};

use crate::{
constant::{ERROR_256X256_ARGB, TIMEOUT_256X256_ARGB, TOOLARGE_256X256_ARGB},
registry::{register_clsid, RegistryData, RegistryKey, RegistryValue},
utils::run_timeout,
win_stream::WinStream,
utils::{create_argb_bitmap, run_timeout, WinStream},
};

use super::Provider;
Expand Down Expand Up @@ -98,9 +98,28 @@ impl IThumbnailProvider_Impl for ThumbnailHandler {
.stream
.take()
.ok_or(windows::core::Error::from(E_FAIL))?;

let filesize = stream.size()?;

if filesize > 300 * 1024 * 1024
/* 300 MB */
{
unsafe {
let mut p_bits: *mut core::ffi::c_void = core::ptr::null_mut();
let hbmp = create_argb_bitmap(256, 256, &mut p_bits);
std::ptr::copy(
TOOLARGE_256X256_ARGB.as_ptr(),
p_bits as *mut _,
TOOLARGE_256X256_ARGB.len(),
);
phbmp.write(hbmp);
pdwalpha.write(WTSAT_ARGB);
}
return Ok(());
}

let mut buffer = Vec::new();
stream
.read_to_end(&mut buffer)
io::Read::read_to_end(&mut stream, &mut buffer)
.ok()
.ok_or(windows::core::Error::from(E_FAIL))?;

Expand All @@ -122,26 +141,8 @@ impl IThumbnailProvider_Impl for ThumbnailHandler {

if let Ok(Some(screenshot_buffer)) = timeout_result {
unsafe {
let bmi = BITMAPINFO {
bmiHeader: BITMAPINFOHEADER {
biSize: size_of::<BITMAPINFOHEADER>() as u32,
biWidth: cx as i32,
biHeight: -(cx as i32),
biPlanes: 1,
biBitCount: 32,
..Default::default()
},
..Default::default()
};
let mut p_bits: *mut core::ffi::c_void = core::ptr::null_mut();
let hbmp = CreateDIBSection(
core::mem::zeroed::<HDC>(),
&bmi,
DIB_RGB_COLORS,
&mut p_bits,
core::mem::zeroed::<windows::Win32::Foundation::HANDLE>(),
0,
);
let hbmp = create_argb_bitmap(cx, cx, &mut p_bits);
for x in 0..cx {
for y in 0..cx {
let index = ((x * cx + y) * 4) as usize;
Expand All @@ -157,8 +158,32 @@ impl IThumbnailProvider_Impl for ThumbnailHandler {
pdwalpha.write(WTSAT_ARGB);
}
Ok(())
} else if matches!(timeout_result, Err(err) if err.kind() == io::ErrorKind::TimedOut) {
unsafe {
let mut p_bits: *mut core::ffi::c_void = core::ptr::null_mut();
let hbmp = create_argb_bitmap(256, 256, &mut p_bits);
std::ptr::copy(
TIMEOUT_256X256_ARGB.as_ptr(),
p_bits as *mut _,
TIMEOUT_256X256_ARGB.len(),
);
phbmp.write(hbmp);
pdwalpha.write(WTSAT_ARGB);
}
Ok(())
} else {
Err(windows::core::Error::from(E_FAIL))
unsafe {
let mut p_bits: *mut core::ffi::c_void = core::ptr::null_mut();
let hbmp = create_argb_bitmap(256, 256, &mut p_bits);
std::ptr::copy(
ERROR_256X256_ARGB.as_ptr(),
p_bits as *mut _,
ERROR_256X256_ARGB.len(),
);
phbmp.write(hbmp);
pdwalpha.write(WTSAT_ARGB);
}
Ok(())
}
}
}
Expand Down
Loading

0 comments on commit 68ad544

Please sign in to comment.