Core: Move rewind state coalescing into mCoreRewindRestore

This commit is contained in:
Vicki Pfau 2024-02-08 17:15:18 -08:00
parent c917a71ef8
commit 49d9b70e6f
4 changed files with 29 additions and 29 deletions

View File

@ -40,7 +40,7 @@ void mCoreRewindContextDeinit(struct mCoreRewindContext*);
struct mCore;
void mCoreRewindAppend(struct mCoreRewindContext*, struct mCore*);
bool mCoreRewindRestore(struct mCoreRewindContext*, struct mCore*);
bool mCoreRewindRestore(struct mCoreRewindContext*, struct mCore*, unsigned count);
CXX_GUARD_END

View File

@ -115,7 +115,7 @@ void _rewindDiff(struct mCoreRewindContext* context) {
context->currentState->unmap(context->currentState, next, size);
}
bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core) {
bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core, unsigned count) {
#ifndef DISABLE_THREADING
if (context->onThread) {
MutexLock(&context->mutex);
@ -129,30 +129,34 @@ bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core)
#endif
return false;
}
--context->size;
mCoreLoadStateNamed(core, context->previousState, SAVESTATE_SAVEDATA | SAVESTATE_RTC);
if (context->current == 0) {
context->current = mCoreRewindPatchesSize(&context->patchMemory);
}
--context->current;
if (context->size) {
struct PatchFast* patch = mCoreRewindPatchesGetPointer(&context->patchMemory, context->current);
size_t size2 = context->previousState->size(context->previousState);
size_t size = context->currentState->size(context->currentState);
if (size2 < size) {
size = size2;
for (; count && context->size; --count, --context->size) {
if (context->current == 0) {
context->current = mCoreRewindPatchesSize(&context->patchMemory);
}
void* current = context->currentState->map(context->currentState, size, MAP_READ);
void* previous = context->previousState->map(context->previousState, size, MAP_WRITE);
patch->d.applyPatch(&patch->d, previous, size, current, size);
context->currentState->unmap(context->currentState, current, size);
context->previousState->unmap(context->previousState, previous, size);
--context->current;
if (context->size > 1) {
struct PatchFast* patch = mCoreRewindPatchesGetPointer(&context->patchMemory, context->current);
size_t size2 = context->previousState->size(context->previousState);
size_t size = context->currentState->size(context->currentState);
if (size2 < size) {
size = size2;
}
void* current = context->currentState->map(context->currentState, size, MAP_READ);
void* previous = context->previousState->map(context->previousState, size, MAP_WRITE);
patch->d.applyPatch(&patch->d, previous, size, current, size);
context->currentState->unmap(context->currentState, current, size);
context->previousState->unmap(context->previousState, previous, size);
}
struct VFile* nextState = context->previousState;
context->previousState = context->currentState;
context->currentState = nextState;
}
struct VFile* nextState = context->previousState;
context->previousState = context->currentState;
context->currentState = nextState;
mCoreLoadStateNamed(core, context->currentState, SAVESTATE_SAVEDATA | SAVESTATE_RTC);
#ifndef DISABLE_THREADING
if (context->onThread) {
MutexUnlock(&context->mutex);

View File

@ -153,7 +153,7 @@ void _frameStarted(void* context) {
return;
}
if (thread->core->opts.rewindEnable && thread->core->opts.rewindBufferCapacity > 0) {
if (!thread->impl->rewinding || !mCoreRewindRestore(&thread->impl->rewind, thread->core)) {
if (!thread->impl->rewinding || !mCoreRewindRestore(&thread->impl->rewind, thread->core, 1)) {
if (thread->impl->rewind.rewindFrameCounter == 0) {
mCoreRewindAppend(&thread->impl->rewind, thread->core);
thread->impl->rewind.rewindFrameCounter = thread->core->opts.rewindBufferInterval;

View File

@ -556,11 +556,7 @@ void CoreController::rewind(int states) {
if (!states) {
states = INT_MAX;
}
for (int i = 0; i < states; ++i) {
if (!mCoreRewindRestore(&m_threadContext.impl->rewind, m_threadContext.core)) {
break;
}
}
mCoreRewindRestore(&m_threadContext.impl->rewind, m_threadContext.core, states);
interrupter.resume();
emit frameAvailable();
emit rewound();