mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #20165 from hrydgard/reintroduce-and-fix-cache-in-ram
Reintroduce and fix feature checks for "Cache full ISO in RAM"
This commit is contained in:
commit
a4af129983
17 changed files with 405 additions and 1 deletions
|
@ -2361,6 +2361,8 @@ add_library(${CoreLibName} ${CoreLinkType}
|
||||||
Core/FileLoaders/HTTPFileLoader.h
|
Core/FileLoaders/HTTPFileLoader.h
|
||||||
Core/FileLoaders/LocalFileLoader.cpp
|
Core/FileLoaders/LocalFileLoader.cpp
|
||||||
Core/FileLoaders/LocalFileLoader.h
|
Core/FileLoaders/LocalFileLoader.h
|
||||||
|
Core/FileLoaders/RamCachingFileLoader.cpp
|
||||||
|
Core/FileLoaders/RamCachingFileLoader.h
|
||||||
Core/FileLoaders/RetryingFileLoader.cpp
|
Core/FileLoaders/RetryingFileLoader.cpp
|
||||||
Core/FileLoaders/RetryingFileLoader.h
|
Core/FileLoaders/RetryingFileLoader.h
|
||||||
Core/MIPS/MIPS.cpp
|
Core/MIPS/MIPS.cpp
|
||||||
|
|
|
@ -219,6 +219,8 @@ enum SystemProperty {
|
||||||
|
|
||||||
SYSPROP_CAN_READ_BATTERY_PERCENTAGE,
|
SYSPROP_CAN_READ_BATTERY_PERCENTAGE,
|
||||||
SYSPROP_BATTERY_PERCENTAGE,
|
SYSPROP_BATTERY_PERCENTAGE,
|
||||||
|
|
||||||
|
SYSPROP_ENOUGH_RAM_FOR_FULL_ISO,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SystemNotification {
|
enum class SystemNotification {
|
||||||
|
|
|
@ -280,6 +280,7 @@ static const ConfigSetting generalSettings[] = {
|
||||||
// "default" means let emulator decide, "" means disable.
|
// "default" means let emulator decide, "" means disable.
|
||||||
ConfigSetting("ReportingHost", &g_Config.sReportHost, "default", CfgFlag::DEFAULT),
|
ConfigSetting("ReportingHost", &g_Config.sReportHost, "default", CfgFlag::DEFAULT),
|
||||||
ConfigSetting("AutoSaveSymbolMap", &g_Config.bAutoSaveSymbolMap, false, CfgFlag::PER_GAME),
|
ConfigSetting("AutoSaveSymbolMap", &g_Config.bAutoSaveSymbolMap, false, CfgFlag::PER_GAME),
|
||||||
|
ConfigSetting("CacheFullIsoInRam", &g_Config.bCacheFullIsoInRam, false, CfgFlag::PER_GAME),
|
||||||
ConfigSetting("RemoteISOPort", &g_Config.iRemoteISOPort, 0, CfgFlag::DEFAULT),
|
ConfigSetting("RemoteISOPort", &g_Config.iRemoteISOPort, 0, CfgFlag::DEFAULT),
|
||||||
ConfigSetting("LastRemoteISOServer", &g_Config.sLastRemoteISOServer, "", CfgFlag::DEFAULT),
|
ConfigSetting("LastRemoteISOServer", &g_Config.sLastRemoteISOServer, "", CfgFlag::DEFAULT),
|
||||||
ConfigSetting("LastRemoteISOPort", &g_Config.iLastRemoteISOPort, 0, CfgFlag::DEFAULT),
|
ConfigSetting("LastRemoteISOPort", &g_Config.iLastRemoteISOPort, 0, CfgFlag::DEFAULT),
|
||||||
|
|
|
@ -122,6 +122,7 @@ public:
|
||||||
int iIOTimingMethod;
|
int iIOTimingMethod;
|
||||||
int iLockedCPUSpeed;
|
int iLockedCPUSpeed;
|
||||||
bool bAutoSaveSymbolMap;
|
bool bAutoSaveSymbolMap;
|
||||||
|
bool bCacheFullIsoInRam;
|
||||||
int iRemoteISOPort;
|
int iRemoteISOPort;
|
||||||
std::string sLastRemoteISOServer;
|
std::string sLastRemoteISOServer;
|
||||||
int iLastRemoteISOPort;
|
int iLastRemoteISOPort;
|
||||||
|
|
|
@ -667,6 +667,7 @@
|
||||||
<ClCompile Include="FileLoaders\DiskCachingFileLoader.cpp" />
|
<ClCompile Include="FileLoaders\DiskCachingFileLoader.cpp" />
|
||||||
<ClCompile Include="FileLoaders\HTTPFileLoader.cpp" />
|
<ClCompile Include="FileLoaders\HTTPFileLoader.cpp" />
|
||||||
<ClCompile Include="FileLoaders\LocalFileLoader.cpp" />
|
<ClCompile Include="FileLoaders\LocalFileLoader.cpp" />
|
||||||
|
<ClCompile Include="FileLoaders\RamCachingFileLoader.cpp" />
|
||||||
<ClCompile Include="FileLoaders\RetryingFileLoader.cpp" />
|
<ClCompile Include="FileLoaders\RetryingFileLoader.cpp" />
|
||||||
<ClCompile Include="FileSystems\BlockDevices.cpp" />
|
<ClCompile Include="FileSystems\BlockDevices.cpp" />
|
||||||
<ClCompile Include="FileSystems\DirectoryFileSystem.cpp" />
|
<ClCompile Include="FileSystems\DirectoryFileSystem.cpp" />
|
||||||
|
@ -1255,6 +1256,7 @@
|
||||||
<ClInclude Include="FileLoaders\DiskCachingFileLoader.h" />
|
<ClInclude Include="FileLoaders\DiskCachingFileLoader.h" />
|
||||||
<ClInclude Include="FileLoaders\HTTPFileLoader.h" />
|
<ClInclude Include="FileLoaders\HTTPFileLoader.h" />
|
||||||
<ClInclude Include="FileLoaders\LocalFileLoader.h" />
|
<ClInclude Include="FileLoaders\LocalFileLoader.h" />
|
||||||
|
<ClInclude Include="FileLoaders\RamCachingFileLoader.h" />
|
||||||
<ClInclude Include="FileLoaders\RetryingFileLoader.h" />
|
<ClInclude Include="FileLoaders\RetryingFileLoader.h" />
|
||||||
<ClInclude Include="FileSystems\BlockDevices.h" />
|
<ClInclude Include="FileSystems\BlockDevices.h" />
|
||||||
<ClInclude Include="FileSystems\DirectoryFileSystem.h" />
|
<ClInclude Include="FileSystems\DirectoryFileSystem.h" />
|
||||||
|
|
|
@ -661,6 +661,9 @@
|
||||||
<ClCompile Include="HW\SasReverb.cpp">
|
<ClCompile Include="HW\SasReverb.cpp">
|
||||||
<Filter>HW</Filter>
|
<Filter>HW</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="FileLoaders\RamCachingFileLoader.cpp">
|
||||||
|
<Filter>FileLoaders</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="MIPS\IR\IRCompALU.cpp">
|
<ClCompile Include="MIPS\IR\IRCompALU.cpp">
|
||||||
<Filter>MIPS\IR</Filter>
|
<Filter>MIPS\IR</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -1887,6 +1890,9 @@
|
||||||
<ClInclude Include="HW\SasReverb.h">
|
<ClInclude Include="HW\SasReverb.h">
|
||||||
<Filter>HW</Filter>
|
<Filter>HW</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FileLoaders\RamCachingFileLoader.h">
|
||||||
|
<Filter>FileLoaders</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="MIPS\IR\IRJit.h">
|
<ClInclude Include="MIPS\IR\IRJit.h">
|
||||||
<Filter>MIPS\IR</Filter>
|
<Filter>MIPS\IR</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
272
Core/FileLoaders/RamCachingFileLoader.cpp
Normal file
272
Core/FileLoaders/RamCachingFileLoader.cpp
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
// Copyright (c) 2015- PPSSPP Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0 or later versions.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official git repository and contact information can be found at
|
||||||
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <thread>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "Common/Thread/ThreadUtil.h"
|
||||||
|
#include "Common/TimeUtil.h"
|
||||||
|
#include "Common/Log.h"
|
||||||
|
#include "Core/FileLoaders/RamCachingFileLoader.h"
|
||||||
|
|
||||||
|
// Takes ownership of backend.
|
||||||
|
RamCachingFileLoader::RamCachingFileLoader(FileLoader *backend)
|
||||||
|
: ProxiedFileLoader(backend) {
|
||||||
|
filesize_ = backend->FileSize();
|
||||||
|
if (filesize_ > 0) {
|
||||||
|
InitCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RamCachingFileLoader::~RamCachingFileLoader() {
|
||||||
|
if (filesize_ > 0) {
|
||||||
|
ShutdownCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RamCachingFileLoader::Exists() {
|
||||||
|
if (exists_ == -1) {
|
||||||
|
exists_ = ProxiedFileLoader::Exists() ? 1 : 0;
|
||||||
|
}
|
||||||
|
return exists_ == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RamCachingFileLoader::ExistsFast() {
|
||||||
|
if (exists_ == -1) {
|
||||||
|
return ProxiedFileLoader::ExistsFast();
|
||||||
|
}
|
||||||
|
return exists_ == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RamCachingFileLoader::IsDirectory() {
|
||||||
|
if (isDirectory_ == -1) {
|
||||||
|
isDirectory_ = ProxiedFileLoader::IsDirectory() ? 1 : 0;
|
||||||
|
}
|
||||||
|
return isDirectory_ == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 RamCachingFileLoader::FileSize() {
|
||||||
|
return filesize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) {
|
||||||
|
size_t readSize = 0;
|
||||||
|
if (cache_ == nullptr || (flags & Flags::HINT_UNCACHED) != 0) {
|
||||||
|
readSize = backend_->ReadAt(absolutePos, bytes, data, flags);
|
||||||
|
} else {
|
||||||
|
readSize = ReadFromCache(absolutePos, bytes, data);
|
||||||
|
// While in case the cache size is too small for the entire read.
|
||||||
|
while (readSize < bytes) {
|
||||||
|
SaveIntoCache(absolutePos + readSize, bytes - readSize, flags);
|
||||||
|
size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
||||||
|
readSize += bytesFromCache;
|
||||||
|
if (bytesFromCache == 0) {
|
||||||
|
// We can't read any more.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StartReadAhead(absolutePos + readSize);
|
||||||
|
}
|
||||||
|
return readSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RamCachingFileLoader::InitCache() {
|
||||||
|
std::lock_guard<std::mutex> guard(blocksMutex_);
|
||||||
|
u32 blockCount = (u32)((filesize_ + BLOCK_SIZE - 1) >> BLOCK_SHIFT);
|
||||||
|
// Overallocate for the last block.
|
||||||
|
cache_ = (u8 *)malloc((size_t)blockCount << BLOCK_SHIFT);
|
||||||
|
if (cache_ == nullptr) {
|
||||||
|
ERROR_LOG(Log::IO, "Failed to allocate cache for Cache full ISO in RAM! Will fall back to regular reads.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
aheadRemaining_ = blockCount;
|
||||||
|
blocks_.resize(blockCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RamCachingFileLoader::ShutdownCache() {
|
||||||
|
Cancel();
|
||||||
|
|
||||||
|
// We can't delete while the thread is running, so have to wait.
|
||||||
|
// This should only happen from the menu.
|
||||||
|
while (aheadThreadRunning_) {
|
||||||
|
sleep_ms(1, "shutdown-ram-cache-poll");
|
||||||
|
}
|
||||||
|
if (aheadThread_.joinable())
|
||||||
|
aheadThread_.join();
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> guard(blocksMutex_);
|
||||||
|
blocks_.clear();
|
||||||
|
if (cache_ != nullptr) {
|
||||||
|
free(cache_);
|
||||||
|
cache_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RamCachingFileLoader::Cancel() {
|
||||||
|
if (aheadThreadRunning_) {
|
||||||
|
std::lock_guard<std::mutex> guard(blocksMutex_);
|
||||||
|
aheadCancel_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProxiedFileLoader::Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t RamCachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) {
|
||||||
|
s64 cacheStartPos = pos >> BLOCK_SHIFT;
|
||||||
|
s64 cacheEndPos = (pos + bytes - 1) >> BLOCK_SHIFT;
|
||||||
|
if ((size_t)cacheEndPos >= blocks_.size()) {
|
||||||
|
cacheEndPos = blocks_.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t readSize = 0;
|
||||||
|
size_t offset = (size_t)(pos - (cacheStartPos << BLOCK_SHIFT));
|
||||||
|
u8 *p = (u8 *)data;
|
||||||
|
|
||||||
|
// Clamp bytes to what's actually available.
|
||||||
|
if (pos + (s64)bytes > filesize_) {
|
||||||
|
// Should've been caught above, but just in case.
|
||||||
|
if (pos >= filesize_) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bytes = (size_t)(filesize_ - pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> guard(blocksMutex_);
|
||||||
|
for (s64 i = cacheStartPos; i <= cacheEndPos; ++i) {
|
||||||
|
if (blocks_[(size_t)i] == 0) {
|
||||||
|
return readSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t toRead = std::min(bytes - readSize, (size_t)BLOCK_SIZE - offset);
|
||||||
|
s64 cachePos = (i << BLOCK_SHIFT) + offset;
|
||||||
|
memcpy(p + readSize, &cache_[cachePos], toRead);
|
||||||
|
readSize += toRead;
|
||||||
|
|
||||||
|
// Don't need an offset after the first read.
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
return readSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RamCachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, Flags flags) {
|
||||||
|
s64 cacheStartPos = pos >> BLOCK_SHIFT;
|
||||||
|
s64 cacheEndPos = (pos + bytes - 1) >> BLOCK_SHIFT;
|
||||||
|
if ((size_t)cacheEndPos >= blocks_.size()) {
|
||||||
|
cacheEndPos = blocks_.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t blocksToRead = 0;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(blocksMutex_);
|
||||||
|
for (s64 i = cacheStartPos; i <= cacheEndPos; ++i) {
|
||||||
|
if (blocks_[(size_t)i] == 0) {
|
||||||
|
++blocksToRead;
|
||||||
|
if (blocksToRead >= MAX_BLOCKS_PER_READ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Shouldn't we break as soon as we see a 1?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 cacheFilePos = cacheStartPos << BLOCK_SHIFT;
|
||||||
|
size_t bytesRead = backend_->ReadAt(cacheFilePos, blocksToRead << BLOCK_SHIFT, &cache_[cacheFilePos], flags);
|
||||||
|
|
||||||
|
// In case there was an error, let's not mark blocks that failed to read as read.
|
||||||
|
u32 blocksActuallyRead = (u32)((bytesRead + BLOCK_SIZE - 1) >> BLOCK_SHIFT);
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(blocksMutex_);
|
||||||
|
|
||||||
|
// In case they were simultaneously read.
|
||||||
|
u32 blocksRead = 0;
|
||||||
|
for (size_t i = 0; i < blocksActuallyRead; ++i) {
|
||||||
|
if (blocks_[(size_t)cacheStartPos + i] == 0) {
|
||||||
|
blocks_[(size_t)cacheStartPos + i] = 1;
|
||||||
|
++blocksRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aheadRemaining_ != 0) {
|
||||||
|
aheadRemaining_ -= blocksRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RamCachingFileLoader::StartReadAhead(s64 pos) {
|
||||||
|
if (cache_ == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> guard(blocksMutex_);
|
||||||
|
aheadPos_ = pos;
|
||||||
|
if (aheadThreadRunning_) {
|
||||||
|
// Already going.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aheadThreadRunning_ = true;
|
||||||
|
aheadCancel_ = false;
|
||||||
|
if (aheadThread_.joinable())
|
||||||
|
aheadThread_.join();
|
||||||
|
aheadThread_ = std::thread([this] {
|
||||||
|
SetCurrentThreadName("FileLoaderReadAhead");
|
||||||
|
|
||||||
|
AndroidJNIThreadContext jniContext;
|
||||||
|
|
||||||
|
while (aheadRemaining_ != 0 && !aheadCancel_) {
|
||||||
|
// Where should we look?
|
||||||
|
const u32 cacheStartPos = NextAheadBlock();
|
||||||
|
if (cacheStartPos == 0xFFFFFFFF) {
|
||||||
|
// Must be full.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
u32 cacheEndPos = cacheStartPos + BLOCK_READAHEAD - 1;
|
||||||
|
if (cacheEndPos >= blocks_.size()) {
|
||||||
|
cacheEndPos = (u32)blocks_.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = cacheStartPos; i <= cacheEndPos; ++i) {
|
||||||
|
if (blocks_[i] == 0) {
|
||||||
|
SaveIntoCache((u64)i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD, Flags::NONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aheadThreadRunning_ = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 RamCachingFileLoader::NextAheadBlock() {
|
||||||
|
std::lock_guard<std::mutex> guard(blocksMutex_);
|
||||||
|
|
||||||
|
// If we had an aheadPos_ set, start reading from there and go forward.
|
||||||
|
u32 startFrom = (u32)(aheadPos_ >> BLOCK_SHIFT);
|
||||||
|
// But next time, start from the beginning again.
|
||||||
|
aheadPos_ = 0;
|
||||||
|
|
||||||
|
for (u32 i = startFrom; i < blocks_.size(); ++i) {
|
||||||
|
if (blocks_[i] == 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
72
Core/FileLoaders/RamCachingFileLoader.h
Normal file
72
Core/FileLoaders/RamCachingFileLoader.h
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright (c) 2015- PPSSPP Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0 or later versions.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official git repository and contact information can be found at
|
||||||
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Core/Loaders.h"
|
||||||
|
|
||||||
|
class RamCachingFileLoader : public ProxiedFileLoader {
|
||||||
|
public:
|
||||||
|
RamCachingFileLoader(FileLoader *backend);
|
||||||
|
~RamCachingFileLoader();
|
||||||
|
|
||||||
|
bool Exists() override;
|
||||||
|
bool ExistsFast() override;
|
||||||
|
bool IsDirectory() override;
|
||||||
|
s64 FileSize() override;
|
||||||
|
|
||||||
|
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||||
|
return ReadAt(absolutePos, bytes * count, data, flags) / bytes;
|
||||||
|
}
|
||||||
|
size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override;
|
||||||
|
|
||||||
|
void Cancel() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitCache();
|
||||||
|
void ShutdownCache();
|
||||||
|
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
||||||
|
// Guaranteed to read at least one block into the cache.
|
||||||
|
void SaveIntoCache(s64 pos, size_t bytes, Flags flags);
|
||||||
|
void StartReadAhead(s64 pos);
|
||||||
|
u32 NextAheadBlock();
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BLOCK_SIZE = 65536,
|
||||||
|
BLOCK_SHIFT = 16,
|
||||||
|
MAX_BLOCKS_PER_READ = 16,
|
||||||
|
BLOCK_READAHEAD = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
s64 filesize_ = 0;
|
||||||
|
u8 *cache_ = nullptr;
|
||||||
|
int exists_ = -1;
|
||||||
|
int isDirectory_ = -1;
|
||||||
|
|
||||||
|
std::vector<u8> blocks_;
|
||||||
|
std::mutex blocksMutex_;
|
||||||
|
u32 aheadRemaining_;
|
||||||
|
s64 aheadPos_;
|
||||||
|
std::thread aheadThread_;
|
||||||
|
bool aheadThreadRunning_ = false;
|
||||||
|
bool aheadCancel_ = false;
|
||||||
|
};
|
|
@ -57,6 +57,7 @@
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/CoreTiming.h"
|
#include "Core/CoreTiming.h"
|
||||||
#include "Core/CoreParameter.h"
|
#include "Core/CoreParameter.h"
|
||||||
|
#include "Core/FileLoaders/RamCachingFileLoader.h"
|
||||||
#include "Core/FileSystems/MetaFileSystem.h"
|
#include "Core/FileSystems/MetaFileSystem.h"
|
||||||
#include "Core/Loaders.h"
|
#include "Core/Loaders.h"
|
||||||
#include "Core/PSPLoaders.h"
|
#include "Core/PSPLoaders.h"
|
||||||
|
@ -424,6 +425,20 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
|
||||||
IdentifiedFileType type = Identify_File(loadedFile, &g_CoreParameter.errorString);
|
IdentifiedFileType type = Identify_File(loadedFile, &g_CoreParameter.errorString);
|
||||||
g_CoreParameter.fileType = type;
|
g_CoreParameter.fileType = type;
|
||||||
|
|
||||||
|
if (System_GetPropertyBool(SYSPROP_ENOUGH_RAM_FOR_FULL_ISO)) {
|
||||||
|
if (g_Config.bCacheFullIsoInRam) {
|
||||||
|
switch (g_CoreParameter.fileType) {
|
||||||
|
case IdentifiedFileType::PSP_ISO:
|
||||||
|
case IdentifiedFileType::PSP_ISO_NP:
|
||||||
|
loadedFile = new RamCachingFileLoader(loadedFile);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
INFO_LOG(Log::System, "RAM caching is on, but file is not an ISO, so ignoring");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (g_Config.bAchievementsEnable) {
|
if (g_Config.bAchievementsEnable) {
|
||||||
// Need to re-identify after ResolveFileLoaderTarget - although in practice probably not,
|
// Need to re-identify after ResolveFileLoaderTarget - although in practice probably not,
|
||||||
// but also, re-using the identification would require some plumbing, to be done later.
|
// but also, re-using the identification would require some plumbing, to be done later.
|
||||||
|
|
|
@ -625,7 +625,13 @@ bool System_GetPropertyBool(SystemProperty prop) {
|
||||||
#endif
|
#endif
|
||||||
case SYSPROP_CAN_READ_BATTERY_PERCENTAGE:
|
case SYSPROP_CAN_READ_BATTERY_PERCENTAGE:
|
||||||
return true;
|
return true;
|
||||||
default:
|
case SYSPROP_ENOUGH_RAM_FOR_FULL_ISO:
|
||||||
|
#if defined(MOBILE_DEVICE)
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1341,6 +1341,10 @@ void GameSettingsScreen::CreateSystemSettings(UI::ViewGroup *systemSettings) {
|
||||||
if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD))
|
if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD))
|
||||||
systemSettings->Add(new CheckBox(&g_Config.bBypassOSKWithKeyboard, sy->T("Use system native keyboard")));
|
systemSettings->Add(new CheckBox(&g_Config.bBypassOSKWithKeyboard, sy->T("Use system native keyboard")));
|
||||||
|
|
||||||
|
if (System_GetPropertyBool(SYSPROP_ENOUGH_RAM_FOR_FULL_ISO)) {
|
||||||
|
systemSettings->Add(new CheckBox(&g_Config.bCacheFullIsoInRam, sy->T("Cache ISO in RAM", "Cache full ISO in RAM")))->SetEnabled(!PSP_IsInited());
|
||||||
|
}
|
||||||
|
|
||||||
systemSettings->Add(new CheckBox(&g_Config.bCheckForNewVersion, sy->T("VersionCheck", "Check for new versions of PPSSPP")));
|
systemSettings->Add(new CheckBox(&g_Config.bCheckForNewVersion, sy->T("VersionCheck", "Check for new versions of PPSSPP")));
|
||||||
systemSettings->Add(new CheckBox(&g_Config.bScreenshotsAsPNG, sy->T("Screenshots as PNG")));
|
systemSettings->Add(new CheckBox(&g_Config.bScreenshotsAsPNG, sy->T("Screenshots as PNG")));
|
||||||
static const char *screenshotModeChoices[] = { "Final processed image", "Raw game image" };
|
static const char *screenshotModeChoices[] = { "Final processed image", "Raw game image" };
|
||||||
|
|
|
@ -163,6 +163,7 @@
|
||||||
<ClInclude Include="..\..\Core\FileLoaders\DiskCachingFileLoader.h" />
|
<ClInclude Include="..\..\Core\FileLoaders\DiskCachingFileLoader.h" />
|
||||||
<ClInclude Include="..\..\Core\FileLoaders\HTTPFileLoader.h" />
|
<ClInclude Include="..\..\Core\FileLoaders\HTTPFileLoader.h" />
|
||||||
<ClInclude Include="..\..\Core\FileLoaders\LocalFileLoader.h" />
|
<ClInclude Include="..\..\Core\FileLoaders\LocalFileLoader.h" />
|
||||||
|
<ClInclude Include="..\..\Core\FileLoaders\RamCachingFileLoader.h" />
|
||||||
<ClInclude Include="..\..\Core\FileLoaders\RetryingFileLoader.h" />
|
<ClInclude Include="..\..\Core\FileLoaders\RetryingFileLoader.h" />
|
||||||
<ClInclude Include="..\..\Core\FileSystems\BlobFileSystem.h" />
|
<ClInclude Include="..\..\Core\FileSystems\BlobFileSystem.h" />
|
||||||
<ClInclude Include="..\..\Core\FileSystems\BlockDevices.h" />
|
<ClInclude Include="..\..\Core\FileSystems\BlockDevices.h" />
|
||||||
|
@ -425,6 +426,7 @@
|
||||||
<ClCompile Include="..\..\Core\FileLoaders\DiskCachingFileLoader.cpp" />
|
<ClCompile Include="..\..\Core\FileLoaders\DiskCachingFileLoader.cpp" />
|
||||||
<ClCompile Include="..\..\Core\FileLoaders\HTTPFileLoader.cpp" />
|
<ClCompile Include="..\..\Core\FileLoaders\HTTPFileLoader.cpp" />
|
||||||
<ClCompile Include="..\..\Core\FileLoaders\LocalFileLoader.cpp" />
|
<ClCompile Include="..\..\Core\FileLoaders\LocalFileLoader.cpp" />
|
||||||
|
<ClCompile Include="..\..\Core\FileLoaders\RamCachingFileLoader.cpp" />
|
||||||
<ClCompile Include="..\..\Core\FileLoaders\RetryingFileLoader.cpp" />
|
<ClCompile Include="..\..\Core\FileLoaders\RetryingFileLoader.cpp" />
|
||||||
<ClCompile Include="..\..\Core\FileSystems\BlobFileSystem.cpp" />
|
<ClCompile Include="..\..\Core\FileSystems\BlobFileSystem.cpp" />
|
||||||
<ClCompile Include="..\..\Core\FileSystems\BlockDevices.cpp" />
|
<ClCompile Include="..\..\Core\FileSystems\BlockDevices.cpp" />
|
||||||
|
|
|
@ -306,6 +306,9 @@
|
||||||
<ClCompile Include="..\..\Core\FileLoaders\LocalFileLoader.cpp">
|
<ClCompile Include="..\..\Core\FileLoaders\LocalFileLoader.cpp">
|
||||||
<Filter>FileLoaders</Filter>
|
<Filter>FileLoaders</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\Core\FileLoaders\RamCachingFileLoader.cpp">
|
||||||
|
<Filter>FileLoaders</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\Core\FileLoaders\RetryingFileLoader.cpp">
|
<ClCompile Include="..\..\Core\FileLoaders\RetryingFileLoader.cpp">
|
||||||
<Filter>FileLoaders</Filter>
|
<Filter>FileLoaders</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -1395,6 +1398,9 @@
|
||||||
<ClInclude Include="..\..\Core\FileLoaders\LocalFileLoader.h">
|
<ClInclude Include="..\..\Core\FileLoaders\LocalFileLoader.h">
|
||||||
<Filter>FileLoaders</Filter>
|
<Filter>FileLoaders</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\Core\FileLoaders\RamCachingFileLoader.h">
|
||||||
|
<Filter>FileLoaders</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\Core\FileLoaders\RetryingFileLoader.h">
|
<ClInclude Include="..\..\Core\FileLoaders\RetryingFileLoader.h">
|
||||||
<Filter>FileLoaders</Filter>
|
<Filter>FileLoaders</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -406,6 +406,8 @@ bool System_GetPropertyBool(SystemProperty prop) {
|
||||||
return true;
|
return true;
|
||||||
case SYSPROP_CAN_READ_BATTERY_PERCENTAGE:
|
case SYSPROP_CAN_READ_BATTERY_PERCENTAGE:
|
||||||
return true;
|
return true;
|
||||||
|
case SYSPROP_ENOUGH_RAM_FOR_FULL_ISO:
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -607,6 +607,7 @@ EXEC_AND_LIB_FILES := \
|
||||||
$(SRC)/Core/FileLoaders/DiskCachingFileLoader.cpp \
|
$(SRC)/Core/FileLoaders/DiskCachingFileLoader.cpp \
|
||||||
$(SRC)/Core/FileLoaders/HTTPFileLoader.cpp \
|
$(SRC)/Core/FileLoaders/HTTPFileLoader.cpp \
|
||||||
$(SRC)/Core/FileLoaders/LocalFileLoader.cpp \
|
$(SRC)/Core/FileLoaders/LocalFileLoader.cpp \
|
||||||
|
$(SRC)/Core/FileLoaders/RamCachingFileLoader.cpp \
|
||||||
$(SRC)/Core/FileLoaders/RetryingFileLoader.cpp \
|
$(SRC)/Core/FileLoaders/RetryingFileLoader.cpp \
|
||||||
$(SRC)/Core/MemFault.cpp \
|
$(SRC)/Core/MemFault.cpp \
|
||||||
$(SRC)/Core/MemMap.cpp \
|
$(SRC)/Core/MemMap.cpp \
|
||||||
|
|
|
@ -656,6 +656,7 @@ SOURCES_CXX += \
|
||||||
$(COREDIR)/FileLoaders/CachingFileLoader.cpp \
|
$(COREDIR)/FileLoaders/CachingFileLoader.cpp \
|
||||||
$(COREDIR)/FileLoaders/DiskCachingFileLoader.cpp \
|
$(COREDIR)/FileLoaders/DiskCachingFileLoader.cpp \
|
||||||
$(COREDIR)/FileLoaders/RetryingFileLoader.cpp \
|
$(COREDIR)/FileLoaders/RetryingFileLoader.cpp \
|
||||||
|
$(COREDIR)/FileLoaders/RamCachingFileLoader.cpp \
|
||||||
$(COREDIR)/FileLoaders/LocalFileLoader.cpp \
|
$(COREDIR)/FileLoaders/LocalFileLoader.cpp \
|
||||||
$(COREDIR)/CoreTiming.cpp \
|
$(COREDIR)/CoreTiming.cpp \
|
||||||
$(COREDIR)/CwCheat.cpp \
|
$(COREDIR)/CwCheat.cpp \
|
||||||
|
|
|
@ -591,6 +591,15 @@ static void check_variables(CoreParameter &coreParam)
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||||
g_Config.iLockedCPUSpeed = atoi(var.value);
|
g_Config.iLockedCPUSpeed = atoi(var.value);
|
||||||
|
|
||||||
|
var.key = "ppsspp_cache_iso";
|
||||||
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||||
|
{
|
||||||
|
if (!strcmp(var.value, "disabled"))
|
||||||
|
g_Config.bCacheFullIsoInRam = false;
|
||||||
|
else
|
||||||
|
g_Config.bCacheFullIsoInRam = true;
|
||||||
|
}
|
||||||
|
|
||||||
var.key = "ppsspp_cheats";
|
var.key = "ppsspp_cheats";
|
||||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue