I had to work on a bitmap intensive app last year and ran into all these problems. First of all, you are right. You can allocate almost whatever native heap you want. On our test devices it was almost up to a GB for example.
No matter what Google says, by my own and obviously your observation bitmaps behave differently though. I was curious and just looked up the source code for the native pixel data allocation. It looks like a method called GraphicsJNI::allocateJavaPixelRef<http://source-android.frandroid.com/frameworks/base/core/jni/android/graphics/Graphics.cpp>is to blame for that. Allocation is not really completely done in native heap, but Java memory is being requested via the JNI method NewByteArray. As far as I know that allocated array resides on the native heap until it is released and copied back to Java. That probably only happens when you alter the pixel data from Java. Which means that the get and setPixel methods must be really slow because in worst case they can cause heavy copy operations between JVM and native code for each access. In any case, allocation of bitmaps does depend on the available Java heap space, even though that space is not necessarily claimed when your Java code does not access the raw pixel data. The only other option that comes to my mind for speeding up things would be writing some NDK code and using a PNG library for encoding the pixel data in native code. Passing that int array to that native code is straightforward. With a trick you can even access the original Java int array directly without waiting for a copy. This is possible with the JNI function GetPrimitiveArrayCritical<http://docs.oracle.com/javase/1.4.2/docs/guide/jni/jni-12.html#GetPrimitiveArrayCritical>. There is no guarantee, though that direct access works in any case. The documentation of that function explains the limits pretty well. On Monday, July 9, 2012 10:26:57 AM UTC-5, Latimerius wrote: > > On Mon, Jul 9, 2012 at 4:53 PM, Nobu Games <[email protected]> > wrote: > > Bitmap behaves like that because it allocates memory on the native heap > for > > storing its bitmap data, meaning: it cannot use your Java int array and > must > > make a copy instead. > > One thing though that puzzles me about this is, there have been > discussions indicating that the native Bitmap memory doesn't count > towards an application's heap limit (I think someone from Google > mentioned it too at last year's I/O?). However, I'm still getting > OOM, and I'm pretty sure it my app's heap limit and not the lack of > RAM in the device that I'm having trouble with (the device is HTC > Desire with pretty much nothing else running on it so there should be > plenty of RAM available to the OS). > > I wouldn't mind the copy if it didn't contribute to my app's heap size... > > > For getting around that problem you should reconsider > > what you are doing. Try to break your big (memory) problem into several > > smaller sub-problems. > > I tried to approach it like that but the ultimate goal is a .png > stored on internal/external storage. It's mainly the > encoding-into-PNG step that I don't know how to handle in a piecemeal > fashion. I'm no PNG expert but I think that in order to produce a > .png file, all image data that are supposed to go into it need to be > in-core at the same time. > > > I don't know where your pixel int array originally > > comes from, but at some point you must have it either loaded from > somewhere > > or constructed. > > It's read in from a GL ES off-screen rendering surface. > > > You could instead operate directly on an already allocated Bitmap object > and > > modify its pixel data instead of having you int array as a step in > between. > > That's the only way I see at this point to achieve the goal at all - > I'd *love* to avoid this though as we're discussing image resolutions > like 2400x1440 here - filling each of those pixels by calling > setPixel() on it is going to take forever (and that adds to the fact > that off-screen rendering in ES 1.1 doesn't seem to be fast by > itself). > > That's why I wanted an int[], so that I can do bulk blits. > > > So if you are loading your int array from a file for example, just apply > > that data directly to the Bitmap. > > As an ugly work-around, I considered taking my int[], writing it out > to a file and releasing its memory. Then use one of the > decodeBitmap() functions to turn the file into a Bitmap. Not sure > though if decodeBitmap() handles "raw" pixel data, or if it insists on > a PNG, JPEG or similar. > > Thanks for your reply! > -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

