1 /* 2 * Copyright (C) 2016-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "LinearMemoryStream.h" 12 13 #include <deque> 14 #include <vector> 15 16 namespace KODI 17 { 18 namespace RETRO 19 { 20 /*! 21 * \brief Implementation of a linear memory stream using XOR deltas 22 */ 23 class CDeltaPairMemoryStream : public CLinearMemoryStream 24 { 25 public: 26 CDeltaPairMemoryStream() = default; 27 28 ~CDeltaPairMemoryStream() override = default; 29 30 // implementation of IMemoryStream via CLinearMemoryStream 31 void Reset() override; 32 uint64_t PastFramesAvailable() const override; 33 uint64_t RewindFrames(uint64_t frameCount) override; 34 35 protected: 36 // implementation of CLinearMemoryStream 37 void SubmitFrameInternal() override; 38 void CullPastFrames(uint64_t frameCount) override; 39 40 /*! 41 * Rewinding is implemented by applying XOR deltas on the specific parts of 42 * the save state buffer which have changed. In practice, this is very fast 43 * and simple (linear scan) and allows deltas to be compressed down to 1-3% 44 * of original save state size depending on the system. The algorithm runs 45 * on 32 bits at a time for speed. 46 * 47 * Use std::deque here to achieve amortized O(1) on pop/push to front and 48 * back. 49 */ 50 struct DeltaPair 51 { 52 size_t pos; 53 uint32_t delta; 54 }; 55 56 using DeltaPairVector = std::vector<DeltaPair>; 57 58 struct MemoryFrame 59 { 60 DeltaPairVector buffer; 61 uint64_t frameHistoryCount; 62 }; 63 64 std::deque<MemoryFrame> m_rewindBuffer; 65 }; 66 } // namespace RETRO 67 } // namespace KODI 68