Android: Make tiles 32-bit color instead of 16-bit by Sublimis · Pull Request #1654 · mapsforge/mapsforge
@Sublimis Can you post 2 screenshots with the same area to see the difference?
As this may affect memory, we better make it optional via the Parameters class.
As this may affect memory, we better make it optional via the
Parametersclass.
Even on xxxhdpi devices this amounts to just several MBs difference per entire screen. If optional, this should at least be the default. Also, keep in mind that the heap size is closely related to the screen resolution on a particular Android device.
@Sublimis Some quick tests do not reveal any significant difference?
Unless hill shading is used, where we have to try hard to see it (at least here).
If we need this, we should add a boolean switch in Parameters with default false and use it like:
public static final Config NON_TRANSPARENT_BITMAP = Parameters.ANDROID_ARGB_BITMAP ? Config.ARGB_8888 : Config.RGB_565;
| // on memory use) and allows transparencies. Use ARGB_8888 whenever | ||
| // Determines size of bitmaps used, RGB_565 is 2 bytes per pixel | ||
| // while ARGB_8888 uses 4 bytes per pixel and allows transparencies. | ||
| // Use ARGB_8888 whenever |
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sublimis Let's keep the old comments, are they are useful.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original comment is still there, just the misleading claim of "severe impact on memory use" was removed, as there's nothing severe about it. Also, there's probably no programmer in the world who doesn't know that 4x8=32 bits is 2x more than 5+6+5=16 bits.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sublimis Is the comment or the calculation wrong?
If it uses more memory, it is better to be mentioned.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sublimis If you do not like the "severe" we can remove it.
But we should still mention the difference memory use.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sublimis Is the comment or the calculation wrong?
The comment is wrong (or rather misleading or manipulative). Doubling memory usage may sound like a lot ("severe"), and it certainly can be, when comparing say 500 GB to 1 TB, but here we're talking about ~4 vs. 8 MB for an entire screen (not per tile bitmap) of a high-end device. In 2025.
If it uses more memory, it is better to be mentioned.
But to whom? That comment is only consumed by library contributors. This RGB vs. ARGB story is so old that if the contributor does not know about it or can't understand the javadoc words "Each pixel is stored on 4 bytes." and "Each pixel is stored on 2 bytes", they'd better not touch anything... :)
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In short, the memory usage comment should be placed on Parameters.ANDROID_ARGB_BITMAP field, if it is to be implemented this way, and should definitely not use the word "severe" as it sounds like there will be some serious consequences if ARGB_8888 is used.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the memory usage comment should be placed on Parameters.ANDROID_ARGB_BITMAP field, if it is to be implemented this way, and should definitely not use the word "severe" as it sounds like there will be some serious consequences if ARGB_8888 is used.
@Sublimis No problem with this. But let's have the same comment here too for easy reference.
@Sublimis Android heap size is unfortunately not the whole device memory, but much more limited, like desktop Java.
Also we do not know how users and apps fill the memory.
Mapsforge is just the map engine, there many more things happening in the apps that can fill the heap.
That's why we better not change such core default.
@Sublimis Some quick tests do not reveal any significant difference? Unless hill shading is used, where we have to try hard to see it (at least here).
Perhaps one thing needs to be clarified, which may not have been emphasized enough in the first post:
AndroidGraphicFactory.NON_TRANSPARENT_BITMAPis only used to draw tiles on the screen, and basically nowhere else.
That's why screen dpi was mentioned, as well as heap size.
It might also be worth noting that we have been using this in our app for some months now without any problems? 😄
@Sublimis What is the status here? Will you add a parameter as we discussed above?
Not sure this will ever be needed, maybe you could reconsider this? Have you done the math, and read the comment above? The reasons against 16-bit color pile up, including the constant 32<->16-bit conversions (all icons are 32-bit, as are all phone screens), to name just one. Can't think of a single additional benefit to 16-bit color, other than the (rather marginal) memory savings. Are there other benefits?
If you think the quality degradation of 16-bit is too small to justify 32-bit always, remember that it depends entirely on the render theme - the more colors it uses, the greater the degradation; the situation will not always be like in the screenshots above. Even the Glide library, a standard image loading library for Android, made ARGB_8888 a default back in 2017.
Sublimis
changed the title
Android: Make tiles use 24/32-bit color istead of 16-bit
Android: Make tiles 32-bit color instead of 16-bit
@Sublimis It's better such core changes to be optional until more tests can be made and we do not force them to all apps.
We're constantly testing, that's the point. Also, since the memory savings are marginal (the only advantage of 16-bit), where do you think the problem could even arise? There are better places in the code for memory optimizations.
It may be overambitious to call this a "core change". It's better to think of it as fixing an old workaround that’s no longer needed (a code maturity issue, if you will): If the library had been created in 2020. instead of 2010., we probably wouldn't be talking about 16-bit color now.
Once this becomes a parameter, it will be much harder to remove later. Maybe you could create a poll to see if anyone needs this parameter (almost guaranteed not)?
Also note that since Android 8.0 (API level 26), the bitmap pixel data is stored in the native heap rather than the "regular" java heap.
@Sublimis Everything can be changed later. The public API was changed recently.
Anyway let's not over analyze this so much. 🙂
Options exist so everyone can test with their apps and not force anything until we are all happy with the results.
Anyway let's not over analyze this so much. 🙂
Well you started it, our solution was a dead-simple old workaround removal 😃
That said, can you implement this the way you want? Just keep 32-bit as default please. As for nomenclature, it's better to use terms like "16-BIT_COLOR" or "32-BIT_COLOR" instead of "RGB" or "ARGB" in field names, which also makes any comments about memory usage redundant.
can you implement this the way you want?
Sure, I can prepare a pull request with default the existing library code.
Something like #1655
Looks good, but the default should be true, or if you want false as default than revert the condition and call the field ANDROID_16BIT_COLOR maybe. Also the comment on that field is highly unnecessary and only adds noise. There's really no need to explain ARGB_4444 for example, it's better to remove the comment altogether.
Besides, 16-bit color can be used only in tile bitmaps, so it's unnatural for this field or the new AndroidGraphicFactory.getNonTransparentBitmapConfig() method to try to act as general solutions for bitmaps, i.e. their names and/or comments suggest that the 16/32-bit color will be used everywhere, which is simply not true. Maybe their names should contain the word "tile"?
It is also used in the publc
createBitmap. I will update the comments.
Yes, but that public method is used only from the FrameBufferBitmapHA3.... ?? Android app using this library will certainly not use AndroidGraphicFactory.createBitmap() to create its bitmaps. That method is public/interface simply because it's being used from other package(s), not because it's expected that users of the library should use it...
It's a method that returns a bitmap config. The constants with the other configs also correctly have generic names.
Apps may use Mapsforge GraphicFactory to create easily various Mapsforge classes for Bitmap, Canvas, Paint, etc.
So how it can be used externally, we do not know, it depends on the apps.
Oh well... The only important thing here is that 32bit should be the default.
And if giving an option, use naming and wording that discourages the use of 16-bit, not the other way around.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

