mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #22394 from hrydgard/gameinfo-priorities
GameInfoCache: Prioritize loads, so launching doesn't wait behind search
This commit is contained in:
4 files changed
+27
-10
No files matched your search
+2
-1
@@ -473,7 +473,8 @@ void GameButton::Draw(UIContext &dc) {
|
||||
}
|
||||
|
||||
std::string GameButton::DescribeText() const {
|
||||
std::shared_ptr<GameInfo> ginfo = g_gameInfoCache->GetInfo(nullptr, gamePath_, GameInfoFlags::PARAM_SFO);
|
||||
// LOW: search calls this for every game in the list, which mustn't hold up the visible ones.
|
||||
std::shared_ptr<GameInfo> ginfo = g_gameInfoCache->GetInfo(nullptr, gamePath_, GameInfoFlags::PARAM_SFO, nullptr, GameInfoFlags::EMPTY, TaskPriority::LOW);
|
||||
if (!ginfo->Ready(GameInfoFlags::PARAM_SFO))
|
||||
return "...";
|
||||
auto u = GetI18NCategory(I18NCat::UI_ELEMENTS);
|
||||
|
||||
+16
-6
@@ -541,8 +541,8 @@ static bool LoadReplacementImage(GameInfo *info, GameInfoTex *tex, const char *f
|
||||
|
||||
class GameInfoWorkItem : public Task {
|
||||
public:
|
||||
GameInfoWorkItem(const Path &gamePath, std::shared_ptr<GameInfo> &info, GameInfoFlags flags)
|
||||
: gamePath_(gamePath), info_(info), flags_(flags) {}
|
||||
GameInfoWorkItem(const Path &gamePath, std::shared_ptr<GameInfo> &info, GameInfoFlags flags, TaskPriority priority)
|
||||
: gamePath_(gamePath), info_(info), flags_(flags), priority_(priority) {}
|
||||
|
||||
~GameInfoWorkItem() {
|
||||
info_->DisposeFileLoader();
|
||||
@@ -553,10 +553,14 @@ public:
|
||||
}
|
||||
|
||||
TaskPriority Priority() const override {
|
||||
if (priority_ == TaskPriority::HIGH) {
|
||||
// Someone's waiting on this, wherever it is.
|
||||
return TaskPriority::HIGH;
|
||||
}
|
||||
switch (gamePath_.Type()) {
|
||||
case PathType::NATIVE:
|
||||
case PathType::CONTENT_URI:
|
||||
return TaskPriority::NORMAL;
|
||||
return priority_;
|
||||
|
||||
default:
|
||||
// Remote/network access.
|
||||
@@ -997,6 +1001,7 @@ private:
|
||||
Path gamePath_;
|
||||
std::shared_ptr<GameInfo> info_;
|
||||
GameInfoFlags flags_{};
|
||||
TaskPriority priority_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GameInfoWorkItem);
|
||||
};
|
||||
@@ -1110,7 +1115,7 @@ void GameInfoCache::PurgeType(IdentifiedFileType fileType) {
|
||||
|
||||
// Call on the main thread ONLY - that is from stuff called from NativeFrame.
|
||||
// Can also be called from the audio thread for menu background music, but that cannot request images!
|
||||
std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const Path &gamePath, GameInfoFlags wantFlags, GameInfoFlags *outHasFlags, GameInfoFlags refetchFlags) {
|
||||
std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const Path &gamePath, GameInfoFlags wantFlags, GameInfoFlags *outHasFlags, GameInfoFlags refetchFlags, TaskPriority priority) {
|
||||
const std::string &pathStr = gamePath.ToString();
|
||||
|
||||
// _dbg_assert_(gamePath != GetSysDirectory(DIRECTORY_SAVEDATA));
|
||||
@@ -1139,6 +1144,11 @@ std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const
|
||||
info->hasFlags &= ~refetchFlags;
|
||||
}
|
||||
GameInfoFlags willHaveFlags = info->hasFlags | info->pendingFlags; // We don't want to re-fetch data that we have, so or in pendingFlags.
|
||||
if (priority == TaskPriority::HIGH) {
|
||||
// A pending load may be sitting at the back of the queue (a search over a big list
|
||||
// queues one per game), and the caller is about to block. Fetch it ourselves.
|
||||
willHaveFlags = info->hasFlags;
|
||||
}
|
||||
wanted = (GameInfoFlags)((int)wantFlags & ~(int)willHaveFlags); // & is reserved for testing so we have to cast to int. ugh.
|
||||
// FILE_TYPE is special: every work item switches on info->fileType, so it's not enough that
|
||||
// some *pending* item is going to compute it - that item may not have got there yet, and we'd
|
||||
@@ -1154,7 +1164,7 @@ std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const
|
||||
|
||||
if (wanted != (GameInfoFlags)0) {
|
||||
// We're missing info that we want. Go get it!
|
||||
GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info, wanted);
|
||||
GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info, wanted, priority);
|
||||
g_threadManager.EnqueueTask(item);
|
||||
}
|
||||
return info;
|
||||
@@ -1170,7 +1180,7 @@ std::shared_ptr<GameInfo> GameInfoCache::GetInfo(Draw::DrawContext *draw, const
|
||||
mapLock_.unlock();
|
||||
|
||||
// Just get all the stuff we wanted.
|
||||
GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info, wantFlags);
|
||||
GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info, wantFlags, priority);
|
||||
g_threadManager.EnqueueTask(item);
|
||||
return info;
|
||||
}
|
||||
+6
-1
@@ -25,6 +25,7 @@
|
||||
#include <condition_variable>
|
||||
|
||||
#include "Common/Thread/Event.h"
|
||||
#include "Common/Thread/ThreadManager.h"
|
||||
#include "Core/ELF/ParamSFO.h"
|
||||
#include "Core/Util/PSARUnpack.h"
|
||||
#include "Common/File/Path.h"
|
||||
@@ -227,7 +228,11 @@ public:
|
||||
// because they're big. bgTextures and sound may be discarded over time as well.
|
||||
// NOTE: This never returns null, so you don't need to check for that. Do check Ready() flags though.
|
||||
// It's OK to pass in nullptr for draw if you don't need the actual texture right now.
|
||||
std::shared_ptr<GameInfo> GetInfo(Draw::DrawContext *draw, const Path &gamePath, GameInfoFlags wantFlags, GameInfoFlags *outHasFlags = nullptr, GameInfoFlags refetchFlags = GameInfoFlags::EMPTY);
|
||||
// priority orders the background loads: NORMAL for what's on screen, LOW for speculative work like
|
||||
// search. HIGH is for a one-off request you're about to block on: it doesn't wait behind a
|
||||
// lower-priority load that's already queued for the same data, it queues its own - so don't use it
|
||||
// every frame.
|
||||
std::shared_ptr<GameInfo> GetInfo(Draw::DrawContext *draw, const Path &gamePath, GameInfoFlags wantFlags, GameInfoFlags *outHasFlags = nullptr, GameInfoFlags refetchFlags = GameInfoFlags::EMPTY, TaskPriority priority = TaskPriority::NORMAL);
|
||||
void FlushBGs(); // Gets rid of all BG textures. Also gets rid of bg sounds.
|
||||
|
||||
void CancelAll();
|
||||
|
||||
+3
-2
@@ -72,9 +72,10 @@ static void LaunchFile(ScreenManager *screenManager, Screen *currentScreen, cons
|
||||
// Check if we already know that this game isn't playable.
|
||||
// If coming from the main screen, the info will already be computed here since the icon is displayed etc.
|
||||
// Otherwise (launching from a file association, a shortcut, drag-and-drop...) we have to block until
|
||||
// it's available - we can't decide what to do below without it.
|
||||
// it's available - we can't decide what to do below without it. HIGH, so we don't wait behind
|
||||
// whatever else is queued, like a search's loads for every game in a big list.
|
||||
const GameInfoFlags neededFlags = GameInfoFlags::FILE_TYPE | GameInfoFlags::PARAM_SFO;
|
||||
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(nullptr, path, neededFlags);
|
||||
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(nullptr, path, neededFlags, nullptr, GameInfoFlags::EMPTY, TaskPriority::HIGH);
|
||||
info->WaitUntilReady(neededFlags);
|
||||
|
||||
switch (info->fileType) {
|
||||
|
||||
Reference in new issue
Block a user