Re: [android-developers] Re: creating Bitmap from pixel data *without* copying the data

2012-07-09 Thread Latimerius
On Mon, Jul 9, 2012 at 4:53 PM, Nobu Games  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 android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


Re: [android-developers] Re: creating Bitmap from pixel data *without* copying the data

2012-07-09 Thread Nobu Games
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::allocateJavaPixelRefis
 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.
 
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  
> 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 android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?h

Re: [android-developers] Re: creating Bitmap from pixel data *without* copying the data

2012-07-09 Thread Romain Guy
Bitmap allocations always count towards your heap limit. Until Android 3.0,
Bitmaps were allocated on the native heap but counted against your maximum
Dalvik heap. Starting with Android 3.0, Bitmaps are allocated directly on
the native heap.


On Mon, Jul 9, 2012 at 8:26 AM, Latimerius wrote:

> On Mon, Jul 9, 2012 at 4:53 PM, Nobu Games 
> 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 android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en
>



-- 
Romain Guy
Android framework engineer
romain...@android.com

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Re: [android-developers] Re: creating Bitmap from pixel data *without* copying the data

2012-07-09 Thread Latimerius
On Mon, Jul 9, 2012 at 6:17 PM, Romain Guy  wrote:
> Bitmap allocations always count towards your heap limit. Until Android 3.0,
> Bitmaps were allocated on the native heap but counted against your maximum
> Dalvik heap. Starting with Android 3.0, Bitmaps are allocated directly on
> the native heap.

Cool, so now we now why I'm running OOM.  However, what are the best
practices handling Bitmap data that don't fit into memory twice?

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


Re: [android-developers] Re: creating Bitmap from pixel data *without* copying the data

2012-07-09 Thread Latimerius
On Mon, Jul 9, 2012 at 6:16 PM, Nobu Games  wrote:
> 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.

I tried in the meantime to fill my large Bitmap by calling setPixel()
on each of its pixels and the running time is in the order of tens
seconds.

> 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. There is no guarantee, though that direct access
> works in any case. The documentation of that function explains the limits
> pretty well.

I don't use NDK in this app, was meant to be pure Java, however as
there are other (performance) problems with bulk GL data handling that
apparently cannot be solved without native code, I might consider NDK
as well.

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


Re: [android-developers] Re: creating Bitmap from pixel data *without* copying the data

2012-07-09 Thread Romain Guy
Could you use setPixels(int[]) instead?


On Mon, Jul 9, 2012 at 9:52 AM, Latimerius wrote:

> On Mon, Jul 9, 2012 at 6:16 PM, Nobu Games 
> wrote:
> > 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.
>
> I tried in the meantime to fill my large Bitmap by calling setPixel()
> on each of its pixels and the running time is in the order of tens
> seconds.
>
> > 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. There is no guarantee, though that direct
> access
> > works in any case. The documentation of that function explains the limits
> > pretty well.
>
> I don't use NDK in this app, was meant to be pure Java, however as
> there are other (performance) problems with bulk GL data handling that
> apparently cannot be solved without native code, I might consider NDK
> as well.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en
>



-- 
Romain Guy
Android framework engineer
romain...@android.com

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Re: [android-developers] Re: creating Bitmap from pixel data *without* copying the data

2012-07-09 Thread Latimerius
On Mon, Jul 9, 2012 at 8:22 PM, Romain Guy  wrote:
> Could you use setPixels(int[]) instead?

I considered passing my int[] to setPixels() but (correct me if I'm
wrong) that wouldn't remove the problem where at some point, the
bitmap data has to exist in two copies.

However, I probably could use setPixels(int[]) and pass subimages
several times until the whole bitmap is filled.  Yes, I'll check that
out, sounds like a good idea.

Thanks!

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


Re: [android-developers] Re: creating Bitmap from pixel data *without* copying the data

2012-07-09 Thread Latimerius
On Mon, Jul 9, 2012 at 8:02 PM, RichardC  wrote:
> A quick search turns up quite a few Java PNG encoders with various license
> conditions.
>
> Encoding a PNG will not require copying the PNG again so grab one with
> source, a license you like, and if necessary modify it to write directly to
> an output stream.

Thanks, this didn't occur to me.  Just took a quick look, haven't
found anything suitable (should be free and take int[] on input) yet
but I'll try a more thorough search later.

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en