Lazily create diff array, only when there is a diff.
Bug: 301261494
Test: all matcher tests
Change-Id: Ie67dcd6352e1046ac9838fae85bf8048ede1ce71
diff --git a/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/AlmostPerfectMatcher.kt b/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/AlmostPerfectMatcher.kt
index 2c96faf..588d926 100644
--- a/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/AlmostPerfectMatcher.kt
+++ b/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/AlmostPerfectMatcher.kt
@@ -42,7 +42,9 @@
var same = 0
var ignored = 0
- val diffArray = IntArray(width * height) { index ->
+ val diffArray = lazy { IntArray(width * height) { Color.TRANSPARENT } }
+
+ expected.indices.forEach { index ->
when {
!filter[index] -> Color.TRANSPARENT.also { ignored++ }
areSame(expected[index], given[index]) -> Color.TRANSPARENT.also { same++ }
@@ -59,7 +61,7 @@
.build()
if (different > (acceptableThreshold * width * height)) {
- val diff = Bitmap.createBitmap(diffArray, width, height, Bitmap.Config.ARGB_8888)
+ val diff = Bitmap.createBitmap(diffArray.value, width, height, Bitmap.Config.ARGB_8888)
return MatchResult(matches = false, diff = diff, comparisonStatistics = stats)
}
return MatchResult(matches = true, diff = null, comparisonStatistics = stats)
diff --git a/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/HumanEyeMatcher.kt b/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/HumanEyeMatcher.kt
index fd646df..c5956f7 100644
--- a/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/HumanEyeMatcher.kt
+++ b/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/HumanEyeMatcher.kt
@@ -56,15 +56,19 @@
fun isIndexSameForLargeArea(index: Int) = isSameForLargeArea(colorDiffArray[index])
if (!accountForGrouping) {
- val diffArray =
- IntArray(width * height) { index ->
- if (isIndexSameForLargeArea(index)) Color.TRANSPARENT else Color.MAGENTA
+ val diffArray = lazy { IntArray(width * height) { Color.TRANSPARENT } }
+ var different = 0
+ expected.indices.forEach { index ->
+ if (!isIndexSameForLargeArea(index)) {
+ diffArray.value[index] = Color.MAGENTA
+ different++
}
+ }
return createMatchResult(
width,
height,
- diffArray.count { diff -> diff == Color.TRANSPARENT } - ignored,
- diffArray.count { diff -> diff == Color.MAGENTA },
+ width * height - ignored - different,
+ different,
ignored,
diffArray,
)
@@ -82,42 +86,40 @@
}
}
- val diffArray =
- IntArray(colorDiffArray.size) { index ->
- // Also covers the ignored case
- if (isIndexSameForLargeArea(index)) return@IntArray Color.TRANSPARENT
+ var different = 0
+ val diffArray = lazy { IntArray(colorDiffArray.size) { Color.TRANSPARENT } }
+ colorDiffArray.indices.forEach { index ->
+ // Also covers the ignored case
+ if (isIndexSameForLargeArea(index)) return@forEach
- val x = index % width
- val y = index / width
+ val x = index % width
+ val y = index / width
- val currThreshold = getEasiestThresholdFailed(x, y)!!
- // null = ignored or out of bounds of image
- val upThreshold = if (y > 0) getEasiestThresholdFailed(x, y - 1) else null
- val downThreshold =
- if (y < height - 1) getEasiestThresholdFailed(x, y + 1) else null
- val leftThreshold = if (x > 0) getEasiestThresholdFailed(x - 1, y) else null
- val rightThreshold =
- if (x < width - 1) getEasiestThresholdFailed(x + 1, y) else null
+ val currThreshold = getEasiestThresholdFailed(x, y)!!
+ // null = ignored or out of bounds of image
+ val upThreshold = if (y > 0) getEasiestThresholdFailed(x, y - 1) else null
+ val downThreshold = if (y < height - 1) getEasiestThresholdFailed(x, y + 1) else null
+ val leftThreshold = if (x > 0) getEasiestThresholdFailed(x - 1, y) else null
+ val rightThreshold = if (x < width - 1) getEasiestThresholdFailed(x + 1, y) else null
- // Pixels with lower diff thresholds are not counted as neighbouring diffs
- var neighbouringDiffs = 4
- if (upThreshold != null && currThreshold > upThreshold) neighbouringDiffs--
- if (downThreshold != null && currThreshold > downThreshold) neighbouringDiffs--
- if (leftThreshold != null && currThreshold > leftThreshold) neighbouringDiffs--
- if (rightThreshold != null && currThreshold > rightThreshold) neighbouringDiffs--
+ // Pixels with lower diff thresholds are not counted as neighbouring diffs
+ var neighbouringDiffs = 4
+ if (upThreshold != null && currThreshold > upThreshold) neighbouringDiffs--
+ if (downThreshold != null && currThreshold > downThreshold) neighbouringDiffs--
+ if (leftThreshold != null && currThreshold > leftThreshold) neighbouringDiffs--
+ if (rightThreshold != null && currThreshold > rightThreshold) neighbouringDiffs--
- if (isSame(colorDiffArray[index], neighbouringDiffs)) {
- Color.TRANSPARENT
- } else {
- Color.MAGENTA
- }
+ if (!isSame(colorDiffArray[index], neighbouringDiffs)) {
+ diffArray.value[index] = Color.MAGENTA
+ different++
}
+ }
return createMatchResult(
width,
height,
- diffArray.count { diff -> diff == Color.TRANSPARENT } - ignored,
- diffArray.count { diff -> diff == Color.MAGENTA },
+ width * height - ignored - different,
+ different,
ignored,
diffArray,
)
@@ -197,7 +199,7 @@
samePixels: Int,
differentPixels: Int,
ignoredPixels: Int,
- diffBitmapArray: IntArray,
+ diffBitmapArray: Lazy<IntArray>,
): MatchResult {
val stats =
ScreenshotResultProto.DiffResult.ComparisonStatistics.newBuilder()
@@ -208,7 +210,8 @@
.build()
return if (differentPixels > 0) {
- val diff = Bitmap.createBitmap(diffBitmapArray, width, height, Bitmap.Config.ARGB_8888)
+ val diff =
+ Bitmap.createBitmap(diffBitmapArray.value, width, height, Bitmap.Config.ARGB_8888)
MatchResult(matches = false, diff = diff, comparisonStatistics = stats)
} else {
MatchResult(matches = true, diff = null, comparisonStatistics = stats)
diff --git a/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/PixelPerfectMatcher.kt b/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/PixelPerfectMatcher.kt
index 2eb3ef8..875716e 100644
--- a/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/PixelPerfectMatcher.kt
+++ b/libraries/screenshot/src/main/java/platform/test/screenshot/matchers/PixelPerfectMatcher.kt
@@ -41,11 +41,13 @@
var same = 0
var ignored = 0
- val diffArray = IntArray(width * height) { index ->
+ val diffArray = lazy { IntArray(width * height) { Color.TRANSPARENT } }
+
+ expected.indices.forEach { index ->
when {
- !filter[index] -> Color.TRANSPARENT.also { ignored++ }
- expected[index] == given[index] -> Color.TRANSPARENT.also { same++ }
- else -> Color.MAGENTA.also { different++ }
+ !filter[index] -> ignored++
+ expected[index] == given[index] -> same++
+ else -> diffArray.value[index] = Color.MAGENTA.also { different++ }
}
}
@@ -58,7 +60,7 @@
.build()
return if (different > 0) {
- val diff = Bitmap.createBitmap(diffArray, width, height, Bitmap.Config.ARGB_8888)
+ val diff = Bitmap.createBitmap(diffArray.value, width, height, Bitmap.Config.ARGB_8888)
MatchResult(matches = false, diff = diff, comparisonStatistics = stats)
} else {
MatchResult(matches = true, diff = null, comparisonStatistics = stats)