From e8bd6b1fcc5abd4813cda08b4921c94ada89509d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 19 Jan 2019 21:03:26 -0700 Subject: QT: Upgrade the Loading Bar to look much better --- src/yuzu/loading_screen.cpp | 108 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 6 deletions(-) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index 0f3c4bb6c..617b8c858 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include #include @@ -13,10 +14,12 @@ #include #include #include -#include +#include +#include #include "common/logging/log.h" #include "core/loader/loader.h" #include "ui_loading_screen.h" +#include "video_core/rasterizer_interface.h" #include "yuzu/loading_screen.h" // Mingw seems to not have QMovie at all. If QMovie is missing then use a single frame instead of an @@ -26,10 +29,63 @@ #endif LoadingScreen::LoadingScreen(QWidget* parent) - : QWidget(parent), ui(std::make_unique()) { + : QWidget(parent), ui(std::make_unique()), + previous_stage(VideoCore::LoadCallbackStage::Complete) { ui->setupUi(this); - // Progress bar is hidden until we have a use for it. - ui->progress_bar->hide(); + + connect(this, &LoadingScreen::LoadProgress, this, &LoadingScreen::OnLoadProgress, + Qt::QueuedConnection); + qRegisterMetaType(); + + stage_translations = { + {VideoCore::LoadCallbackStage::Prepare, tr("Loading...")}, + {VideoCore::LoadCallbackStage::Raw, tr("Preparing Shaders %1 / %2")}, + {VideoCore::LoadCallbackStage::Binary, tr("Loading Shaders %1 / %2")}, + {VideoCore::LoadCallbackStage::Complete, tr("Launching...")}, + }; + progressbar_style = { + {VideoCore::LoadCallbackStage::Prepare, + R"( +QProgressBar { + background-color: black; +} +QProgressBar::chunk { + background-color: white; +})"}, + {VideoCore::LoadCallbackStage::Raw, + R"( +QProgressBar { + background-color: black; + border: 2px solid white; + border-radius: 4px; + padding: 2px; +} +QProgressBar::chunk { + background-color: #0ab9e6; +})"}, + {VideoCore::LoadCallbackStage::Binary, + R"( +QProgressBar { + background-color: black; + border: 2px solid white; + border-radius: 4px; + padding: 2px; +} +QProgressBar::chunk { + background-color: #ff3c28; +})"}, + {VideoCore::LoadCallbackStage::Complete, + R"( +QProgressBar { + background-color: black; + border: 2px solid white; + border-radius: 4px; + padding: 2px; +} +QProgressBar::chunk { + background-color: #ff3c28; +})"}, + }; } LoadingScreen::~LoadingScreen() = default; @@ -46,7 +102,7 @@ void LoadingScreen::Prepare(Loader::AppLoader& loader) { std::make_unique(reinterpret_cast(buffer.data()), buffer.size()); backing_buf = std::make_unique(backing_mem.get()); backing_buf->open(QIODevice::ReadOnly); - animation = std::make_unique(backing_buf.get(), QByteArray("GIF")); + animation = std::make_unique(backing_buf.get(), QByteArray()); animation->start(); ui->banner->setMovie(animation.get()); #endif @@ -57,14 +113,54 @@ void LoadingScreen::Prepare(Loader::AppLoader& loader) { map.loadFromData(buffer.data(), buffer.size()); ui->logo->setPixmap(map); } + + OnLoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 100); } -void LoadingScreen::OnLoadProgress(std::size_t value, std::size_t total) { +void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, + std::size_t total) { + using namespace std::chrono; + auto now = high_resolution_clock::now(); + // reset the timer if the stage changes + if (stage != previous_stage) { + ui->progress_bar->setStyleSheet(progressbar_style[stage]); + previous_stage = stage; + // reset back to fast shader compiling since the stage changed + slow_shader_compile_start = false; + } + // update the max of the progress bar if the number of shaders change if (total != previous_total) { ui->progress_bar->setMaximum(total); previous_total = total; } + + QString estimate; + // If theres a drastic slowdown in the rate, then display an estimate + if (now - previous_time > milliseconds{20}) { + if (!slow_shader_compile_start) { + slow_shader_start = high_resolution_clock::now(); + slow_shader_compile_start = true; + slow_shader_first_value = value; + } + // only calculate an estimate time after a second has passed since stage change + auto diff = duration_cast(now - slow_shader_start); + if (diff > seconds{1}) { + auto eta_mseconds = + static_cast(static_cast(total - slow_shader_first_value) / + (value - slow_shader_first_value) * diff.count()); + estimate = + tr("Estimated Time %1") + .arg(QTime(0, 0, 0, 0) + .addMSecs(std::max(eta_mseconds - diff.count() + 1000, 1000)) + .toString("mm:ss")); + } + } + + // update labels and progress bar + ui->stage->setText(stage_translations[stage].arg(value).arg(total)); + ui->value->setText(estimate); ui->progress_bar->setValue(value); + previous_time = now; } void LoadingScreen::paintEvent(QPaintEvent* event) { -- cgit v1.2.3 From 63783db1b3ad50b8b7d4448ebb3195db7706742c Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sun, 20 Jan 2019 15:09:14 -0700 Subject: Hide progress bar on Prepare step --- src/yuzu/loading_screen.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index 617b8c858..530f5173c 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -46,12 +46,8 @@ LoadingScreen::LoadingScreen(QWidget* parent) progressbar_style = { {VideoCore::LoadCallbackStage::Prepare, R"( -QProgressBar { - background-color: black; -} -QProgressBar::chunk { - background-color: white; -})"}, +QProgressBar {} +QProgressBar::chunk {})"}, {VideoCore::LoadCallbackStage::Raw, R"( QProgressBar { @@ -114,7 +110,7 @@ void LoadingScreen::Prepare(Loader::AppLoader& loader) { ui->logo->setPixmap(map); } - OnLoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 100); + OnLoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); } void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, @@ -124,6 +120,11 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size // reset the timer if the stage changes if (stage != previous_stage) { ui->progress_bar->setStyleSheet(progressbar_style[stage]); + if (stage == VideoCore::LoadCallbackStage::Prepare) { + ui->progress_bar->hide(); + } else { + ui->progress_bar->show(); + } previous_stage = stage; // reset back to fast shader compiling since the stage changed slow_shader_compile_start = false; -- cgit v1.2.3 From 4bce57b1495aec153041da0cb5bd5be8f518aea8 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sun, 20 Jan 2019 18:20:21 -0700 Subject: Move progress bar style into constexpr strings --- src/yuzu/loading_screen.cpp | 60 ++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 28 deletions(-) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index 530f5173c..608ab6f02 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -28,28 +28,11 @@ #include #endif -LoadingScreen::LoadingScreen(QWidget* parent) - : QWidget(parent), ui(std::make_unique()), - previous_stage(VideoCore::LoadCallbackStage::Complete) { - ui->setupUi(this); - - connect(this, &LoadingScreen::LoadProgress, this, &LoadingScreen::OnLoadProgress, - Qt::QueuedConnection); - qRegisterMetaType(); - - stage_translations = { - {VideoCore::LoadCallbackStage::Prepare, tr("Loading...")}, - {VideoCore::LoadCallbackStage::Raw, tr("Preparing Shaders %1 / %2")}, - {VideoCore::LoadCallbackStage::Binary, tr("Loading Shaders %1 / %2")}, - {VideoCore::LoadCallbackStage::Complete, tr("Launching...")}, - }; - progressbar_style = { - {VideoCore::LoadCallbackStage::Prepare, - R"( +constexpr const char* PROGRESSBAR_STYLE_PREPARE = R"( QProgressBar {} -QProgressBar::chunk {})"}, - {VideoCore::LoadCallbackStage::Raw, - R"( +QProgressBar::chunk {})"; + +constexpr const char* PROGRESSBAR_STYLE_RAW = R"( QProgressBar { background-color: black; border: 2px solid white; @@ -58,9 +41,9 @@ QProgressBar { } QProgressBar::chunk { background-color: #0ab9e6; -})"}, - {VideoCore::LoadCallbackStage::Binary, - R"( +})"; + +constexpr const char* PROGRESSBAR_STYLE_BINARY = R"( QProgressBar { background-color: black; border: 2px solid white; @@ -69,9 +52,9 @@ QProgressBar { } QProgressBar::chunk { background-color: #ff3c28; -})"}, - {VideoCore::LoadCallbackStage::Complete, - R"( +})"; + +constexpr const char* PROGRESSBAR_STYLE_COMPLETE = R"( QProgressBar { background-color: black; border: 2px solid white; @@ -80,7 +63,28 @@ QProgressBar { } QProgressBar::chunk { background-color: #ff3c28; -})"}, +})"; + +LoadingScreen::LoadingScreen(QWidget* parent) + : QWidget(parent), ui(std::make_unique()), + previous_stage(VideoCore::LoadCallbackStage::Complete) { + ui->setupUi(this); + + connect(this, &LoadingScreen::LoadProgress, this, &LoadingScreen::OnLoadProgress, + Qt::QueuedConnection); + qRegisterMetaType(); + + stage_translations = { + {VideoCore::LoadCallbackStage::Prepare, tr("Loading...")}, + {VideoCore::LoadCallbackStage::Raw, tr("Preparing Shaders %1 / %2")}, + {VideoCore::LoadCallbackStage::Binary, tr("Loading Shaders %1 / %2")}, + {VideoCore::LoadCallbackStage::Complete, tr("Launching...")}, + }; + progressbar_style = { + {VideoCore::LoadCallbackStage::Prepare, PROGRESSBAR_STYLE_PREPARE}, + {VideoCore::LoadCallbackStage::Raw, PROGRESSBAR_STYLE_RAW}, + {VideoCore::LoadCallbackStage::Binary, PROGRESSBAR_STYLE_BINARY}, + {VideoCore::LoadCallbackStage::Complete, PROGRESSBAR_STYLE_COMPLETE}, }; } -- cgit v1.2.3 From 56541b1ae5078ed0b47fefb963d38b46c3f7858b Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sun, 20 Jan 2019 18:22:29 -0700 Subject: Prevent estimated time from flashing after slow shader compilation starts --- src/yuzu/loading_screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index 608ab6f02..ffa7f5bb2 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -141,7 +141,7 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size QString estimate; // If theres a drastic slowdown in the rate, then display an estimate - if (now - previous_time > milliseconds{20}) { + if (now - previous_time > milliseconds{50} || slow_shader_compile_start) { if (!slow_shader_compile_start) { slow_shader_start = high_resolution_clock::now(); slow_shader_compile_start = true; -- cgit v1.2.3 From ea73ffe202e44ed45191eea10bbecbf35e158f32 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sun, 20 Jan 2019 18:40:25 -0700 Subject: Rename step 1 and step 2 to be a little more descriptive --- src/yuzu/loading_screen.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index ffa7f5bb2..9ce606863 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -32,7 +32,7 @@ constexpr const char* PROGRESSBAR_STYLE_PREPARE = R"( QProgressBar {} QProgressBar::chunk {})"; -constexpr const char* PROGRESSBAR_STYLE_RAW = R"( +constexpr const char* PROGRESSBAR_STYLE_DECOMPILE = R"( QProgressBar { background-color: black; border: 2px solid white; @@ -43,7 +43,7 @@ QProgressBar::chunk { background-color: #0ab9e6; })"; -constexpr const char* PROGRESSBAR_STYLE_BINARY = R"( +constexpr const char* PROGRESSBAR_STYLE_BUILD = R"( QProgressBar { background-color: black; border: 2px solid white; @@ -76,14 +76,14 @@ LoadingScreen::LoadingScreen(QWidget* parent) stage_translations = { {VideoCore::LoadCallbackStage::Prepare, tr("Loading...")}, - {VideoCore::LoadCallbackStage::Raw, tr("Preparing Shaders %1 / %2")}, - {VideoCore::LoadCallbackStage::Binary, tr("Loading Shaders %1 / %2")}, + {VideoCore::LoadCallbackStage::Decompile, tr("Preparing Shaders %1 / %2")}, + {VideoCore::LoadCallbackStage::Build, tr("Loading Shaders %1 / %2")}, {VideoCore::LoadCallbackStage::Complete, tr("Launching...")}, }; progressbar_style = { {VideoCore::LoadCallbackStage::Prepare, PROGRESSBAR_STYLE_PREPARE}, - {VideoCore::LoadCallbackStage::Raw, PROGRESSBAR_STYLE_RAW}, - {VideoCore::LoadCallbackStage::Binary, PROGRESSBAR_STYLE_BINARY}, + {VideoCore::LoadCallbackStage::Decompile, PROGRESSBAR_STYLE_DECOMPILE}, + {VideoCore::LoadCallbackStage::Build, PROGRESSBAR_STYLE_BUILD}, {VideoCore::LoadCallbackStage::Complete, PROGRESSBAR_STYLE_COMPLETE}, }; } -- cgit v1.2.3 From 636cc2a4964f99bfa2d5ca12baf10357cf80ba8d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sun, 20 Jan 2019 19:14:14 -0700 Subject: Change the background color of Stage Complete to yuzu blue --- src/yuzu/loading_screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index 9ce606863..ae4d4a249 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -56,7 +56,7 @@ QProgressBar::chunk { constexpr const char* PROGRESSBAR_STYLE_COMPLETE = R"( QProgressBar { - background-color: black; + background-color: #0ab9e6; border: 2px solid white; border-radius: 4px; padding: 2px; -- cgit v1.2.3 From 3740adb6f582963e50afba0a248163e3a37dd659 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 21 Jan 2019 08:51:37 -0700 Subject: Set Minimum Size to the same as renderwindow --- src/yuzu/loading_screen.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index ae4d4a249..63c547b49 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -69,6 +69,7 @@ LoadingScreen::LoadingScreen(QWidget* parent) : QWidget(parent), ui(std::make_unique()), previous_stage(VideoCore::LoadCallbackStage::Complete) { ui->setupUi(this); + setMinimumSize(1280, 720); connect(this, &LoadingScreen::LoadProgress, this, &LoadingScreen::OnLoadProgress, Qt::QueuedConnection); -- cgit v1.2.3 From 3ca0af8bb3dfd7c67320a842db8eabe198058bd6 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 21 Jan 2019 09:20:16 -0700 Subject: Add fade out effect to the loading screen --- src/yuzu/loading_screen.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index 63c547b49..76ef86b8c 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -13,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +73,25 @@ LoadingScreen::LoadingScreen(QWidget* parent) ui->setupUi(this); setMinimumSize(1280, 720); + // Create a fade out effect to hide this loading screen widget. + // When fading opacity, it will fade to the parent widgets background color, which is why we + // create an internal widget named fade_widget that we use the effect on, while keeping the + // loading screen widget's background color black. This way we can create a fade to black effect + opacity_effect = new QGraphicsOpacityEffect(this); + opacity_effect->setOpacity(1); + ui->fade_parent->setGraphicsEffect(opacity_effect); + fadeout_animation = std::make_unique(opacity_effect, "opacity"); + fadeout_animation->setDuration(500); + fadeout_animation->setStartValue(1); + fadeout_animation->setEndValue(0); + fadeout_animation->setEasingCurve(QEasingCurve::OutBack); + + // After the fade completes, hide the widget and reset the opacity + connect(fadeout_animation.get(), &QPropertyAnimation::finished, [this] { + hide(); + opacity_effect->setOpacity(1); + emit Hidden(); + }); connect(this, &LoadingScreen::LoadProgress, this, &LoadingScreen::OnLoadProgress, Qt::QueuedConnection); qRegisterMetaType(); @@ -115,9 +136,14 @@ void LoadingScreen::Prepare(Loader::AppLoader& loader) { ui->logo->setPixmap(map); } + slow_shader_compile_start = false; OnLoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); } +void LoadingScreen::OnLoadComplete() { + fadeout_animation->start(QPropertyAnimation::KeepWhenStopped); +} + void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { using namespace std::chrono; @@ -125,6 +151,7 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size // reset the timer if the stage changes if (stage != previous_stage) { ui->progress_bar->setStyleSheet(progressbar_style[stage]); + // Hide the progress bar during the prepare stage if (stage == VideoCore::LoadCallbackStage::Prepare) { ui->progress_bar->hide(); } else { -- cgit v1.2.3 From 372245e0b52a738148a9291fbe448e3c61fa07bd Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 21 Jan 2019 09:39:45 -0700 Subject: Fix mingw compile error and warnings --- src/yuzu/loading_screen.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index 76ef86b8c..8ac7f5059 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -120,8 +120,8 @@ void LoadingScreen::Prepare(Loader::AppLoader& loader) { map.loadFromData(buffer.data(), buffer.size()); ui->banner->setPixmap(map); #else - backing_mem = - std::make_unique(reinterpret_cast(buffer.data()), buffer.size()); + backing_mem = std::make_unique(reinterpret_cast(buffer.data()), + static_cast(buffer.size())); backing_buf = std::make_unique(backing_mem.get()); backing_buf->open(QIODevice::ReadOnly); animation = std::make_unique(backing_buf.get(), QByteArray()); @@ -132,7 +132,7 @@ void LoadingScreen::Prepare(Loader::AppLoader& loader) { } if (loader.ReadLogo(buffer) == Loader::ResultStatus::Success) { QPixmap map; - map.loadFromData(buffer.data(), buffer.size()); + map.loadFromData(buffer.data(), static_cast(buffer.size())); ui->logo->setPixmap(map); } @@ -163,7 +163,7 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size } // update the max of the progress bar if the number of shaders change if (total != previous_total) { - ui->progress_bar->setMaximum(total); + ui->progress_bar->setMaximum(static_cast(total)); previous_total = total; } @@ -192,7 +192,7 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size // update labels and progress bar ui->stage->setText(stage_translations[stage].arg(value).arg(total)); ui->value->setText(estimate); - ui->progress_bar->setValue(value); + ui->progress_bar->setValue(static_cast(value)); previous_time = now; } -- cgit v1.2.3 From 3049ea45d3f1621e48714022a195f6a2971dce56 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 21 Jan 2019 10:28:32 -0700 Subject: Change const char* to const char[] --- src/yuzu/loading_screen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index 8ac7f5059..907aac4f1 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -30,11 +30,11 @@ #include #endif -constexpr const char* PROGRESSBAR_STYLE_PREPARE = R"( +constexpr const char PROGRESSBAR_STYLE_PREPARE[] = R"( QProgressBar {} QProgressBar::chunk {})"; -constexpr const char* PROGRESSBAR_STYLE_DECOMPILE = R"( +constexpr const char PROGRESSBAR_STYLE_DECOMPILE[] = R"( QProgressBar { background-color: black; border: 2px solid white; @@ -45,7 +45,7 @@ QProgressBar::chunk { background-color: #0ab9e6; })"; -constexpr const char* PROGRESSBAR_STYLE_BUILD = R"( +constexpr const char PROGRESSBAR_STYLE_BUILD[] = R"( QProgressBar { background-color: black; border: 2px solid white; @@ -56,7 +56,7 @@ QProgressBar::chunk { background-color: #ff3c28; })"; -constexpr const char* PROGRESSBAR_STYLE_COMPLETE = R"( +constexpr const char PROGRESSBAR_STYLE_COMPLETE[] = R"( QProgressBar { background-color: #0ab9e6; border: 2px solid white; -- cgit v1.2.3