mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
✨ Removed some artifacts when tile rendering
This commit is contained in:
@@ -192,6 +192,7 @@ pub extern "C" fn set_view(zoom: f32, x: f32, y: f32) {
|
|||||||
with_state_mut!(state, {
|
with_state_mut!(state, {
|
||||||
let render_state = state.render_state_mut();
|
let render_state = state.render_state_mut();
|
||||||
render_state.viewbox.set_all(zoom, x, y);
|
render_state.viewbox.set_all(zoom, x, y);
|
||||||
|
state.render_state.cancel_animation_frame();
|
||||||
state.render_from_cache();
|
state.render_from_cache();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1515,6 +1515,8 @@ impl RenderState {
|
|||||||
}
|
}
|
||||||
self.render_in_progress = false;
|
self.render_in_progress = false;
|
||||||
|
|
||||||
|
self.surfaces.gc();
|
||||||
|
|
||||||
// Cache target surface in a texture
|
// Cache target surface in a texture
|
||||||
self.cached_viewbox = self.viewbox;
|
self.cached_viewbox = self.viewbox;
|
||||||
self.cached_target_snapshot = Some(self.surfaces.snapshot(SurfaceId::Cache));
|
self.cached_target_snapshot = Some(self.surfaces.snapshot(SurfaceId::Cache));
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use skia_safe::{self as skia, IRect, Paint, RRect};
|
|||||||
use super::{gpu_state::GpuState, tiles::Tile, tiles::TileViewbox, tiles::TILE_SIZE};
|
use super::{gpu_state::GpuState, tiles::Tile, tiles::TileViewbox, tiles::TILE_SIZE};
|
||||||
|
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
const TEXTURES_CACHE_CAPACITY: usize = 512;
|
const TEXTURES_CACHE_CAPACITY: usize = 512;
|
||||||
const TEXTURES_BATCH_DELETE: usize = 32;
|
const TEXTURES_BATCH_DELETE: usize = 32;
|
||||||
@@ -322,17 +322,12 @@ impl Surfaces {
|
|||||||
self.tiles.has(tile)
|
self.tiles.has(tile)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_cached_tile_surface(
|
pub fn remove_cached_tile_surface(&mut self, tile: Tile, rect: skia::Rect, color: skia::Color) {
|
||||||
&mut self,
|
|
||||||
tile: Tile,
|
|
||||||
rect: skia::Rect,
|
|
||||||
color: skia::Color,
|
|
||||||
) -> bool {
|
|
||||||
// Clear the specific tile area in the cache surface with color
|
// Clear the specific tile area in the cache surface with color
|
||||||
let mut paint = skia::Paint::default();
|
let mut paint = skia::Paint::default();
|
||||||
paint.set_color(color);
|
paint.set_color(color);
|
||||||
self.cache.canvas().draw_rect(rect, &paint);
|
self.cache.canvas().draw_rect(rect, &paint);
|
||||||
self.tiles.remove(tile)
|
self.tiles.remove(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_cached_tile_surface(&mut self, tile: Tile, rect: skia::Rect, color: skia::Color) {
|
pub fn draw_cached_tile_surface(&mut self, tile: Tile, rect: skia::Rect, color: skia::Color) {
|
||||||
@@ -352,24 +347,50 @@ impl Surfaces {
|
|||||||
self.tiles.clear();
|
self.tiles.clear();
|
||||||
self.cache.canvas().clear(color);
|
self.cache.canvas().clear(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gc(&mut self) {
|
||||||
|
self.tiles.gc();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TileTextureCache {
|
pub struct TileTextureCache {
|
||||||
grid: HashMap<Tile, skia::Image>,
|
grid: HashMap<Tile, skia::Image>,
|
||||||
|
removed: HashSet<Tile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TileTextureCache {
|
impl TileTextureCache {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
grid: HashMap::new(),
|
grid: HashMap::default(),
|
||||||
|
removed: HashSet::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has(&self, tile: Tile) -> bool {
|
pub fn has(&self, tile: Tile) -> bool {
|
||||||
self.grid.contains_key(&tile)
|
self.grid.contains_key(&tile) && !self.removed.contains(&tile)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_list(&mut self, marked: Vec<Tile>) {
|
fn gc(&mut self) {
|
||||||
|
// Make a real remove
|
||||||
|
for tile in self.removed.iter() {
|
||||||
|
self.grid.remove(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn free_tiles(&mut self, tile_viewbox: &TileViewbox) {
|
||||||
|
let marked: Vec<_> = self
|
||||||
|
.grid
|
||||||
|
.iter_mut()
|
||||||
|
.filter_map(|(tile, _)| {
|
||||||
|
if !tile_viewbox.is_visible(tile) {
|
||||||
|
Some(*tile)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.take(TEXTURES_BATCH_DELETE)
|
||||||
|
.collect();
|
||||||
|
|
||||||
for tile in marked.iter() {
|
for tile in marked.iter() {
|
||||||
self.grid.remove(tile);
|
self.grid.remove(tile);
|
||||||
}
|
}
|
||||||
@@ -377,21 +398,19 @@ impl TileTextureCache {
|
|||||||
|
|
||||||
pub fn add(&mut self, tile_viewbox: &TileViewbox, tile: &Tile, image: skia::Image) {
|
pub fn add(&mut self, tile_viewbox: &TileViewbox, tile: &Tile, image: skia::Image) {
|
||||||
if self.grid.len() > TEXTURES_CACHE_CAPACITY {
|
if self.grid.len() > TEXTURES_CACHE_CAPACITY {
|
||||||
let marked: Vec<_> = self
|
// First we try to remove the obsolete tiles
|
||||||
.grid
|
self.gc();
|
||||||
.iter_mut()
|
|
||||||
.filter_map(|(tile, _)| {
|
|
||||||
if !tile_viewbox.is_visible(tile) {
|
|
||||||
Some(*tile)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.take(TEXTURES_BATCH_DELETE)
|
|
||||||
.collect();
|
|
||||||
self.remove_list(marked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.grid.len() > TEXTURES_CACHE_CAPACITY {
|
||||||
|
self.free_tiles(tile_viewbox);
|
||||||
|
}
|
||||||
|
|
||||||
self.grid.insert(*tile, image);
|
self.grid.insert(*tile, image);
|
||||||
|
|
||||||
|
if self.removed.contains(tile) {
|
||||||
|
self.removed.remove(tile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&mut self, tile: Tile) -> Result<&mut skia::Image, String> {
|
pub fn get(&mut self, tile: Tile) -> Result<&mut skia::Image, String> {
|
||||||
@@ -399,15 +418,13 @@ impl TileTextureCache {
|
|||||||
Ok(image)
|
Ok(image)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, tile: Tile) -> bool {
|
pub fn remove(&mut self, tile: Tile) {
|
||||||
if !self.grid.contains_key(&tile) {
|
self.removed.insert(tile);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
self.grid.remove(&tile);
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.grid.clear();
|
for k in self.grid.keys() {
|
||||||
|
self.removed.insert(*k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user