Skip to content

Separated PR 3117 changes that have nothing to do with graphics#3164

Open
ApoloApps wants to merge 21 commits into
JetBrains:jb-mainfrom
ApoloApps:separateCollectionsOptimizations
Open

Separated PR 3117 changes that have nothing to do with graphics#3164
ApoloApps wants to merge 21 commits into
JetBrains:jb-mainfrom
ApoloApps:separateCollectionsOptimizations

Conversation

@ApoloApps

Copy link
Copy Markdown

Separated the changes from #3117 that don't involve graphics (which are currently blocked until separation of Skiko from Compose Ui and migration to Runtime Registration) as to unblock them from merging into main
This includes changes SyntheticEventSender and more minor changes

Release Notes

N/A

…lections to avoid boxing, iterators and improve performance. (Similar change to PointerToPositionMap)
…e dirtyLayers.clear() inside the dirtyLayers.isNotEmpty() check as it does not make sense to clear if dirtyLayers is empty
ApoloApps and others added 6 commits June 26, 2026 20:20
…hod was iterating over a js value API in a kotlin loop and removing first child. This could cause freezes of up to 50 ms (observed during high-usage memory in a device). I observed a 5.8% reduction in time between main function call and Compose being composed, which amounted to around 7-8 ms (a frame, in my device). Also, the method used has been baseline since 2020 and it is the preferred way as it avoids crossing wasm to Js boundary over and over several times
…nstead Unspecified and Zero versions of it (compiles down to a simple primitive)
…init. (onPointerCallback was being created 6 times on init, delaying scene startup). It also avoid an iterator allocation on init
@ApoloApps ApoloApps marked this pull request as draft June 28, 2026 22:15
… from the buildLongSet method instead of the outer extension function, causing the Set to be empty each time
@ApoloApps ApoloApps marked this pull request as ready for review June 28, 2026 23:37
@ApoloApps

Copy link
Copy Markdown
Author

Ivan Matkov (@MatkovIvan) separated changes that have nothing to do with graphics (the other changes are blocked until #3126 is merged) to at least unblock them from merging from #3117

// modifiers as the previous event.
// Note that missing move events for this event should have already been sent
fun areSameParams(e1: PointerInputEvent, e2: PointerInputEvent): Boolean {
if (e1.pressedIds().toSet() != e2.pressedIds().toSet()) return false

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It seems it changes the logic here (remove duplicates)
Igor Demin (@igordmn) ptal

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ApoloApps, pressedIds can arrive in a different order, we need to check that.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

So do I need to readd toSet method call so that duplicates are cleared?? No pointer order has been changed, I was just trying to avoid 2 avoidable allocations (2 Sets)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Platforms most probably can't send duplicates (if some platform can, it should be filtered on the ComposeScene level, not here).

But they can send pointers in another order, this is valid. If you know a way to compare without an allocation, you can use it, but it should be simple or extracted to a simple function.

@ApoloApps ApoloApps Jul 14, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I was a bit tired and didn't get it. Set equality uses a loop with contains check which makes it so that order does not matter. List does care about order though. Got it! Refactored and added some overload to avoid intermediate Lists and instead return Set (added also some fast paths to avoid even more allocations). Done!

* This is used to avoid [Rect] object allocations on hot paths
*/
@Stable
internal inline fun IntSize.contains(offset: Offset): Boolean {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it seems semantically wrong - "contains" is not something that we can ask from size.
It might be just naming issues, but I'm not sure what fits better here

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

yep, I had the same dichotomy. encloses?? bounds??
if (size.bounds(offset)) bounds being used here as a verb
if (size.encloses(offset)) it is inferred (at least imo) that we are referring to the area between 0,0 and this Size's coordinates

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

renamed to bounds and updated KDoc. Done

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.

4 participants