diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 2b8645d277..a9c68f6621 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -253,7 +253,7 @@ void EmuScreen::render() { glstate.viewport.set(0, 0, pixel_xres, pixel_yres); glstate.viewport.restore(); - ui_draw2d.Begin(DBMODE_NORMAL); + ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL); if (g_Config.bShowTouchControls) DrawGamepad(ui_draw2d); @@ -262,7 +262,7 @@ void EmuScreen::render() { glsl_bind(UIShader_Get()); ui_draw2d.End(); - ui_draw2d.Flush(UIShader_Get()); + ui_draw2d.Flush(); // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index b552c03a09..e8812824ae 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -25,6 +25,9 @@ #include "Core/FileSystems/ISOFileSystem.h" #include "Core/FileSystems/DirectoryFileSystem.h" + +GameInfoCache g_gameInfoCache; + GameInfoCache::~GameInfoCache() { for (auto iter = info_.begin(); iter != info_.end(); iter++) { @@ -74,12 +77,28 @@ void GameInfoCache::FlushBGs() GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, bool wantBG) { auto iter = info_.find(gamePath); if (iter != info_.end()) { + GameInfo *info = iter->second; + if (info->iconTextureData.size()) { + info->iconTexture = new Texture(); + // TODO: We could actually do the PNG decoding as well on the async thread. + // We'd have to split up Texture->LoadPNG though, creating some intermediate Image class maybe. + if (info->iconTexture->LoadPNG((const u8 *)info->iconTextureData.data(), info->iconTextureData.size())) { + info->timeIconWasLoaded = time_now_d(); + } + info->iconTextureData.clear(); + } + if (info->bgTextureData.size()) { + info->bgTexture = new Texture(); + if (info->bgTexture->LoadPNG((const u8 *)info->bgTextureData.data(), info->bgTextureData.size())) { + info->timeBgWasLoaded = time_now_d(); + } + info->bgTextureData.clear(); + } iter->second->lastAccessedTime = time_now_d(); return iter->second; } GameInfo *info = new GameInfo(); - info_[gamePath] = info; // return info; @@ -88,8 +107,9 @@ GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, bool wantBG) { // A game can be either an UMD or a directory under ms0:/PSP/GAME . if (startsWith(gamePath, "ms0:/PSP/GAME")) { - + return 0; } else { + info_[gamePath] = info; SequentialHandleAllocator handles; // Let's assume it's an ISO. // TODO: This will currently read in the whole directory tree. Not really necessary for just a @@ -104,27 +124,11 @@ GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, bool wantBG) { info->title = info->paramSFO.GetValueString("TITLE"); } - std::string imgContents; - if (ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &imgContents)) { - lock_guard lock(info->lock); - info->iconTexture = new Texture(); - if (info->iconTexture->LoadPNG((const u8 *)imgContents.data(), imgContents.size())) { - info->timeIconWasLoaded = time_now_d(); - } - } - + ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info->iconTextureData); if (wantBG) { - if (ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &imgContents)) { - lock_guard lock(info->lock); - info->bgTexture = new Texture(); - info->bgTexture->LoadPNG((const u8 *)imgContents.data(), imgContents.size()); - if (info->bgTexture->LoadPNG((const u8 *)imgContents.data(), imgContents.size())) { - info->timeBGWasLoaded = time_now_d(); - } - } + ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info->bgTextureData); } } - info_[gamePath] = info; return info; } diff --git a/UI/GameInfoCache.h b/UI/GameInfoCache.h index 6cbb4ce8ae..c24b19ad13 100644 --- a/UI/GameInfoCache.h +++ b/UI/GameInfoCache.h @@ -35,8 +35,10 @@ struct GameInfo { std::string title; // for easy access, also available in paramSFO. ParamSFOData paramSFO; - // For display. + // Pre read the data, create a texture the next time (GL thread..) + std::string iconTextureData; Texture *iconTexture; + std::string bgTextureData; Texture *bgTexture; double lastAccessedTime; @@ -44,7 +46,7 @@ struct GameInfo { // The time at which the Icon and the BG were loaded. // Can be useful to fade them in smoothly once they appear. double timeIconWasLoaded; - double timeBGWasLoaded; + double timeBgWasLoaded; }; class GameInfoCache { @@ -66,4 +68,7 @@ public: private: // Maps ISO path to info. std::map info_; -}; \ No newline at end of file +}; + +// This one can be global, no good reason not to. +extern GameInfoCache g_gameInfoCache; \ No newline at end of file diff --git a/UI/MenuScreens.cpp b/UI/MenuScreens.cpp index 3b03f7f50e..affdafcb0c 100644 --- a/UI/MenuScreens.cpp +++ b/UI/MenuScreens.cpp @@ -55,6 +55,7 @@ namespace MainWindow { #include "MenuScreens.h" #include "EmuScreen.h" +#include "GameInfoCache.h" #include "android/jni/TestRunner.h" #ifdef USING_QT_UI @@ -63,11 +64,9 @@ namespace MainWindow { #include #endif - // Ugly communication with NativeApp extern std::string game_title; - static const int symbols[4] = { I_CROSS, I_CIRCLE, @@ -142,7 +141,7 @@ void LogoScreen::render() { if (t > 2.0f) alphaText = 3.0f - t; UIShader_Prepare(); - UIBegin(); + UIBegin(UIShader_Get()); DrawBackground(alpha); ui_draw2d.SetFontScale(1.5f, 1.5f); @@ -157,9 +156,6 @@ void LogoScreen::render() { DrawWatermark(); UIEnd(); - - glsl_bind(UIShader_Get()); - ui_draw2d.Flush(UIShader_Get()); } @@ -180,7 +176,7 @@ void MenuScreen::sendMessage(const char *message, const char *value) { void MenuScreen::render() { UIShader_Prepare(); - UIBegin(); + UIBegin(UIShader_Get()); DrawBackground(1.0f); double xoff = 150 - frames_ * frames_ * 0.4f; @@ -258,16 +254,25 @@ void MenuScreen::render() { for (size_t j = 0; j < rec.size(); j++) if (rec[j] == '\\') rec[j] = '/'; SplitPath(rec, nullptr, &filename, nullptr); - if (UIButton(GEN_ID_LOOP(i), vlinear2, recentW, filename.c_str(), ALIGN_LEFT)) { - screenManager()->switchScreen(new EmuScreen(g_Config.recentIsos[i])); + + UIContext *ctx = screenManager()->getUIContext(); + // This might create a texture so we must flush first. + UIFlush(); + GameInfo *ginfo = g_gameInfoCache.GetInfo(g_Config.recentIsos[i], false); + + if (ginfo) { + if (UITextureButton(ctx, GEN_ID_LOOP(i), vlinear2, 144, 80, ginfo->iconTexture, ALIGN_LEFT)) { + screenManager()->switchScreen(new EmuScreen(g_Config.recentIsos[i])); + } + } else { + if (UIButton(GEN_ID_LOOP(i), vlinear2, recentW, filename.c_str(), ALIGN_LEFT)) { + screenManager()->switchScreen(new EmuScreen(g_Config.recentIsos[i])); + } } } DrawWatermark(); UIEnd(); - - glsl_bind(UIShader_Get()); - ui_draw2d.Flush(UIShader_Get()); } @@ -286,7 +291,7 @@ void PauseScreen::sendMessage(const char *msg, const char *value) { void PauseScreen::render() { UIShader_Prepare(); - UIBegin(); + UIBegin(UIShader_Get()); DrawBackground(1.0f); const char *title; @@ -351,9 +356,6 @@ void PauseScreen::render() { DrawWatermark(); UIEnd(); - - glsl_bind(UIShader_Get()); - ui_draw2d.Flush(UIShader_Get()); } void SettingsScreen::update(InputState &input) { @@ -366,7 +368,7 @@ void SettingsScreen::update(InputState &input) { void SettingsScreen::render() { UIShader_Prepare(); - UIBegin(); + UIBegin(UIShader_Get()); DrawBackground(1.0f); ui_draw2d.DrawText(UBUNTU48, "Settings", dp_xres / 2, 20, 0xFFFFFFFF, ALIGN_HCENTER); @@ -425,9 +427,6 @@ void SettingsScreen::render() { } UIEnd(); - - glsl_bind(UIShader_Get()); - ui_draw2d.Flush(UIShader_Get()); } void DeveloperScreen::update(InputState &input) { @@ -439,7 +438,7 @@ void DeveloperScreen::update(InputState &input) { void DeveloperScreen::render() { UIShader_Prepare(); - UIBegin(); + UIBegin(UIShader_Get()); DrawBackground(1.0f); ui_draw2d.DrawText(UBUNTU48, "Developer Tools", dp_xres / 2, 20, 0xFFFFFFFF, ALIGN_HCENTER); @@ -460,9 +459,6 @@ void DeveloperScreen::render() { } UIEnd(); - - glsl_bind(UIShader_Get()); - ui_draw2d.Flush(UIShader_Get()); } @@ -519,7 +515,7 @@ void FileSelectScreen::render() { FileListAdapter adapter(options_, &listing_); UIShader_Prepare(); - UIBegin(); + UIBegin(UIShader_Get()); DrawBackground(1.0f); if (list_.Do(GEN_ID, 10, BUTTON_HEIGHT + 20, dp_xres-20, dp_yres - BUTTON_HEIGHT - 30, &adapter)) { @@ -552,9 +548,6 @@ void FileSelectScreen::render() { } #endif UIEnd(); - - glsl_bind(UIShader_Get()); - ui_draw2d.Flush(UIShader_Get()); } void CreditsScreen::update(InputState &input_state) { @@ -631,7 +624,7 @@ void CreditsScreen::render() { credits[0] = (const char *)temp; UIShader_Prepare(); - UIBegin(); + UIBegin(UIShader_Get()); DrawBackground(1.0f); const int numItems = ARRAY_SIZE(credits); @@ -651,9 +644,6 @@ void CreditsScreen::render() { } UIEnd(); - - glsl_bind(UIShader_Get()); - ui_draw2d.Flush(UIShader_Get()); } void ErrorScreen::update(InputState &input_state) { @@ -665,7 +655,7 @@ void ErrorScreen::update(InputState &input_state) { void ErrorScreen::render() { UIShader_Prepare(); - UIBegin(); + UIBegin(UIShader_Get()); DrawBackground(1.0f); ui_draw2d.DrawText(UBUNTU48, errorTitle_.c_str(), dp_xres / 2, 30, 0xFFFFFFFF, ALIGN_HCENTER); @@ -676,7 +666,4 @@ void ErrorScreen::render() } UIEnd(); - - glsl_bind(UIShader_Get()); - ui_draw2d.Flush(UIShader_Get()); } diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 1e389ad23e..b569698ca4 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -35,6 +35,7 @@ #include "math/lin/matrix4x4.h" #include "ui/screen.h" #include "ui/ui.h" +#include "ui/ui_context.h" #include "base/mutex.h" #include "FileUtil.h" @@ -65,6 +66,7 @@ recursive_mutex pendingMutex; static bool isMessagePending; static std::string pendingMessage; static std::string pendingValue; +static UIContext *uiContext; class AndroidLogger : public LogListener @@ -339,6 +341,11 @@ void NativeInitGraphics() } uiTexture->Bind(0); + uiContext = new UIContext(); + uiContext->Init(UIShader_Get(), UIShader_GetPlain(), uiTexture, &ui_draw2d, &ui_draw2d_front); + + screenManager->setUIContext(uiContext); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); diff --git a/UI/UIShader.cpp b/UI/UIShader.cpp index 054d970b0a..cf23a64f4c 100644 --- a/UI/UIShader.cpp +++ b/UI/UIShader.cpp @@ -76,6 +76,12 @@ GLSLProgram *UIShader_Get() return glslModulate; } + +GLSLProgram *UIShader_GetPlain() +{ + return glslPlain; +} + void UIShader_Shutdown() { glsl_destroy(glslModulate); diff --git a/native b/native index faf8b260ed..7ec766a980 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit faf8b260ed7617aaa08e6d420db95e03eef659d3 +Subproject commit 7ec766a980dd9f77c407f482d8b570c43f35461c