mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Make the workqueue slightly safer. Put g_gameInfoCache on the heap.
Cherry-picked from #8592
This commit is contained in:
@@ -206,7 +206,7 @@ int PlayBackgroundAudio() {
|
||||
// last changed... (to prevent crazy amount of reads when skipping through a list)
|
||||
if (!at3Reader && bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) {
|
||||
// Grab some audio from the current game and play it.
|
||||
GameInfo *gameInfo = g_gameInfoCache.GetInfo(NULL, bgGamePath, GAMEINFO_WANTSND);
|
||||
GameInfo *gameInfo = g_gameInfoCache->GetInfo(NULL, bgGamePath, GAMEINFO_WANTSND);
|
||||
if (!gameInfo)
|
||||
return 0;
|
||||
|
||||
|
||||
+2
-2
@@ -89,7 +89,7 @@ void EmuScreen::bootGame(const std::string &filename) {
|
||||
}
|
||||
|
||||
//pre-emptive loading of game specific config if possible, to get all the settings
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, filename, 0);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, filename, 0);
|
||||
if (info && !info->id.empty()) {
|
||||
g_Config.loadGameConfig(info->id);
|
||||
}
|
||||
@@ -139,7 +139,7 @@ void EmuScreen::bootComplete() {
|
||||
host->BootDone();
|
||||
host->UpdateDisassembly();
|
||||
|
||||
g_gameInfoCache.FlushBGs();
|
||||
g_gameInfoCache->FlushBGs();
|
||||
|
||||
NOTICE_LOG(BOOT, "Loading %s...", PSP_CoreParameter().fileToStart.c_str());
|
||||
autoLoad();
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#define unique_ptr auto_ptr
|
||||
#endif
|
||||
|
||||
GameInfoCache g_gameInfoCache;
|
||||
GameInfoCache *g_gameInfoCache;
|
||||
|
||||
GameInfo::~GameInfo() {
|
||||
delete iconTexture;
|
||||
@@ -583,6 +583,7 @@ handleELF:
|
||||
}
|
||||
info_->pending = false;
|
||||
info_->DisposeFileLoader();
|
||||
// ILOG("Completed writing info for %s", info_->GetTitle().c_str());
|
||||
}
|
||||
|
||||
virtual float priority() {
|
||||
@@ -595,9 +596,13 @@ private:
|
||||
DISALLOW_COPY_AND_ASSIGN(GameInfoWorkItem);
|
||||
};
|
||||
|
||||
GameInfoCache::GameInfoCache() : gameInfoWQ_(nullptr) {
|
||||
Init();
|
||||
}
|
||||
|
||||
GameInfoCache::~GameInfoCache() {
|
||||
Clear();
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void GameInfoCache::Init() {
|
||||
@@ -614,8 +619,10 @@ void GameInfoCache::Shutdown() {
|
||||
}
|
||||
|
||||
void GameInfoCache::Clear() {
|
||||
if (gameInfoWQ_)
|
||||
if (gameInfoWQ_) {
|
||||
gameInfoWQ_->Flush();
|
||||
gameInfoWQ_->WaitUntilDone();
|
||||
}
|
||||
for (auto iter = info_.begin(); iter != info_.end(); iter++) {
|
||||
{
|
||||
lock_guard lock(iter->second->lock);
|
||||
|
||||
+5
-4
@@ -175,13 +175,12 @@ protected:
|
||||
|
||||
class GameInfoCache {
|
||||
public:
|
||||
GameInfoCache() : gameInfoWQ_(0) {}
|
||||
GameInfoCache();
|
||||
~GameInfoCache();
|
||||
|
||||
// This creates a background worker thread!
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void Clear();
|
||||
void ClearTextures();
|
||||
void PurgeType(IdentifiedFileType fileType);
|
||||
|
||||
// All data in GameInfo including iconTexture may be zero the first time you call this
|
||||
@@ -199,6 +198,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void SetupTexture(GameInfo *info, std::string &textureData, Thin3DContext *thin3d, Thin3DTexture *&tex, double &loadTime);
|
||||
|
||||
// Maps ISO path to info.
|
||||
@@ -209,4 +210,4 @@ private:
|
||||
};
|
||||
|
||||
// This one can be global, no good reason not to.
|
||||
extern GameInfoCache g_gameInfoCache;
|
||||
extern GameInfoCache *g_gameInfoCache;
|
||||
|
||||
+12
-12
@@ -44,8 +44,8 @@ GameScreen::~GameScreen() {
|
||||
}
|
||||
|
||||
void GameScreen::CreateViews() {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
g_gameInfoCache.WaitUntilDone(info);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
g_gameInfoCache->WaitUntilDone(info);
|
||||
|
||||
I18NCategory *di = GetI18NCategory("Dialog");
|
||||
I18NCategory *ga = GetI18NCategory("Game");
|
||||
@@ -117,7 +117,7 @@ void GameScreen::CreateViews() {
|
||||
|
||||
UI::EventReturn GameScreen::OnCreateConfig(UI::EventParams &e)
|
||||
{
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_,0);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_,0);
|
||||
g_Config.createGameConfig(info->id);
|
||||
g_Config.saveGameConfig(info->id);
|
||||
info->hasConfig = true;
|
||||
@@ -130,7 +130,7 @@ void GameScreen::CallbackDeleteConfig(bool yes)
|
||||
{
|
||||
if (yes)
|
||||
{
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0);
|
||||
g_Config.deleteGameConfig(info->id);
|
||||
info->hasConfig = false;
|
||||
screenManager()->RecreateAllViews();
|
||||
@@ -155,7 +155,7 @@ void GameScreen::update(InputState &input) {
|
||||
|
||||
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
||||
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(thin3d, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(thin3d, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
|
||||
if (tvTitle_)
|
||||
tvTitle_->SetText(info->GetTitle() + " (" + info->id + ")");
|
||||
@@ -216,7 +216,7 @@ UI::EventReturn GameScreen::OnPlay(UI::EventParams &e) {
|
||||
}
|
||||
|
||||
UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
if (info && info->paramSFOLoaded) {
|
||||
std::string discID = info->paramSFO.GetValueString("DISC_ID");
|
||||
screenManager()->push(new GameSettingsScreen(gamePath_, discID, true));
|
||||
@@ -227,7 +227,7 @@ UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
|
||||
UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
|
||||
I18NCategory *di = GetI18NCategory("Dialog");
|
||||
I18NCategory *ga = GetI18NCategory("Game");
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
if (info) {
|
||||
// Check that there's any savedata to delete
|
||||
std::vector<std::string> saveDirs = info->GetSaveDataDirectories();
|
||||
@@ -243,7 +243,7 @@ UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
|
||||
}
|
||||
|
||||
void GameScreen::CallbackDeleteSaveData(bool yes) {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0);
|
||||
if (yes) {
|
||||
info->DeleteAllSaveData();
|
||||
info->saveDataSize = 0;
|
||||
@@ -254,7 +254,7 @@ void GameScreen::CallbackDeleteSaveData(bool yes) {
|
||||
UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
|
||||
I18NCategory *di = GetI18NCategory("Dialog");
|
||||
I18NCategory *ga = GetI18NCategory("Game");
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
if (info) {
|
||||
screenManager()->push(
|
||||
new PromptScreen(di->T("DeleteConfirmGame", "Do you really want to delete this game\nfrom your device? You can't undo this."), ga->T("ConfirmDelete"), di->T("Cancel"),
|
||||
@@ -265,16 +265,16 @@ UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
|
||||
}
|
||||
|
||||
void GameScreen::CallbackDeleteGame(bool yes) {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0);
|
||||
if (yes) {
|
||||
info->Delete();
|
||||
g_gameInfoCache.Clear();
|
||||
g_gameInfoCache->Clear();
|
||||
screenManager()->switchScreen(new MainScreen());
|
||||
}
|
||||
}
|
||||
|
||||
UI::EventReturn GameScreen::OnCreateShortcut(UI::EventParams &e) {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0);
|
||||
if (info) {
|
||||
host->CreateDesktopShortcut(gamePath_, info->GetTitle());
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ bool GameSettingsScreen::UseVerticalLayout() const {
|
||||
}
|
||||
|
||||
void GameSettingsScreen::CreateViews() {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
|
||||
if (bEditThenRestore)
|
||||
{
|
||||
|
||||
+3
-3
@@ -173,7 +173,7 @@ private:
|
||||
};
|
||||
|
||||
void GameButton::Draw(UIContext &dc) {
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath_, 0);
|
||||
GameInfo *ginfo = g_gameInfoCache->GetInfo(dc.GetThin3DContext(), gamePath_, 0);
|
||||
Thin3DTexture *texture = 0;
|
||||
u32 color = 0, shadowColor = 0;
|
||||
using namespace UI;
|
||||
@@ -976,7 +976,7 @@ bool MainScreen::DrawBackgroundFor(UIContext &dc, const std::string &gamePath, f
|
||||
|
||||
GameInfo *ginfo = 0;
|
||||
if (!gamePath.empty()) {
|
||||
ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
|
||||
ginfo = g_gameInfoCache->GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
|
||||
// Loading texture data may bind a texture.
|
||||
dc.RebindTexture();
|
||||
|
||||
@@ -1009,7 +1009,7 @@ UI::EventReturn MainScreen::OnGameSelected(UI::EventParams &e) {
|
||||
std::string path = e.s;
|
||||
#endif
|
||||
GameInfo *ginfo = 0;
|
||||
ginfo = g_gameInfoCache.GetInfo(nullptr, path, GAMEINFO_WANTBG);
|
||||
ginfo = g_gameInfoCache->GetInfo(nullptr, path, GAMEINFO_WANTBG);
|
||||
if (ginfo && ginfo->fileType == FILETYPE_PSP_SAVEDATA_DIRECTORY) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ void DrawBackground(UIContext &dc, float alpha = 1.0f) {
|
||||
}
|
||||
|
||||
void DrawGameBackground(UIContext &dc, const std::string &gamePath) {
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
|
||||
GameInfo *ginfo = g_gameInfoCache->GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
|
||||
dc.Flush();
|
||||
|
||||
if (ginfo) {
|
||||
|
||||
+5
-7
@@ -486,8 +486,6 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
|
||||
if (!boot_filename.empty() && stateToLoad != NULL)
|
||||
SaveState::Load(stateToLoad);
|
||||
|
||||
g_gameInfoCache.Init();
|
||||
|
||||
screenManager = new ScreenManager();
|
||||
if (skipLogo) {
|
||||
screenManager->switchScreen(new EmuScreen(boot_filename));
|
||||
@@ -596,6 +594,8 @@ void NativeInitGraphics(GraphicsContext *graphicsContext) {
|
||||
winAudioBackend = CreateAudioBackend((AudioBackendType)g_Config.iAudioBackend);
|
||||
winAudioBackend->Init(MainWindow::GetHWND(), &Win32Mix, 44100);
|
||||
#endif
|
||||
|
||||
g_gameInfoCache = new GameInfoCache();
|
||||
}
|
||||
|
||||
void NativeShutdownGraphics() {
|
||||
@@ -606,7 +606,8 @@ void NativeShutdownGraphics() {
|
||||
|
||||
screenManager->deviceLost();
|
||||
|
||||
g_gameInfoCache.Clear();
|
||||
delete g_gameInfoCache;
|
||||
g_gameInfoCache = nullptr;
|
||||
|
||||
uiTexture->Release();
|
||||
|
||||
@@ -764,13 +765,12 @@ void NativeUpdate(InputState &input) {
|
||||
}
|
||||
|
||||
void NativeDeviceLost() {
|
||||
g_gameInfoCache.Clear();
|
||||
// g_gameInfoCache.Clear();
|
||||
screenManager->deviceLost();
|
||||
|
||||
if (GetGPUBackend() == GPUBackend::OPENGL) {
|
||||
gl_lost();
|
||||
}
|
||||
// Should dirty EVERYTHING
|
||||
}
|
||||
|
||||
bool NativeIsAtTopLevel() {
|
||||
@@ -933,8 +933,6 @@ void NativeShutdown() {
|
||||
delete screenManager;
|
||||
screenManager = 0;
|
||||
|
||||
g_gameInfoCache.Shutdown();
|
||||
|
||||
delete host;
|
||||
host = 0;
|
||||
g_Config.Save();
|
||||
|
||||
+3
-3
@@ -181,7 +181,7 @@ SaveSlotView::SaveSlotView(const std::string &gameFilename, int slot, UI::Layout
|
||||
using namespace UI;
|
||||
|
||||
screenshotFilename_ = SaveState::GenerateSaveSlotFilename(gamePath_, slot, "jpg");
|
||||
PrioritizedWorkQueue *wq = g_gameInfoCache.WorkQueue();
|
||||
PrioritizedWorkQueue *wq = g_gameInfoCache->WorkQueue();
|
||||
Add(new Spacer(5));
|
||||
|
||||
AsyncImageFileView *fv = Add(new AsyncImageFileView(screenshotFilename_, IS_DEFAULT, wq, new UI::LayoutParams(82 * 2, 47 * 2)));
|
||||
@@ -409,7 +409,7 @@ UI::EventReturn GamePauseScreen::OnSwitchUMD(UI::EventParams &e) {
|
||||
void GamePauseScreen::CallbackDeleteConfig(bool yes)
|
||||
{
|
||||
if (yes) {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0);
|
||||
g_Config.unloadGameConfig();
|
||||
g_Config.deleteGameConfig(info->id);
|
||||
info->hasConfig = false;
|
||||
@@ -423,7 +423,7 @@ UI::EventReturn GamePauseScreen::OnCreateConfig(UI::EventParams &e)
|
||||
g_Config.createGameConfig(gameId);
|
||||
g_Config.changeGameSpecific(gameId);
|
||||
g_Config.saveGameConfig(gameId);
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
|
||||
GameInfo *info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0);
|
||||
if (info) {
|
||||
info->hasConfig = true;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override {
|
||||
using namespace UI;
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(screenManager()->getThin3DContext(), savePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *ginfo = g_gameInfoCache->GetInfo(screenManager()->getThin3DContext(), savePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
LinearLayout *root = new LinearLayout(ORIENT_VERTICAL);
|
||||
parent->Add(root);
|
||||
if (!ginfo)
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
} else {
|
||||
std::string image_path = ReplaceAll(savePath_, ".ppst", ".jpg");
|
||||
if (File::Exists(image_path)) {
|
||||
PrioritizedWorkQueue *wq = g_gameInfoCache.WorkQueue();
|
||||
PrioritizedWorkQueue *wq = g_gameInfoCache->WorkQueue();
|
||||
toprow->Add(new AsyncImageFileView(image_path, IS_DEFAULT, wq, new UI::LayoutParams(500, 500/16*9)));
|
||||
} else {
|
||||
toprow->Add(new TextView(sa->T("No screenshot"), new LinearLayoutParams(Margins(10, 5))));
|
||||
@@ -128,7 +128,7 @@ private:
|
||||
};
|
||||
|
||||
UI::EventReturn SavedataPopupScreen::OnDeleteButtonClick(UI::EventParams &e) {
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(nullptr, savePath_, GAMEINFO_WANTSIZE);
|
||||
GameInfo *ginfo = g_gameInfoCache->GetInfo(nullptr, savePath_, GAMEINFO_WANTSIZE);
|
||||
ginfo->Delete();
|
||||
screenManager()->finishDialog(this, DR_NO);
|
||||
return UI::EVENT_DONE;
|
||||
@@ -142,7 +142,7 @@ static std::string CleanSaveString(std::string str) {
|
||||
}
|
||||
|
||||
void SavedataButton::Draw(UIContext &dc) {
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), savePath_, GAMEINFO_WANTSIZE);
|
||||
GameInfo *ginfo = g_gameInfoCache->GetInfo(dc.GetThin3DContext(), savePath_, GAMEINFO_WANTSIZE);
|
||||
Thin3DTexture *texture = 0;
|
||||
u32 color = 0, shadowColor = 0;
|
||||
using namespace UI;
|
||||
@@ -274,8 +274,8 @@ SavedataBrowser::SavedataBrowser(std::string path, UI::LayoutParams *layoutParam
|
||||
}
|
||||
|
||||
SavedataBrowser::~SavedataBrowser() {
|
||||
g_gameInfoCache.PurgeType(FILETYPE_PPSSPP_SAVESTATE);
|
||||
g_gameInfoCache.PurgeType(FILETYPE_PSP_SAVEDATA_DIRECTORY);
|
||||
g_gameInfoCache->PurgeType(FILETYPE_PPSSPP_SAVESTATE);
|
||||
g_gameInfoCache->PurgeType(FILETYPE_PSP_SAVEDATA_DIRECTORY);
|
||||
}
|
||||
|
||||
void SavedataBrowser::Refresh() {
|
||||
@@ -368,7 +368,7 @@ void SavedataScreen::CreateViews() {
|
||||
}
|
||||
|
||||
UI::EventReturn SavedataScreen::OnSavedataButtonClick(UI::EventParams &e) {
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(screenManager()->getThin3DContext(), e.s, 0);
|
||||
GameInfo *ginfo = g_gameInfoCache->GetInfo(screenManager()->getThin3DContext(), e.s, 0);
|
||||
screenManager()->push(new SavedataPopupScreen(e.s, ginfo->GetTitle()));
|
||||
// the game path: e.s;
|
||||
return UI::EVENT_DONE;
|
||||
|
||||
+1
-3
@@ -552,7 +552,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
|
||||
{
|
||||
//hack to enable/disable menu command accelerate keys
|
||||
MainWindow::UpdateCommands();
|
||||
|
||||
|
||||
//hack to make it possible to get to main window from floating windows with Esc
|
||||
if (msg.hwnd != hwndMain && msg.wParam == VK_ESCAPE)
|
||||
BringWindowToTop(hwndMain);
|
||||
@@ -600,8 +600,6 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
|
||||
delete host;
|
||||
|
||||
g_Config.Save();
|
||||
g_gameInfoCache.Clear();
|
||||
g_gameInfoCache.Shutdown();
|
||||
LogManager::Shutdown();
|
||||
|
||||
if (g_Config.bRestartRequired) {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "Common/GraphicsContext.h"
|
||||
#include "Common/GL/GLInterfaceBase.h"
|
||||
#include "UI/GameInfoCache.h"
|
||||
|
||||
#include "app-android.h"
|
||||
|
||||
@@ -736,7 +737,9 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
|
||||
ProcessFrameCommands(env);
|
||||
}
|
||||
|
||||
// Restore lost device objects. TODO: This feels like the wrong place for this.
|
||||
ILOG("After render loop.");
|
||||
g_gameInfoCache->WorkQueue()->Flush();
|
||||
|
||||
NativeDeviceLost();
|
||||
ILOG("NativeDeviceLost completed.");
|
||||
|
||||
|
||||
+1
-1
Submodule ext/glslang updated: c49d1ab8cd...7aaea5a33b
@@ -49,10 +49,10 @@ void gl_lost() {
|
||||
// TODO: We should really do this when we get the context back, not during gl_lost...
|
||||
ILOG("gl_lost() restoring %i items:", (int)holders->size());
|
||||
for (size_t i = 0; i < holders->size(); i++) {
|
||||
ILOG("GLLost(%i / %i, %p)", (int)(i + 1), (int) holders->size(), (*holders)[i]);
|
||||
ILOG("GLLost(%i / %i, %p, %08x)", (int)(i + 1), (int) holders->size(), (*holders)[i], *((uint32_t *)((*holders)[i])));
|
||||
(*holders)[i]->GLLost();
|
||||
}
|
||||
ILOG("gl_lost() completed restoring %i items:", (int)holders->size());
|
||||
ILOG("gl_lost() completed on %i items:", (int)holders->size());
|
||||
inLost = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -473,17 +473,11 @@ public:
|
||||
}
|
||||
|
||||
void GLLost() override {
|
||||
// We lost our GL context - zero out the tex_.
|
||||
tex_ = 0;
|
||||
generatedMips_ = false;
|
||||
if (!filename_.empty()) {
|
||||
if (LoadFromFile(filename_.c_str())) {
|
||||
ILOG("Reloaded lost texture %s", filename_.c_str());
|
||||
} else {
|
||||
ELOG("Failed to reload lost texture %s", filename_.c_str());
|
||||
}
|
||||
} else {
|
||||
WLOG("Texture %p cannot be restored - has no filename", this);
|
||||
tex_ = 0;
|
||||
}
|
||||
// Don't try to restore stuff, that's not what this is for. Lost just means
|
||||
// that all our textures and buffers are invalid.
|
||||
}
|
||||
void Finalize(int zim_flags) override;
|
||||
|
||||
|
||||
@@ -23,13 +23,14 @@ void PrioritizedWorkQueue::Stop() {
|
||||
}
|
||||
|
||||
void PrioritizedWorkQueue::Flush() {
|
||||
if (queue_.empty())
|
||||
return;
|
||||
lock_guard guard(mutex_);
|
||||
int flush_count = 0;
|
||||
for (auto iter = queue_.begin(); iter != queue_.end(); ++iter) {
|
||||
delete *iter;
|
||||
flush_count++;
|
||||
}
|
||||
queue_.clear();
|
||||
ILOG("Flushed %d un-executed tasks", flush_count);
|
||||
}
|
||||
|
||||
void PrioritizedWorkQueue::WaitUntilDone() {
|
||||
@@ -40,7 +41,7 @@ void PrioritizedWorkQueue::WaitUntilDone() {
|
||||
bool empty;
|
||||
{
|
||||
lock_guard guard(mutex_);
|
||||
empty = queue_.empty();
|
||||
empty = queue_.empty() && !working_;
|
||||
}
|
||||
if (empty) {
|
||||
break;
|
||||
@@ -53,6 +54,7 @@ void PrioritizedWorkQueue::WaitUntilDone() {
|
||||
// The worker should simply call this in a loop. Will block when appropriate.
|
||||
PrioritizedWorkQueueItem *PrioritizedWorkQueue::Pop() {
|
||||
lock_guard guard(mutex_);
|
||||
working_ = false; // The thread only calls Pop if it's done.
|
||||
if (done_) {
|
||||
return 0;
|
||||
}
|
||||
@@ -77,6 +79,7 @@ PrioritizedWorkQueueItem *PrioritizedWorkQueue::Pop() {
|
||||
if (best != queue_.end()) {
|
||||
PrioritizedWorkQueueItem *poppedItem = *best;
|
||||
queue_.erase(best);
|
||||
working_ = true; // This will be worked on.
|
||||
return poppedItem;
|
||||
} else {
|
||||
// Not really sure how this can happen, but let's be safe.
|
||||
|
||||
@@ -23,7 +23,7 @@ private:
|
||||
|
||||
class PrioritizedWorkQueue {
|
||||
public:
|
||||
PrioritizedWorkQueue() : done_(false) {}
|
||||
PrioritizedWorkQueue() : done_(false), working_(false) {}
|
||||
~PrioritizedWorkQueue();
|
||||
// Takes ownership.
|
||||
void Add(PrioritizedWorkQueueItem *item);
|
||||
@@ -36,8 +36,13 @@ public:
|
||||
void Stop();
|
||||
void WaitUntilDone();
|
||||
|
||||
bool IsWorking() {
|
||||
return working_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool done_;
|
||||
bool working_;
|
||||
recursive_mutex mutex_;
|
||||
condition_variable notEmpty_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user