citra-emu
/
citra
Archived
1
0
Fork 0

Serialize core timing

This commit is contained in:
Hamish Milne 2020-01-12 20:01:29 +00:00 committed by zhupengfei
parent 8abc5525be
commit c24ea0f0ee
5 changed files with 54 additions and 3 deletions

3
TODO
View File

@ -1,9 +1,10 @@
☐ Save/load UI
✔ Basic version @done(20-01-03 15:27)
☐ Multiple slots etc.
☐ Add 'force flush all' to Rasterizer interface + impls
☐ Custom texture cache
☐ Review constructor/initialization code
☐ Core timing events
✔ Core timing events @done(20-01-12 15:14)
☐ Serialize codeset with an apploader reference instead
✔ Review base class serialization everywhere @done(20-01-10 23:47)
Make sure that all base/derived relationships are registered

View File

@ -434,6 +434,7 @@ void System::Reset() {
template <class Archive>
void System::serialize(Archive& ar, const unsigned int file_version) {
Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF);
ar&* timing.get();
ar&* cpu_core.get();
ar&* service_manager.get();
ar& GPU::g_regs;

View File

@ -11,6 +11,8 @@
namespace Core {
Timing* Timing::deserializing = nullptr;
// Sort by time, unless the times are the same, in which case sort by the order added to the queue
bool Timing::Event::operator>(const Event& right) const {
return std::tie(time, fifo_order) > std::tie(right.time, right.fifo_order);
@ -26,7 +28,9 @@ TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback ca
auto info = event_types.emplace(name, TimingEventType{});
TimingEventType* event_type = &info.first->second;
event_type->name = &info.first->first;
event_type->callback = callback;
if (callback != nullptr) {
event_type->callback = callback;
}
return event_type;
}
@ -129,7 +133,9 @@ void Timing::Advance() {
LOG_ERROR(Core, "Unknown queued event");
continue;
}
evt.type->callback(evt.userdata, global_timer - evt.time);
if (evt.type->callback != nullptr) {
evt.type->callback(evt.userdata, global_timer - evt.time);
}
}
is_global_timer_sane = false;

View File

@ -23,6 +23,8 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/vector.hpp>
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/threadsafe_queue.h"
@ -190,6 +192,8 @@ public:
s64 GetDowncount() const;
private:
static Timing* deserializing;
struct Event {
s64 time;
u64 fifo_order;
@ -198,6 +202,29 @@ private:
bool operator>(const Event& right) const;
bool operator<(const Event& right) const;
private:
template <class Archive>
void save(Archive& ar, const unsigned int) const {
ar& time;
ar& fifo_order;
ar& userdata;
std::string name = *(type->name);
ar << name;
}
template <class Archive>
void load(Archive& ar, const unsigned int) {
ar& time;
ar& fifo_order;
ar& userdata;
std::string name;
ar >> name;
type = Timing::deserializing->RegisterEvent(name, nullptr);
}
friend class boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
static constexpr int MAX_SLICE_LENGTH = 20000;
@ -229,6 +256,21 @@ private:
// executing the first cycle of each slice to prepare the slice length and downcount for
// that slice.
bool is_global_timer_sane = true;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
// event_types set during initialization of other things
deserializing = this;
MoveEvents();
ar& global_timer;
ar& slice_length;
ar& downcount;
ar& event_queue;
ar& event_fifo_id;
ar& idled_cycles;
deserializing = nullptr;
}
friend class boost::serialization::access;
};
} // namespace Core

View File

@ -172,6 +172,7 @@ private:
ar& ready_queue;
ar& wakeup_callback_table;
ar& thread_list;
SwitchContext(current_thread.get());
}
};