aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
authorflow <flowlnlnln@gmail.com>2022-12-11 04:16:21 -0800
committerGitHub <noreply@github.com>2022-12-11 04:16:21 -0800
commit5622bcc5632a0706634da1ab519a3346a018b159 (patch)
treec0bcd17c16c76945cde3d9a05519b4edbb66730f /launcher
parent4a13d72997d4ed4d7f0df72c80c6e0aaabfea1e0 (diff)
parentc4c1e75de8825a4af403046536a7b2acd72a56c3 (diff)
downloadPrismLauncher-5622bcc5632a0706634da1ab519a3346a018b159.tar.gz
PrismLauncher-5622bcc5632a0706634da1ab519a3346a018b159.tar.bz2
PrismLauncher-5622bcc5632a0706634da1ab519a3346a018b159.zip
Merge pull request #461 from flowln/fix_big_resource_pack_imgs
Fixes https://github.com/PrismLauncher/PrismLauncher/issues/360
Diffstat (limited to 'launcher')
-rw-r--r--launcher/Application.cpp6
-rw-r--r--launcher/CMakeLists.txt2
-rw-r--r--launcher/MTPixmapCache.h95
-rw-r--r--launcher/minecraft/mod/ResourcePack.cpp14
4 files changed, 114 insertions, 3 deletions
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 4ba9eb9b..ab23f013 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -97,6 +97,7 @@
#include <QIcon>
#include "InstanceList.h"
+#include "MTPixmapCache.h"
#include <minecraft/auth/AccountList.h>
#include "icons/IconList.h"
@@ -141,6 +142,8 @@
static const QLatin1String liveCheckFile("live.check");
+PixmapCache* PixmapCache::s_instance = nullptr;
+
namespace {
void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
@@ -693,6 +696,9 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_globalSettingsProvider->addPage<AccountListPage>();
m_globalSettingsProvider->addPage<APIPage>();
}
+
+ PixmapCache::setInstance(new PixmapCache(this));
+
qDebug() << "<> Settings loaded.";
}
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 245b6995..33086121 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -89,6 +89,8 @@ set(CORE_SOURCES
# Time
MMCTime.h
MMCTime.cpp
+
+ MTPixmapCache.h
)
set(PATHMATCHER_SOURCES
diff --git a/launcher/MTPixmapCache.h b/launcher/MTPixmapCache.h
new file mode 100644
index 00000000..57847a0e
--- /dev/null
+++ b/launcher/MTPixmapCache.h
@@ -0,0 +1,95 @@
+#pragma once
+
+#include <QCoreApplication>
+#include <QPixmapCache>
+#include <QThread>
+
+#define GET_TYPE() \
+ Qt::ConnectionType type; \
+ if (QThread::currentThread() != QCoreApplication::instance()->thread()) \
+ type = Qt::BlockingQueuedConnection; \
+ else \
+ type = Qt::DirectConnection;
+
+#define DEFINE_FUNC_NO_PARAM(NAME, RET_TYPE) \
+ static RET_TYPE NAME() \
+ { \
+ RET_TYPE ret; \
+ GET_TYPE() \
+ QMetaObject::invokeMethod(s_instance, "_" #NAME, type, Q_RETURN_ARG(RET_TYPE, ret)); \
+ return ret; \
+ }
+#define DEFINE_FUNC_ONE_PARAM(NAME, RET_TYPE, PARAM_1_TYPE) \
+ static RET_TYPE NAME(PARAM_1_TYPE p1) \
+ { \
+ RET_TYPE ret; \
+ GET_TYPE() \
+ QMetaObject::invokeMethod(s_instance, "_" #NAME, type, Q_RETURN_ARG(RET_TYPE, ret), Q_ARG(PARAM_1_TYPE, p1)); \
+ return ret; \
+ }
+#define DEFINE_FUNC_TWO_PARAM(NAME, RET_TYPE, PARAM_1_TYPE, PARAM_2_TYPE) \
+ static RET_TYPE NAME(PARAM_1_TYPE p1, PARAM_2_TYPE p2) \
+ { \
+ RET_TYPE ret; \
+ GET_TYPE() \
+ QMetaObject::invokeMethod(s_instance, "_" #NAME, type, Q_RETURN_ARG(RET_TYPE, ret), Q_ARG(PARAM_1_TYPE, p1), \
+ Q_ARG(PARAM_2_TYPE, p2)); \
+ return ret; \
+ }
+
+/** A wrapper around QPixmapCache with thread affinity with the main thread.
+ */
+class PixmapCache final : public QObject {
+ Q_OBJECT
+
+ public:
+ PixmapCache(QObject* parent) : QObject(parent) {}
+ ~PixmapCache() override = default;
+
+ static PixmapCache& instance() { return *s_instance; }
+ static void setInstance(PixmapCache* i) { s_instance = i; }
+
+ public:
+ DEFINE_FUNC_NO_PARAM(cacheLimit, int)
+ DEFINE_FUNC_NO_PARAM(clear, bool)
+ DEFINE_FUNC_TWO_PARAM(find, bool, const QString&, QPixmap*)
+ DEFINE_FUNC_TWO_PARAM(find, bool, const QPixmapCache::Key&, QPixmap*)
+ DEFINE_FUNC_TWO_PARAM(insert, bool, const QString&, const QPixmap&)
+ DEFINE_FUNC_ONE_PARAM(insert, QPixmapCache::Key, const QPixmap&)
+ DEFINE_FUNC_ONE_PARAM(remove, bool, const QString&)
+ DEFINE_FUNC_ONE_PARAM(remove, bool, const QPixmapCache::Key&)
+ DEFINE_FUNC_TWO_PARAM(replace, bool, const QPixmapCache::Key&, const QPixmap&)
+ DEFINE_FUNC_ONE_PARAM(setCacheLimit, bool, int)
+
+ // NOTE: Every function returns something non-void to simplify the macros.
+ private slots:
+ int _cacheLimit() { return QPixmapCache::cacheLimit(); }
+ bool _clear()
+ {
+ QPixmapCache::clear();
+ return true;
+ }
+ bool _find(const QString& key, QPixmap* pixmap) { return QPixmapCache::find(key, pixmap); }
+ bool _find(const QPixmapCache::Key& key, QPixmap* pixmap) { return QPixmapCache::find(key, pixmap); }
+ bool _insert(const QString& key, const QPixmap& pixmap) { return QPixmapCache::insert(key, pixmap); }
+ QPixmapCache::Key _insert(const QPixmap& pixmap) { return QPixmapCache::insert(pixmap); }
+ bool _remove(const QString& key)
+ {
+ QPixmapCache::remove(key);
+ return true;
+ }
+ bool _remove(const QPixmapCache::Key& key)
+ {
+ QPixmapCache::remove(key);
+ return true;
+ }
+ bool _replace(const QPixmapCache::Key& key, const QPixmap& pixmap) { return QPixmapCache::replace(key, pixmap); }
+ bool _setCacheLimit(int n)
+ {
+ QPixmapCache::setCacheLimit(n);
+ return true;
+ }
+
+ private:
+ static PixmapCache* s_instance;
+};
diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp
index 4a9ad21b..3a2fd771 100644
--- a/launcher/minecraft/mod/ResourcePack.cpp
+++ b/launcher/minecraft/mod/ResourcePack.cpp
@@ -1,9 +1,11 @@
#include "ResourcePack.h"
+#include <QCoreApplication>
#include <QDebug>
#include <QMap>
#include <QRegularExpression>
+#include "MTPixmapCache.h"
#include "Version.h"
#include "minecraft/mod/tasks/LocalResourcePackParseTask.h"
@@ -43,16 +45,22 @@ void ResourcePack::setImage(QImage new_image)
Q_ASSERT(!new_image.isNull());
if (m_pack_image_cache_key.key.isValid())
- QPixmapCache::remove(m_pack_image_cache_key.key);
+ PixmapCache::instance().remove(m_pack_image_cache_key.key);
- m_pack_image_cache_key.key = QPixmapCache::insert(QPixmap::fromImage(new_image));
+ m_pack_image_cache_key.key = PixmapCache::instance().insert(QPixmap::fromImage(new_image));
m_pack_image_cache_key.was_ever_used = true;
+
+ // This can happen if the pixmap is too big to fit in the cache :c
+ if (!m_pack_image_cache_key.key.isValid()) {
+ qWarning() << "Could not insert a image cache entry! Ignoring it.";
+ m_pack_image_cache_key.was_ever_used = false;
+ }
}
QPixmap ResourcePack::image(QSize size)
{
QPixmap cached_image;
- if (QPixmapCache::find(m_pack_image_cache_key.key, &cached_image)) {
+ if (PixmapCache::instance().find(m_pack_image_cache_key.key, &cached_image)) {
if (size.isNull())
return cached_image;
return cached_image.scaled(size);