Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] Add BitmapRegistry #15

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open

Conversation

aednlaxer
Copy link
Collaborator

@aednlaxer aednlaxer commented Jan 24, 2025

Bitmap registry PR for internal review. Idea is simple: register bitmap with a registry then reuse it by using RegisteredBitmap as marker icon, this improves performance since bitmaps are cached on the platform side.

TODO:

  • Provide numbers on performance improvement
  • Example pages for Android and iOS
  • Check if solution works with cluster
  • Test with bigger images
  • Check how to update marker image
  • Check how it works before map is initlialized
  • Check how it works with multiple registries (Dart singleton?)
  • Tests
  • Check if iOS performance can be improved (I see no changes here)

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Copy link

@jokerttu jokerttu left a comment

Choose a reason for hiding this comment

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

Looks good, few review comments added

/// Registers a [bitmap] with the registry.
///
/// Returns a unique identifier for the registered bitmap.
Future<int> register(MapBitmap bitmap) async {
Copy link

Choose a reason for hiding this comment

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

this could return RegisteredMapBitmap object directly

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is what I was doing initially but then there was a comment to my other PR about not mixing platform and user-facing packages. I think it will be the case here too because RegisteredMapBitmap is part of platform interface while this comment is about user-facing plugin.

I see these options:

  • Use int (the way it's done now)
  • Add GoogleMapsRegisteredMapBitmap or something like that to the user-facing plugin
  • Use RegisteredMapBitmap and see what maintainers say

Copy link

@jokerttu jokerttu Feb 5, 2025

Choose a reason for hiding this comment

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

Oh, BitmapDescriptor classes are used already as icon objects etc.
I think the case was more about the internal configuration umbrella objects?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

AFAIR it was about using platform interface's MarkerType in google_maps_flutter, exposing it for end users. All other objects are exposed but I was asked not to do that because they're changing how federated plugins are doing things.

I'd rather keep it like it is now and wait for review or ask a question when main PR is created. What do you think?

Copy link

Choose a reason for hiding this comment

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

Yes, it is quite easy to change later if they want to

}

/// Unregisters a bitmap with the given [id].
Future<void> unregister(int id) {
Copy link

@jokerttu jokerttu Feb 3, 2025

Choose a reason for hiding this comment

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

should this take RegisteredMapBitmap as a parameter.

@aednlaxer
Copy link
Collaborator Author

@illuminati1911 can you please review the iOS part? Feel free to leave comments about everything else too, I'm just very unsure about the Objective-C code

@illuminati1911 illuminati1911 self-requested a review February 5, 2025 08:10
@aednlaxer
Copy link
Collaborator Author

I've added some tests. What else should be added/changed before PR can be created in the main repository @jokerttu?

@aednlaxer
Copy link
Collaborator Author

This is some results of my performance tests (will be copied to the main PR). I've done plenty of tests in different configurations but I think it's important to show that using registry in the example page makes a difference.

Performance improvements

There's a new example page called Bitmap registry to evaluate performance when adding many markers with and without the registry. It's a simple page that adds 500 markers with a bitmap. Bitmap is relatively large (800x600px, 332KB). This example shows performance drop on iOS and Android. Other examples I've tried (more markers and smaller bitmaps) don't show much improvements on iOS. Web is quite performant with or without the registry.

The data was measured using Stopwatch in updateMarkers call. First button press adds first set of markers with random positions. Consecutive calls clear existing markers and add next set of markers.

There are two buttons in the example. First button adds markers and sets their icon by sending each marker's icon to the platform layer. Second button adds bitmap to the registry and adds markers with the registered bitmap.

  1. Not using registry
  • First call ~ 11 seconds
  • Consecutive call ~ 12 seconds
  1. Using registry
  • First call ~ 0.17 second
  • Consecutive call ~ 0.61 second

I've tried this on iOS and Android multiple times with different bitmaps. The results are different depending on current platform, number of markers and bitmap configuration (size, scaling)

Copy link

@jokerttu jokerttu left a comment

Choose a reason for hiding this comment

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

I'll continue with this later... here is first foundings.

App facing package is missing intergration tests as well!

imagePixelRatio: 1.0,
);

await GoogleMapBitmapRegistry.instance.register(bitmap);
Copy link

Choose a reason for hiding this comment

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

We should extend the inspector api to have methods
bool supportsBitmapRegistry => false (overrided in platform implementations)
bool hasRegisteredMapBitmap => api call to check if there is registered bitmap...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Why do we need the first method?

I'm hitting an obstacle with these - implementation needs to have mapId to call inspectorProvider in google_map_inspector_android.dart but for bitmap registry mapId is not used. BitmapRegistry is not attached to a map, it's a singleton which part of the plugin that different map instances could use

Copy link

Choose a reason for hiding this comment

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

even when this is now supported by all platforms, it seems its recommend to have supports queries for certain calls (that are called for example in tests).
We have added similar to other features lately,
not sure if supportsBitmapRegistry is too generic, it could actually be supportsHasRegisteredMapBitmap

Copy link

Choose a reason for hiding this comment

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

I'm hitting an obstacle with these - implementation needs to have mapId to call inspectorProvider in google_map_inspector_android.dart but for bitmap registry mapId is not used. BitmapRegistry is not attached to a map, it's a singleton which part of the plugin that different map instances could use

I can check this next week, but it is always possible to create separate inspector api for bitmapregistry that does not require mapid

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've ended up pumping a map widget and getting a map ID from it for these tests. I've added just the hasRegisteredMapBitmap because I still don't see why we should have the supportsBitmapRegistry method if it's never used

Choose a reason for hiding this comment

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

You should be able to for example skip tests if supportsBitmapRegistry return false.
https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#api-support-queries

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants