mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 19:28:12 +00:00
only use 100%
This commit is contained in:
parent
f1362ba73a
commit
55a70e7b88
@ -422,6 +422,21 @@ impl RenderState {
|
||||
})
|
||||
}
|
||||
|
||||
/// Device scale when workspace zoom is 100% (`viewbox.zoom == 1`): `1.0 * dpr`.
|
||||
fn base_zoom_placeholder_scale_bits(&self) -> u32 {
|
||||
(1.0_f32 * self.options.dpr()).to_bits()
|
||||
}
|
||||
|
||||
/// Scale bits used to look up tile textures in the cache.
|
||||
/// In `fast_mode`, always use the 100% zoom cache; otherwise use current scale.
|
||||
fn tile_texture_cache_lookup_scale_bits(&self) -> u32 {
|
||||
if self.options.is_fast_mode() {
|
||||
self.base_zoom_placeholder_scale_bits()
|
||||
} else {
|
||||
self.get_scale().to_bits()
|
||||
}
|
||||
}
|
||||
|
||||
fn rect_union(a: Rect, b: Rect) -> Rect {
|
||||
Rect::from_ltrb(
|
||||
a.left().min(b.left()),
|
||||
@ -1489,6 +1504,9 @@ impl RenderState {
|
||||
target_world_rect,
|
||||
current_scale,
|
||||
current_scale_bits,
|
||||
self.options
|
||||
.is_fast_mode()
|
||||
.then_some(self.base_zoom_placeholder_scale_bits()),
|
||||
true,
|
||||
);
|
||||
}
|
||||
@ -1576,9 +1594,14 @@ impl RenderState {
|
||||
|
||||
let _tile_start = performance::begin_timed_log!("tile_cache_update");
|
||||
performance::begin_measure!("tile_cache");
|
||||
let scale_bits = scale.to_bits();
|
||||
self.pending_tiles
|
||||
.update(&self.tile_viewbox, &self.surfaces, scale_bits);
|
||||
let lookup_bits = self.tile_texture_cache_lookup_scale_bits();
|
||||
self.pending_tiles.update(
|
||||
&self.tile_viewbox,
|
||||
&self.surfaces,
|
||||
scale,
|
||||
self.options.is_fast_mode(),
|
||||
lookup_bits,
|
||||
);
|
||||
performance::end_measure!("tile_cache");
|
||||
performance::end_timed_log!("tile_cache_update", _tile_start);
|
||||
|
||||
@ -2612,16 +2635,14 @@ impl RenderState {
|
||||
while !should_stop {
|
||||
if let Some(current_tile) = self.current_tile {
|
||||
let scale = self.get_scale();
|
||||
let scale_bits = scale.to_bits();
|
||||
if self
|
||||
.surfaces
|
||||
.has_cached_tile_surface(current_tile, scale_bits)
|
||||
{
|
||||
let lookup_bits = self.tile_texture_cache_lookup_scale_bits();
|
||||
let fast_mode = self.options.is_fast_mode();
|
||||
if !fast_mode && self.surfaces.has_cached_tile_surface(current_tile, lookup_bits) {
|
||||
performance::begin_measure!("render_shape_tree::cached");
|
||||
let tile_rect = self.get_current_tile_bounds()?;
|
||||
self.surfaces.draw_cached_tile_surface(
|
||||
current_tile,
|
||||
scale_bits,
|
||||
lookup_bits,
|
||||
tile_rect,
|
||||
self.background_color,
|
||||
);
|
||||
@ -2646,7 +2667,8 @@ impl RenderState {
|
||||
self.background_color,
|
||||
target_world_rect,
|
||||
scale,
|
||||
scale_bits,
|
||||
lookup_bits,
|
||||
fast_mode.then_some(self.base_zoom_placeholder_scale_bits()),
|
||||
true,
|
||||
);
|
||||
performance::begin_measure!("render_shape_tree::uncached");
|
||||
|
||||
@ -566,6 +566,24 @@ impl Surfaces {
|
||||
self.tiles.has(tile, scale_bits)
|
||||
}
|
||||
|
||||
pub fn world_rect_has_any_tile_at_scale_bits(&self, world_rect: Rect, scale_bits: u32) -> bool {
|
||||
let scale = f32::from_bits(scale_bits);
|
||||
if !scale.is_finite() || scale <= 0.0 {
|
||||
return false;
|
||||
}
|
||||
let tile_size_world = super::tiles::get_tile_size(scale);
|
||||
let super::tiles::TileRect(sx, sy, ex, ey) =
|
||||
super::tiles::get_tiles_for_rect(world_rect, tile_size_world);
|
||||
for x in sx..=ex {
|
||||
for y in sy..=ey {
|
||||
if self.tiles.has_stale(Tile::from(x, y), scale_bits) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn cached_scale_bits(&self) -> Vec<u32> {
|
||||
self.tiles.scale_bits().collect()
|
||||
}
|
||||
@ -670,6 +688,7 @@ impl Surfaces {
|
||||
}
|
||||
|
||||
/// Draw a placeholder for a missing tile using cached tiles from other zoom levels.
|
||||
/// If `forced_src_scale_bits` is set, only that scale is used as the source (used by fast_mode).
|
||||
pub fn draw_tile_fallback_cross_zoom(
|
||||
&mut self,
|
||||
tile_viewbox: &TileViewbox,
|
||||
@ -678,12 +697,15 @@ impl Surfaces {
|
||||
target_world_rect: Rect,
|
||||
target_scale: f32,
|
||||
target_scale_bits: u32,
|
||||
forced_src_scale_bits: Option<u32>,
|
||||
debug_trace: bool,
|
||||
) -> usize {
|
||||
let Some(candidate_scale_bits) = self
|
||||
.tiles
|
||||
.best_fallback_scale_bits(target_scale, target_scale_bits)
|
||||
else {
|
||||
let Some(candidate_scale_bits) = (if let Some(bits) = forced_src_scale_bits {
|
||||
Some(bits)
|
||||
} else {
|
||||
self.tiles
|
||||
.best_fallback_scale_bits(target_scale, target_scale_bits)
|
||||
}) else {
|
||||
if debug_trace {
|
||||
}
|
||||
return 0;
|
||||
@ -706,7 +728,12 @@ impl Surfaces {
|
||||
for x in sx..=ex {
|
||||
for y in sy..=ey {
|
||||
let src_tile = Tile::from(x, y);
|
||||
let Some(src_image) = self.tiles.get(src_tile, candidate_scale_bits) else {
|
||||
let src_image_opt = if forced_src_scale_bits.is_some() {
|
||||
self.tiles.get_stale(src_tile, candidate_scale_bits)
|
||||
} else {
|
||||
self.tiles.get(src_tile, candidate_scale_bits)
|
||||
};
|
||||
let Some(src_image) = src_image_opt else {
|
||||
continue;
|
||||
};
|
||||
|
||||
@ -833,6 +860,12 @@ impl TileTextureCache {
|
||||
self.grid.contains_key(&key) && !self.removed.contains(&key)
|
||||
}
|
||||
|
||||
/// Like `has` but ignores the `removed` tombstone (stale placeholder).
|
||||
pub fn has_stale(&self, tile: Tile, scale_bits: u32) -> bool {
|
||||
let key = TileCacheKey { tile, scale_bits };
|
||||
self.grid.contains_key(&key)
|
||||
}
|
||||
|
||||
fn gc(&mut self) {
|
||||
println!("gc");
|
||||
// Make a real remove
|
||||
@ -896,6 +929,12 @@ impl TileTextureCache {
|
||||
self.grid.get(&key)
|
||||
}
|
||||
|
||||
/// Like `get` but returns the image even if it is marked as `removed`.
|
||||
pub fn get_stale(&self, tile: Tile, scale_bits: u32) -> Option<&skia::Image> {
|
||||
let key = TileCacheKey { tile, scale_bits };
|
||||
self.grid.get(&key)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, tile: Tile, scale_bits: u32) {
|
||||
self.removed.insert(TileCacheKey { tile, scale_bits });
|
||||
}
|
||||
|
||||
@ -261,7 +261,14 @@ impl PendingTiles {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn update(&mut self, tile_viewbox: &TileViewbox, surfaces: &Surfaces, scale_bits: u32) {
|
||||
pub fn update(
|
||||
&mut self,
|
||||
tile_viewbox: &TileViewbox,
|
||||
surfaces: &Surfaces,
|
||||
current_scale: f32,
|
||||
fast_mode: bool,
|
||||
lookup_scale_bits: u32,
|
||||
) {
|
||||
self.list.clear();
|
||||
|
||||
// Generate spiral for the interest area (viewport + margin)
|
||||
@ -279,7 +286,14 @@ impl PendingTiles {
|
||||
|
||||
for tile in spiral {
|
||||
let is_visible = tile_viewbox.visible_rect.contains(&tile);
|
||||
let is_cached = surfaces.has_cached_tile_surface(tile, scale_bits);
|
||||
let is_cached = if fast_mode {
|
||||
// fast_mode reads only 100% zoom cache; tile indices differ across scales,
|
||||
// so decide cacheability by world rect coverage at the lookup scale.
|
||||
let world_rect = super::tiles::get_tile_rect(tile, current_scale);
|
||||
surfaces.world_rect_has_any_tile_at_scale_bits(world_rect, lookup_scale_bits)
|
||||
} else {
|
||||
surfaces.has_cached_tile_surface(tile, lookup_scale_bits)
|
||||
};
|
||||
|
||||
match (is_visible, is_cached) {
|
||||
(true, true) => visible_cached.push(tile),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user