- Use std::recursive_mutex instead of CMutex which is exactly the same

- Load icons in one async task instead of creating one task for each icon to improve stability with many icons
This commit is contained in:
Maschell 2020-02-21 14:22:36 +01:00
parent 72bb786fa2
commit b4f5393906
8 changed files with 48 additions and 115 deletions

View File

@ -13,14 +13,13 @@
#include "fs/FSUtils.h"
#include "utils/logger.h"
#include "utils/StringTools.h"
#include "system/CMutex.h"
void GameList::clear() {
lock();
for (auto const& x : fullGameList) {
if(x != NULL) {
if(x->imageData != NULL) {
delete x->imageData;
AsyncExecutor::pushForDelete(x->imageData);
x->imageData = NULL;
}
delete x;
@ -37,7 +36,6 @@ void GameList::clear() {
titleListChanged(this);
}
gameInfo * GameList::getGameInfo(uint64_t titleId) const {
for (uint32_t i = 0; i < filteredList.size(); ++i) {
if(titleId == filteredList[i]->titleId)
@ -83,8 +81,6 @@ int32_t GameList::readGameList() {
titles.resize(realTitleCount);
}
CMutex extraInfoMutex;
for (auto title_candidate : titles) {
if((title_candidate.titleId & 0xFFFFFFFF00000000L) == 0x0005000000000000L) {
gameInfo* newGameInfo = new gameInfo;
@ -97,42 +93,45 @@ int32_t GameList::readGameList() {
fullGameList.push_back(newGameInfo);
titleAdded(newGameInfo);
cnt++;
AsyncExecutor::execute([newGameInfo, this, &extraInfoMutex] {
extraInfoMutex.lock();
DEBUG_FUNCTION_LINE("Load extra infos of %016llX\n",newGameInfo->titleId);
ACPMetaXml* meta = (ACPMetaXml*)calloc(1, 0x4000); //TODO fix wut
if(meta) {
auto acp = ACPGetTitleMetaXml(newGameInfo->titleId, meta);
if(acp >= 0) {
newGameInfo->name = meta->shortname_en;
}
free(meta);
}
if(newGameInfo->imageData == NULL) {
std::string filepath = "fs:" + newGameInfo->gamePath + META_PATH + "/iconTex.tga";
uint8_t *buffer = NULL;
uint32_t bufferSize = 0;
int iResult = FSUtils::LoadFileToMem(filepath.c_str(), &buffer, &bufferSize);
if(iResult > 0) {
GuiImageData * imageData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MODE_MIRROR);
if(imageData) {
newGameInfo->imageData = imageData;
}
//! free original image buffer which is converted to texture now and not needed anymore
free(buffer);
}
}
DCFlushRange(newGameInfo, sizeof(gameInfo));
titleUpdated(newGameInfo);
extraInfoMutex.unlock();
});
}
}
AsyncExecutor::execute([this] {
lock();
for (uint32_t i = 0; i < fullGameList.size(); ++i) {
gameInfo *header = fullGameList[i];
DEBUG_FUNCTION_LINE("Load extra infos of %016llX\n",header->titleId);
ACPMetaXml* meta = (ACPMetaXml*)calloc(1, 0x4000); //TODO fix wut
if(meta) {
auto acp = ACPGetTitleMetaXml(header->titleId, meta);
if(acp >= 0) {
header->name = meta->shortname_en;
}
free(meta);
}
if(header->imageData == NULL) {
std::string filepath = "fs:" + header->gamePath + META_PATH + "/iconTex.tga";
uint8_t *buffer = NULL;
uint32_t bufferSize = 0;
int iResult = FSUtils::LoadFileToMem(filepath.c_str(), &buffer, &bufferSize);
if(iResult > 0) {
GuiImageData * imageData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MODE_MIRROR);
if(imageData) {
header->imageData = imageData;
}
//! free original image buffer which is converted to texture now and not needed anymore
free(buffer);
}
}
DCFlushRange(header, sizeof(gameInfo));
titleUpdated(header);
}
unlock();
});
return cnt;
}

View File

@ -2,6 +2,7 @@
#define GAME_LIST_H_
#include <vector>
#include <mutex>
#include <stdint.h>
#include <coreinit/mcp.h>
#include <gui/sigslot.h>
@ -132,7 +133,7 @@ protected:
std::vector<gameInfo *> filteredList;
std::vector<gameInfo *> fullGameList;
CMutex _lock;
std::recursive_mutex _lock;
};
#endif

View File

@ -113,8 +113,9 @@ uint64_t GuiIconGrid::getSelectedGame(void) {
}
void GuiIconGrid::OnGameTitleListUpdated(GameList * gameList) {
containerMutex.lock();
gameList->lock();
containerMutex.lock();
// At first delete the ones that were deleted;
auto it = gameInfoContainers.begin();
while (it != gameInfoContainers.end()) {
@ -148,12 +149,14 @@ void GuiIconGrid::OnGameTitleListUpdated(GameList * gameList) {
}
}
if(container == NULL) {
OnGameTitleAdded(info);
}
}
gameList->unlock();
containerMutex.unlock();
gameList->unlock();
bUpdatePositions = true;
}
@ -249,11 +252,11 @@ void GuiIconGrid::OnGameTitleUpdated(gameInfo * info) {
break;
}
}
containerMutex.unlock();
if(container != NULL) {
container->updateImageData();
}
containerMutex.unlock();
bUpdatePositions = true;
}

View File

@ -120,6 +120,6 @@ private:
GuiButton * button;
};
CMutex containerMutex;
std::recursive_mutex containerMutex;
std::map<uint64_t, GameInfoContainer *> gameInfoContainers;
};

View File

@ -138,7 +138,6 @@ void MainWindow::OnGameTitleUpdated(gameInfo * info) {
}
void MainWindow::OnGameTitleAdded(gameInfo * info) {
currentTvFrame->OnGameTitleAdded(info);
if(currentTvFrame != currentDrcFrame) {
currentDrcFrame->OnGameTitleAdded(info);

View File

@ -21,7 +21,6 @@
#include <queue>
#include <gui/Gui.h>
#include "game/GameList.h"
#include "system/CMutex.h"
#include "KeyboardHelper.h"
#include "gui/GuiTitleBrowser.h"
#include "MainDrcButtonsFrame.h"
@ -147,7 +146,7 @@ private:
GameList gameList;
CMutex guiMutex;
std::recursive_mutex guiMutex;
KeyboardHelper * keyboardInstance = NULL;
};

View File

@ -1,67 +0,0 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* 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, either version 3 of the License, or
* (at your option) any later version.
*
* 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef _CMUTEX_H_
#define _CMUTEX_H_
#include <malloc.h>
#include <coreinit/mutex.h>
class CMutex {
public:
CMutex() {
pMutex = (OSMutex*) malloc(sizeof(OSMutex));
if(!pMutex)
return;
OSInitMutex(pMutex);
}
virtual ~CMutex() {
if(pMutex)
free(pMutex);
}
void lock(void) {
if(pMutex)
OSLockMutex(pMutex);
}
void unlock(void) {
if(pMutex)
OSUnlockMutex(pMutex);
}
bool tryLock(void) {
if(!pMutex)
return false;
return (OSTryLockMutex(pMutex) != 0);
}
private:
OSMutex *pMutex;
};
class CMutexLock {
public:
CMutexLock() {
mutex.lock();
}
virtual ~CMutexLock() {
mutex.unlock();
}
private:
CMutex mutex;
};
#endif // _CMUTEX_H_

View File

@ -6,7 +6,6 @@
#include <future>
#include <thread>
#include <gui/GuiElement.h>
#include <system/CMutex.h>
#include <coreinit/cache.h>
#include "utils/logger.h"
@ -32,7 +31,7 @@ private:
DCFlushRange((void*)&exitThread, sizeof(exitThread));
}
CMutex mutex;
std::recursive_mutex mutex;
std::thread * thread;
volatile bool exitThread = false;