From 97743420a0ebbc2d6073062718f7ee3a08a26390 Mon Sep 17 00:00:00 2001 From: Aaron Seigo Date: Sun, 30 Oct 2011 10:24:57 +0100 Subject: [PATCH] add a wallpaper render that takes a pre-loaded QImage. FAR FAR faster than re-loading from disk if already in memory. new API (new overload, really), but required to fix iperformance issues elsewhere, so considered a bug fix --- private/wallpaper_p.h | 18 +++++++++------- private/wallpaperrenderthread.cpp | 10 ++++++--- private/wallpaperrenderthread_p.h | 1 + wallpaper.cpp | 35 +++++++++++++++++++++++-------- wallpaper.h | 16 ++++++++++++++ 5 files changed, 60 insertions(+), 20 deletions(-) diff --git a/private/wallpaper_p.h b/private/wallpaper_p.h index 32a0fdcd4..7df8e14a5 100644 --- a/private/wallpaper_p.h +++ b/private/wallpaper_p.h @@ -46,6 +46,8 @@ public: void newRenderCompleted(const WallpaperRenderRequest &render, const QImage &image); void setupScriptSupport(); + void renderWallpaper(const QString &sourceImagePath, const QImage &image, const QSize &size, + Wallpaper::ResizeMethod resizeMethod, const QColor &color); static PackageStructure::Ptr s_packageStructure; @@ -70,16 +72,16 @@ public: class LoadImageThread : public QObject, public QRunnable { Q_OBJECT - - private: - QString m_filePath; - Q_SIGNALS: - void done(const QImage &pixmap); +public: + LoadImageThread(const QString &filePath); + void run(); - public: - LoadImageThread(const QString &filePath); - void run(); +Q_SIGNALS: + void done(const QImage &pixmap); + +private: + QString m_filePath; }; } // namespace Plasma diff --git a/private/wallpaperrenderthread.cpp b/private/wallpaperrenderthread.cpp index a5f3fdcbf..0a4e21575 100644 --- a/private/wallpaperrenderthread.cpp +++ b/private/wallpaperrenderthread.cpp @@ -115,12 +115,12 @@ void WallpaperRenderThread::run() QImage result(m_request.size, QImage::Format_ARGB32_Premultiplied); result.fill(m_request.color.rgba()); - if (m_request.file.isEmpty() || !QFile::exists(m_request.file)) { + if (m_request.file.isEmpty() && m_request.providedImage.isNull() && !QFile::exists(m_request.file)) { if (!m_abort) { emit done(m_request, result); } - kDebug() << "oh, fuck it"; + kDebug() << "wrong request or file does not exist"; deleteLater(); return; } @@ -134,7 +134,11 @@ void WallpaperRenderThread::run() // set image size QSize imgSize(1, 1); - if (scalable) { + if (!m_request.providedImage.isNull()) { + img = m_request.providedImage; + kDebug() << "going to resize the img" << img.size(); + imgSize = imgSize.expandedTo(img.size()); + } else if (scalable) { // scalable: image can be of any size imgSize = imgSize.expandedTo(m_request.size); } else { diff --git a/private/wallpaperrenderthread_p.h b/private/wallpaperrenderthread_p.h index 7a31d591d..677c0273b 100644 --- a/private/wallpaperrenderthread_p.h +++ b/private/wallpaperrenderthread_p.h @@ -42,6 +42,7 @@ public: } QWeakPointer requester; + QImage providedImage; QString file; QSize size; Wallpaper::ResizeMethod resizeMethod; diff --git a/wallpaper.cpp b/wallpaper.cpp index 8cae0d4bf..35d744f7d 100644 --- a/wallpaper.cpp +++ b/wallpaper.cpp @@ -442,6 +442,16 @@ QSizeF Wallpaper::targetSizeHint() const return d->targetSize; } +void Wallpaper::render(const QImage &image, const QSize &size, + Wallpaper::ResizeMethod resizeMethod, const QColor &color) +{ + if (image.isNull()) { + return; + } + + d->renderWallpaper(QString(), image, size, resizeMethod, color); +} + void Wallpaper::render(const QString &sourceImagePath, const QSize &size, Wallpaper::ResizeMethod resizeMethod, const QColor &color) { @@ -450,23 +460,30 @@ void Wallpaper::render(const QString &sourceImagePath, const QSize &size, return; } - resizeMethod = qBound(ScaledResize, resizeMethod, LastResizeMethod); - if (d->lastResizeMethod != resizeMethod) { - d->lastResizeMethod = resizeMethod; - emit renderHintsChanged(); + d->renderWallpaper(sourceImagePath, QImage(), size, resizeMethod, color); +} + +void WallpaperPrivate::renderWallpaper(const QString &sourceImagePath, const QImage &image, const QSize &size, + Wallpaper::ResizeMethod resizeMethod, const QColor &color) +{ + resizeMethod = qBound(Wallpaper::ScaledResize, resizeMethod, Wallpaper::LastResizeMethod); + if (lastResizeMethod != resizeMethod) { + lastResizeMethod = resizeMethod; + emit q->renderHintsChanged(); } - if (d->cacheRendering) { + if (cacheRendering) { QFileInfo info(sourceImagePath); - QString cache = d->cacheKey(sourceImagePath, size, resizeMethod, color); - if (d->findInCache(cache, info.lastModified().toTime_t())) { + QString cache = cacheKey(sourceImagePath, size, resizeMethod, color); + if (findInCache(cache, info.lastModified().toTime_t())) { return; } } WallpaperRenderRequest request; - d->renderToken = request.token; - request.requester = this; + renderToken = request.token; + request.requester = q; + request.providedImage = image; request.file = sourceImagePath; request.size = size; request.resizeMethod = resizeMethod; diff --git a/wallpaper.h b/wallpaper.h index 3bfa2b3ed..ecc08be61 100644 --- a/wallpaper.h +++ b/wallpaper.h @@ -486,6 +486,22 @@ class PLASMA_EXPORT Wallpaper : public QObject Wallpaper::ResizeMethod resizeMethod = ScaledResize, const QColor &color = QColor(0, 0, 0)); + /** + * Renders the wallpaper asyncronously with the given parameters. When the rendering is + * complete, the renderCompleted signal is emitted. + * + * @param image the raw QImage + * @param size the size to render the image as + * @param resizeMethod the method to use when resizing the image to fit size, @see + * ResizeMethod + * @param color the color to use to pad the rendered image if it doesn't take up the + * entire size with the given ResizeMethod + * @since 4.7.4 + */ + void render(const QImage &image, const QSize &size, + Wallpaper::ResizeMethod resizeMethod = ScaledResize, + const QColor &color = QColor(0, 0, 0)); + /** * Sets whether or not to cache on disk the results of calls to render. If the wallpaper * changes often or is innexpensive to render, then it's probably best not to cache them.