Improve performance for matrix inversion

This commit is contained in:
Kyant0 committed 2025-09-20 12:00:59 +08:00
1 parent 4f6a483c3c
commit 1a2e29a07e
3 files changed
+44 -15

No files matched your search

@@ -49,8 +49,8 @@ class Backdrop internal constructor(
val offset = backdropCoordinates.localPositionOf(coordinates)
val layerBlock = layerBlock
if (layerBlock != null) {
val layerScope = layerScope ?: SimpleGraphicsLayerScope().also { layerScope = it }
withTransform({
val layerScope = layerScope ?: SimpleGraphicsLayerScope().also { layerScope = it }
with(layerScope) { inverseTransform(this@drawBackdrop, layerBlock) }
translate(-offset.x, -offset.y)
}) {
@@ -204,8 +204,8 @@ private class ContentBackdropNode(
val layerBlock = layerBlock
if (layerBlock != null) {
val layerScope = layerScope ?: SimpleGraphicsLayerScope().also { layerScope = it }
withTransform({
val layerScope = layerScope ?: SimpleGraphicsLayerScope().also { layerScope = it }
with(layerScope) { inverseTransform(this@draw, layerBlock) }
}) {
drawLayer(layer)
@@ -14,6 +14,9 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.DrawTransform
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
internal class SimpleGraphicsLayerScope : GraphicsLayerScope {
@@ -53,19 +56,45 @@ internal class SimpleGraphicsLayerScope : GraphicsLayerScope {
layerBlock()
if (rotationX == 0f && rotationY == 0f && rotationZ == 0f) {
scale(1f / scaleX, 1f / scaleY, Offset.Zero)
} else {
val matrix = matrix ?: Matrix().also { matrix = it }
matrix.resetToPivotedTransform(
rotationX = rotationX,
rotationY = rotationY,
rotationZ = rotationZ,
scaleX = scaleX,
scaleY = scaleY
)
matrix.invert()
transform(matrix)
inverseTransformAtTopLeft(
rotationZ = rotationZ,
scaleX = scaleX,
scaleY = scaleY
)
}
private fun DrawTransform.inverseTransformAtTopLeft(
rotationZ: Float = 0f,
scaleX: Float = 1f,
scaleY: Float = 1f
) {
if (rotationZ == 0f) {
if (scaleX != 0f && scaleY != 0f) {
scale(1f / scaleX, 1f / scaleY, Offset.Zero)
}
return
}
val matrix = matrix ?: Matrix().also { matrix = it }
if (matrix.values.size < 16) return
val rz = rotationZ * (PI / 180.0)
val rsz = sin(rz).toFloat()
val rcz = cos(rz).toFloat()
val a00 = rcz * scaleX
val a01 = rsz * scaleY
val a10 = -rsz * scaleX
val a11 = rcz * scaleY
val det = a00 * a11 - a01 * a10
if (det == 0.0f) return
val invDet = 1.0f / det
matrix[0, 0] = a11 * invDet
matrix[0, 1] = -a01 * invDet
matrix[1, 0] = -a10 * invDet
matrix[1, 1] = a00 * invDet
transform(matrix)
}
}