Setup:
I have implemented a native (read JNI) mechanism to copy pixels from a Bitmap object, to native memory. This is done by malloc() uint23_t array in native memory and later using memcpy() to copy pixels to/from Bitmap's native pointer. This works well and have been tested. Pixels are successfully saved in native memory from a Bitmap object, and copied back to a Bitmap object, and visible on screen. Its pretty fast in copying, up to order of several milliseconds for fairly large bitmaps. But extremely slow in rendering it.
Intention:
The above was done to break free of heap limit on default android Bitmaps (refer to https://stackoverflow.com/a/1949205/1531054). There would be only 1 Java Bitmap object acting as buffer between native memory and target canvas.
Save a shape:
So, any number of shapes can be saved to native memory, without running into heap size limits. This works.
Later when need to draw a shape (say in onDraw()):
canvas.Problem When quickly drawing many shapes from memory, The Buffer Bitmap sorts of lags. Basically we're doing
clear bitmap -> load pixels from memory onto it -> draw it on view canvas
in Quick succession inside onDraw(), only the latest shape's pixels are drawn onto canvas. It appears as if:
canvas.drawBitmap() is asynchronous and copies pixels off the bitmap later sometimes.Bitmaps have some hidden caching mechanism. Has anyone run into such trouble before ? Or has some insight regarding this ?
I know one can get native skia lib's canvas instance in JNI and draw on it, but this is a non standard way.
In recent Android versions (3.0 and on, which is the majority of devices), pixels use regular Java memory heap. With the introduction of hardware acceleration, bitmaps are drawn asynchronously, and there is a caching system that manages bitmaps loaded as textures to the GPU. Therefore the hack you are trying to do will probably degrade performance on new devices. If you need more memory, try to use largeHeap="true" in your manifest.
On relatively new Androids (from 3.0 if I recall correctly) with hardware acceleration canvas.drawBitmap method does not actually draws anything (as well as dispatchDraw, draw, and onDraw). Instead, it creates record in display list which:
Those two points, I think are the answer to your question.
Alternatively, you can disable hardware acceleration for your view/window and see if your approach is working.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With