From 27350cf51e3ea9a29e475f0bbb7a245220447c68 Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@hotmail.de>
Date: Wed, 29 Apr 2020 20:23:00 +0200
Subject: [PATCH] Fix high CPU usage on high dpi screens

Fixes #180
---
 src/RoomInfoListItem.cpp |  3 ++-
 src/ui/Avatar.cpp        | 37 ++++++++++++++++++++++---------------
 src/ui/Avatar.h          |  1 +
 3 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp
index 11818649b..13c7b54d4 100644
--- a/src/RoomInfoListItem.cpp
+++ b/src/RoomInfoListItem.cpp
@@ -151,7 +151,8 @@ RoomInfoListItem::paintEvent(QPaintEvent *event)
 
         auto wm = getMetrics(QFont{});
 
-        QPixmap pixmap(avatar_->size());
+        QPixmap pixmap(avatar_->size() * p.device()->devicePixelRatioF());
+        pixmap.setDevicePixelRatio(p.device()->devicePixelRatioF());
         if (isPressed_) {
                 p.fillRect(rect(), highlightedBackgroundColor_);
                 titlePen.setColor(highlightedTitleColor_);
diff --git a/src/ui/Avatar.cpp b/src/ui/Avatar.cpp
index b8703e877..cb77d1a84 100644
--- a/src/ui/Avatar.cpp
+++ b/src/ui/Avatar.cpp
@@ -71,11 +71,12 @@ Avatar::setImage(const QString &avatar_url)
         AvatarProvider::resolve(avatar_url,
                                 static_cast<int>(size_ * pixmap_.devicePixelRatio()),
                                 this,
-                                [this](QPixmap pm) {
+                                [this, requestedRatio = pixmap_.devicePixelRatio()](QPixmap pm) {
                                         if (pm.isNull())
                                                 return;
                                         type_   = ui::AvatarType::Image;
                                         pixmap_ = pm;
+                                        pixmap_.setDevicePixelRatio(requestedRatio);
                                         update();
                                 });
 }
@@ -89,15 +90,30 @@ Avatar::setImage(const QString &room, const QString &user)
                                 user,
                                 static_cast<int>(size_ * pixmap_.devicePixelRatio()),
                                 this,
-                                [this](QPixmap pm) {
+                                [this, requestedRatio = pixmap_.devicePixelRatio()](QPixmap pm) {
                                         if (pm.isNull())
                                                 return;
                                         type_   = ui::AvatarType::Image;
                                         pixmap_ = pm;
+                                        pixmap_.setDevicePixelRatio(requestedRatio);
                                         update();
                                 });
 }
 
+void
+Avatar::setDevicePixelRatio(double ratio)
+{
+        if (type_ == ui::AvatarType::Image && abs(pixmap_.devicePixelRatio() - ratio) > 0.01) {
+                pixmap_ = pixmap_.scaled(QSize(size_, size_) * ratio);
+                pixmap_.setDevicePixelRatio(ratio);
+
+                if (!avatar_url_.isEmpty())
+                        setImage(avatar_url_);
+                else
+                        setImage(room_, user_);
+        }
+}
+
 void
 Avatar::paintEvent(QPaintEvent *)
 {
@@ -106,7 +122,7 @@ Avatar::paintEvent(QPaintEvent *)
         QPainter painter(this);
         painter.setRenderHint(QPainter::Antialiasing);
 
-        QRect r      = rect();
+        QRectF r     = rect();
         const int hs = size_ / 2;
 
         if (type_ != ui::AvatarType::Image) {
@@ -116,18 +132,9 @@ Avatar::paintEvent(QPaintEvent *)
 
                 painter.setPen(Qt::NoPen);
                 painter.setBrush(brush);
-                rounded ? painter.drawEllipse(r.center(), hs, hs)
-                        : painter.drawRoundedRect(r, 3, 3);
-        } else if (painter.isActive() &&
-                   abs(pixmap_.devicePixelRatio() - painter.device()->devicePixelRatioF()) > 0.01) {
-                pixmap_ =
-                  pixmap_.scaled(QSize(size_, size_) * painter.device()->devicePixelRatioF());
-                pixmap_.setDevicePixelRatio(painter.device()->devicePixelRatioF());
-
-                if (!avatar_url_.isEmpty())
-                        setImage(avatar_url_);
-                else
-                        setImage(room_, user_);
+                rounded ? painter.drawEllipse(r) : painter.drawRoundedRect(r, 3, 3);
+        } else if (painter.isActive()) {
+                setDevicePixelRatio(painter.device()->devicePixelRatioF());
         }
 
         switch (type_) {
diff --git a/src/ui/Avatar.h b/src/ui/Avatar.h
index da8a57edd..229a980d5 100644
--- a/src/ui/Avatar.h
+++ b/src/ui/Avatar.h
@@ -21,6 +21,7 @@ public:
         void setImage(const QString &room, const QString &user);
         void setLetter(const QString &letter);
         void setTextColor(const QColor &color);
+        void setDevicePixelRatio(double ratio);
 
         QColor backgroundColor() const;
         QColor textColor() const;
-- 
GitLab