fix: use QPixmapCache only from the main thread
It's a required condition. Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
parent
7705f290ca
commit
c4c1e75de8
@ -90,6 +90,7 @@
|
||||
#include <QIcon>
|
||||
|
||||
#include "InstanceList.h"
|
||||
#include "MTPixmapCache.h"
|
||||
|
||||
#include <minecraft/auth/AccountList.h>
|
||||
#include "icons/IconList.h"
|
||||
@ -134,6 +135,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.";
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,8 @@ set(CORE_SOURCES
|
||||
# Time
|
||||
MMCTime.h
|
||||
MMCTime.cpp
|
||||
|
||||
MTPixmapCache.h
|
||||
)
|
||||
|
||||
set(PATHMATCHER_SOURCES
|
||||
|
95
launcher/MTPixmapCache.h
Normal file
95
launcher/MTPixmapCache.h
Normal file
@ -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;
|
||||
};
|
@ -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,9 +45,9 @@ 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
|
||||
@ -58,7 +60,7 @@ void ResourcePack::setImage(QImage new_image)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user