From 0cbff84489d1103fa614d78ea227ecda613574f6 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 31 Dec 2014 16:50:23 +0100 Subject: [PATCH] Draw "OSM" as a view. ES 3.0: Tell tilers to discard depth/stencil of the backbuffer. Also, don't even bind the UI texture unless there's UI to draw (probably negligible optimization). --- UI/EmuScreen.cpp | 97 ++++++++++++++++++++++-------------------- UI/OnScreenDisplay.cpp | 58 ++++++++++++++----------- UI/OnScreenDisplay.h | 22 +++++++++- UI/PauseScreen.cpp | 3 +- 4 files changed, 106 insertions(+), 74 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 82a8629c1d..0d5528d4d2 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -562,6 +562,7 @@ void EmuScreen::CreateViews() { if (g_Config.bShowDeveloperMenu) { root_->Add(new UI::Button("DevMenu"))->OnClick.Handle(this, &EmuScreen::OnDevTools); } + root_->Add(new OnScreenMessagesView(new UI::AnchorLayoutParams((UI::Size)bounds.w, (UI::Size)bounds.h))); } UI::EventReturn EmuScreen::OnDevTools(UI::EventParams ¶ms) { @@ -735,57 +736,61 @@ void EmuScreen::render() { thin3d->SetRenderState(T3DRenderState::CULL_MODE, T3DCullMode::NO_CULL); thin3d->SetScissorEnabled(false); - ui_draw2d.Begin(thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), DBMODE_NORMAL); + if (!osm.IsEmpty() || g_Config.bShowDebugStats || g_Config.iShowFPSCounter || g_Config.bShowTouchControls || g_Config.bShowDeveloperMenu) { + ui_draw2d.Begin(thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), DBMODE_NORMAL); - if (root_) { - UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_); - root_->Draw(*screenManager()->getUIContext()); - } - - if (!osm.IsEmpty()) { - osm.Draw(ui_draw2d, screenManager()->getUIContext()->GetBounds()); - } - - if (g_Config.bShowDebugStats) { - char statbuf[4096] = {0}; - __DisplayGetDebugStats(statbuf, sizeof(statbuf)); - ui_draw2d.SetFontScale(.7f, .7f); - ui_draw2d.DrawText(UBUNTU24, statbuf, 11, 11, 0xc0000000, FLAG_DYNAMIC_ASCII); - ui_draw2d.DrawText(UBUNTU24, statbuf, 10, 10, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); - ui_draw2d.SetFontScale(1.0f, 1.0f); - } - - if (g_Config.iShowFPSCounter) { - float vps, fps, actual_fps; - __DisplayGetFPS(&vps, &fps, &actual_fps); - char fpsbuf[256]; - switch (g_Config.iShowFPSCounter) { - case 1: - snprintf(fpsbuf, sizeof(fpsbuf), "Speed: %0.1f%%", vps / (59.94f / 100.0f)); break; - case 2: - snprintf(fpsbuf, sizeof(fpsbuf), "FPS: %0.1f", actual_fps); break; - case 3: - snprintf(fpsbuf, sizeof(fpsbuf), "%0.0f/%0.0f (%0.1f%%)", actual_fps, fps, vps / (59.94f / 100.0f)); break; - default: - return; + if (root_) { + UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_); + root_->Draw(*screenManager()->getUIContext()); } - const Bounds &bounds = screenManager()->getUIContext()->GetBounds(); - ui_draw2d.SetFontScale(0.7f, 0.7f); - ui_draw2d.DrawText(UBUNTU24, fpsbuf, bounds.x2() - 8, 12, 0xc0000000, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); - ui_draw2d.DrawText(UBUNTU24, fpsbuf, bounds.x2() - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); - ui_draw2d.SetFontScale(1.0f, 1.0f); + if (g_Config.bShowDebugStats) { + char statbuf[4096] = {0}; + __DisplayGetDebugStats(statbuf, sizeof(statbuf)); + ui_draw2d.SetFontScale(.7f, .7f); + ui_draw2d.DrawText(UBUNTU24, statbuf, 11, 11, 0xc0000000, FLAG_DYNAMIC_ASCII); + ui_draw2d.DrawText(UBUNTU24, statbuf, 10, 10, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + ui_draw2d.SetFontScale(1.0f, 1.0f); + } + + if (g_Config.iShowFPSCounter) { + float vps, fps, actual_fps; + __DisplayGetFPS(&vps, &fps, &actual_fps); + char fpsbuf[256]; + switch (g_Config.iShowFPSCounter) { + case 1: + snprintf(fpsbuf, sizeof(fpsbuf), "Speed: %0.1f%%", vps / (59.94f / 100.0f)); break; + case 2: + snprintf(fpsbuf, sizeof(fpsbuf), "FPS: %0.1f", actual_fps); break; + case 3: + snprintf(fpsbuf, sizeof(fpsbuf), "%0.0f/%0.0f (%0.1f%%)", actual_fps, fps, vps / (59.94f / 100.0f)); break; + default: + return; + } + + const Bounds &bounds = screenManager()->getUIContext()->GetBounds(); + ui_draw2d.SetFontScale(0.7f, 0.7f); + ui_draw2d.DrawText(UBUNTU24, fpsbuf, bounds.x2() - 8, 12, 0xc0000000, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); + ui_draw2d.DrawText(UBUNTU24, fpsbuf, bounds.x2() - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); + ui_draw2d.SetFontScale(1.0f, 1.0f); + } + + ui_draw2d.End(); + ui_draw2d.Flush(); } - ui_draw2d.End(); - ui_draw2d.Flush(); - - // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? -#if defined(USING_GLES2) - bool hasDiscard = gl_extensions.EXT_discard_framebuffer; // TODO - if (hasDiscard) { - //const GLenum targets[3] = { GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT }; - //glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, targets); +#ifdef USING_GLES2 + // We have no use for backbuffer depth or stencil, so let tiled renderers discard them after tiling. + if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) { + GLenum attachments[3] = { GL_DEPTH, GL_STENCIL }; + glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments); + } else if (!gl_extensions.GLES3) { + // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? + bool hasDiscard = gl_extensions.EXT_discard_framebuffer; // TODO + if (hasDiscard) { + //const GLenum targets[3] = { GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT }; + //glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, targets); + } } #endif } diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index 4bb80c5300..d21cd6c1fa 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -5,12 +5,43 @@ #include "base/timeutil.h" #include "gfx_es2/draw_buffer.h" +#include "ui/ui_context.h" + OnScreenMessages osm; -void OnScreenMessages::Draw(DrawBuffer &draw, const Bounds &bounds) { +void OnScreenMessagesView::Draw(UIContext &dc) { // First, clean out old messages. - std::lock_guard guard(mutex_); + osm.Lock(); + osm.Clean(); + // Get height + float w, h; + dc.Draw()->MeasureText(UBUNTU24, "Wg", &w, &h); + + float y = 10.0f; + // Then draw them all. + const std::list &messages = osm.Messages(); + for (auto iter = messages.begin(); iter != messages.end(); ++iter) { + float alpha = (iter->endTime - time_now_d()) * 4.0f; + if (alpha > 1.0) alpha = 1.0f; + if (alpha < 0.0) alpha = 0.0f; + // Messages that are wider than the screen are left-aligned instead of centered. + float tw, th; + dc.Draw()->MeasureText(UBUNTU24, iter->text.c_str(), &tw, &th); + float x = bounds_.centerX(); + int align = ALIGN_TOP | ALIGN_HCENTER; + if (tw > bounds_.w) { + align = ALIGN_TOP | ALIGN_LEFT; + x = 2; + } + dc.Draw()->DrawTextShadow(UBUNTU24, iter->text.c_str(), x, y, colorAlpha(iter->color, alpha), align); + y += h; + } + + osm.Unlock(); +} + +void OnScreenMessages::Clean() { restart: double now = time_now_d(); for (auto iter = messages_.begin(); iter != messages_.end(); iter++) { @@ -19,29 +50,6 @@ restart: goto restart; } } - - // Get height - float w, h; - draw.MeasureText(UBUNTU24, "Wg", &w, &h); - - float y = 10.0f; - // Then draw them all. - for (auto iter = messages_.begin(); iter != messages_.end(); ++iter) { - float alpha = (iter->endTime - time_now_d()) * 4.0f; - if (alpha > 1.0) alpha = 1.0f; - if (alpha < 0.0) alpha = 0.0f; - // Messages that are wider than the screen are left-aligned instead of centered. - float tw, th; - draw.MeasureText(UBUNTU24, iter->text.c_str(), &tw, &th); - float x = bounds.centerX(); - int align = ALIGN_TOP | ALIGN_HCENTER; - if (tw > bounds.w) { - align = ALIGN_TOP | ALIGN_LEFT; - x = 2; - } - draw.DrawTextShadow(UBUNTU24, iter->text.c_str(), x, y, colorAlpha(iter->color, alpha), align); - y += h; - } } void OnScreenMessages::Show(const std::string &message, float duration_s, uint32_t color, int icon, bool checkUnique) { diff --git a/UI/OnScreenDisplay.h b/UI/OnScreenDisplay.h index 8a3aa8a82d..2782728214 100644 --- a/UI/OnScreenDisplay.h +++ b/UI/OnScreenDisplay.h @@ -7,16 +7,25 @@ #include "math/geom2d.h" #include "Common/StdMutex.h" +#include "ui/view.h" + class DrawBuffer; class OnScreenMessages { public: void Show(const std::string &message, float duration_s = 1.0f, uint32_t color = 0xFFFFFF, int icon = -1, bool checkUnique = true); void ShowOnOff(const std::string &message, bool b, float duration_s = 1.0f, uint32_t color = 0xFFFFFF, int icon = -1); - void Draw(DrawBuffer &draw, const Bounds &bounds); bool IsEmpty() const { return messages_.empty(); } -private: + void Lock() { + mutex_.lock(); + } + void Unlock() { + mutex_.unlock(); + } + + void Clean(); + struct Message { int icon; uint32_t color; @@ -24,9 +33,18 @@ private: double endTime; double duration; }; + const std::list &Messages() { return messages_; } + +private: std::list messages_; std::recursive_mutex mutex_; }; +class OnScreenMessagesView : public UI::InertView { +public: + OnScreenMessagesView(UI::LayoutParams *layoutParams = nullptr) : UI::InertView(layoutParams) {} + void Draw(UIContext &dc); +}; + extern OnScreenMessages osm; diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 705eaf2dbf..b942d8b5b5 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -102,6 +102,7 @@ public: SaveSlotView(int slot, UI::LayoutParams *layoutParams = nullptr) : UI::LinearLayout(UI::ORIENT_HORIZONTAL, layoutParams), slot_(slot) { std::string filename = SaveState::GenerateSaveSlotFilename(slot, "jpg"); PrioritizedWorkQueue *wq = g_gameInfoCache.WorkQueue(); + Add(new UI::Spacer(10)); Add(new UI::TextView(StringFromFormat("%i", slot_ + 1), 0, false, new UI::LinearLayoutParams(0.0, UI::G_CENTER))); Add(new AsyncImageFileView(filename, UI::IS_DEFAULT, wq, new UI::LayoutParams(80 * 2, 45 * 2))); @@ -177,7 +178,7 @@ void GamePauseScreen::CreateViews() { root_ = new LinearLayout(ORIENT_HORIZONTAL); - ViewGroup *leftColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(510, FILL_PARENT, actionMenuMargins)); + ViewGroup *leftColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(520, FILL_PARENT, actionMenuMargins)); root_->Add(leftColumn); root_->Add(new Spacer(new LinearLayoutParams(1.0)));