feat: add vaapi path for video wallpapers on generic gpus
C++ / fmt (pull_request) Failing after 6s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 11s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Failing after 32s
Rust / build (pull_request) Successful in 52s
Python / verify (pull_request) Failing after 1m23s
Rust / fmt (pull_request) Successful in 51s
Rust / clippy (pull_request) Successful in 1m2s
C++ / fmt (pull_request) Failing after 6s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 11s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Failing after 32s
Rust / build (pull_request) Successful in 52s
Python / verify (pull_request) Failing after 1m23s
Rust / fmt (pull_request) Successful in 51s
Rust / clippy (pull_request) Successful in 1m2s
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
#include "wallpapercache.hpp"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QImageReader>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
#include <QThread>
|
||||
|
||||
namespace ZShell::wallpaper {
|
||||
|
||||
namespace {
|
||||
|
||||
QString connectionName() {
|
||||
return QStringLiteral("wallpaper-cache-%1")
|
||||
.arg(quintptr(QThread::currentThreadId()));
|
||||
}
|
||||
|
||||
QSqlDatabase openDatabase(const QString& databasePath) {
|
||||
const QString connection = connectionName();
|
||||
|
||||
QSqlDatabase database =
|
||||
QSqlDatabase::contains(connection)
|
||||
? QSqlDatabase::database(connection, false)
|
||||
: QSqlDatabase::addDatabase("QSQLITE", connection);
|
||||
|
||||
if (database.databaseName() != databasePath) {
|
||||
if (database.isOpen()) database.close();
|
||||
database.setDatabaseName(databasePath);
|
||||
}
|
||||
|
||||
if (!database.isOpen() && !database.open()) return {};
|
||||
return database;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void WallpaperCache::setDbPath(const QString& path) {
|
||||
std::lock_guard<std::mutex> lock(m_mtx);
|
||||
m_dbPath = path;
|
||||
}
|
||||
|
||||
QString WallpaperCache::dbPath() const {
|
||||
std::lock_guard<std::mutex> lock(m_mtx);
|
||||
return m_dbPath;
|
||||
}
|
||||
|
||||
QByteArray WallpaperCache::cachedBlob(const QString& path) const {
|
||||
if (path.isEmpty()) return {};
|
||||
|
||||
const QString databasePath = dbPath();
|
||||
if (databasePath.isEmpty()) return {};
|
||||
|
||||
const QFileInfo info(path);
|
||||
|
||||
QSqlDatabase database = openDatabase(databasePath);
|
||||
if (!database.isOpen()) return {};
|
||||
|
||||
QSqlQuery query(database);
|
||||
query.prepare("SELECT cache, size, mtime FROM wallpapers WHERE path = ?");
|
||||
query.addBindValue(info.absoluteFilePath());
|
||||
if (!query.exec() || !query.next()) return {};
|
||||
|
||||
const QByteArray blob = query.value(0).toByteArray();
|
||||
if (blob.isEmpty()) return {};
|
||||
|
||||
const qint64 mtime = info.lastModified().toMSecsSinceEpoch() / 1000;
|
||||
if (query.value(1).toLongLong() != info.size() ||
|
||||
query.value(2).toLongLong() != mtime) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
QImage WallpaperCache::decodeImage(
|
||||
const QString& path, const QSize& decodeSize) const {
|
||||
if (path.isEmpty()) return {};
|
||||
|
||||
QImageReader probe(path);
|
||||
const QSize source = probe.size();
|
||||
QSize required = source.isEmpty() ? decodeSize : source;
|
||||
if (!source.isEmpty() && !decodeSize.isEmpty()) {
|
||||
const QSize cover =
|
||||
source.scaled(decodeSize, Qt::KeepAspectRatioByExpanding);
|
||||
if (cover.width() <= source.width() &&
|
||||
cover.height() <= source.height())
|
||||
required = cover;
|
||||
}
|
||||
|
||||
const QByteArray blob = cachedBlob(path);
|
||||
if (!blob.isEmpty()) {
|
||||
QImage image = QImage::fromData(blob, "JPEG");
|
||||
if (!image.isNull() && image.width() >= required.width() &&
|
||||
image.height() >= required.height()) {
|
||||
return image.convertToFormat(QImage::Format_RGBA8888);
|
||||
}
|
||||
}
|
||||
|
||||
QImageReader reader(path);
|
||||
reader.setAutoTransform(true);
|
||||
|
||||
if (!decodeSize.isEmpty() && !source.isEmpty())
|
||||
reader.setScaledSize(
|
||||
source.scaled(decodeSize, Qt::KeepAspectRatioByExpanding));
|
||||
|
||||
QImage image = reader.read();
|
||||
if (image.isNull()) return {};
|
||||
|
||||
return image.convertToFormat(QImage::Format_RGBA8888);
|
||||
}
|
||||
|
||||
QByteArray WallpaperCache::posterBlob(const QString& path) const {
|
||||
if (path.isEmpty()) return {};
|
||||
|
||||
const QString databasePath = dbPath();
|
||||
if (databasePath.isEmpty()) return {};
|
||||
|
||||
const QFileInfo info(path);
|
||||
|
||||
QSqlDatabase database = openDatabase(databasePath);
|
||||
if (!database.isOpen()) return {};
|
||||
|
||||
QSqlQuery query(database);
|
||||
query.prepare("SELECT poster, size, mtime FROM wallpapers WHERE path = ?");
|
||||
query.addBindValue(info.absoluteFilePath());
|
||||
if (!query.exec() || !query.next()) return {};
|
||||
|
||||
const QByteArray blob = query.value(0).toByteArray();
|
||||
if (blob.isEmpty()) return {};
|
||||
|
||||
const qint64 mtime = info.lastModified().toMSecsSinceEpoch() / 1000;
|
||||
if (query.value(1).toLongLong() != info.size() ||
|
||||
query.value(2).toLongLong() != mtime) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
QVariantMap WallpaperCache::cropsForPath(const QString& path) const {
|
||||
if (path.isEmpty()) return {};
|
||||
|
||||
const QString databasePath = dbPath();
|
||||
if (databasePath.isEmpty()) return {};
|
||||
|
||||
const QFileInfo info(path);
|
||||
|
||||
QSqlDatabase database = openDatabase(databasePath);
|
||||
if (!database.isOpen()) return {};
|
||||
|
||||
QSqlQuery query(database);
|
||||
query.prepare("SELECT crop FROM wallpapers WHERE path = ?");
|
||||
query.addBindValue(info.absoluteFilePath());
|
||||
if (!query.exec() || !query.next()) return {};
|
||||
|
||||
const QByteArray json = query.value(0).toByteArray();
|
||||
if (json.isEmpty()) return {};
|
||||
|
||||
const auto doc = QJsonDocument::fromJson(json);
|
||||
if (!doc.isObject()) return {};
|
||||
|
||||
return doc.object().toVariantMap();
|
||||
}
|
||||
|
||||
} // namespace ZShell::wallpaper
|
||||
Reference in New Issue
Block a user