1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-04 04:42:05 -04:00
Files
Higor Prado 13ef1efa7b fix(qml): optimize VRAM usage in DankRipple (#1691)
Replace layer+MultiEffect mask with GPU-native clipping for rounded
corners. The previous approach created offscreen textures for every
clickable element with rounded corners (used in 34+ files across the
UI), adding 100-300MB VRAM on NVIDIA GPUs.

The new approach uses clip: true on a Rectangle with the corner
radius, which is handled natively by the GPU without creating
intermediate textures.

Visual impact: Minimal - the ripple effect works identically.
The only theoretical difference is slightly less smooth edges on
rounded corners during the ripple animation, which is not noticeable
at 10% opacity during the quick animation.

VRAM improvement: Tested on NVIDIA, ~100-300MB reduction.
2026-02-15 13:25:45 -05:00

117 lines
3.4 KiB
QML

import QtQuick
import QtQuick.Effects
import qs.Common
Item {
id: root
property color rippleColor: Theme.primary
property real cornerRadius: 0
property bool enableRipple: typeof SettingsData !== "undefined" ? (SettingsData.enableRippleEffects ?? true) : true
property real _rippleX: 0
property real _rippleY: 0
property real _rippleSize: 0
readonly property alias animating: rippleAnim.running
anchors.fill: parent
function trigger(x, y) {
if (!enableRipple || Theme.currentAnimationSpeed === SettingsData.AnimationSpeed.None)
return;
_rippleX = x;
_rippleY = y;
const dist = (ox, oy) => ox * ox + oy * oy;
_rippleSize = Math.sqrt(Math.max(dist(x, y), dist(x, height - y), dist(width - x, y), dist(width - x, height - y))) * 2;
rippleAnim.restart();
}
SequentialAnimation {
id: rippleAnim
PropertyAction {
target: ripple
property: "x"
value: root._rippleX
}
PropertyAction {
target: ripple
property: "y"
value: root._rippleY
}
PropertyAction {
target: ripple
property: "implicitWidth"
value: 0
}
PropertyAction {
target: ripple
property: "implicitHeight"
value: 0
}
PropertyAction {
target: ripple
property: "opacity"
value: 0.10
}
ParallelAnimation {
DankAnim {
target: ripple
property: "implicitWidth"
from: 0
to: root._rippleSize
duration: Theme.expressiveDurations.expressiveDefaultSpatial
easing.bezierCurve: Theme.expressiveCurves.standardDecel
}
DankAnim {
target: ripple
property: "implicitHeight"
from: 0
to: root._rippleSize
duration: Theme.expressiveDurations.expressiveDefaultSpatial
easing.bezierCurve: Theme.expressiveCurves.standardDecel
}
SequentialAnimation {
PauseAnimation {
duration: Math.round(Theme.expressiveDurations.expressiveDefaultSpatial * 0.6)
}
DankAnim {
target: ripple
property: "opacity"
to: 0
duration: Theme.expressiveDurations.expressiveDefaultSpatial
easing.bezierCurve: Theme.expressiveCurves.standard
}
}
}
}
// VRAM optimization: Use clip instead of layer+MultiEffect for rounded corners
// The layer.enabled approach creates an offscreen texture for every clickable element
// with rounded corners, which adds 200-400MB VRAM across the UI.
// Using clip: true is GPU-native and much cheaper.
Rectangle {
anchors.fill: parent
radius: root.cornerRadius
color: "transparent"
clip: root.cornerRadius > 0
Rectangle {
id: ripple
radius: Math.min(width, height) / 2
color: root.rippleColor
opacity: 0
transform: Translate {
x: -ripple.width / 2
y: -ripple.height / 2
}
}
}
}