rutabaga_gfx: use serde for snapshots

... to avoid re-inventing the wheel when supporting snapshotting
more of rutabaga in upcoming changes.

Bug: b/369615058
Test: cvd start --enable_virtiofs=false
Test: cvd snapshot_take --snapshot_path=/tmp/snapshot1
Test: cvd create --snapshot_path=/tmp/snapshot1
Change-Id: Ibf73ac103e4796f2e70a01991f4a06046c01d08e
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5917179
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: Jason Macnak <natsu@google.com>
This commit is contained in:
Jason Macnak 2024-10-07 15:28:19 -07:00 committed by crosvm LUCI
parent fc8a9dd071
commit 9148e0136f
4 changed files with 11 additions and 59 deletions

2
Cargo.lock generated
View file

@ -2594,6 +2594,8 @@ dependencies = [
"nix 0.28.0",
"pkg-config",
"remain",
"serde",
"serde_json",
"thiserror",
"winapi",
"zerocopy",

View file

@ -20,6 +20,8 @@ x = []
cfg-if = "1.0.0"
libc = "0.2.116"
remain = "0.2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "1.0.23"
zerocopy = { version = "0.7", features = ["derive"] }

View file

@ -416,7 +416,7 @@ impl Rutabaga {
.collect::<RutabagaResult<_>>()?,
};
return snapshot.serialize_to(w).map_err(RutabagaError::IoError);
serde_json::to_writer(w, &snapshot).map_err(|e| RutabagaError::IoError(e.into()))
} else {
Err(RutabagaError::Unsupported)
}
@ -452,7 +452,8 @@ impl Rutabaga {
component.restore(directory)
} else if self.default_component == RutabagaComponentType::Rutabaga2D {
let snapshot = RutabagaSnapshot::deserialize_from(r).map_err(RutabagaError::IoError)?;
let snapshot: RutabagaSnapshot =
serde_json::from_reader(r).map_err(|e| RutabagaError::IoError(e.into()))?;
self.resources = snapshot
.resources

View file

@ -3,71 +3,18 @@
// found in the LICENSE file.
use std::collections::BTreeMap;
use std::io::Read;
use std::io::Write;
use zerocopy::AsBytes;
use zerocopy::FromBytes;
use serde::Deserialize;
use serde::Serialize;
#[derive(Serialize, Deserialize)]
pub struct RutabagaSnapshot {
pub resources: BTreeMap<u32, RutabagaResourceSnapshot>,
}
#[derive(Serialize, Deserialize)]
pub struct RutabagaResourceSnapshot {
pub resource_id: u32,
pub width: u32,
pub height: u32,
}
impl RutabagaSnapshot {
// To avoid adding a build dependency, we use a custom serialization format. It is an internal
// detail, doesn't need to support host migration (e.g. we don't need to care about endianess
// or integer sizes), and isn't expected to be stable across releases.
pub fn serialize_to(&self, w: &mut impl Write) -> std::io::Result<()> {
fn write(w: &mut impl Write, v: impl AsBytes) -> std::io::Result<()> {
w.write_all(v.as_bytes())
}
write(w, self.resources.len())?;
for (id, resource) in self.resources.iter() {
assert_eq!(*id, resource.resource_id);
write(w, resource.resource_id)?;
write(w, resource.width)?;
write(w, resource.height)?;
}
Ok(())
}
pub fn deserialize_from(r: &mut impl Read) -> std::io::Result<Self> {
fn read<T: AsBytes + FromBytes + Default>(r: &mut impl Read) -> std::io::Result<T> {
let mut v: T = Default::default();
r.read_exact(v.as_bytes_mut())?;
Ok(v)
}
let num_resources: usize = read::<usize>(r)?;
let mut resources = BTreeMap::new();
for _ in 0..num_resources {
let resource_id = read(r)?;
let width = read(r)?;
let height = read(r)?;
resources.insert(
resource_id,
RutabagaResourceSnapshot {
resource_id,
width,
height,
},
);
}
// Verify we have consumed the all the input by checking for EOF.
let mut buf = [0u8];
if r.read(&mut buf)? != 0 {
return Err(std::io::ErrorKind::InvalidData.into());
}
Ok(RutabagaSnapshot { resources })
}
}