Skip to content

Commit

Permalink
More gameinfocache fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Jan 30, 2024
1 parent d7e5928 commit 6f610fd
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 34 deletions.
70 changes: 39 additions & 31 deletions UI/GameInfoCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void GameInfoTex::Clear() {
}
}

GameInfo::GameInfo() {
GameInfo::GameInfo(const Path &gamePath) : filePath_(gamePath) {
// here due to a forward decl.
fileType = IdentifiedFileType::UNKNOWN;
}
Expand Down Expand Up @@ -231,26 +231,13 @@ u64 GameInfo::GetInstallDataSizeInBytes() {
return totalSize;
}

bool GameInfo::LoadFromPath(const Path &gamePath) {
{
std::lock_guard<std::mutex> guard(lock);
// No need to rebuild if we already have it loaded.
if (filePath_ == gamePath) {
return true;
}
}

{
bool GameInfo::CreateLoader() {
if (!fileLoader) {
std::lock_guard<std::mutex> guard(loaderLock);
fileLoader.reset(ConstructFileLoader(gamePath));
fileLoader.reset(ConstructFileLoader(filePath_));
if (!fileLoader)
return false;
}

std::lock_guard<std::mutex> guard(lock);
filePath_ = gamePath;
// This is a fallback title, while we're loading / if unable to load.
title = filePath_.GetFilename();
return true;
}

Expand Down Expand Up @@ -463,7 +450,7 @@ class GameInfoWorkItem : public Task {
void Run() override {
// An early-return will result in the destructor running, where we can set
// flags like working and pending.
if (!info_->LoadFromPath(gamePath_)) {
if (!info_->CreateLoader()) {
return;
}

Expand Down Expand Up @@ -515,6 +502,7 @@ class GameInfoWorkItem : public Task {
info_->id_version = info_->id + "_1.00";
info_->region = GAMEREGION_MAX + 1; // Homebrew
}
info_->MarkReadyNoLock(GameInfoFlags::PARAM_SFO);
}
}

Expand Down Expand Up @@ -606,6 +594,7 @@ class GameInfoWorkItem : public Task {
std::lock_guard<std::mutex> lock(info_->lock);
info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
info_->ParseParamSFO();
info_->MarkReadyNoLock(GameInfoFlags::PARAM_SFO);
}
}
if (flags_ & GameInfoFlags::ICON) {
Expand All @@ -623,6 +612,8 @@ class GameInfoWorkItem : public Task {
{
if (flags_ & GameInfoFlags::PARAM_SFO) {
info_->SetTitle(SaveState::GetTitle(gamePath_));
std::lock_guard<std::mutex> lock(info_->lock);
info_->MarkReadyNoLock(GameInfoFlags::PARAM_SFO);
}

// Let's use the screenshot as an icon, too.
Expand Down Expand Up @@ -664,8 +655,10 @@ class GameInfoWorkItem : public Task {
}
}

ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->icon.data, &info_->lock);
info_->icon.dataLoaded = true;
if (flags_ & GameInfoFlags::ICON) {
ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->icon.data, &info_->lock);
info_->icon.dataLoaded = true;
}
if (flags_ & GameInfoFlags::BG) {
ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info_->pic0.data, &info_->lock);
info_->pic0.dataLoaded = true;
Expand Down Expand Up @@ -704,6 +697,9 @@ class GameInfoWorkItem : public Task {
std::lock_guard<std::mutex> lock(info_->lock);
info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
info_->ParseParamSFO();

// quick-update the info while we have the lock, so we don't need to wait for the image load to display the title.
info_->MarkReadyNoLock(GameInfoFlags::PARAM_SFO);
}
}
}
Expand Down Expand Up @@ -781,8 +777,7 @@ class GameInfoWorkItem : public Task {

// Time to update the flags.
std::unique_lock<std::mutex> lock(info_->lock);
info_->hasFlags |= flags_;
info_->pendingFlags &= ~flags_;
info_->MarkReadyNoLock(flags_);
// INFO_LOG(SYSTEM, "Completed writing info for %s", info_->GetTitle().c_str());
}

Expand Down Expand Up @@ -846,26 +841,39 @@ void GameInfoCache::FlushBGs() {

void GameInfoCache::PurgeType(IdentifiedFileType fileType) {
bool retry = false;
int retryCount = 10;
// Trickery to avoid sleeping with the lock held.
do {
if (retry) {
retryCount--;
if (retryCount == 0) {
break;
}
}
retry = false;
{
std::lock_guard<std::mutex> lock(mapLock_);
for (auto iter = info_.begin(); iter != info_.end();) {
auto &info = iter->second;

if (!(info->hasFlags & GameInfoFlags::FILE_TYPE)) {
iter++;
continue;
}
if (info->fileType != fileType) {
iter++;
continue;
}
// TODO: Find a better way to wait here.
while (info->pendingFlags != (GameInfoFlags)0) {
if (info->pendingFlags != (GameInfoFlags)0) {
INFO_LOG(LOADER, "%s: pending flags %08x, retrying", info->GetTitle().c_str(), info->pendingFlags);
retry = true;
break;
}
if (info->fileType == fileType) {
iter = info_.erase(iter);
} else {
iter++;
}
iter = info_.erase(iter);
}
}
sleep_ms(1);

sleep_ms(10);
} while (retry);
}

Expand Down Expand Up @@ -903,7 +911,7 @@ std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const
return info;
}

std::shared_ptr<GameInfo> info = std::make_shared<GameInfo>();
std::shared_ptr<GameInfo> info = std::make_shared<GameInfo>(gamePath);
info->pendingFlags = wantFlags;
info->lastAccessedTime = time_now_d();
info_.insert(std::make_pair(pathStr, info));
Expand Down
9 changes: 7 additions & 2 deletions UI/GameInfoCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ struct GameInfoTex {

class GameInfo {
public:
GameInfo();
GameInfo(const Path &gamePath);
~GameInfo();

bool Delete(); // Better be sure what you're doing when calling this.
bool DeleteAllSaveData();
bool LoadFromPath(const Path &gamePath);
bool CreateLoader();

bool HasFileLoader() const {
return fileLoader.get() != nullptr;
Expand All @@ -114,6 +114,11 @@ class GameInfo {
return (hasFlags & flags) != 0;
}

void MarkReadyNoLock(GameInfoFlags flags) {
hasFlags |= flags;
pendingFlags &= ~flags;
}

GameInfoTex *GetBGPic() {
if (pic1.texture)
return &pic1;
Expand Down
2 changes: 1 addition & 1 deletion UI/SavedataScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ void SavedataButton::Draw(UIContext &dc) {
u32 color = 0, shadowColor = 0;
using namespace UI;

if (ginfo->icon.texture) {
if (ginfo->Ready(GameInfoFlags::ICON) && ginfo->icon.texture) {
texture = ginfo->icon.texture;
}

Expand Down

0 comments on commit 6f610fd

Please sign in to comment.