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 <QIcon>
|
||||||
|
|
||||||
#include "InstanceList.h"
|
#include "InstanceList.h"
|
||||||
|
#include "MTPixmapCache.h"
|
||||||
|
|
||||||
#include <minecraft/auth/AccountList.h>
|
#include <minecraft/auth/AccountList.h>
|
||||||
#include "icons/IconList.h"
|
#include "icons/IconList.h"
|
||||||
@ -134,6 +135,8 @@
|
|||||||
|
|
||||||
static const QLatin1String liveCheckFile("live.check");
|
static const QLatin1String liveCheckFile("live.check");
|
||||||
|
|
||||||
|
PixmapCache* PixmapCache::s_instance = nullptr;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
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<AccountListPage>();
|
||||||
m_globalSettingsProvider->addPage<APIPage>();
|
m_globalSettingsProvider->addPage<APIPage>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PixmapCache::setInstance(new PixmapCache(this));
|
||||||
|
|
||||||
qDebug() << "<> Settings loaded.";
|
qDebug() << "<> Settings loaded.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +89,8 @@ set(CORE_SOURCES
|
|||||||
# Time
|
# Time
|
||||||
MMCTime.h
|
MMCTime.h
|
||||||
MMCTime.cpp
|
MMCTime.cpp
|
||||||
|
|
||||||
|
MTPixmapCache.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PATHMATCHER_SOURCES
|
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 "ResourcePack.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
#include "MTPixmapCache.h"
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
|
|
||||||
#include "minecraft/mod/tasks/LocalResourcePackParseTask.h"
|
#include "minecraft/mod/tasks/LocalResourcePackParseTask.h"
|
||||||
@ -43,9 +45,9 @@ void ResourcePack::setImage(QImage new_image)
|
|||||||
Q_ASSERT(!new_image.isNull());
|
Q_ASSERT(!new_image.isNull());
|
||||||
|
|
||||||
if (m_pack_image_cache_key.key.isValid())
|
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;
|
m_pack_image_cache_key.was_ever_used = true;
|
||||||
|
|
||||||
// This can happen if the pixmap is too big to fit in the cache :c
|
// 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 ResourcePack::image(QSize size)
|
||||||
{
|
{
|
||||||
QPixmap cached_image;
|
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())
|
if (size.isNull())
|
||||||
return cached_image;
|
return cached_image;
|
||||||
return cached_image.scaled(size);
|
return cached_image.scaled(size);
|
||||||
|
Loading…
Reference in New Issue
Block a user