Add simple zstd compression

Just a simple default compression is able to shrink savestate file size from ~160MB to ~20MB.
This commit is contained in:
zhupengfei 2020-02-16 23:25:30 +08:00
parent 57efc41973
commit 7d880f94db
No known key found for this signature in database
GPG key ID: DD129E108BD09378
2 changed files with 24 additions and 7 deletions

View file

@ -13,6 +13,7 @@
#include "common/archives.h" #include "common/archives.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/texture.h" #include "common/texture.h"
#include "common/zstd_compression.h"
#include "core/arm/arm_interface.h" #include "core/arm/arm_interface.h"
#ifdef ARCHITECTURE_x86_64 #ifdef ARCHITECTURE_x86_64
#include "core/arm/dynarmic/arm_dynarmic.h" #include "core/arm/dynarmic/arm_dynarmic.h"
@ -116,7 +117,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
case Signal::Load: { case Signal::Load: {
LOG_INFO(Core, "Begin load"); LOG_INFO(Core, "Begin load");
auto stream = std::ifstream("save0.citrasave", std::fstream::binary); auto stream = std::ifstream("save0.citrasave", std::fstream::binary);
System::Load(stream); System::Load(stream, FileUtil::GetSize("save0.citrasave"));
LOG_INFO(Core, "Load completed"); LOG_INFO(Core, "Load completed");
} break; } break;
case Signal::Save: { case Signal::Save: {
@ -464,27 +465,43 @@ void System::serialize(Archive& ar, const unsigned int file_version) {
} }
void System::Save(std::ostream& stream) const { void System::Save(std::ostream& stream) const {
std::ostringstream sstream{std::ios_base::binary};
try { try {
{ {
oarchive oa{stream}; oarchive oa{sstream};
oa&* this; oa&* this;
} }
VideoCore::Save(stream); VideoCore::Save(sstream);
} catch (const std::exception& e) { } catch (const std::exception& e) {
LOG_ERROR(Core, "Error saving: {}", e.what()); LOG_ERROR(Core, "Error saving: {}", e.what());
} }
const std::string& str{sstream.str()};
auto buffer = Common::Compression::CompressDataZSTDDefault(
reinterpret_cast<const u8*>(str.data()), str.size());
stream.write(reinterpret_cast<const char*>(buffer.data()), buffer.size());
} }
void System::Load(std::istream& stream) { void System::Load(std::istream& stream, std::size_t size) {
std::vector<u8> decompressed;
{
std::vector<u8> buffer(size);
stream.read(reinterpret_cast<char*>(buffer.data()), size);
decompressed = Common::Compression::DecompressDataZSTD(buffer);
}
std::istringstream sstream{
std::string{reinterpret_cast<char*>(decompressed.data()), decompressed.size()},
std::ios_base::binary};
decompressed.clear();
try { try {
{ {
iarchive ia{stream}; iarchive ia{sstream};
ia&* this; ia&* this;
} }
VideoCore::Load(stream); VideoCore::Load(sstream);
} catch (const std::exception& e) { } catch (const std::exception& e) {
LOG_ERROR(Core, "Error loading: {}", e.what()); LOG_ERROR(Core, "Error loading: {}", e.what());

View file

@ -278,7 +278,7 @@ public:
void Save(std::ostream& stream) const; void Save(std::ostream& stream) const;
void Load(std::istream& stream); void Load(std::istream& stream, std::size_t size);
private: private:
/** /**