From 95a74533f12a2636caafc93f24a8058adc8d27c9 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Thu, 27 Jan 2022 10:27:14 -0500 Subject: gnu: jami: Reduce memory consumption in conversation view. This fixes . * gnu/packages/patches/jami-images-loading.patch: New patch. * gnu/packages/patches/jami-memory-usage.patch: Likewise. * gnu/local.mk (dist_patch_DATA): Register them. * gnu/packages/jami.scm (jami)[source]: Apply them. --- gnu/local.mk | 2 + gnu/packages/jami.scm | 4 +- gnu/packages/patches/jami-images-loading.patch | 152 +++++++++++++++++++++++++ gnu/packages/patches/jami-memory-usage.patch | 70 ++++++++++++ 4 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/patches/jami-images-loading.patch create mode 100644 gnu/packages/patches/jami-memory-usage.patch diff --git a/gnu/local.mk b/gnu/local.mk index 76354b5ea1..b52e7b29cb 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1299,6 +1299,8 @@ dist_patch_DATA = \ %D%/packages/patches/json-c-0.12-CVE-2020-12762.patch \ %D%/packages/patches/jsoncpp-pkg-config-version.patch \ %D%/packages/patches/jami-fix-crash-on-quit.patch \ + %D%/packages/patches/jami-images-loading.patch \ + %D%/packages/patches/jami-memory-usage.patch \ %D%/packages/patches/jamvm-1.5.1-aarch64-support.patch \ %D%/packages/patches/jamvm-1.5.1-armv7-support.patch \ %D%/packages/patches/jamvm-2.0.0-aarch64-support.patch \ diff --git a/gnu/packages/jami.scm b/gnu/packages/jami.scm index 9fcf55815b..c4300daf1b 100644 --- a/gnu/packages/jami.scm +++ b/gnu/packages/jami.scm @@ -568,7 +568,9 @@ decentralized calling using P2P-DHT.") (version %jami-version) (source (origin (inherit %jami-sources) - (patches (search-patches "jami-fix-crash-on-quit.patch")))) + (patches (search-patches "jami-fix-crash-on-quit.patch" + "jami-images-loading.patch" + "jami-memory-usage.patch")))) (build-system qt-build-system) (outputs '("out" "debug")) (arguments diff --git a/gnu/packages/patches/jami-images-loading.patch b/gnu/packages/patches/jami-images-loading.patch new file mode 100644 index 0000000000..caf9e1e198 --- /dev/null +++ b/gnu/packages/patches/jami-images-loading.patch @@ -0,0 +1,152 @@ +From be9dd0d0d8cb4556cd930edd783c0a1699565ac0 Mon Sep 17 00:00:00 2001 +From: kkostiuk +Date: Mon, 1 Nov 2021 17:39:23 -0400 +Subject: [PATCH] conversation: fix long loading time for images + +Change-Id: Id88cfbd571f4b504f258758bd13b4e4a91bf1b49 +--- + .../DataTransferMessageDelegate.qml | 52 +++++++++++++++++-- + src/messagesadapter.cpp | 20 +++++-- + src/messagesadapter.h | 2 +- + 3 files changed, 66 insertions(+), 8 deletions(-) + +diff --git a/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml b/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml +index 7875e01..2e7dcc0 100644 +--- a/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml ++++ b/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml +@@ -252,10 +252,11 @@ Loader { + Loader { + id: localMediaCompLoader + anchors.right: isOutgoing ? parent.right : undefined ++ asynchronous: true + width: sourceComponent.width + height: sourceComponent.height + sourceComponent: mediaInfo.isImage !== undefined ? +- imageComp : ++ imageComp : mediaInfo.isAnimatedImage !== undefined ? animatedImageComp : + avComp + Component { + id: avComp +@@ -302,9 +303,9 @@ Loader { + } + } + Component { +- id: imageComp ++ id: animatedImageComp + AnimatedImage { +- id: img ++ id: animatedImg + anchors.right: isOutgoing ? parent.right : undefined + property real minSize: 192 + property real maxSize: 256 +@@ -327,6 +328,51 @@ Loader { + anchors.fill: parent + } + layer.enabled: true ++ layer.effect: OpacityMask { ++ maskSource: MessageBubble { ++ out: isOutgoing ++ type: seq ++ width: animatedImg.width ++ height: animatedImg.height ++ radius: msgRadius ++ } ++ } ++ HoverHandler { ++ target : parent ++ onHoveredChanged: { ++ localMediaMsgItem.hoveredLink = hovered ? animatedImg.source : "" ++ } ++ cursorShape: Qt.PointingHandCursor ++ } ++ } ++ } ++ ++ Component { ++ id: imageComp ++ Image { ++ id: img ++ anchors.right: isOutgoing ? parent.right : undefined ++ property real minSize: 192 ++ property real maxSize: 256 ++ cache: true ++ fillMode: Image.PreserveAspectCrop ++ mipmap: true ++ antialiasing: true ++ autoTransform: false ++ asynchronous: true ++ source: "file:///" + Body ++ property real aspectRatio: implicitWidth / implicitHeight ++ property real adjustedWidth: Math.min(maxSize, ++ Math.max(minSize, ++ innerContent.width - senderMargin)) ++ width: adjustedWidth ++ height: Math.ceil(adjustedWidth / aspectRatio) ++ Rectangle { ++ color: JamiTheme.previewImageBackgroundColor ++ z: -1 ++ anchors.fill: parent ++ } ++ layer.enabled: true + layer.effect: OpacityMask { + maskSource: MessageBubble { + out: isOutgoing +diff --git a/client-qt/src/messagesadapter.cpp b/client-qt/src/messagesadapter.cpp +index 91f8eed..ba38e53 100644 +--- a/client-qt/src/messagesadapter.cpp ++++ b/client-qt/src/messagesadapter.cpp +@@ -458,13 +458,24 @@ MessagesAdapter::conversationTypersUrlToName(const QSet& typersSet) + return nameList; + } + +-bool ++QVariantMap + MessagesAdapter::isLocalImage(const QString& msg) + { + QImageReader reader; + reader.setDecideFormatFromContent(true); + reader.setFileName(msg); +- return !reader.read().isNull(); ++ QByteArray fileFormat = reader.format(); ++ if (fileFormat == "gif") { ++ return {{"isAnimatedImage", true}}; ++ } ++ QList supportedFormats = reader.supportedImageFormats(); ++ auto iterator = std::find_if(supportedFormats.begin(), ++ supportedFormats.end(), ++ [fileFormat](QByteArray format) { return format == fileFormat; }); ++ if (iterator != supportedFormats.end()) { ++ return {{"isImage", true}}; ++ } ++ return {{"isImage", false}}; + } + + QVariantMap +@@ -476,8 +487,9 @@ MessagesAdapter::getMediaInfo(const QString& msg) + "<%1 style='width:100%;height:%2;outline:none;background-color:#f1f3f4;" + "object-fit:cover;' " + "controls controlsList='nodownload' src='file://%3' type='%4'/>"; +- if (isLocalImage(msg)) { +- return {{"isImage", true}}; ++ QVariantMap fileInfo = isLocalImage(msg); ++ if (fileInfo["isImage"].toBool() || fileInfo["isAnimatedImage"].toBool()) { ++ return fileInfo; + } + QRegularExpression vPattern("[^\\s]+(.*?)\\.(avi|mov|webm|webp|rmvb)$", + QRegularExpression::CaseInsensitiveOption); +diff --git a/client-qt/src/messagesadapter.h b/client-qt/src/messagesadapter.h +index bfa4e62..1965c5e 100644 +--- a/client-qt/src/messagesadapter.h ++++ b/client-qt/src/messagesadapter.h +@@ -101,7 +101,7 @@ protected: + Q_INVOKABLE void deleteInteraction(const QString& interactionId); + Q_INVOKABLE void copyToDownloads(const QString& interactionId, const QString& displayName); + Q_INVOKABLE void userIsComposing(bool isComposing); +- Q_INVOKABLE bool isLocalImage(const QString& msg); ++ Q_INVOKABLE QVariantMap isLocalImage(const QString& msg); + Q_INVOKABLE QVariantMap getMediaInfo(const QString& msg); + Q_INVOKABLE bool isRemoteImage(const QString& msg); + Q_INVOKABLE QString getFormattedTime(const quint64 timestamp); +-- +GitLab + diff --git a/gnu/packages/patches/jami-memory-usage.patch b/gnu/packages/patches/jami-memory-usage.patch new file mode 100644 index 0000000000..75fcde8d0a --- /dev/null +++ b/gnu/packages/patches/jami-memory-usage.patch @@ -0,0 +1,70 @@ +From e796b3325d95b5ddd6162b5513c8325210f41fc5 Mon Sep 17 00:00:00 2001 +From: Sébastien Blin +Date: Wed, 26 Jan 2022 11:37:07 -0500 +Subject: [PATCH] datatransferimage: improve memory usage + ++ Reduce listview caching' size by 50% ++ use sourceSize to compress images and speedup loading ++ use autoTransform: true to rotate images when needed + +Change-Id: Idf1babdc73f43aa6a79b89428c25c5d06856c0ef +GitLab: #649 +--- + +diff --git a/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml b/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml +index d017c03..ca5913e 100644 +--- a/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml ++++ b/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml +@@ -255,9 +255,13 @@ + asynchronous: true + width: sourceComponent.width + height: sourceComponent.height +- sourceComponent: mediaInfo.isImage !== undefined ? +- imageComp : mediaInfo.isAnimatedImage !== undefined ? animatedImageComp : +- avComp ++ sourceComponent: { ++ if (mediaInfo.isImage) ++ return imageComp ++ if (mediaInfo.isAnimatedImage) ++ return animatedImageComp ++ return avComp ++ } + Component { + id: avComp + WebEngineView { +@@ -316,7 +320,7 @@ + fillMode: Image.PreserveAspectCrop + mipmap: true + antialiasing: true +- autoTransform: false ++ autoTransform: true + asynchronous: true + source: "file:///" + Body + property real aspectRatio: implicitWidth / implicitHeight +@@ -361,8 +365,10 @@ + fillMode: Image.PreserveAspectCrop + mipmap: true + antialiasing: true +- autoTransform: false ++ autoTransform: true + asynchronous: true ++ sourceSize.width: width ++ sourceSize.height: height + source: "file:///" + Body + property real aspectRatio: implicitWidth / implicitHeight + property real adjustedWidth: Math.min(maxSize, +diff --git a/client-qt/src/mainview/components/MessageListView.qml b/client-qt/src/mainview/components/MessageListView.qml +index 2b7c326..f65e67b 100644 +--- a/client-qt/src/mainview/components/MessageListView.qml ++++ b/client-qt/src/mainview/components/MessageListView.qml +@@ -174,8 +174,8 @@ + width: parent.width + // this offscreen caching is pretty huge + // displayMarginEnd may be removed +- displayMarginBeginning: 4096 +- displayMarginEnd: 4096 ++ displayMarginBeginning: 2048 ++ displayMarginEnd: 2048 + maximumFlickVelocity: 2048 + verticalLayoutDirection: ListView.BottomToTop + boundsBehavior: Flickable.StopAtBounds -- cgit v1.2.3