Hello dear community!
I have faced enormous memory allocation (1GB per second) and application crash when drawing surface paths on terrain textures in my 3D GIS engine on Mali GPUs since Android 12.
Here you can find a code in methods drawShapesToTexture and drawTextureToTerrain https://github.com/WorldWindEarth/WorldWindKotlin/blob/develop/worldwind/src/commonMain/kotlin/earth/worldwind/draw/DrawableSurfaceShape.kt
This issue is available only on Mali GPU and only starting from Android 12+
Affected and tested devices are:
Galaxy Tab Active3 Mali G72 Android 13
Galaxy A53 Mali G68 Android 13
Galaxy S20 Mali G77 Android 12
Devices which works ok:
Galaxy Note 9 Mali G72 Android 10 (the same GPU as in the affected list above)
Any Adreno, PowerVR or other GPU equipped device.
It seems that new driver allocates copy of texture memory each time I bind frame buffer and use color attachment to draw lines in terrain texture. Drawing terrain textures without shapes works ok.
To reproduce an issue you can build a project using link above and run worldwind-examples application MGRSGraticuleActivity and just zoom map.
It is required only 2 seconds to overflow 2 GB of VRAM and crash the application.
Could you please assist is it a driver bug or what was conceptually changed?
Why the same code works on all other GPUs and worked already 4 years before on many devices, but now started providing OOM errors on modern Mali equipped devices?
Thanks.
Memory leak appears during drawElements call:
override fun drawTriangles(dc: DrawContext): Boolean { val bufferBound = elements?.bindBuffer(dc)?:false if (bufferBound) dc.gl.drawElements( GL_TRIANGLE_STRIP, triStripElementRange.length, GL_UNSIGNED_SHORT, triStripElementRange.lower * 2 ) return bufferBound }
I really do not understand why it leaks and how it worked before Android 12? Is it a bug in driver?
Hi,
Could you please send your APK to developer@arm.com?
Thanks,
Roberto
Thank you for quick reply.
APK was sent to specified email.
I'd guess you are modifying textures and/or buffers that are referenced by an earlier draw in the same renderpass, so the driver takes a copy to avoid draining the GPU pipeline and making an incremental render.
Even if you avoid the memory bloat, this has horrible performance on a tiler. (I don't think this is a new behavior, so I'm somewhat surprised that this ever worked, assuming this is the problem).
Current implementation may be not optimal, but what is the reason why it works on my Galaxy Note 9 Mali G72 Android 10 and worked since 2017 on most devices, but now do not work on Galaxy Tab Active3 Mali G72 (same GPU) Android 13? What was changed in driver since then?
Could you, please, assist how to make correct workaround to be compatible with the new driver changed if it is not a bug in driver.
Application is doing something unconventional its for sure. Its reusing rendertarget for subsequent renders. But original algorithm was written by NASA and rewriting it is multple man-month effort. Which is not an option for a fix within required release schedule. We specifically are looking for a workaround.Specifically we need either code path withing driver with proper barriers or a way to recaim memory.
By the way, if you look in the following code, we at first use glFramebufferTexture2d to draw lines, than release it and only then use this buffer as a texture. So I do not see any simultaneous usage of buffer for reading and writing or any other case which can cause memory leak. Looking on code it does not do anything critically wrong on our opinion.
Could you please look on it and provide any feedback how to workaround a problem to avoid memory allocation or force Mali to free memory implicitly.
github.com/.../DrawableSurfaceShape.kt
Hi, Peter Harris
Is there any workaround how to avoid memory leak on Mali Android 12+ without huge rendering code refactoring? Even if it will be performance ineffective.
This issue is very critical for our project.
Please, help.
After long investigation with the help of ARM team we found a bug in memory allocator in Mali drivers 32-38, possibly fixed in 44.
Bug in memory allocator is somehow related with AFBC compression.
Workaround which helps to solve an issue is to add additional glTexImage2d call with size 1x1 pixels before normal texture load for all render target textures, which disables AFBC compression to this texture.