Android Bitmap Object as paint buffer
Customization:
I have implemented my own (JNI read) mechanism to copy pixels from an object Bitmap
to my own memory. This is done using malloc()
uint23_t array
in its own memory and then using memcpy()
to copy the pixels to / from the built-in Bitmap pointer. This works well and has been tested. The pixels are successfully stored in their own memory from the object Bitmap
and copied back to the object Bitmap
and displayed on the screen. It's pretty fast to copy, up to the order of a few milliseconds for fairly large bitmaps. But very slow in rendering.
Intent: The
above was done to get rid of the android default heap constraint Bitmaps
(see https://stackoverflow.com/a/11103/ ... ). There will be only one Java Bitmap
object acting as a buffer between native memory and target canvas.
Save shape:
- clear Buffer bitmap.
- Draw a shape in a bitmap.
- Copy the pixels to original memory and store the memory pointer.
- Clear buffer bitmap.
Thus, any number of shapes can be stored in source memory, with no limit on the size of the heap. It works.
Later, when you need to draw a shape (say in onDraw()
):
- clear Buffer bitmap.
- Copy pixels from on-board memory to a bit buffer using the stored memory pointer.
- Draw Buffer bitmap on
canvas
. - Clear buffer bitmap.
- Repeat again for the next shape.
Problem When quickly retrieving many shapes from memory, Buffer Bitmap
sorts lags. We mainly do
clear bitmap -> load pixels from memory onto it -> draw it on view canvas
in quick succession, onDraw()
only the last pixels of the shape are drawn to the canvas internally . It looks like this:
- The internal one
canvas.drawBitmap()
is asynchronous and sometimes copies pixels from the bitmap. - Android
Bitmaps
has a hidden caching mechanism.
Has anyone encountered such problems before? Or has some idea about it?
I know it is possible in JNI to get a custom canvas lib canvas lib instance and draw it, but this is a non-standard way.
source to share
In recent versions of Android (3.0 and up, which is most devices) pixels use the usual Java heap of memory. With the introduction of hardware acceleration, bitmaps are drawn asynchronously, and there is a caching system that manages the bitmaps loaded as textures into the GPU. Therefore, the jailbreak you are trying to do may degrade performance on newer devices. If you need more memory, try using largeHeap = "true" in your manifest.
source to share
On relatively new androids (from 3.0, if I remember correctly) with hardware acceleration, the canvas.drawBitmap
method doesn't actually draw anything (and also dispatchDraw
, draw
and onDraw
). Instead, it creates an entry in the display list that:
- Caching is possible indefinitely.
- They can (and will) draw in the future, and not immediately. It's not quite asynchronous as it is now, it just gets executed later on the same thread.
These two points, I think, are the answer to your question.
Alternatively, you can turn off hardware acceleration for your view / viewport and see if your approach works.
For further reading:
http://android-developers.blogspot.de/2011/03/android-30-hardware-acceleration.html
http://developer.android.com/guide/topics/graphics/hardware-accel.html#model
source to share