mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 20:48:11 +08:00
Reduce history system's excessive memory usage from storing copies of images each step (#845)
* Limit saved undo history * Do not commit path every mouse move event * Reference count images in history system instead of cloning the image data * Increase history storage step limit to 100 Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
be353878d0
commit
4cda84521f
@@ -583,6 +583,7 @@ impl Document {
|
||||
image_data,
|
||||
mime,
|
||||
} => {
|
||||
let image_data = std::rc::Rc::new(image_data);
|
||||
let layer = Layer::new(LayerDataType::Image(ImageLayer::new(mime, image_data)), transform);
|
||||
|
||||
self.set_layer(&path, layer, insert_index)?;
|
||||
@@ -606,6 +607,7 @@ impl Document {
|
||||
Operation::SetNodeGraphFrameImageData { layer_path, image_data } => {
|
||||
let layer = self.layer_mut(&layer_path).expect("Setting NodeGraphFrame image data for invalid layer");
|
||||
if let LayerDataType::NodeGraphFrame(node_graph_frame) = &mut layer.data {
|
||||
let image_data = std::rc::Rc::new(image_data);
|
||||
node_graph_frame.image_data = Some(crate::layers::nodegraph_layer::ImageData { image_data });
|
||||
} else {
|
||||
panic!("Incorrectly trying to set image data for a layer that is not an NodeGraphFrame layer type");
|
||||
@@ -831,6 +833,7 @@ impl Document {
|
||||
Operation::ImaginateSetImageData { layer_path, image_data } => {
|
||||
let layer = self.layer_mut(&layer_path).expect("Setting Imaginate image data for invalid layer");
|
||||
if let LayerDataType::Imaginate(imaginate) = &mut layer.data {
|
||||
let image_data = std::rc::Rc::new(image_data);
|
||||
imaginate.image_data = Some(ImaginateImageData { image_data });
|
||||
} else {
|
||||
panic!("Incorrectly trying to set image data for a layer that is not an Imaginate layer type");
|
||||
|
||||
@@ -2,20 +2,21 @@
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serializer};
|
||||
|
||||
pub fn as_base64<T, S>(key: &T, serializer: S) -> Result<S::Ok, S::Error>
|
||||
pub fn as_base64<S>(key: &std::rc::Rc<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
T: AsRef<[u8]>,
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&base64::encode(key.as_ref()))
|
||||
serializer.serialize_str(&base64::encode(key.as_slice()))
|
||||
}
|
||||
|
||||
pub fn from_base64<'a, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
||||
pub fn from_base64<'a, D>(deserializer: D) -> Result<std::rc::Rc<Vec<u8>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'a>,
|
||||
{
|
||||
use serde::de::Error;
|
||||
|
||||
String::deserialize(deserializer)
|
||||
.and_then(|string| base64::decode(&string).map_err(|err| Error::custom(err.to_string())))
|
||||
.and_then(|string| base64::decode(string).map_err(|err| Error::custom(err.to_string())))
|
||||
.map(std::rc::Rc::new)
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ use std::fmt::Write;
|
||||
pub struct ImageLayer {
|
||||
pub mime: String,
|
||||
#[serde(serialize_with = "base64_serde::as_base64", deserialize_with = "base64_serde::from_base64")]
|
||||
pub image_data: Vec<u8>,
|
||||
pub image_data: std::rc::Rc<Vec<u8>>,
|
||||
// TODO: Have the browser dispose of this blob URL when this is dropped (like when the layer is deleted)
|
||||
#[serde(skip)]
|
||||
pub blob_url: Option<String>,
|
||||
@@ -75,7 +75,7 @@ impl LayerData for ImageLayer {
|
||||
}
|
||||
|
||||
impl ImageLayer {
|
||||
pub fn new(mime: String, image_data: Vec<u8>) -> Self {
|
||||
pub fn new(mime: String, image_data: std::rc::Rc<Vec<u8>>) -> Self {
|
||||
Self {
|
||||
mime,
|
||||
image_data,
|
||||
|
||||
@@ -53,7 +53,7 @@ pub enum ImaginateStatus {
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
|
||||
pub struct ImaginateImageData {
|
||||
#[serde(serialize_with = "base64_serde::as_base64", deserialize_with = "base64_serde::from_base64")]
|
||||
pub image_data: Vec<u8>,
|
||||
pub image_data: std::rc::Rc<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
|
||||
@@ -29,7 +29,7 @@ pub struct NodeGraphFrameLayer {
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
|
||||
pub struct ImageData {
|
||||
#[serde(serialize_with = "base64_serde::as_base64", deserialize_with = "base64_serde::from_base64")]
|
||||
pub image_data: Vec<u8>,
|
||||
pub image_data: std::rc::Rc<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl LayerData for NodeGraphFrameLayer {
|
||||
|
||||
Reference in New Issue
Block a user