Skip to content

REPLAY-1891: Optimize bitmap processing#1576

Merged
jonathanmos merged 1 commit into
feature/base64-jmoskovichfrom
jmoskovich/replay-1891/optimize-bitmapdrawable
Aug 30, 2023
Merged

REPLAY-1891: Optimize bitmap processing#1576
jonathanmos merged 1 commit into
feature/base64-jmoskovichfrom
jmoskovich/replay-1891/optimize-bitmapdrawable

Conversation

@jonathanmos

@jonathanmos jonathanmos commented Aug 16, 2023

Copy link
Copy Markdown
Member

What does this PR do?

• Gets the bitmap from BitmapDrawable if available (use new EnrichedBitmap class to know if we should later cache it)
• Extraction of the base64 logic from the ImageButtonMapper to ImageWireframeHelper
• Gets background images if they exist (added an example to the sample app)
• Support scaletypes (atm only fitXY and center-crop)
• Move registration of bitmapPool for callbacks from DrawableUtils to Base64Serializer

Motivation

Additional improvements necessary to rollout base64 imagebutton support

What inspired you to submit this pull request?

Additional Notes

Anything else we should know when reviewing?

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Make sure you discussed the feature or bugfix with the maintaining team in an Issue
  • Make sure each commit and the PR mention the Issue number (cf the CONTRIBUTING doc)

@jonathanmos
jonathanmos changed the base branch from feature/base64-jmoskovich to jmoskovich/replay-1943/refactor-cache-singletons August 16, 2023 10:02
@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1891/optimize-bitmapdrawable branch 3 times, most recently from 4b3f6bc to bc46d0d Compare August 20, 2023 12:53
@codecov-commenter

codecov-commenter commented Aug 20, 2023

Copy link
Copy Markdown

Codecov Report

Merging #1576 (e814de7) into feature/base64-jmoskovich (69f88d0) will decrease coverage by 0.09%.
The diff coverage is 93.83%.

@@                      Coverage Diff                      @@
##           feature/base64-jmoskovich    #1576      +/-   ##
=============================================================
- Coverage                      83.38%   83.29%   -0.09%     
=============================================================
  Files                            444      446       +2     
  Lines                          15095    15181      +86     
  Branches                        2279     2288       +9     
=============================================================
+ Hits                           12586    12644      +58     
- Misses                          1910     1932      +22     
- Partials                         599      605       +6     
Files Changed Coverage Δ
...sionreplay/material/MaskInputTabWireframeMapper.kt 0.00% <ø> (ø)
...d/sessionreplay/material/MaskTabWireframeMapper.kt 100.00% <ø> (ø)
...y/internal/recorder/base64/ImageWireframeHelper.kt 90.91% <90.91%> (ø)
...play/internal/recorder/mapper/ImageButtonMapper.kt 93.33% <92.31%> (-0.28%) ⬇️
...ay/internal/recorder/mapper/BaseWireframeMapper.kt 86.76% <93.88%> (+16.18%) ⬆️
...roid/sessionreplay/internal/utils/DrawableUtils.kt 95.74% <94.44%> (-1.23%) ⬇️
...eplay/internal/recorder/base64/Base64Serializer.kt 84.52% <95.24%> (+0.02%) ⬆️
...droid/sessionreplay/material/TabWireframeMapper.kt 97.83% <100.00%> (+2.27%) ⬆️
...adog/android/sessionreplay/SessionReplayPrivacy.kt 100.00% <100.00%> (ø)
...y/internal/recorder/base64/WebPImageCompression.kt 90.00% <100.00%> (ø)
... and 2 more

... and 17 files with indirect coverage changes

@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1891/optimize-bitmapdrawable branch 2 times, most recently from ae02b0d to 48d83f7 Compare August 21, 2023 12:25
@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1943/refactor-cache-singletons branch from c7b5c2f to 0f66105 Compare August 23, 2023 09:41
@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1891/optimize-bitmapdrawable branch from 48d83f7 to 8e2d12a Compare August 23, 2023 11:25
@jonathanmos
jonathanmos marked this pull request as ready for review August 23, 2023 11:27
@jonathanmos
jonathanmos requested a review from a team as a code owner August 23, 2023 11:27

@0xnm 0xnm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! I left some comments, let me know wdyt.


import android.graphics.Bitmap

internal data class EnrichedBitmap(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this class name a bit generic. There is no enrichment here, it is just an additional flag attached to the bitmap. Maybe we can have some better name?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - I've eliminated the class and moved it to being just an additional boolean flag

view: ImageView,
drawable: Drawable,
density: Float
): Pair<Long, Long> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably need to document that first is width, last is height.

@jonathanmos jonathanmos Aug 24, 2023

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing it to DrawableDimensions

)

// Then
verify(mockDrawableUtils, times(1)).createBitmapOfApproxSizeFromDrawable(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is times(1) by default, so I guess we can omit this argument here and in similar calls

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to make it explicit that the call should happen only once. If I omit times(1) then the test will pass regardless of how many calls were made to the method (>0)

)

// Then
verify(mockBitmapPool, times(0)).put(any())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is better to use never instead of times(0) or maybe something like verifyNoInteractions even.

@LongForgery(min = 1, max = 1000)
var fakeDrawableHeight: Long = 0L

val mockDrawableXY: Pair<Long, Long> = Pair(30, 30)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictly speaking it is not a mock. maybe we can also randomize the point? knowing dimensions of the drawable.

Comment thread sample/kotlin/src/main/res/layout/fragment_image_components.xml
mariusc83
mariusc83 previously approved these changes Aug 24, 2023

@mariusc83 mariusc83 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from @0xnm comments LGTM, very nice job there.

@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1891/optimize-bitmapdrawable branch from 8e2d12a to c8741a0 Compare August 24, 2023 10:30
@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1943/refactor-cache-singletons branch from 0f66105 to be9a3a8 Compare August 24, 2023 11:23
@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1891/optimize-bitmapdrawable branch from c8741a0 to 2929fee Compare August 24, 2023 11:28
@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1943/refactor-cache-singletons branch from be9a3a8 to 5be1cc0 Compare August 24, 2023 12:03
@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1891/optimize-bitmapdrawable branch from 2929fee to 923b9e0 Compare August 24, 2023 12:16
Base automatically changed from jmoskovich/replay-1943/refactor-cache-singletons to feature/base64-jmoskovich August 24, 2023 13:08
@jonathanmos
jonathanmos dismissed mariusc83’s stale review August 24, 2023 13:08

The base branch was changed.

drawable.bitmap != null &&
!drawable.bitmap.isRecycled
) {
shouldCacheBitmap = false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this is not required as shouldCacheBitmap was initialised as falsed a few lines above.
Another option would be to do something like:

val (bitmap, shouldCache) = if (…) {
    drawable.bitmap to false
} else {
    drawableUtils.createBitmapOfApproxSizeFromDrawable(…) to true
}

}

bitmapPool?.put(bitmap)
if (shouldCacheBitmap) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add some size limit to the cachable bitmaps? E.g.: only cache bitmaps smaller than x Mb?

@jonathanmos jonathanmos Aug 28, 2023

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the cached bitmaps will be after resizing, so they would at most be around 15kbs each. The original bitmaps that aren't resized won't be cached

@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1891/optimize-bitmapdrawable branch 3 times, most recently from a6c445b to 556a0ca Compare August 29, 2023 07:18
mariusc83
mariusc83 previously approved these changes Aug 29, 2023

@mariusc83 mariusc83 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am letting this go but I strongly recommend that you refactor the way you resolve your View backgrounds in the BaseWireframeMapper

mariusc83
mariusc83 previously approved these changes Aug 30, 2023
base64Serializer?.registerAsyncLoadingCallback(asyncImageProcessingCallback)
}

private fun resolveViewBackground(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks way better now, tks for this change.

xgouchet
xgouchet previously approved these changes Aug 30, 2023
0xnm
0xnm previously approved these changes Aug 30, 2023
@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1891/optimize-bitmapdrawable branch 2 times, most recently from fb59d82 to 7753112 Compare August 30, 2023 09:46
Get Bitmap from BitmapDrawable if available
Extract base64 logic from mapper to ImageWireframeHelper
Get background images if they exist
Support scaletypes
@jonathanmos
jonathanmos dismissed stale reviews from 0xnm, mariusc83, and xgouchet via e814de7 August 30, 2023 10:11
@jonathanmos
jonathanmos force-pushed the jmoskovich/replay-1891/optimize-bitmapdrawable branch from 7753112 to e814de7 Compare August 30, 2023 10:11
@jonathanmos
jonathanmos merged commit d4c8e5b into feature/base64-jmoskovich Aug 30, 2023
@jonathanmos
jonathanmos deleted the jmoskovich/replay-1891/optimize-bitmapdrawable branch August 30, 2023 11:08
@xgouchet xgouchet added this to the 2.2.0 milestone Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants